import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:get_it/get_it.dart'; import 'package:logging/logging.dart'; import 'package:moxplatform/moxplatform.dart'; import 'package:moxxyv2/service/service.dart'; import 'package:moxxyv2/shared/commands.dart'; import 'package:moxxyv2/ui/bloc/addcontact_bloc.dart'; import 'package:moxxyv2/ui/bloc/blocklist_bloc.dart'; import 'package:moxxyv2/ui/bloc/conversation_bloc.dart'; import 'package:moxxyv2/ui/bloc/conversations_bloc.dart'; import 'package:moxxyv2/ui/bloc/crop_bloc.dart'; import 'package:moxxyv2/ui/bloc/cropbackground_bloc.dart'; import 'package:moxxyv2/ui/bloc/keys_bloc.dart'; import 'package:moxxyv2/ui/bloc/login_bloc.dart'; import 'package:moxxyv2/ui/bloc/navigation_bloc.dart'; import 'package:moxxyv2/ui/bloc/newconversation_bloc.dart'; import 'package:moxxyv2/ui/bloc/own_keys_bloc.dart'; import 'package:moxxyv2/ui/bloc/preferences_bloc.dart'; import 'package:moxxyv2/ui/bloc/profile_bloc.dart'; import 'package:moxxyv2/ui/bloc/sendfiles_bloc.dart'; import 'package:moxxyv2/ui/bloc/server_info_bloc.dart'; import 'package:moxxyv2/ui/bloc/share_selection_bloc.dart'; import 'package:moxxyv2/ui/bloc/sharedmedia_bloc.dart'; import 'package:moxxyv2/ui/constants.dart'; import 'package:moxxyv2/ui/events.dart'; /* import "package:moxxyv2/ui/pages/register/register.dart"; import "package:moxxyv2/ui/pages/postregister/postregister.dart"; */ import 'package:moxxyv2/ui/pages/addcontact.dart'; import 'package:moxxyv2/ui/pages/blocklist.dart'; import 'package:moxxyv2/ui/pages/conversation/conversation.dart'; import 'package:moxxyv2/ui/pages/conversations.dart'; import 'package:moxxyv2/ui/pages/crop.dart'; import 'package:moxxyv2/ui/pages/intro.dart'; import 'package:moxxyv2/ui/pages/login.dart'; import 'package:moxxyv2/ui/pages/newconversation.dart'; import 'package:moxxyv2/ui/pages/profile/keys.dart'; import 'package:moxxyv2/ui/pages/profile/own_keys.dart'; import 'package:moxxyv2/ui/pages/profile/profile.dart'; import 'package:moxxyv2/ui/pages/sendfiles.dart'; import 'package:moxxyv2/ui/pages/server_info.dart'; import 'package:moxxyv2/ui/pages/settings/about.dart'; import 'package:moxxyv2/ui/pages/settings/appearance/cropbackground.dart'; import 'package:moxxyv2/ui/pages/settings/conversation.dart'; import 'package:moxxyv2/ui/pages/settings/debugging.dart'; import 'package:moxxyv2/ui/pages/settings/licenses.dart'; import 'package:moxxyv2/ui/pages/settings/network.dart'; import 'package:moxxyv2/ui/pages/settings/privacy/privacy.dart'; import 'package:moxxyv2/ui/pages/settings/settings.dart'; import 'package:moxxyv2/ui/pages/share_selection.dart'; import 'package:moxxyv2/ui/pages/sharedmedia.dart'; import 'package:moxxyv2/ui/pages/splashscreen/splashscreen.dart'; import 'package:moxxyv2/ui/service/data.dart'; import 'package:moxxyv2/ui/service/progress.dart'; import 'package:moxxyv2/ui/service/thumbnail.dart'; import 'package:page_transition/page_transition.dart'; import 'package:share_handler/share_handler.dart'; void setupLogging() { Logger.root.level = Level.ALL; Logger.root.onRecord.listen((record) { // ignore: avoid_print print('[${record.level.name}] (${record.loggerName}) ${record.time}: ${record.message}'); }); GetIt.I.registerSingleton(Logger('MoxxyMain')); } Future setupUIServices() async { GetIt.I.registerSingleton(UIProgressService()); GetIt.I.registerSingleton(UIDataService()); GetIt.I.registerSingleton(ThumbnailCacheService()); } void setupBlocs(GlobalKey navKey) { GetIt.I.registerSingleton(NavigationBloc(navigationKey: navKey)); GetIt.I.registerSingleton(ConversationsBloc()); GetIt.I.registerSingleton(NewConversationBloc()); GetIt.I.registerSingleton(ConversationBloc()); GetIt.I.registerSingleton(BlocklistBloc()); GetIt.I.registerSingleton(ProfileBloc()); GetIt.I.registerSingleton(PreferencesBloc()); GetIt.I.registerSingleton(AddContactBloc()); GetIt.I.registerSingleton(SharedMediaBloc()); GetIt.I.registerSingleton(CropBloc()); GetIt.I.registerSingleton(SendFilesBloc()); GetIt.I.registerSingleton(CropBackgroundBloc()); GetIt.I.registerSingleton(ShareSelectionBloc()); GetIt.I.registerSingleton(ServerInfoBloc()); GetIt.I.registerSingleton(KeysBloc()); GetIt.I.registerSingleton(OwnKeysBloc()); } // TODO(Unknown): Replace all Column(children: [ Padding(), Padding, ...]) with a // Padding(padding: ..., child: Column(children: [ ... ])) // TODO(Unknown): Theme the switches void main() async { GetIt.I.registerSingleton>(Completer()); setupLogging(); await setupUIServices(); setupEventHandler(); final navKey = GlobalKey(); setupBlocs(navKey); await initializeServiceIfNeeded(); runApp( MultiBlocProvider( providers: [ BlocProvider( create: (_) => GetIt.I.get(), ), BlocProvider( create: (_) => LoginBloc(), ), BlocProvider( create: (_) => GetIt.I.get(), ), BlocProvider( create: (_) => GetIt.I.get(), ), BlocProvider( create: (_) => GetIt.I.get(), ), BlocProvider( create: (_) => GetIt.I.get(), ), BlocProvider( create: (_) => GetIt.I.get(), ), BlocProvider( create: (_) => GetIt.I.get(), ), BlocProvider( create: (_) => GetIt.I.get(), ), BlocProvider( create: (_) => GetIt.I.get(), ), BlocProvider( create: (_) => GetIt.I.get(), ), BlocProvider( create: (_) => GetIt.I.get(), ), BlocProvider( create: (_) => GetIt.I.get(), ), BlocProvider( create: (_) => GetIt.I.get(), ), BlocProvider( create: (_) => GetIt.I.get(), ), BlocProvider( create: (_) => GetIt.I.get(), ), BlocProvider( create: (_) => GetIt.I.get(), ), ], child: MyApp(navKey), ), ); } class MyApp extends StatefulWidget { const MyApp(this.navigationKey, { Key? key }) : super(key: key); final GlobalKey navigationKey; @override MyAppState createState() => MyAppState(); } class MyAppState extends State with WidgetsBindingObserver { MyAppState(); @override void initState() { super.initState(); WidgetsBinding.instance.addObserver(this); // Lift the UI block GetIt.I.get>().complete(); _setupSharingHandler(); } Future _handleSharedMedia(SharedMedia media) async { final attachments = media.attachments ?? []; GetIt.I.get().add( ShareSelectionRequestedEvent( attachments.map((a) => a!.path).toList(), media.content, media.content != null ? ShareSelectionType.text : ShareSelectionType.media, ), ); } Future _setupSharingHandler() async { final handler = ShareHandlerPlatform.instance; final media = await handler.getInitialSharedMedia(); // Shared while the app was closed if (media != null) { if (GetIt.I.get().isLoggedIn) { await _handleSharedMedia(media); } await handler.resetInitialSharedMedia(); } // Shared while the app is stil running handler.sharedMediaStream.listen((SharedMedia media) async { if (GetIt.I.get().isLoggedIn) { await _handleSharedMedia(media); } await handler.resetInitialSharedMedia(); }); } @override void dispose() { WidgetsBinding.instance.removeObserver(this); super.dispose(); } @override void didChangeAppLifecycleState(AppLifecycleState state) { super.didChangeAppLifecycleState(state); final sender = MoxplatformPlugin.handler.getDataSender(); switch (state) { case AppLifecycleState.paused: sender.sendData( SetCSIStateCommand(active: false), ); GetIt.I.get().add(AppStateChanged(false)); break; case AppLifecycleState.resumed: sender.sendData( SetCSIStateCommand(active: true), ); GetIt.I.get().add(AppStateChanged(true)); break; case AppLifecycleState.detached: case AppLifecycleState.inactive: break; } } @override Widget build(BuildContext context) { return MaterialApp( title: 'Moxxy', theme: ThemeData( elevatedButtonTheme: ElevatedButtonThemeData( style: ElevatedButton.styleFrom( primary: primaryColor, onPrimary: Colors.white, ), ), textButtonTheme: TextButtonThemeData( style: TextButton.styleFrom( primary: primaryColor, ), ), // NOTE: Mainly for the SettingsSection colorScheme: const ColorScheme.light( secondary: primaryColor, ), ), darkTheme: ThemeData( brightness: Brightness.dark, elevatedButtonTheme: ElevatedButtonThemeData( style: ElevatedButton.styleFrom( primary: primaryColor, onPrimary: Colors.white, ), ), textButtonTheme: TextButtonThemeData( style: TextButton.styleFrom( primary: primaryColor, ), ), // NOTE: Mainly for the SettingsSection colorScheme: const ColorScheme.dark( secondary: primaryColor, ), backgroundColor: const Color(0xff303030), ), navigatorKey: widget.navigationKey, onGenerateRoute: (settings) { switch (settings.name) { case introRoute: return Intro.route; case loginRoute: return Login.route; case conversationsRoute: return ConversationsPage.route; case newConversationRoute: return NewConversationPage.route; case conversationRoute: return PageTransition( type: PageTransitionType.rightToLeft, settings: settings, child: const ConversationPage(), ); case sharedMediaRoute: return SharedMediaPage.route; case blocklistRoute: return BlocklistPage.route; case profileRoute: return ProfilePage.route; case settingsRoute: return SettingsPage.route; case aboutRoute: return SettingsAboutPage.route; case licensesRoute: return SettingsLicensesPage.route; case networkRoute: return NetworkPage.route; case privacyRoute: return PrivacyPage.route; case debuggingRoute: return DebuggingPage.route; case addContactRoute: return AddContactPage.route; case cropRoute: return CropPage.route; case sendFilesRoute: return SendFilesPage.route; case backgroundCroppingRoute: return CropBackgroundPage.route; case shareSelectionRoute: return ShareSelectionPage.route; case serverInfoRoute: return ServerInfoPage.route; case conversationSettingsRoute: return ConversationSettingsPage.route; case keysRoute: return KeysPage.route; case ownKeysRoute: return OwnKeysPage.route; } return null; }, home: const Splashscreen(), ); } }