terriajs
Version:
Geospatial data visualization platform.
103 lines (91 loc) • 2.96 kB
text/typescript
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;
}
}
private get _pollingTimer(): number | undefined {
if (this.refreshInterval !== undefined) {
return now(this.refreshInterval * 1000);
} else {
return undefined;
}
}
get isPolling() {
return this._pollingTimer !== undefined;
}
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;
}