| … | … | @@ -3813,42 +3813,45 @@ function showNotification(title, body, type = 'info') { |
| 3813 | 3813 | // Always log to console (primary notification method) |
| 3814 | 3814 | console.log(`📢 Notification: ${title} - ${body}`) |
| 3815 | 3815 | |
| 3816 | | // Try to show native notification, but don't crash if it fails |
| 3817 | | try { |
| 3818 | | // Check if Notification API is available |
| 3819 | | if ('Notification' in window) { |
| 3820 | | // Request permission if not already granted |
| 3821 | | if (Notification.permission === 'granted') { |
| 3822 | | new Notification(title, { |
| 3823 | | body: body, |
| 3824 | | icon: '/assets/icon.png', // Add app icon if available |
| 3825 | | badge: '/assets/badge.png' |
| 3826 | | }) |
| 3827 | | } else if (Notification.permission !== 'denied') { |
| 3828 | | Notification.requestPermission().then(permission => { |
| 3829 | | if (permission === 'granted') { |
| 3830 | | try { |
| 3831 | | new Notification(title, { |
| 3832 | | body: body, |
| 3833 | | icon: '/assets/icon.png', |
| 3834 | | badge: '/assets/badge.png' |
| 3835 | | }) |
| 3836 | | } catch (err) { |
| 3837 | | // Silently fail - notification not critical |
| 3838 | | console.log('📢 Native notification unavailable (not critical)') |
| 3816 | // Run notification in a separate task to avoid blocking UI |
| 3817 | // Wrap everything in setTimeout(0) to make it non-blocking |
| 3818 | setTimeout(() => { |
| 3819 | try { |
| 3820 | // Check if Notification API is available |
| 3821 | if ('Notification' in window) { |
| 3822 | // Request permission if not already granted |
| 3823 | if (Notification.permission === 'granted') { |
| 3824 | new Notification(title, { |
| 3825 | body: body, |
| 3826 | icon: '/assets/icon.png', // Add app icon if available |
| 3827 | badge: '/assets/badge.png' |
| 3828 | }) |
| 3829 | } else if (Notification.permission !== 'denied') { |
| 3830 | Notification.requestPermission().then(permission => { |
| 3831 | if (permission === 'granted') { |
| 3832 | try { |
| 3833 | new Notification(title, { |
| 3834 | body: body, |
| 3835 | icon: '/assets/icon.png', |
| 3836 | badge: '/assets/badge.png' |
| 3837 | }) |
| 3838 | } catch (err) { |
| 3839 | // Silently fail - notification not critical |
| 3840 | console.log('📢 Native notification unavailable (not critical)') |
| 3841 | } |
| 3839 | 3842 | } |
| 3840 | | } |
| 3841 | | }).catch(err => { |
| 3842 | | // Silently fail - notification not critical |
| 3843 | | console.log('📢 Notification permission request failed (not critical)') |
| 3844 | | }) |
| 3843 | }).catch(err => { |
| 3844 | // Silently fail - notification not critical |
| 3845 | console.log('📢 Notification permission request failed (not critical)') |
| 3846 | }) |
| 3847 | } |
| 3845 | 3848 | } |
| 3849 | } catch (err) { |
| 3850 | // Silently fail if notification system not available |
| 3851 | // This is expected on systems without notification daemon |
| 3852 | console.log('📢 Native notifications unavailable (not critical):', err.message) |
| 3846 | 3853 | } |
| 3847 | | } catch (err) { |
| 3848 | | // Silently fail if notification system not available |
| 3849 | | // This is expected on systems without notification daemon |
| 3850 | | console.log('📢 Native notifications unavailable (not critical):', err.message) |
| 3851 | | } |
| 3854 | }, 0) |
| 3852 | 3855 | } |
| 3853 | 3856 | |
| 3854 | 3857 | // Expose functions to global window object for onclick/onchange handlers |