import 'dart:async'; import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/material.dart'; import 'package:nexo_messaging/nexo_messaging.dart'; Future main() async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp(); runApp(const MyApp()); } class MyApp extends StatefulWidget { const MyApp({super.key, this.initializePlugin = true}); final bool initializePlugin; @override State createState() => _MyAppState(); } class _MyAppState extends State { String? _deviceToken; String? _lastNotification; String? _lastOpened; String? _lastNavigation; StreamSubscription>? _notificationSubscription; StreamSubscription? _openedSubscription; @override void initState() { super.initState(); final plugin = NexoMessagingPlugin.instance; plugin.onDeviceTokenReady = (token) { if (!mounted) return; setState(() => _deviceToken = token); }; plugin.onNavigateToChannel = (serverUrl, channelId) { if (!mounted) return; setState(() => _lastNavigation = 'channel:$serverUrl/$channelId'); }; plugin.onNavigateToThread = (serverUrl, rootId) { if (!mounted) return; setState(() => _lastNavigation = 'thread:$serverUrl/$rootId'); }; _notificationSubscription = plugin.onNotification.listen((event) { if (!mounted) return; setState(() => _lastNotification = _formatMap(event)); }); _openedSubscription = plugin.onNotificationOpened.listen((event) { if (!mounted) return; setState(() => _lastOpened = _formatOpened(event)); }); if (widget.initializePlugin) { unawaited(_initializePlugin(plugin)); } } Future _initializePlugin(NexoMessagingPlugin plugin) async { try { await _configureSmokeAuthToken(plugin); await plugin.initialize(); } catch (error, stackTrace) { debugPrint('[NexoClient] Failed to initialize messaging plugin: $error'); debugPrintStack(stackTrace: stackTrace); } } Future _configureSmokeAuthToken(NexoMessagingPlugin plugin) async { const serverUrl = String.fromEnvironment('NEXO_SMOKE_SERVER_URL'); const authToken = String.fromEnvironment('NEXO_SMOKE_AUTH_TOKEN'); const identifier = String.fromEnvironment('NEXO_SMOKE_SERVER_IDENTIFIER'); if (serverUrl.isEmpty || authToken.isEmpty) return; await plugin.setAuthToken( serverUrl, authToken, identifier: identifier.isEmpty ? null : identifier, ); debugPrint('[NexoClient] Smoke auth token configured'); } @override void dispose() { _notificationSubscription?.cancel(); _openedSubscription?.cancel(); final plugin = NexoMessagingPlugin.instance; plugin.onDeviceTokenReady = null; plugin.onNavigateToChannel = null; plugin.onNavigateToThread = null; super.dispose(); } String _formatMap(Map map) { return map.entries.map((e) => '${e.key}: ${e.value}').join(', '); } String _formatOpened(NotificationOpenedEvent event) { return 'server_url: ${event.serverUrl}, channel_id: ${event.channelId}, root_id: ${event.rootId}, is_crt_enabled: ${event.isCRTEnabled}'; } @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar(title: const Text('Nexo client')), body: ListView( padding: const EdgeInsets.all(16), children: [ Text('Device token: ${_deviceToken ?? 'pending'}'), Text('Last notification: ${_lastNotification ?? 'none'}'), Text('Last opened: ${_lastOpened ?? 'none'}'), Text('Last navigation: ${_lastNavigation ?? 'none'}'), ], ), ), ); } }