UNPKG

terriajs

Version:

Geospatial data visualization platform.

103 lines (91 loc) 2.96 kB
import { computed, IReactionDisposer, onBecomeObserved, onBecomeUnobserved, reaction, makeObservable } from "mobx"; import { now } from "mobx-utils"; import AbstractConstructor from "../Core/AbstractConstructor"; import Model from "../Models/Definition/Model"; import AutoRefreshingTraits from "../Traits/TraitsClasses/AutoRefreshingTraits"; import MappableMixin from "./MappableMixin"; type BaseType = Model<AutoRefreshingTraits> & MappableMixin.Instance; export default function AutoRefreshingMixin< T extends AbstractConstructor<BaseType> >(Base: T) { abstract class AutoRefreshingMixin extends Base { private autoRefreshDisposer: IReactionDisposer | undefined; private autorunRefreshEnableDisposer: IReactionDisposer | undefined; /** Return the interval in seconds to poll for updates. */ abstract get refreshInterval(): number | undefined; /** Call hook for refreshing the item */ abstract refreshData(): void; constructor(...args: any[]) { super(...args); makeObservable(this); // We should only poll when our map items have consumers onBecomeObserved(this, "mapItems", this.startAutoRefresh.bind(this)); onBecomeUnobserved(this, "mapItems", this.stopAutoRefresh.bind(this)); } private startAutoRefresh() { if (!this.autorunRefreshEnableDisposer) { // Toggle autorefresh when `refreshEnabled` trait changes this.autorunRefreshEnableDisposer = reaction( () => this.refreshEnabled, () => { if (this.refreshEnabled) { this.startAutoRefresh(); } else { this.stopAutoRefresh(); } } ); } if (!this.autoRefreshDisposer && this.refreshEnabled) { this.autoRefreshDisposer = reaction( () => this._pollingTimer, () => { if (this.show) this.refreshData(); } ); } } private stopAutoRefresh() { if (this.autorunRefreshEnableDisposer) { this.autorunRefreshEnableDisposer(); this.autorunRefreshEnableDisposer = undefined; } if (this.autoRefreshDisposer) { this.autoRefreshDisposer(); this.autoRefreshDisposer = undefined; } } @computed private get _pollingTimer(): number | undefined { if (this.refreshInterval !== undefined) { return now(this.refreshInterval * 1000); } else { return undefined; } } @computed get isPolling() { return this._pollingTimer !== undefined; } @computed get nextScheduledUpdateTime(): Date | undefined { if ( this.refreshEnabled && this._pollingTimer !== undefined && this.refreshInterval !== undefined ) { return new Date(this._pollingTimer + this.refreshInterval * 1000); } else { return undefined; } } } return AutoRefreshingMixin; }