105 lines
3.4 KiB
JavaScript
105 lines
3.4 KiB
JavaScript
(() => {
|
|
if (!('serviceWorker' in navigator)) return;
|
|
|
|
const toast = document.querySelector('[data-pwa-toast]');
|
|
const title = toast?.querySelector('[data-pwa-title]');
|
|
const message = toast?.querySelector('[data-pwa-message]');
|
|
const primary = toast?.querySelector('[data-pwa-primary]');
|
|
const close = toast?.querySelector('[data-pwa-close]');
|
|
let installPrompt = null;
|
|
let waitingWorker = null;
|
|
let toastMode = '';
|
|
let refreshing = false;
|
|
|
|
const showToast = (mode, heading, detail, actionLabel) => {
|
|
if (!toast || !title || !message || !primary) return;
|
|
toastMode = mode;
|
|
title.textContent = heading;
|
|
message.textContent = detail;
|
|
primary.textContent = actionLabel;
|
|
primary.hidden = !actionLabel;
|
|
toast.hidden = false;
|
|
};
|
|
|
|
const hideToast = () => {
|
|
if (toast) toast.hidden = true;
|
|
};
|
|
|
|
const installDismissedRecently = () => {
|
|
try {
|
|
const dismissedAt = Number(localStorage.getItem('pwa-install-dismissed-at'));
|
|
return dismissedAt > 0 && Date.now() - dismissedAt < 30 * 86400000;
|
|
} catch {
|
|
return false;
|
|
}
|
|
};
|
|
|
|
window.addEventListener('beforeinstallprompt', (event) => {
|
|
event.preventDefault();
|
|
installPrompt = event;
|
|
if (!installDismissedRecently()) {
|
|
window.setTimeout(() => {
|
|
if (installPrompt) showToast('install', '安装 Bi\'s Blog', '添加到桌面,像应用一样打开并阅读缓存过的文章。', '立即安装');
|
|
}, 2500);
|
|
}
|
|
});
|
|
|
|
window.addEventListener('appinstalled', () => {
|
|
installPrompt = null;
|
|
showToast('ready', '安装完成', '博客已经添加到你的设备。', '知道了');
|
|
});
|
|
|
|
primary?.addEventListener('click', async () => {
|
|
if (toastMode === 'install' && installPrompt) {
|
|
await installPrompt.prompt();
|
|
await installPrompt.userChoice;
|
|
installPrompt = null;
|
|
hideToast();
|
|
return;
|
|
}
|
|
|
|
if (toastMode === 'update' && waitingWorker) {
|
|
refreshing = true;
|
|
waitingWorker.postMessage({ type: 'SKIP_WAITING' });
|
|
return;
|
|
}
|
|
|
|
hideToast();
|
|
});
|
|
|
|
close?.addEventListener('click', () => {
|
|
if (toastMode === 'install') {
|
|
try { localStorage.setItem('pwa-install-dismissed-at', String(Date.now())); } catch {}
|
|
}
|
|
hideToast();
|
|
});
|
|
|
|
navigator.serviceWorker.addEventListener('controllerchange', () => {
|
|
if (refreshing) window.location.reload();
|
|
});
|
|
|
|
navigator.serviceWorker.register('/sw.js', { scope: '/' }).then((registration) => {
|
|
if (registration.waiting && navigator.serviceWorker.controller) {
|
|
waitingWorker = registration.waiting;
|
|
showToast('update', '发现新版本', '刷新后即可使用博客的最新内容和功能。', '立即更新');
|
|
}
|
|
|
|
registration.addEventListener('updatefound', () => {
|
|
const worker = registration.installing;
|
|
worker?.addEventListener('statechange', () => {
|
|
if (worker.state === 'installed' && navigator.serviceWorker.controller) {
|
|
waitingWorker = worker;
|
|
showToast('update', '发现新版本', '刷新后即可使用博客的最新内容和功能。', '立即更新');
|
|
}
|
|
});
|
|
});
|
|
}).catch((error) => {
|
|
console.warn('PWA registration failed:', error);
|
|
});
|
|
|
|
const params = new URLSearchParams(window.location.search);
|
|
if (params.get('action') === 'search') {
|
|
window.setTimeout(() => document.querySelector('.search-typesense-trigger')?.click(), 350);
|
|
}
|
|
})();
|