mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-02-28 06:22:45 -08:00
108 lines
2.8 KiB
TypeScript
108 lines
2.8 KiB
TypeScript
import { NotificationOptions } from "./types";
|
|
|
|
export interface UiFeedbackState {
|
|
progressDepth: number;
|
|
progressTimer: ReturnType<typeof setInterval> | null;
|
|
progressMessage: string;
|
|
progressFrame: number;
|
|
}
|
|
|
|
export interface UiFeedbackNotificationContext {
|
|
getNotificationType: () => string | undefined;
|
|
showOsd: (text: string) => void;
|
|
showSystemNotification: (
|
|
title: string,
|
|
options: NotificationOptions,
|
|
) => void;
|
|
}
|
|
|
|
export interface UiFeedbackOptions {
|
|
setUpdateInProgress: (value: boolean) => void;
|
|
showOsdNotification: (text: string) => void;
|
|
}
|
|
|
|
export function createUiFeedbackState(): UiFeedbackState {
|
|
return {
|
|
progressDepth: 0,
|
|
progressTimer: null,
|
|
progressMessage: "",
|
|
progressFrame: 0,
|
|
};
|
|
}
|
|
|
|
export function showStatusNotification(
|
|
message: string,
|
|
context: UiFeedbackNotificationContext,
|
|
): void {
|
|
const type = context.getNotificationType() || "osd";
|
|
|
|
if (type === "osd" || type === "both") {
|
|
context.showOsd(message);
|
|
}
|
|
|
|
if (type === "system" || type === "both") {
|
|
context.showSystemNotification("SubMiner", { body: message });
|
|
}
|
|
}
|
|
|
|
export function beginUpdateProgress(
|
|
state: UiFeedbackState,
|
|
initialMessage: string,
|
|
showProgressTick: (text: string) => void,
|
|
): void {
|
|
state.progressDepth += 1;
|
|
if (state.progressDepth > 1) return;
|
|
|
|
state.progressMessage = initialMessage;
|
|
state.progressFrame = 0;
|
|
showProgressTick(`${state.progressMessage}`);
|
|
state.progressTimer = setInterval(() => {
|
|
showProgressTick(`${state.progressMessage} ${["|", "/", "-", "\\"][state.progressFrame % 4]}`);
|
|
state.progressFrame += 1;
|
|
}, 180);
|
|
}
|
|
|
|
export function endUpdateProgress(
|
|
state: UiFeedbackState,
|
|
clearProgressTimer: (timer: ReturnType<typeof setInterval>) => void,
|
|
): void {
|
|
state.progressDepth = Math.max(0, state.progressDepth - 1);
|
|
if (state.progressDepth > 0) return;
|
|
|
|
if (state.progressTimer) {
|
|
clearProgressTimer(state.progressTimer);
|
|
state.progressTimer = null;
|
|
}
|
|
state.progressMessage = "";
|
|
state.progressFrame = 0;
|
|
}
|
|
|
|
export function showProgressTick(
|
|
state: UiFeedbackState,
|
|
showOsdNotification: (text: string) => void,
|
|
): void {
|
|
if (!state.progressMessage) return;
|
|
const frames = ["|", "/", "-", "\\"];
|
|
const frame = frames[state.progressFrame % frames.length];
|
|
state.progressFrame += 1;
|
|
showOsdNotification(`${state.progressMessage} ${frame}`);
|
|
}
|
|
|
|
export async function withUpdateProgress<T>(
|
|
state: UiFeedbackState,
|
|
options: UiFeedbackOptions,
|
|
initialMessage: string,
|
|
action: () => Promise<T>,
|
|
): Promise<T> {
|
|
beginUpdateProgress(state, initialMessage, (message) =>
|
|
showProgressTick(state, options.showOsdNotification),
|
|
);
|
|
options.setUpdateInProgress(true);
|
|
try {
|
|
return await action();
|
|
} finally {
|
|
options.setUpdateInProgress(false);
|
|
endUpdateProgress(state, clearInterval);
|
|
}
|
|
}
|