// Version: 1.3.0 | Created: 2026-04-01 | Updated: 2026-09-25 // Application entry point. // v1.3.0: wires SessionJourney (session/journey/friction tracking, ported // from the WordPress sites per plan ancient-petting-hejlsberg.md §3/§5). // WidgetsFlutterBinding.ensureInitialized() stays the literal first line — // calling SessionJourney.init() before it crashes the release web build // with a null-check error (found and fixed on GardenBuddy the same day, // 2026-09-25 — not repeating that mistake here). 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/analytics/session_journey.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 }; // SessionJourney.init() runs AFTER the two handlers above so it CHAINS to // them (captures them as "previous", calls them after its own reporting) // rather than replacing them. See session_journey.dart's header. SessionJourney.init(appVersion: '1.12.0'); runApp(const ProviderScope(child: M8ChatApp())); }