forked from jsnbuchanan/crowd-funder-for-time-pwa
feat: integrate PWA functionality with platform service architecture
- Add PWA methods to PlatformService interface (registerServiceWorker, isPWAEnabled) - Implement PWA logic in WebPlatformService with service worker registration - Add no-op PWA implementations for Capacitor and Electron platforms - Create PWAInstallPrompt component with custom install UI and event handling - Integrate PWA components into App.vue with platform-aware conditional rendering - Ensure PWA features only load on web platform via platform service pattern - Centralize PWA logic in platform service for consistent cross-platform behavior - Add comprehensive PWA documentation and installation flow support Platform service now handles all PWA operations including service worker registration, install prompts, and platform-specific feature detection.
This commit is contained in:
@@ -82,7 +82,7 @@ define(['./workbox-54d0af47'], (function (workbox) { 'use strict';
|
|||||||
"revision": "3ca0b8505b4bec776b69afdba2768812"
|
"revision": "3ca0b8505b4bec776b69afdba2768812"
|
||||||
}, {
|
}, {
|
||||||
"url": "index.html",
|
"url": "index.html",
|
||||||
"revision": "0.o6v2v3gkt"
|
"revision": "0.a5osc9fdkj8"
|
||||||
}], {});
|
}], {});
|
||||||
workbox.cleanupOutdatedCaches();
|
workbox.cleanupOutdatedCaches();
|
||||||
workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), {
|
workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), {
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
15
src/App.vue
15
src/App.vue
@@ -2,7 +2,7 @@
|
|||||||
<router-view />
|
<router-view />
|
||||||
|
|
||||||
<!-- PWA Install Prompt -->
|
<!-- PWA Install Prompt -->
|
||||||
<PWAInstallPrompt />
|
<PWAInstallPrompt v-if="isPWAEnabled" />
|
||||||
|
|
||||||
<!-- Messages in the upper-right - https://github.com/emmanuelsw/notiwind -->
|
<!-- Messages in the upper-right - https://github.com/emmanuelsw/notiwind -->
|
||||||
<NotificationGroup group="alert">
|
<NotificationGroup group="alert">
|
||||||
@@ -338,6 +338,7 @@ import { NotificationIface } from "./constants/app";
|
|||||||
import { PlatformServiceMixin } from "@/utils/PlatformServiceMixin";
|
import { PlatformServiceMixin } from "@/utils/PlatformServiceMixin";
|
||||||
import { logger } from "./utils/logger";
|
import { logger } from "./utils/logger";
|
||||||
import PWAInstallPrompt from "@/components/PWAInstallPrompt.vue";
|
import PWAInstallPrompt from "@/components/PWAInstallPrompt.vue";
|
||||||
|
import { PlatformServiceFactory } from "@/services/PlatformServiceFactory";
|
||||||
|
|
||||||
interface Settings {
|
interface Settings {
|
||||||
notifyingNewActivityTime?: string;
|
notifyingNewActivityTime?: string;
|
||||||
@@ -355,6 +356,18 @@ export default class App extends Vue {
|
|||||||
|
|
||||||
stopAsking = false;
|
stopAsking = false;
|
||||||
|
|
||||||
|
get isPWAEnabled() {
|
||||||
|
return PlatformServiceFactory.getInstance().isPWAEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
// Register service worker only if PWA is enabled
|
||||||
|
const platformService = PlatformServiceFactory.getInstance();
|
||||||
|
if (platformService.isPWAEnabled && platformService.registerServiceWorker) {
|
||||||
|
platformService.registerServiceWorker();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// created() {
|
// created() {
|
||||||
// logger.log(
|
// logger.log(
|
||||||
// "Component created: Reactivity set up.",
|
// "Component created: Reactivity set up.",
|
||||||
|
|||||||
@@ -59,6 +59,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Component, Vue } from "vue-facing-decorator";
|
import { Component, Vue } from "vue-facing-decorator";
|
||||||
import { logger } from "@/utils/logger";
|
import { logger } from "@/utils/logger";
|
||||||
|
import { PlatformServiceFactory } from "@/services/PlatformServiceFactory";
|
||||||
|
|
||||||
interface BeforeInstallPromptEvent extends Event {
|
interface BeforeInstallPromptEvent extends Event {
|
||||||
prompt(): Promise<void>;
|
prompt(): Promise<void>;
|
||||||
@@ -67,11 +68,13 @@ interface BeforeInstallPromptEvent extends Event {
|
|||||||
|
|
||||||
@Component({ name: "PWAInstallPrompt" })
|
@Component({ name: "PWAInstallPrompt" })
|
||||||
export default class PWAInstallPrompt extends Vue {
|
export default class PWAInstallPrompt extends Vue {
|
||||||
|
$notify!: (notification: any, timeout?: number) => void;
|
||||||
private showInstallPrompt = false;
|
private showInstallPrompt = false;
|
||||||
private deferredPrompt: BeforeInstallPromptEvent | null = null;
|
private deferredPrompt: BeforeInstallPromptEvent | null = null;
|
||||||
private dismissed = false;
|
private dismissed = false;
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
|
if (!PlatformServiceFactory.getInstance().isPWAEnabled) return;
|
||||||
this.setupInstallPrompt();
|
this.setupInstallPrompt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -154,4 +154,15 @@ export interface PlatformService {
|
|||||||
* @returns Promise resolving to the first row as an array, or undefined if no results
|
* @returns Promise resolving to the first row as an array, or undefined if no results
|
||||||
*/
|
*/
|
||||||
dbGetOneRow(sql: string, params?: unknown[]): Promise<unknown[] | undefined>;
|
dbGetOneRow(sql: string, params?: unknown[]): Promise<unknown[] | undefined>;
|
||||||
|
|
||||||
|
// --- PWA/Web-only methods (optional, only implemented on web) ---
|
||||||
|
/**
|
||||||
|
* Registers the service worker for PWA support (web only)
|
||||||
|
*/
|
||||||
|
registerServiceWorker?(): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if PWA is enabled (web only)
|
||||||
|
*/
|
||||||
|
readonly isPWAEnabled?: boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1299,4 +1299,8 @@ export class CapacitorPlatformService implements PlatformService {
|
|||||||
isWeb(): boolean {
|
isWeb(): boolean {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- PWA/Web-only methods (no-op for Capacitor) ---
|
||||||
|
public registerServiceWorker(): void {}
|
||||||
|
public get isPWAEnabled(): boolean { return false; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -163,4 +163,8 @@ export class ElectronPlatformService extends CapacitorPlatformService {
|
|||||||
isWeb(): boolean {
|
isWeb(): boolean {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- PWA/Web-only methods (no-op for Electron) ---
|
||||||
|
public registerServiceWorker(): void {}
|
||||||
|
public get isPWAEnabled(): boolean { return false; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -645,6 +645,17 @@ export class WebPlatformService implements PlatformService {
|
|||||||
throw new Error("Camera rotation not implemented in web platform");
|
throw new Error("Camera rotation not implemented in web platform");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- PWA/Web-only methods ---
|
||||||
|
public registerServiceWorker(): void {
|
||||||
|
if (this.isPWAEnabled) {
|
||||||
|
import("@/registerServiceWorker");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public get isPWAEnabled(): boolean {
|
||||||
|
return process.env.VITE_PWA_ENABLED === "true";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if running in a worker context
|
* Checks if running in a worker context
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user