From b60f6cb18d1d55d367ae2f3c322d76b709eacdfe Mon Sep 17 00:00:00 2001 From: Vendicated Date: Fri, 25 Nov 2022 18:07:29 +0100 Subject: WhoReacted: Make more reliable & don't spam api --- src/utils/Queue.ts | 45 ++++++++++++++++++++++++++++++++++++++++++--- src/utils/misc.tsx | 5 +++++ 2 files changed, 47 insertions(+), 3 deletions(-) (limited to 'src/utils') diff --git a/src/utils/Queue.ts b/src/utils/Queue.ts index 46959a0..6153d40 100644 --- a/src/utils/Queue.ts +++ b/src/utils/Queue.ts @@ -19,9 +19,48 @@ import { Promisable } from "type-fest"; export class Queue { - private promise: Promise = Promise.resolve(); + /** + * @param maxSize The maximum amount of functions that can be queued at once. + * If the queue is full, the oldest function will be removed. + */ + constructor(public maxSize = Infinity) { } - add(func: (lastValue: unknown) => Promisable): Promise { - return (this.promise = this.promise.then(func)); + queue = [] as Array<() => Promisable>; + + private promise?: Promise; + + private next() { + const func = this.queue.shift(); + if (func) + this.promise = Promise.resolve() + .then(func) + .then(() => this.next()); + else + this.promise = undefined; + } + + private run() { + if (!this.promise) + this.next(); + } + + push(func: () => Promisable) { + if (this.size >= this.maxSize) + this.queue.shift(); + + this.queue.push(func); + this.run(); + } + + unshift(func: () => Promisable) { + if (this.size >= this.maxSize) + this.queue.pop(); + + this.queue.unshift(func); + this.run(); + } + + get size() { + return this.queue.length; } } diff --git a/src/utils/misc.tsx b/src/utils/misc.tsx index 005bcc0..44fc819 100644 --- a/src/utils/misc.tsx +++ b/src/utils/misc.tsx @@ -70,6 +70,11 @@ export function useAwaiter(factory: () => Promise, fallbackValue: T | null return [state.value, state.error, state.pending, () => setSignal(signal + 1)]; } +export function useForceUpdater() { + const [, set] = React.useState(0); + return () => set(s => s + 1); +} + /** * A lazy component. The factory method is called on first render. For example useful * for const Component = LazyComponent(() => findByDisplayName("...").default) -- cgit