123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- export const presence = new Presence({
- clientId: "820023496934817804",
- });
- export const browsingTimestamp = Math.floor(Date.now() / 1000);
- export const slideshow = presence.createSlideshow();
- let oldSlideshowKey: string;
- /**
- * Registers a new slideshow key and clears the current slideshow on changes.
- */
- export function registerSlideshowKey(key: string): boolean {
- if (oldSlideshowKey !== key) {
- presence.info(`Slideshow key changed from ${oldSlideshowKey} to ${key}`);
- slideshow.deleteAllSlides();
- oldSlideshowKey = key;
- return true;
- }
- return false;
- }
- const iconCache: Record<string, Promise<Blob>> = {};
- /**
- * Converts an icon <i> element to a Blob.
- *
- * @param icon
- * @param backgroundColor The background color of the icon
- */
- export function getIconImage(
- icon: HTMLElement,
- backgroundColor = "#fff"
- ): Promise<Blob> {
- const canvas = document.createElement("canvas");
- canvas.width = 512;
- canvas.height = 512;
- const ctx = canvas.getContext("2d"),
- // get the icon's computed style
- { fontFamily, fontWeight, color } = getComputedStyle(icon),
- { content } = getComputedStyle(icon, ":before"),
- text = content.replace(/"/g, ""),
- key = `${fontFamily}-${fontWeight}-${backgroundColor}-${color}-${text}`;
- if (iconCache[key]) return iconCache[key];
- // render the background
- ctx.fillStyle = backgroundColor;
- ctx.fillRect(0, 0, 512, 512);
- // render the text
- ctx.font = `${fontWeight} 384px/1 ${fontFamily}`;
- ctx.fillStyle = color;
- ctx.textAlign = "center";
- ctx.textBaseline = "middle";
- ctx.fillText(text, 256, 256);
- const blobPromise: Promise<Blob> = new Promise(resolve => {
- canvas.toBlob(blob => {
- // for debugging
- const url = URL.createObjectURL(blob);
- presence.info(`${key} -> ${url}`);
- setTimeout(() => URL.revokeObjectURL(url), 15e3);
- resolve(blob);
- });
- });
- iconCache[key] = blobPromise;
- return iconCache[key];
- }
- let batchCacheKey: string,
- batchCache: unknown[] = [],
- batchInterval: number,
- batchIndex = 0,
- batchItems: unknown[] = [],
- batchAborter = new AbortController();
- /**
- * Batches a list of items and maps them to a new list of items.
- * Useful for expensive operations.
- *
- * The batch will execute every 5 seconds and will stop if the key changes.
- * If new items are added, the batch will restart.
- *
- * @param key A unique key for the batch
- * @param itemList The list of items to batch
- * @param mapper The function to map the items
- */
- export async function batch<I, O>(
- key: string,
- itemList: I[],
- mapper: (input: I) => Awaitable<O>
- ): Promise<O[]> {
- if (batchCacheKey === key) {
- // check if items changed
- if (batchItems.length !== itemList.length) {
- presence.info(
- `Batched items changed from ${batchItems.length} to ${itemList.length}`
- );
- batchAborter.abort();
- batchCache = [];
- batchIndex = 0;
- batchItems = itemList;
- if (batchInterval === null) executeBatch();
- }
- return batchCache as O[];
- }
- presence.info(`Batched key changed from ${batchCacheKey} to ${key}`);
- clearTimeout(batchInterval);
- batchAborter.abort();
- batchCacheKey = key;
- batchCache = [];
- batchItems = itemList;
- batchIndex = 0;
- async function executeBatch() {
- for (let i = batchIndex, j = 0; i < batchItems.length && j < 10; i++, j++) {
- const data = await mapper((batchItems as I[])[i]);
- if (batchAborter.signal.aborted) {
- presence.info("Batch aborted");
- batchAborter = new AbortController();
- break;
- }
- batchCache.push(data);
- batchIndex++;
- }
- presence.info(`Batched ${batchIndex} of ${batchItems.length}`);
- if (batchIndex === batchItems.length) {
- clearTimeout(batchInterval);
- batchInterval = null;
- } else if (key === batchCacheKey)
- batchInterval = setTimeout(executeBatch, 5000);
- }
- executeBatch();
- return batchCache as O[];
- }
|