1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-12-21 09:38:01 +02:00
joplin/packages/lib/PoorManIntervals.ts

112 lines
3.0 KiB
TypeScript

// On mobile all the setTimeout and setInterval should go through this class
// as it will either use the native timeout/interval for short intervals or
// the custom one for long intervals.
// For custom intervals, they are triggered
// whenever the update() function is called, and in mobile it's called for
// example on the Redux action middleware or when the app gets focus.
import { Hour } from '@joplin/utils/time';
import time from './time';
type IntervalId = number;
interface Interval {
id: IntervalId;
// eslint-disable-next-line @typescript-eslint/ban-types -- Old code before rule was applied
callback: Function;
interval: number;
lastIntervalTime: number;
isTimeout: boolean;
}
interface Intervals {
[key: number]: Interval;
}
export default class PoorManIntervals {
// We disable the custom logic since React Native no longer emit a warning for long timer, and
// using long timers is fine as long as we are fine with it not being triggered while the app is
// in the background:
// https://github.com/facebook/react-native/issues/12981#issuecomment-652745831
private static maxNativeTimerDuration_ = 24 * Hour; // 10 * 1000;
private static lastUpdateTime_ = 0;
private static intervalId_: IntervalId = 0;
private static intervals_: Intervals = {};
// eslint-disable-next-line @typescript-eslint/ban-types -- Old code before rule was applied
public static setInterval(callback: Function, interval: number): IntervalId {
if (interval <= this.maxNativeTimerDuration_) return setInterval(callback, interval);
this.intervalId_++;
const id = this.intervalId_;
this.intervals_[id] = {
id: id,
callback: callback,
interval: interval,
lastIntervalTime: time.unixMs(),
isTimeout: false,
};
return id;
}
// eslint-disable-next-line @typescript-eslint/ban-types -- Old code before rule was applied
public static setTimeout(callback: Function, interval: number): IntervalId {
if (interval <= this.maxNativeTimerDuration_) return setTimeout(callback, interval);
this.intervalId_++;
const id = this.intervalId_;
this.intervals_[id] = {
id: id,
callback: callback,
interval: interval,
lastIntervalTime: time.unixMs(),
isTimeout: true,
};
return id;
}
public static clearInterval(id: IntervalId) {
const r = this.intervals_[id];
if (!r) {
clearInterval(id);
} else {
delete this.intervals_[id];
}
}
public static clearTimeout(id: IntervalId) {
const r = this.intervals_[id];
if (!r) {
clearTimeout(id);
} else {
delete this.intervals_[id];
}
}
public static update() {
// Don't update more than once a second
if (this.lastUpdateTime_ + 1000 > time.unixMs()) return;
for (const id in this.intervals_) {
const interval = this.intervals_[id];
const now = time.unixMs();
if (now - interval.lastIntervalTime >= interval.interval) {
interval.lastIntervalTime = now;
interval.callback();
if (interval.isTimeout) {
this.clearTimeout(interval.id);
}
}
}
this.lastUpdateTime_ = time.unixMs();
}
}