Telegram Web K with changes to work inside I2P
https://web.telegram.i2p/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
88 lines
2.5 KiB
88 lines
2.5 KiB
/* |
|
* https://github.com/morethanwords/tweb |
|
* Copyright (C) 2019-2021 Eduard Kuzmenko |
|
* https://github.com/morethanwords/tweb/blob/master/LICENSE |
|
*/ |
|
|
|
import deferredPromise, {CancellablePromise} from './cancellablePromise'; |
|
import {getHeavyAnimationPromise} from '../hooks/useHeavyAnimationCheck'; |
|
import {fastRaf} from './schedulers'; |
|
import {ArgumentTypes} from '../types'; |
|
|
|
type HeavyQueue<T extends HeavyQueue<any>> = { |
|
items: ArgumentTypes<T['process']>[], |
|
process: (...args: any[]) => ReturnType<T['process']>, |
|
context: any, |
|
promise?: CancellablePromise<ReturnType<T['process']>[]> |
|
}; |
|
const heavyQueue: HeavyQueue<any>[] = []; |
|
let processingQueue = false; |
|
|
|
export default function addHeavyTask<T extends HeavyQueue<T>>(queue: T, method: 'push' | 'unshift' = 'push') { |
|
if(!queue.items.length) { |
|
return Promise.resolve([]) as typeof promise; |
|
} |
|
|
|
const promise = queue.promise = deferredPromise(); |
|
heavyQueue[method](queue); |
|
processHeavyQueue(); |
|
|
|
return promise; |
|
} |
|
|
|
function processHeavyQueue() { |
|
if(!processingQueue) { |
|
const queue = heavyQueue.shift(); |
|
timedChunk(queue).finally(() => { |
|
processingQueue = false; |
|
if(heavyQueue.length) { |
|
processHeavyQueue(); |
|
} |
|
}); |
|
} |
|
} |
|
|
|
function timedChunk<T extends HeavyQueue<T>>(queue: HeavyQueue<T>) { |
|
if(!queue.items.length) { |
|
queue.promise.resolve([] as any); |
|
return Promise.resolve([]); |
|
} |
|
|
|
const todo = queue.items.slice(); |
|
const results: ReturnType<T['process']>[] = []; |
|
|
|
return new Promise<typeof results>((resolve, reject) => { |
|
const f = async() => { |
|
const start = performance.now(); |
|
|
|
do { |
|
await getHeavyAnimationPromise(); |
|
const possiblePromise = queue.process.apply(queue.context, todo.shift()); |
|
let realResult: typeof results[0]; |
|
// @ts-ignore |
|
if(possiblePromise instanceof Promise) { |
|
try { |
|
realResult = await possiblePromise; |
|
} catch(err) { |
|
reject(err); |
|
return; |
|
} |
|
} else { |
|
realResult = possiblePromise; |
|
} |
|
|
|
results.push(realResult); |
|
} while(todo.length > 0 && (performance.now() - start) < 6); |
|
|
|
if(todo.length > 0) { |
|
fastRaf(f); |
|
// setTimeout(f, 25); |
|
} else { |
|
resolve(results); |
|
} |
|
}; |
|
|
|
fastRaf(f); |
|
// setTimeout(f, 25); |
|
}).then(queue.promise.resolve, queue.promise.reject); |
|
}
|
|
|