51 lines
1.7 KiB
TypeScript
51 lines
1.7 KiB
TypeScript
export const BEFORE_PAGE_REFRESH = "app:before-page-refresh";
|
|
export const PAGE_DOWNLOAD_ACTIVE_ATTRIBUTE = "data-page-download-active";
|
|
export type PageRefreshRequest = {
|
|
save: (action: () => Promise<void>) => void;
|
|
block: (message: string) => void;
|
|
};
|
|
|
|
const downloadListeners = new Set<() => void>();
|
|
let activePageDownloads = 0;
|
|
|
|
export function isPageDownloadActive() {
|
|
return activePageDownloads > 0;
|
|
}
|
|
|
|
export function subscribeToPageDownloadActivity(listener: () => void) {
|
|
downloadListeners.add(listener);
|
|
return () => { downloadListeners.delete(listener); };
|
|
}
|
|
|
|
function publishDownloadActivity() {
|
|
if (typeof document !== "undefined") {
|
|
document.documentElement?.toggleAttribute(PAGE_DOWNLOAD_ACTIVE_ATTRIBUTE, isPageDownloadActive());
|
|
}
|
|
for (const listener of downloadListeners) listener();
|
|
}
|
|
|
|
export async function withActivePageDownload<T>(download: () => Promise<T>): Promise<T> {
|
|
if (++activePageDownloads === 1) publishDownloadActivity();
|
|
try {
|
|
return await download();
|
|
} finally {
|
|
if (--activePageDownloads === 0) publishDownloadActivity();
|
|
}
|
|
}
|
|
|
|
function assertPageDownloadFinished() {
|
|
if (isPageDownloadActive()) throw new Error("文件正在下载,请等下载完成后再刷新。");
|
|
}
|
|
|
|
export async function preparePageRefresh() {
|
|
assertPageDownloadFinished();
|
|
const actions: Array<() => Promise<void>> = [];
|
|
let blocked = "";
|
|
window.dispatchEvent(new CustomEvent<PageRefreshRequest>(BEFORE_PAGE_REFRESH, {
|
|
detail: { save: action => actions.push(action), block: message => { blocked ||= message; } },
|
|
}));
|
|
if (blocked) throw new Error(blocked);
|
|
for (const action of actions) await action();
|
|
assertPageDownloadFinished();
|
|
}
|