diff --git a/src/services/database.service.ts b/src/services/database.service.ts index 1dd7556..abb5fe2 100755 --- a/src/services/database.service.ts +++ b/src/services/database.service.ts @@ -120,6 +120,9 @@ export class Database { // No existing workers: register a new one. this.serviceWorkerRegistration = await navigator.serviceWorker.register(path, { type: 'module' }); console.log('Service Worker registered with scope:', this.serviceWorkerRegistration.scope); + + // Show spinner during service worker initialization + this.showServiceWorkerSpinner('Initializing database service...'); } else if (registrations.length === 1) { // One existing worker: update it (restart it) without unregistering. this.serviceWorkerRegistration = registrations[0]; @@ -132,10 +135,16 @@ export class Database { console.log('All previous Service Workers unregistered.'); this.serviceWorkerRegistration = await navigator.serviceWorker.register(path, { type: 'module' }); console.log('Service Worker registered with scope:', this.serviceWorkerRegistration.scope); + + // Show spinner during service worker initialization + this.showServiceWorkerSpinner('Initializing database service...'); } await this.checkForUpdates(); + // Hide spinner once service worker is ready + this.hideServiceWorkerSpinner(); + // Set up a global message listener for responses from the service worker. navigator.serviceWorker.addEventListener('message', async (event) => { console.log('Received message from service worker:', event.data); @@ -449,6 +458,101 @@ export class Database { throw e; } } + + private showServiceWorkerSpinner(message: string = 'Initializing...') { + // Remove existing spinner if any + this.hideServiceWorkerSpinner(); + + // Create spinner overlay + const overlay = document.createElement('div'); + overlay.id = 'service-worker-spinner-overlay'; + overlay.style.cssText = ` + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(0, 0, 0, 0.8); + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + z-index: 10000; + backdrop-filter: blur(5px); + `; + + // Create spinner content + const spinnerContent = document.createElement('div'); + spinnerContent.style.cssText = ` + background: rgba(255, 255, 255, 0.95); + border-radius: 12px; + padding: 30px; + text-align: center; + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3); + border: 1px solid rgba(255, 255, 255, 0.2); + max-width: 400px; + width: 90%; + `; + + // Create spinner + const spinner = document.createElement('div'); + spinner.style.cssText = ` + width: 40px; + height: 40px; + border: 3px solid #f3f3f3; + border-top: 3px solid #3a506b; + border-radius: 50%; + animation: spin 1s linear infinite; + margin: 0 auto 15px auto; + `; + + // Create message + const messageEl = document.createElement('div'); + messageEl.textContent = message; + messageEl.style.cssText = ` + font-size: 14px; + color: #3a506b; + font-weight: 500; + margin-bottom: 10px; + `; + + // Create progress indicator + const progressEl = document.createElement('div'); + progressEl.textContent = 'Please wait...'; + progressEl.style.cssText = ` + font-size: 12px; + color: #666; + `; + + // Add CSS animation if not already present + if (!document.getElementById('service-worker-spinner-styles')) { + const style = document.createElement('style'); + style.id = 'service-worker-spinner-styles'; + style.textContent = ` + @keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } + } + `; + document.head.appendChild(style); + } + + // Assemble spinner + spinnerContent.appendChild(spinner); + spinnerContent.appendChild(messageEl); + spinnerContent.appendChild(progressEl); + overlay.appendChild(spinnerContent); + + // Add to document + document.body.appendChild(overlay); + } + + private hideServiceWorkerSpinner() { + const overlay = document.getElementById('service-worker-spinner-overlay'); + if (overlay) { + overlay.remove(); + } + } } export default Database;