The attodo.app, uhh... app.

notification stuff

+598 -13
+55 -5
docs/features.md
··· 270 270 Get notified even when AT Todo isn't open. 271 271 272 272 **Enabling Push Notifications:** 273 - 1. Open Settings 274 - 2. Click "Enable Push Notifications" 275 - 3. Grant permission when prompted 276 - 4. Configure your preferences 273 + 274 + 1. **Open Settings**: 275 + - Click the "Settings" link in the top navigation bar 276 + - A settings dialog (modal) will open 277 + 278 + 2. **Find Notification Settings**: 279 + - In the Settings dialog, scroll to "Notification Settings" 280 + - You'll see your current notification status 281 + 282 + 3. **Enable Notifications**: 283 + - Click "Enable Push Notifications" button 284 + - Your browser will ask for permission - click "Allow" 285 + - The page will automatically subscribe this device 286 + 287 + 4. **Configure Your Preferences**: 288 + - Once enabled, notification preferences will appear 289 + - Customize timing, frequency, and quiet hours 290 + - Click "Save Preferences" 277 291 278 292 **Notification Settings:** 279 293 ··· 338 352 - **Privacy-first**: All tracking stored in your AT Protocol repository 339 353 - **Automatic**: No configuration needed 340 354 355 + ### Multi-Device Notifications 356 + 357 + AT Todo supports receiving notifications on multiple devices (phone, tablet, desktop, etc.). 358 + 359 + **Registering Multiple Devices:** 360 + 361 + Each device needs to be registered separately to receive notifications: 362 + 363 + 1. **On Each Device**: 364 + - Open AT Todo in your browser 365 + - Click the "Settings" link in the top navigation 366 + - Scroll to "Notification Settings" in the settings dialog 367 + - Click "Enable Push Notifications" (or "Register This Device" if already enabled) 368 + - Grant browser permission when prompted 369 + 370 + 2. **Verify Registration**: 371 + - In Settings, look for "Registered Devices" section 372 + - You should see a list of all your registered devices 373 + - Each device shows its browser/OS and registration date 374 + - Example: "Device 1: Mozilla/5.0 (Macintosh; Intel Mac OS...) (added 11/22/2024)" 375 + 376 + 3. **Managing Devices**: 377 + - Click the X button next to any device to remove it from notifications 378 + - Devices can be re-registered at any time by clicking "Register This Device" 379 + - Remove old/unused devices to keep your device list clean 380 + - Inactive subscriptions expire automatically over time 381 + 382 + **How It Works:** 383 + - Each browser/device gets a unique push subscription 384 + - Notifications are sent to **all registered devices simultaneously** 385 + - You'll receive notifications on your phone, tablet, and desktop 386 + - Completing a task on one device doesn't clear notifications on others 387 + 341 388 ### Test Notifications 342 389 343 390 **Test your notification setup:** 344 391 1. Open Settings 345 392 2. Enable notifications if not already enabled 346 393 3. Click "Send Test Notification" 347 - 4. You should see a test notification appear 394 + 4. You should see a test notification on **all registered devices** 395 + 5. Check the response message to see how many devices received it 348 396 349 397 **If notifications aren't working:** 350 398 - Check browser notification permissions 351 399 - Ensure notifications aren't blocked in system settings 352 400 - Try a different browser (Chrome/Edge have best support) 353 401 - Check quiet hours settings 402 + - Click "Register This Device" to refresh registration 403 + - Verify device appears in "Registered Devices" list 354 404 355 405 ### Browser Compatibility 356 406
+416
docs/notifications.md
··· 1 + # Notification Setup Guide 2 + 3 + Complete guide to setting up and managing push notifications in AT Todo. 4 + 5 + ## Table of Contents 6 + 7 + - [Getting Started](#getting-started) 8 + - [Multi-Device Setup](#multi-device-setup) 9 + - [Notification Settings](#notification-settings) 10 + - [Troubleshooting](#troubleshooting) 11 + 12 + --- 13 + 14 + ## Getting Started 15 + 16 + ### Enabling Push Notifications 17 + 18 + Push notifications allow you to receive alerts about due tasks even when AT Todo isn't open. 19 + 20 + **Step 1: Access Settings** 21 + 22 + 1. Click the "Settings" link in the navigation bar 23 + 2. A settings dialog (modal) will open 24 + 25 + **Step 2: Enable Notifications** 26 + 27 + 1. In the Settings dialog, scroll down to "Notification Settings" 28 + 2. You'll see your current notification status (e.g., "Not enabled") 29 + 3. Click the "Enable Push Notifications" button 30 + 4. Your browser will prompt for permission - click "Allow" 31 + 32 + **Step 3: Configure Preferences** 33 + 34 + Once enabled, you'll see notification preferences: 35 + 36 + - **Timing**: Choose which types of tasks trigger notifications 37 + - Overdue tasks (default: on) 38 + - Tasks due today (default: on) 39 + - Tasks due within 3 days (default: off) 40 + 41 + - **Check Frequency**: How often to check for new notifications 42 + - Every 15 minutes 43 + - Every 30 minutes (default) 44 + - Every hour 45 + - Every 2 hours 46 + 47 + - **Quiet Hours**: Set Do Not Disturb times 48 + - Enable/disable quiet hours 49 + - Start time (default: 10 PM) 50 + - End time (default: 8 AM) 51 + 52 + **Step 4: Test Your Setup** 53 + 54 + 1. Click "Send Test Notification" button 55 + 2. You should see a test notification appear 56 + 3. If successful, you'll see a confirmation toast 57 + 58 + --- 59 + 60 + ## Multi-Device Setup 61 + 62 + AT Todo supports notifications on multiple devices - your phone, tablet, desktop, etc. 63 + 64 + ### How Multi-Device Works 65 + 66 + - Each browser/device needs to register separately 67 + - Notifications are sent to **all registered devices** simultaneously 68 + - Each device maintains its own subscription 69 + - All devices receive the same notifications 70 + 71 + ### Registering Additional Devices 72 + 73 + **For each device you want to receive notifications:** 74 + 75 + 1. **Open AT Todo** on the new device 76 + 2. **Login** with your account 77 + 3. **Open Settings** (click the "Settings" link in the top navigation) 78 + 4. **Enable Notifications**: 79 + - If this is your first device: Click "Enable Push Notifications" 80 + - If you already have notifications enabled on another device: Click "Register This Device" 81 + 5. **Grant Permission** when your browser prompts 82 + 6. **Verify** the device appears in "Registered Devices" list 83 + 84 + ### Viewing Registered Devices 85 + 86 + In the Settings → Notification Settings section, you'll see a "Registered Devices" list showing: 87 + 88 + - Device count 89 + - Browser/OS information for each device 90 + - Registration date 91 + 92 + Example: 93 + ``` 94 + Registered Devices: 95 + • Device 1: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)... (added 11/22/2024) 96 + • Device 2: Mozilla/5.0 (iPhone; CPU iPhone OS 17_0)... (added 11/22/2024) 97 + • Device 3: Mozilla/5.0 (Windows NT 10.0; Win64; x64)... (added 11/23/2024) 98 + ``` 99 + 100 + ### Re-registering a Device 101 + 102 + If notifications stop working on a device: 103 + 104 + 1. Open Settings on that device 105 + 2. Click "Register This Device" button 106 + 3. The device will refresh its subscription 107 + 4. Test with "Send Test Notification" 108 + 109 + ### Removing Devices 110 + 111 + To remove a device from receiving notifications: 112 + 113 + 1. **Open Settings** on any device 114 + 2. **Find the device** in the "Registered Devices" list 115 + 3. **Click the X button** next to the device you want to remove 116 + 4. **Confirm removal** when prompted 117 + 5. The device will no longer receive notifications 118 + 119 + **Notes:** 120 + - You can remove devices from any logged-in device (not just the device itself) 121 + - Devices can be re-registered at any time 122 + - Removing the last device will reset the notification UI 123 + - If you remove the current device, you'll need to re-enable notifications 124 + 125 + ### Managing Old Devices 126 + 127 + - Inactive device subscriptions expire automatically over time 128 + - Failed notifications to old devices won't affect active ones 129 + - Manual removal via the X button is the recommended cleanup method 130 + 131 + --- 132 + 133 + ## Notification Settings 134 + 135 + ### Timing Preferences 136 + 137 + Control which tasks trigger notifications: 138 + 139 + **Overdue Tasks** (Recommended: ON) 140 + - Notifies when tasks are past their due date 141 + - Highest priority - shown first 142 + - Example: "Submit report" was due yesterday 143 + 144 + **Tasks Due Today** (Recommended: ON) 145 + - Notifies about tasks due within 24 hours 146 + - Shows time until due 147 + - Example: "Team meeting" due at 2:00 PM today 148 + 149 + **Tasks Due Soon** (Optional) 150 + - Notifies about tasks due within 3 days 151 + - Helpful for planning ahead 152 + - Example: "Project deadline" due in 2 days 153 + 154 + **Hours Before Due** (Advanced) 155 + - Get advance notice before tasks are due 156 + - Range: 0-72 hours 157 + - Example: Set to 2 hours to get notified 2 hours before due time 158 + 159 + ### Check Frequency 160 + 161 + How often AT Todo checks for new due tasks: 162 + 163 + - **Every 15 minutes**: Most responsive, more battery usage 164 + - **Every 30 minutes**: Balanced (default) 165 + - **Every hour**: Less frequent, better battery life 166 + - **Every 2 hours**: Minimal battery impact 167 + 168 + **Note**: Server-side checks also run every 5 minutes regardless of client settings. 169 + 170 + ### Quiet Hours (Do Not Disturb) 171 + 172 + Prevent notifications during sleep or focus time: 173 + 174 + **Enable Quiet Hours:** 175 + 1. Check "Enable Do Not Disturb mode" 176 + 2. Set start time (hour, 0-23) 177 + - Default: 22 (10 PM) 178 + 3. Set end time (hour, 0-23) 179 + - Default: 8 (8 AM) 180 + 181 + **How It Works:** 182 + - No notifications during quiet hours 183 + - Notifications queued will appear after quiet hours end 184 + - Works independently on each device 185 + 186 + ### Saving Changes 187 + 188 + After configuring preferences: 189 + 1. Click "Save Preferences" button 190 + 2. You'll see a success toast 191 + 3. Settings are synced to your AT Protocol repository 192 + 193 + --- 194 + 195 + ## Troubleshooting 196 + 197 + ### Notifications Not Appearing 198 + 199 + **Check Browser Permissions:** 200 + 201 + 1. **Chrome/Edge**: 202 + - Click lock icon in address bar 203 + - Check "Notifications" is set to "Allow" 204 + 205 + 2. **Firefox**: 206 + - Click lock icon → Permissions → Notifications 207 + - Should be "Allowed" 208 + 209 + 3. **Safari**: 210 + - Safari → Settings → Websites → Notifications 211 + - Find your domain, should be "Allow" 212 + 213 + **Check System Settings:** 214 + 215 + - **macOS**: System Settings → Notifications → [Your Browser] 216 + - **Windows**: Settings → System → Notifications → [Your Browser] 217 + - **iOS**: Settings → [Your Browser] → Notifications 218 + - **Android**: Settings → Apps → [Your Browser] → Notifications 219 + 220 + **Verify AT Todo Settings:** 221 + 222 + 1. Open Settings 223 + 2. Check notification status shows "Enabled ✓" 224 + 3. Verify device appears in "Registered Devices" 225 + 4. Try clicking "Register This Device" to refresh 226 + 227 + **Test Connection:** 228 + 229 + 1. Click "Send Test Notification" 230 + 2. Check the response: 231 + - Success: "Test notification sent to X device(s)" 232 + - Failure: Error message with details 233 + 3. Check browser console for errors (F12 → Console) 234 + 235 + ### Device Not Listed 236 + 237 + If a device doesn't appear in "Registered Devices": 238 + 239 + 1. Click "Enable Push Notifications" or "Register This Device" 240 + 2. Grant permission when prompted 241 + 3. Wait 2-3 seconds for registration 242 + 4. Refresh the Settings page 243 + 5. Device should now appear 244 + 245 + ### Notifications on Some Devices Only 246 + 247 + If notifications work on one device but not others: 248 + 249 + 1. On the non-working device, open Settings 250 + 2. Check notification permission status 251 + 3. Click "Register This Device" 252 + 4. Send test notification 253 + 5. All devices should receive it 254 + 255 + **Common causes:** 256 + - Device wasn't registered (no subscription created) 257 + - Browser permission denied 258 + - Browser doesn't support push notifications 259 + - System notifications disabled for browser 260 + 261 + ### Wrong Notification Times 262 + 263 + If notifications appear at wrong times: 264 + 265 + **Check Timezone:** 266 + 1. Verify system timezone is correct 267 + 2. Edit a task and check the time shown 268 + 3. Times should match your local timezone 269 + 270 + **Check Task Due Times:** 271 + 1. Tasks without times trigger at midnight 272 + 2. Add specific times for better scheduling 273 + 3. Example: "tomorrow at 3pm" vs just "tomorrow" 274 + 275 + ### Too Many/Few Notifications 276 + 277 + **Adjust Settings:** 278 + 279 + 1. **Too many**: 280 + - Disable "Tasks due soon" notifications 281 + - Increase check frequency to 2 hours 282 + - Enable quiet hours 283 + 284 + 2. **Too few**: 285 + - Enable all notification types 286 + - Decrease check frequency to 15 minutes 287 + - Check quiet hours aren't blocking 288 + 289 + **Notification Cooldown:** 290 + - Each task only notifies once per 12 hours 291 + - Prevents spam for the same task 292 + - Resets after task is completed 293 + 294 + ### Browser Compatibility Issues 295 + 296 + **Best Support:** 297 + - Chrome (desktop & Android) 298 + - Edge (desktop) 299 + - Safari (iOS 16.4+, macOS) 300 + 301 + **Limited Support:** 302 + - Firefox (no background sync) 303 + - Older Safari versions 304 + - Mobile browsers (varies) 305 + 306 + **If using unsupported browser:** 307 + 1. Switch to Chrome or Edge for best experience 308 + 2. Or keep AT Todo open for notifications 309 + 3. Check server logs for notification sends 310 + 311 + ### Service Worker Issues 312 + 313 + If notifications completely stop working: 314 + 315 + **Reset Service Worker:** 316 + 317 + 1. Open browser DevTools (F12) 318 + 2. Go to Application tab → Service Workers 319 + 3. Click "Unregister" next to AT Todo worker 320 + 4. Refresh the page 321 + 5. Service worker will reinstall 322 + 6. Re-enable notifications in Settings 323 + 324 + **Check Service Worker Status:** 325 + 326 + 1. Navigate to `/app/settings` 327 + 2. Open Console (F12) 328 + 3. Look for `[Push]` prefixed logs 329 + 4. Should see "Service worker ready" 330 + 5. Should see "Subscription registered successfully" 331 + 332 + --- 333 + 334 + ## Advanced Topics 335 + 336 + ### How Notifications Work 337 + 338 + **Architecture:** 339 + 340 + 1. **Client-Side Check** (Browser): 341 + - Service worker runs periodic checks 342 + - Compares current time to task due dates 343 + - Shows notifications for matching tasks 344 + 345 + 2. **Server-Side Check** (Background Job): 346 + - Runs every 5 minutes 347 + - Checks all enabled users 348 + - Sends push notifications to registered devices 349 + 350 + 3. **Push Service** (Browser Vendor): 351 + - Chrome uses FCM (Firebase Cloud Messaging) 352 + - Safari uses APNs (Apple Push Notification service) 353 + - Delivers notifications to devices 354 + 355 + **Data Flow:** 356 + 357 + ``` 358 + Task Due → Server Check → Push Service → Your Device → Notification 359 + ``` 360 + 361 + ### Privacy & Security 362 + 363 + **What's Stored:** 364 + 365 + - **In Database**: 366 + - Your DID (user identifier) 367 + - Device push subscriptions (endpoints, keys) 368 + - Notification history (prevents spam) 369 + 370 + - **In AT Protocol**: 371 + - Notification preferences 372 + - Task data (titles, due dates) 373 + 374 + - **Never Stored**: 375 + - Notification content (generated on-demand) 376 + - Which notifications you viewed 377 + - Device location or tracking data 378 + 379 + **Encryption:** 380 + 381 + - Push subscriptions use public/private key encryption 382 + - VAPID (Voluntary Application Server Identification) 383 + - End-to-end encrypted between server and device 384 + 385 + ### Notification History 386 + 387 + Prevent notification spam with built-in cooldown: 388 + 389 + - Each task can only notify once per 12 hours 390 + - Tracked in `notification_history` table 391 + - Resets when task is completed 392 + - Separate tracking per notification type (overdue, today, soon) 393 + 394 + --- 395 + 396 + ## Getting Help 397 + 398 + If you're still having issues: 399 + 400 + 1. Check the [Features Guide](/docs/features) for more details 401 + 2. Review browser console for error messages 402 + 3. Check server logs for notification sending 403 + 4. Report issues on GitHub 404 + 5. Contact via Bluesky 405 + 406 + --- 407 + 408 + ## Tips for Best Experience 409 + 410 + 1. **Enable on all devices** you regularly use 411 + 2. **Set appropriate check frequency** based on urgency 412 + 3. **Use quiet hours** to avoid sleep disruption 413 + 4. **Test notifications** after first setup 414 + 5. **Keep browser updated** for best compatibility 415 + 6. **Grant persistent permissions** (don't use Incognito mode) 416 + 7. **Check "Registered Devices"** periodically to verify active devices
+127 -8
templates/partials/notification-settings.html
··· 9 9 </p> 10 10 <div id="registered-devices" style="display: none; margin-top: 1rem;"> 11 11 <p><strong>Registered Devices:</strong></p> 12 - <ul id="device-list" style="font-size: 0.9rem; color: var(--pico-muted-color);"></ul> 12 + <ul id="device-list" style="font-size: 0.9rem; color: var(--pico-muted-color); list-style: none; padding: 0;"></ul> 13 13 </div> 14 14 </div> 15 15 ··· 183 183 deviceList.innerHTML = ''; 184 184 subscriptions.forEach((sub, index) => { 185 185 const li = document.createElement('li'); 186 + li.style.cssText = 'display: flex; justify-content: space-between; align-items: center; padding: 0.5rem; margin: 0.25rem 0; border: 1px solid var(--pico-muted-border-color); border-radius: var(--pico-border-radius);'; 187 + 188 + const deviceInfo = document.createElement('span'); 186 189 const userAgent = sub.userAgent || 'Unknown device'; 187 190 const createdAt = new Date(sub.createdAt).toLocaleDateString(); 188 - li.textContent = `Device ${index + 1}: ${userAgent.substring(0, 50)}... (added ${createdAt})`; 191 + deviceInfo.textContent = `Device ${index + 1}: ${userAgent.substring(0, 50)}... (added ${createdAt})`; 192 + deviceInfo.style.flex = '1'; 193 + 194 + const removeBtn = document.createElement('button'); 195 + removeBtn.innerHTML = '&times;'; 196 + removeBtn.className = 'secondary'; 197 + removeBtn.style.cssText = 'padding: 0.25rem 0.5rem; margin: 0; font-size: 1.25rem; line-height: 1; min-width: auto;'; 198 + removeBtn.setAttribute('aria-label', 'Remove device'); 199 + removeBtn.onclick = () => removeDevice(sub.endpoint, li); 200 + 201 + li.appendChild(deviceInfo); 202 + li.appendChild(removeBtn); 189 203 deviceList.appendChild(li); 190 204 }); 191 205 ··· 196 210 } 197 211 } 198 212 213 + async function removeDevice(endpoint, listItem) { 214 + if (!confirm('Remove this device from receiving notifications?')) { 215 + return; 216 + } 217 + 218 + try { 219 + const response = await fetch('/app/push/unsubscribe', { 220 + method: 'POST', 221 + headers: { 222 + 'Content-Type': 'application/json' 223 + }, 224 + body: JSON.stringify({ endpoint }) 225 + }); 226 + 227 + if (!response.ok) { 228 + const errorText = await response.text(); 229 + throw new Error(`Failed to unsubscribe: ${response.status} ${errorText}`); 230 + } 231 + 232 + const result = await response.json(); 233 + 234 + // Remove the device from the UI with animation 235 + listItem.style.transition = 'opacity 0.3s ease-out, transform 0.3s ease-out'; 236 + listItem.style.opacity = '0'; 237 + listItem.style.transform = 'translateX(-20px)'; 238 + 239 + setTimeout(async () => { 240 + listItem.remove(); 241 + 242 + // Check if this was the last device 243 + const deviceList = document.getElementById('device-list'); 244 + if (deviceList.children.length === 0) { 245 + document.getElementById('registered-devices').style.display = 'none'; 246 + 247 + // If we removed the current device, disable notifications UI 248 + const currentEndpoint = await getCurrentDeviceEndpoint(); 249 + if (currentEndpoint === endpoint) { 250 + // Reset UI to not enabled state 251 + const statusEl = document.getElementById('notification-permission-status'); 252 + const registerBtn = document.getElementById('register-device'); 253 + const prefsEl = document.getElementById('notification-preferences'); 254 + 255 + statusEl.textContent = 'Not enabled'; 256 + statusEl.style.color = ''; 257 + registerBtn.style.display = 'none'; 258 + prefsEl.style.display = 'none'; 259 + 260 + // Show enable button 261 + document.getElementById('enable-notifications').style.display = 'block'; 262 + } 263 + } 264 + 265 + showToast('Device removed from notifications', 'success'); 266 + }, 300); 267 + 268 + } catch (error) { 269 + console.error('Failed to remove device:', error); 270 + showToast('Failed to remove device: ' + error.message, 'error'); 271 + } 272 + } 273 + 274 + async function getCurrentDeviceEndpoint() { 275 + try { 276 + if (!('serviceWorker' in navigator) || !('PushManager' in window)) { 277 + return null; 278 + } 279 + 280 + const registration = await navigator.serviceWorker.ready; 281 + const subscription = await registration.pushManager.getSubscription(); 282 + return subscription ? subscription.endpoint : null; 283 + } catch (error) { 284 + console.error('Failed to get current device endpoint:', error); 285 + return null; 286 + } 287 + } 288 + 199 289 async function requestNotificationPermission() { 200 290 try { 201 291 const permission = await Notification.requestPermission(); ··· 206 296 // Update UI to show preferences 207 297 const statusEl = document.getElementById('notification-permission-status'); 208 298 const enableBtn = document.getElementById('enable-notifications'); 299 + const registerBtn = document.getElementById('register-device'); 209 300 const prefsEl = document.getElementById('notification-preferences'); 210 301 211 302 statusEl.textContent = 'Enabled ✓'; 212 303 statusEl.style.color = 'var(--pico-primary)'; 213 304 enableBtn.style.display = 'none'; 305 + registerBtn.style.display = 'inline-block'; 214 306 prefsEl.style.display = 'block'; 215 307 216 308 // Load current settings or use defaults (this populates the form) ··· 237 329 } 238 330 239 331 // Subscribe to push notifications 240 - await subscribeToPush(); 332 + const subResult = await subscribeToPush(); 333 + 334 + // Show registration feedback 335 + if (subResult && subResult.message === 'Subscription created successfully') { 336 + showToast('Device registered for notifications!', 'success', 2000); 337 + } else if (subResult && subResult.message === 'Subscription already exists') { 338 + showToast('Device already registered', 'info', 2000); 339 + } 340 + 341 + // Reload devices list to show the new registration 342 + await loadRegisteredDevices(); 241 343 242 344 // Register periodic sync for background notifications 243 345 await registerPeriodicSync(); ··· 246 348 } 247 349 } catch (error) { 248 350 console.error('Error requesting notification permission:', error); 249 - showToast('Failed to enable notifications', 'error'); 351 + showToast('Failed to enable notifications: ' + error.message, 'error'); 250 352 } 251 353 } 252 354 ··· 415 517 throw new Error(`Failed to register push subscription: ${subscribeResponse.status} ${errorText}`); 416 518 } 417 519 418 - console.log('[Push] Subscription registered successfully'); 520 + const result = await subscribeResponse.json(); 521 + console.log('[Push] Subscription registered successfully:', result.message); 522 + 523 + // Return the result so caller can show appropriate message 524 + return result; 419 525 } catch (error) { 420 526 console.error('[Push] Failed to subscribe:', error); 421 527 // Don't show toast on page load - only when user explicitly enables 422 528 // showToast('Failed to set up push notifications', 'error'); 529 + throw error; 423 530 } 424 531 } 425 532 ··· 503 610 // Add event listener for register device button 504 611 document.getElementById('register-device')?.addEventListener('click', async () => { 505 612 try { 506 - await subscribeToPush(); 613 + const result = await subscribeToPush(); 507 614 await loadRegisteredDevices(); 508 - showToast('Device registration refreshed!', 'success'); 615 + 616 + // Show appropriate message based on backend response 617 + if (result && result.message) { 618 + if (result.message === 'Subscription already exists') { 619 + showToast('This device is already registered for notifications', 'info'); 620 + } else if (result.message === 'Subscription created successfully') { 621 + showToast('Device registered successfully!', 'success'); 622 + } else { 623 + showToast('Device registration updated', 'success'); 624 + } 625 + } else { 626 + showToast('Device registration refreshed!', 'success'); 627 + } 509 628 } catch (error) { 510 629 console.error('Failed to register device:', error); 511 - showToast('Failed to register device', 'error'); 630 + showToast('Failed to register device: ' + error.message, 'error'); 512 631 } 513 632 }); 514 633 </script>