aboutsummaryrefslogtreecommitdiff
path: root/src/frontend/app/utils
diff options
context:
space:
mode:
authorAriel Costas Guerrero <ariel@costas.dev>2025-08-06 00:12:19 +0200
committerAriel Costas Guerrero <ariel@costas.dev>2025-08-06 00:12:19 +0200
commit5cc27f852b02446659e0ab85305916c9f5e5a5f0 (patch)
tree622636a2a7eade5442a3efb1726d822657d30295 /src/frontend/app/utils
parentb04fd7d33d07f9eddea2eb53e1389d5ca5453413 (diff)
feat: Implement pull-to-refresh functionality across various components
- Added `PullToRefresh` component to enable pull-to-refresh behavior in `StopList` and `Estimates` pages. - Integrated `usePullToRefresh` hook to manage pull-to-refresh state and actions. - Created `UpdateNotification` component to inform users of available updates from the service worker. - Enhanced service worker management with `ServiceWorkerManager` class for better update handling and caching strategies. - Updated CSS styles for new components and improved layout for better user experience. - Refactored API caching logic in service worker to handle multiple endpoints and dynamic cache expiration. - Added auto-refresh functionality for estimates data to keep information up-to-date.
Diffstat (limited to 'src/frontend/app/utils')
-rw-r--r--src/frontend/app/utils/serviceWorkerManager.ts80
1 files changed, 80 insertions, 0 deletions
diff --git a/src/frontend/app/utils/serviceWorkerManager.ts b/src/frontend/app/utils/serviceWorkerManager.ts
new file mode 100644
index 0000000..cbff748
--- /dev/null
+++ b/src/frontend/app/utils/serviceWorkerManager.ts
@@ -0,0 +1,80 @@
+export class ServiceWorkerManager {
+ private registration: ServiceWorkerRegistration | null = null;
+ private updateAvailable = false;
+ private onUpdateCallback?: () => void;
+
+ async initialize() {
+ if (!("serviceWorker" in navigator)) {
+ console.log("Service Workers not supported");
+ return;
+ }
+
+ try {
+ this.registration = await navigator.serviceWorker.register("/sw.js");
+ console.log("Service Worker registered with scope:", this.registration.scope);
+
+ // Listen for updates
+ this.registration.addEventListener("updatefound", () => {
+ const newWorker = this.registration!.installing;
+ if (newWorker) {
+ newWorker.addEventListener("statechange", () => {
+ if (newWorker.state === "installed" && navigator.serviceWorker.controller) {
+ // New service worker is installed and ready
+ this.updateAvailable = true;
+ this.onUpdateCallback?.();
+ }
+ });
+ }
+ });
+
+ // Listen for messages from the service worker
+ navigator.serviceWorker.addEventListener("message", (event) => {
+ if (event.data.type === "SW_UPDATED") {
+ this.updateAvailable = true;
+ this.onUpdateCallback?.();
+ }
+ });
+
+ // Check for updates periodically
+ setInterval(() => {
+ this.checkForUpdates();
+ }, 60 * 1000); // Check every minute
+
+ } catch (error) {
+ console.error("Service Worker registration failed:", error);
+ }
+ }
+
+ async checkForUpdates() {
+ if (this.registration) {
+ try {
+ await this.registration.update();
+ } catch (error) {
+ console.error("Failed to check for updates:", error);
+ }
+ }
+ }
+
+ activateUpdate() {
+ if (this.registration && this.registration.waiting) {
+ this.registration.waiting.postMessage({ type: "SKIP_WAITING" });
+ this.updateAvailable = false;
+ }
+ }
+
+ onUpdate(callback: () => void) {
+ this.onUpdateCallback = callback;
+ }
+
+ isUpdateAvailable() {
+ return this.updateAvailable;
+ }
+
+ async clearCache() {
+ if (this.registration && this.registration.active) {
+ this.registration.active.postMessage({ type: "CLEAR_CACHE" });
+ }
+ }
+}
+
+export const swManager = new ServiceWorkerManager();