feat(pwa): Admin-Tab "App" mit Install + Sync + Cache-Reset
All checks were successful
Build & Publish Docker Image / build-and-push (push) Successful in 1m20s
All checks were successful
Build & Publish Docker Image / build-and-push (push) Successful in 1m20s
Neuer vierter Admin-Tab (Smartphone-Icon) mit drei Karten: 1. Installieren — fängt beforeinstallprompt (Android), zeigt iOS-Teilen-Hinweis, sonst Info "nicht verfügbar". 2. Offline-Synchronisation — Status + "Jetzt synchronisieren"- Button, disabled wenn offline. 3. Cache — "Offline-Cache leeren" löscht alle kochwas-*-Caches via caches.keys() + delete. install-prompt.svelte.ts hält das deferred-Event und die Plattform (android/ios/other) per UA-Detection. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
44
src/lib/client/install-prompt.svelte.ts
Normal file
44
src/lib/client/install-prompt.svelte.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
// Captures the beforeinstallprompt event (Android Chrome) and holds it for
|
||||
// manual triggering by the user. On iOS Safari this event does not exist —
|
||||
// we detect the browser via UserAgent and show an info hint instead.
|
||||
class InstallPromptStore {
|
||||
available = $state(false);
|
||||
platform = $state<'android' | 'ios' | 'other'>('other');
|
||||
private deferred: BeforeInstallPromptEvent | null = null;
|
||||
|
||||
init(): void {
|
||||
if (typeof window === 'undefined') return;
|
||||
this.platform = detectPlatform();
|
||||
window.addEventListener('beforeinstallprompt', (e) => {
|
||||
e.preventDefault();
|
||||
this.deferred = e as BeforeInstallPromptEvent;
|
||||
this.available = true;
|
||||
});
|
||||
window.addEventListener('appinstalled', () => {
|
||||
this.deferred = null;
|
||||
this.available = false;
|
||||
});
|
||||
}
|
||||
|
||||
async prompt(): Promise<void> {
|
||||
if (!this.deferred) return;
|
||||
await this.deferred.prompt();
|
||||
this.deferred = null;
|
||||
this.available = false;
|
||||
}
|
||||
}
|
||||
|
||||
function detectPlatform(): 'android' | 'ios' | 'other' {
|
||||
const ua = navigator.userAgent;
|
||||
if (/iPhone|iPad|iPod/i.test(ua)) return 'ios';
|
||||
if (/Android/i.test(ua)) return 'android';
|
||||
return 'other';
|
||||
}
|
||||
|
||||
// Minimal type for the Chrome-specific event
|
||||
type BeforeInstallPromptEvent = Event & {
|
||||
prompt: () => Promise<void>;
|
||||
userChoice: Promise<{ outcome: 'accepted' | 'dismissed' }>;
|
||||
};
|
||||
|
||||
export const installPrompt = new InstallPromptStore();
|
||||
Reference in New Issue
Block a user