/** * The ConnectStateManager helper class helps maintain the connection state. A disconnect goes * through multiple stages, to inform the user of long disconnects while minimizing the disruption * for short ones. This class manages these timings, and triggers ConnectState changes. */ import {Disposable, Observable} from 'grainjs'; // Describes the connection state, which is shown as part of the notifications UI. // See https://grist.quip.com/X92IAHZV3uoo/Notifications export enum ConnectState { Connected, JustDisconnected, RecentlyDisconnected, ReallyDisconnected } export class ConnectStateManager extends Disposable { // On disconnect, ConnectState changes to JustDisconnected. These intervals set how long after // the disconnect ConnectState should change to other values. public static timeToRecentlyDisconnected = 5000; public static timeToReallyDisconnected = 30000; public readonly connectState = Observable.create(this, ConnectState.Connected); private _timers: Array> = []; public setConnected(yesNo: boolean) { if (yesNo) { this._timers.forEach((t) => clearTimeout(t)); this._timers = []; this._setState(ConnectState.Connected); } else if (this.connectState.get() === ConnectState.Connected) { this._timers = [ setTimeout(() => this._setState(ConnectState.RecentlyDisconnected), ConnectStateManager.timeToRecentlyDisconnected), setTimeout(() => this._setState(ConnectState.ReallyDisconnected), ConnectStateManager.timeToReallyDisconnected), ]; this._setState(ConnectState.JustDisconnected); } } private _setState(state: ConnectState) { this.connectState.set(state); } }