// Version: 1.2.0 | Created: 2026-04-01 | Updated: 2026-04-27 // Application entry point. import 'dart:async'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:olm/olm.dart' as olm; import 'app/app.dart'; import 'core/push/web_push_service.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); // Check Olm availability — this prints to the browser console. try { await olm.init(); debugPrint('[M8Chat] Olm initialized successfully: ${olm.get_library_version()}'); } catch (e) { debugPrint('[M8Chat] Olm NOT available: $e'); } // Register the push service worker at startup so the browser knows about it. // The actual push subscription happens after login (in auth_notifier.dart). if (kIsWeb) { unawaited(registerPushServiceWorker()); } // Catch Flutter framework errors (widget build, rendering) without crashing. FlutterError.onError = (details) { debugPrint('[M8Chat] Flutter error: ${details.exceptionAsString()}'); }; // Catch all unhandled async errors — including those thrown by the Matrix SDK // in runInRoot() after login (encryption init, sync startup). Without this // handler the browser runtime crashes and the UI freezes on the spinner. PlatformDispatcher.instance.onError = (error, stack) { debugPrint('[M8Chat] Uncaught error: $error'); return true; // returning true marks the error as handled }; runApp(const ProviderScope(child: M8ChatApp())); }