import { NotificationOptions } from '../types'; export interface UiFeedbackState { progressDepth: number; progressTimer: ReturnType | 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) => 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( state: UiFeedbackState, options: UiFeedbackOptions, initialMessage: string, action: () => Promise, ): Promise { beginUpdateProgress(state, initialMessage, () => showProgressTick(state, options.showOsdNotification), ); options.setUpdateInProgress(true); try { return await action(); } finally { options.setUpdateInProgress(false); endUpdateProgress(state, clearInterval); } }