@@ -14,6 +14,7 @@ import 'package:material_symbols_icons/symbols.dart';
1414import 'package:shared_preferences/shared_preferences.dart' ;
1515import 'package:webview_flutter/webview_flutter.dart' ;
1616import '../services/bluetooth_manager.dart' ;
17+ import 'package:agixt/services/web_notification_bridge_service.dart' ;
1718import 'package:url_launcher/url_launcher.dart' ;
1819
1920class HomePage extends StatefulWidget {
@@ -37,6 +38,8 @@ class _HomePageState extends State<HomePage> {
3738 final BluetoothManager bluetoothManager = BluetoothManager ();
3839 final AIService aiService = AIService ();
3940 final LocationService _locationService = LocationService ();
41+ final WebNotificationBridgeService _webNotificationBridge =
42+ WebNotificationBridgeService ();
4043
4144 // Static flag to prevent multiple instances from showing the glasses prompt dialog
4245 static bool _isShowingGlassesPrompt = false ;
@@ -122,6 +125,10 @@ class _HomePageState extends State<HomePage> {
122125 // Connect WebSocket for real-time streaming and client commands
123126 debugPrint ('HomeScreen: Connecting WebSocket for streaming' );
124127 await aiService.connectWebSocket ();
128+
129+ // Initialize the web notification bridge (creates notification channels)
130+ await _webNotificationBridge.initialize ();
131+
125132 debugPrint ('HomeScreen: App initialization complete' );
126133 }
127134
@@ -280,6 +287,10 @@ class _HomePageState extends State<HomePage> {
280287 // Inject agent selection observer
281288 await _injectAgentSelectionObserver ();
282289
290+ // Inject web notification bridge to forward in-page
291+ // notifications as native push + glasses on-lens display
292+ await _injectWebNotificationBridge ();
293+
283294 // Set up location injection for the webview
284295 await _setupLocationInjection ();
285296
@@ -719,6 +730,16 @@ class _HomePageState extends State<HomePage> {
719730 },
720731 );
721732
733+ // Register the web notification bridge channel
734+ // Intercepts chat:notification and browser Notification API events
735+ // from the web app and forwards them as native push + glasses display
736+ await _webViewController! .addJavaScriptChannel (
737+ 'WebNotificationBridge' ,
738+ onMessageReceived: (JavaScriptMessage message) {
739+ _webNotificationBridge.handleBridgeMessage (message.message);
740+ },
741+ );
742+
722743 _jsChannelsRegistered = true ;
723744 debugPrint ('JavaScript channels registered successfully' );
724745 } catch (e) {
@@ -871,6 +892,21 @@ class _HomePageState extends State<HomePage> {
871892 }
872893 }
873894
895+ /// Inject the web notification bridge script into the WebView.
896+ /// This intercepts `chat:notification` CustomEvents and the browser
897+ /// Notification API, forwarding them to the native [WebNotificationBridge]
898+ /// JavaScript channel for push notifications and glasses on-lens display.
899+ Future <void > _injectWebNotificationBridge () async {
900+ if (_webViewController == null ) return ;
901+
902+ try {
903+ await _webViewController! .runJavaScript (webNotificationBridgeScript);
904+ debugPrint ('Web notification bridge script injected' );
905+ } catch (e) {
906+ debugPrint ('Error injecting web notification bridge: $e ' );
907+ }
908+ }
909+
874910 // Helper method to save agent value
875911 Future <void > _saveAgentValue (String agentValue) async {
876912 // Remove quotes that might be surrounding the agent value
0 commit comments