import 'package:flutter/material.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:firebase_core/firebase_core.dart'; import 'config/config_loader.dart'; import 'data/local/local_storage_service.dart'; import 'data/nostr/nostr_service.dart'; import 'data/sync/sync_engine.dart'; import 'data/firebase/firebase_service.dart'; import 'data/session/session_service.dart'; import 'data/immich/immich_service.dart'; import 'ui/navigation/main_navigation_scaffold.dart'; Future main() async { WidgetsFlutterBinding.ensureInitialized(); // Load .env file (optional - falls back to defaults if not found) try { await dotenv.load(fileName: '.env'); } catch (e) { debugPrint('Note: .env file not found, using default values: $e'); } // Load configuration based on environment const String environment = String.fromEnvironment( 'ENV', defaultValue: 'dev', ); final config = ConfigLoader.load(environment); // Initialize Firebase if enabled if (config.firebaseConfig.enabled) { try { await Firebase.initializeApp(); if (config.enableLogging) { debugPrint('Firebase initialized successfully'); } } catch (e) { debugPrint('Firebase initialization failed: $e'); debugPrint('Note: Firebase requires google-services.json (Android) and GoogleService-Info.plist (iOS)'); } } if (config.enableLogging) { debugPrint('App initialized with config: $config'); } runApp(const MyApp()); } /// The root widget of the application. class MyApp extends StatefulWidget { const MyApp({super.key}); @override State createState() => _MyAppState(); } class _MyAppState extends State { LocalStorageService? _storageService; NostrService? _nostrService; SyncEngine? _syncEngine; FirebaseService? _firebaseService; SessionService? _sessionService; ImmichService? _immichService; bool _isInitialized = false; @override void initState() { super.initState(); _initializeStorage(); } Future _initializeStorage() async { try { _storageService = LocalStorageService(); await _storageService!.initialize(); // Initialize Nostr service and sync engine _nostrService = NostrService(); final nostrKeyPair = _nostrService!.generateKeyPair(); _syncEngine = SyncEngine( localStorage: _storageService!, nostrService: _nostrService!, nostrKeyPair: nostrKeyPair, ); // Load relays from config final config = ConfigLoader.load( const String.fromEnvironment('ENV', defaultValue: 'dev'), ); for (final relayUrl in config.nostrRelays) { _nostrService!.addRelay(relayUrl); } // Initialize Immich service _immichService = ImmichService( baseUrl: config.immichBaseUrl, apiKey: config.immichApiKey, localStorage: _storageService!, ); // Initialize Firebase service if enabled if (config.firebaseConfig.enabled) { try { _firebaseService = FirebaseService( config: config.firebaseConfig, localStorage: _storageService!, ); await _firebaseService!.initialize(); if (config.enableLogging) { debugPrint('Firebase service initialized: ${_firebaseService!.isEnabled}'); } } catch (e) { debugPrint('Firebase service initialization failed: $e'); _firebaseService = null; } } // Initialize SessionService with Firebase integration _sessionService = SessionService( localStorage: _storageService!, syncEngine: _syncEngine, firebaseService: _firebaseService, ); setState(() { _isInitialized = true; }); } catch (e) { debugPrint('Failed to initialize storage: $e'); // Reset to null if initialization failed _storageService = null; _nostrService = null; _syncEngine = null; _firebaseService = null; _sessionService = null; _immichService = null; } } @override void dispose() { _syncEngine?.dispose(); _nostrService?.dispose(); _firebaseService?.dispose(); // Only close if storage service was initialized if (_storageService != null) { try { _storageService!.close(); } catch (e) { debugPrint('Error closing storage service: $e'); } } super.dispose(); } @override Widget build(BuildContext context) { return MaterialApp( title: 'App Boilerplate', theme: ThemeData( colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue), useMaterial3: true, ), home: _isInitialized ? MainNavigationScaffold( sessionService: _sessionService, localStorageService: _storageService, nostrService: _nostrService, syncEngine: _syncEngine, firebaseService: _firebaseService, immichService: _immichService, ) : const Scaffold( body: Center( child: CircularProgressIndicator(), ), ), ); } }