import {NylasSyncStatusStore, React, Actions} from 'nylas-exports'; import {Notification} from 'nylas-component-kit'; const DISCONNECT_DEBOUNCE_INTERVAL = 15000; const CHECK_STATUS_INTERVAL = 3000 export default class OfflineNotification extends React.Component { static displayName = 'OfflineNotification'; constructor() { super(); this._updateInterval = null; this._setOfflineTimeout = null; this._setRetryingTimeout = null; this.state = this.getStateFromStores(); } componentDidMount() { this.unlisten = NylasSyncStatusStore.listen(this.onConnectedStatusChanged); window.addEventListener('browser-window-focus', this.onWindowFocusChanged); window.addEventListener('browser-window-blur', this.onWindowFocusChanged); this.ensureCountdownInterval(); } componentDidUpdate() { this.ensureCountdownInterval(); } componentWillUnmount() { this.unlisten(); window.removeEventListener('browser-window-focus', this.onWindowFocusChanged); window.removeEventListener('browser-window-blur', this.onWindowFocusChanged); } onConnectedStatusChanged = () => { const nextState = this.getStateFromStores(); if (this.state.connected) { if (!nextState.connected && !this._setOfflineTimeout) { this._setOfflineTimeout = setTimeout(this._didBecomeDisconnected, DISCONNECT_DEBOUNCE_INTERVAL); } return; } if (nextState.connected) { this._didBecomeConnected(); } } onTryAgain = () => { clearTimeout(this._setRetryingTimeout) this.setState({retrying: true}) this._setRetryingTimeout = setTimeout(() => this.setState({retrying: false}), 2000) Actions.retryDeltaConnection(); } onWindowFocusChanged = () => { const nextState = this.getStateFromStores(); // If we notice we've reconnected we want to immediately remove the notification. if (nextState.connected && !this.state.connected) { this._didBecomeConnected(); return; } this.ensureCountdownInterval(); } getStateFromStores() { return {connected: NylasSyncStatusStore.connected()}; } _clearOfflineTimeout = () => { if (this._setOfflineTimeout) { clearTimeout(this._setOfflineTimeout); this._setOfflineTimeout = null; } } _clearUpdateInterval = () => { if (this._updateInterval) { clearInterval(this._updateInterval); this._updateInterval = null; } } _didBecomeConnected = () => { this._clearOfflineTimeout(); this._clearUpdateInterval(); this.setState({connected: true}); } _didBecomeDisconnected = () => { this._clearOfflineTimeout(); // We will call ensureCountdownInterval() in componentDidUpdate when this // setState is complete. this.setState({connected: false}); } ensureCountdownInterval = () => { this._clearUpdateInterval(); // only attempt to retry if the window is in the foreground to avoid // the battery hit. if (!this.state.connected && !document.body.classList.contains('is-blurred')) { this._updateInterval = setInterval(() => { Actions.retryDeltaConnection(); }, CHECK_STATUS_INTERVAL); } } render() { const {connected, retrying} = this.state; if (connected) { return ; } const tryLabel = retrying ? 'Retrying...' : 'Try now'; return ( ) } }