GenerAI / worldmonitor /src /components /map /input-delay-interactions.ts
amogaddy's picture
Integra World Monitor (AGPL-3.0, self-hosted) nello Space: pagina, menu, e arricchimento notizie per la AI (part 7)
9d2d895 verified
Raw
History Blame Contribute Delete
1.73 kB
export interface CountryIdentity {
code: string;
name: string;
}
export interface CountryHoverCache {
code: string | null;
name: string | null;
}
export type CancelableFrameTask = (() => void) & { cancel(): void };
export interface CountryHoverQueryController<TPoint> {
queue(point: TPoint): void;
cancel(): void;
isPending(): boolean;
}
export function shouldRunInputSensitiveMapWork(isInputPending: () => boolean): boolean {
return !isInputPending();
}
export function shouldRenderTradeAnimationFrame(frameCount: number, isInputPending: () => boolean): boolean {
return frameCount % 2 === 0 && shouldRunInputSensitiveMapWork(isInputPending);
}
export function resolveCountryForPointerInteraction(
hover: CountryHoverCache,
hoverQueryPending: boolean,
resolveFromCoordinate: () => CountryIdentity | null,
): CountryIdentity | null {
if (!hoverQueryPending && hover.code && hover.name) {
return { code: hover.code, name: hover.name };
}
return resolveFromCoordinate();
}
export function createCountryHoverQueryController<TPoint>(
scheduleFrame: (run: () => void) => CancelableFrameTask,
runQuery: (point: TPoint) => void,
): CountryHoverQueryController<TPoint> {
let pendingPoint: TPoint | null = null;
let pending = false;
const frameTask = scheduleFrame(() => {
const point = pendingPoint;
pendingPoint = null;
pending = false;
if (point !== null) runQuery(point);
});
return {
queue(point: TPoint): void {
pendingPoint = point;
pending = true;
frameTask();
},
cancel(): void {
pendingPoint = null;
pending = false;
frameTask.cancel();
},
isPending(): boolean {
return pending;
},
};
}