main.dart 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. import 'dart:async';
  2. import 'dart:io';
  3. import 'package:adaptive_theme/adaptive_theme.dart';
  4. import "package:ente_auth/app/view/app.dart";
  5. import 'package:ente_auth/core/configuration.dart';
  6. import 'package:ente_auth/core/constants.dart';
  7. import 'package:ente_auth/core/logging/super_logging.dart';
  8. import 'package:ente_auth/core/network.dart';
  9. import 'package:ente_auth/ente_theme_data.dart';
  10. import 'package:ente_auth/locale.dart';
  11. import 'package:ente_auth/services/authenticator_service.dart';
  12. import 'package:ente_auth/services/billing_service.dart';
  13. import 'package:ente_auth/services/notification_service.dart';
  14. import 'package:ente_auth/services/preference_service.dart';
  15. import 'package:ente_auth/services/update_service.dart';
  16. import 'package:ente_auth/services/user_remote_flag_service.dart';
  17. import 'package:ente_auth/services/user_service.dart';
  18. import 'package:ente_auth/services/window_listener_service.dart';
  19. import 'package:ente_auth/store/code_store.dart';
  20. import 'package:ente_auth/ui/tools/app_lock.dart';
  21. import 'package:ente_auth/ui/tools/lock_screen.dart';
  22. import 'package:ente_auth/ui/utils/icon_utils.dart';
  23. import 'package:ente_auth/utils/platform_util.dart';
  24. import 'package:ente_auth/utils/window_protocol_handler.dart';
  25. import 'package:ente_crypto_dart/ente_crypto_dart.dart';
  26. import 'package:flutter/foundation.dart';
  27. import "package:flutter/material.dart";
  28. import 'package:flutter/scheduler.dart';
  29. import 'package:flutter_displaymode/flutter_displaymode.dart';
  30. import 'package:logging/logging.dart';
  31. import 'package:path_provider/path_provider.dart';
  32. import 'package:privacy_screen/privacy_screen.dart';
  33. import 'package:tray_manager/tray_manager.dart';
  34. import 'package:window_manager/window_manager.dart';
  35. final _logger = Logger("main");
  36. Future<void> initSystemTray() async {
  37. if (PlatformUtil.isMobile()) return;
  38. String path = Platform.isWindows
  39. ? 'assets/icons/auth-icon.ico'
  40. : 'assets/icons/auth-icon.png';
  41. await trayManager.setIcon(path);
  42. Menu menu = Menu(
  43. items: [
  44. MenuItem(
  45. key: 'hide_window',
  46. label: 'Hide Window',
  47. ),
  48. MenuItem(
  49. key: 'show_window',
  50. label: 'Show Window',
  51. ),
  52. MenuItem.separator(),
  53. MenuItem(
  54. key: 'exit_app',
  55. label: 'Exit App',
  56. ),
  57. ],
  58. );
  59. await trayManager.setContextMenu(menu);
  60. }
  61. void main() async {
  62. WidgetsFlutterBinding.ensureInitialized();
  63. initSystemTray().ignore();
  64. if (PlatformUtil.isDesktop()) {
  65. await windowManager.ensureInitialized();
  66. await WindowListenerService.instance.init();
  67. WindowOptions windowOptions = WindowOptions(
  68. size: WindowListenerService.instance.getWindowSize(),
  69. );
  70. await windowManager.waitUntilReadyToShow(windowOptions, () async {
  71. await windowManager.show();
  72. await windowManager.focus();
  73. });
  74. }
  75. await _runInForeground();
  76. await _setupPrivacyScreen();
  77. if (Platform.isAndroid) {
  78. FlutterDisplayMode.setHighRefreshRate().ignore();
  79. }
  80. }
  81. Future<void> _runInForeground() async {
  82. final savedThemeMode = _themeMode(await AdaptiveTheme.getThemeMode());
  83. return await _runWithLogs(() async {
  84. _logger.info("Starting app in foreground");
  85. await _init(false, via: 'mainMethod');
  86. final Locale locale = await getLocale();
  87. unawaited(UpdateService.instance.showUpdateNotification());
  88. runApp(
  89. AppLock(
  90. builder: (args) => App(locale: locale),
  91. lockScreen: const LockScreen(),
  92. enabled: Configuration.instance.shouldShowLockScreen(),
  93. locale: locale,
  94. lightTheme: lightThemeData,
  95. darkTheme: darkThemeData,
  96. savedThemeMode: savedThemeMode,
  97. ),
  98. );
  99. });
  100. }
  101. ThemeMode _themeMode(AdaptiveThemeMode? savedThemeMode) {
  102. if (savedThemeMode == null) return ThemeMode.system;
  103. if (savedThemeMode.isLight) return ThemeMode.light;
  104. if (savedThemeMode.isDark) return ThemeMode.dark;
  105. return ThemeMode.system;
  106. }
  107. Future _runWithLogs(Function() function, {String prefix = ""}) async {
  108. String dir = "";
  109. try {
  110. dir = "${(await getApplicationSupportDirectory()).path}/logs";
  111. } catch (_) {}
  112. await SuperLogging.main(
  113. LogConfig(
  114. body: function,
  115. logDirPath: dir,
  116. maxLogFiles: 5,
  117. sentryDsn: sentryDSN,
  118. enableInDebugMode: true,
  119. prefix: prefix,
  120. ),
  121. );
  122. }
  123. void _registerWindowsProtocol() {
  124. const kWindowsScheme = 'ente';
  125. // Register our protocol only on Windows platform
  126. if (!kIsWeb && Platform.isWindows) {
  127. WindowsProtocolHandler()
  128. .register(kWindowsScheme, executable: null, arguments: null);
  129. }
  130. }
  131. Future<void> _init(bool bool, {String? via}) async {
  132. _registerWindowsProtocol();
  133. await initCryptoUtil();
  134. await PreferenceService.instance.init();
  135. await CodeStore.instance.init();
  136. await Configuration.instance.init();
  137. await Network.instance.init();
  138. await UserService.instance.init();
  139. await UserRemoteFlagService.instance.init();
  140. await AuthenticatorService.instance.init();
  141. await BillingService.instance.init();
  142. await NotificationService.instance.init();
  143. await UpdateService.instance.init();
  144. await IconUtils.instance.init();
  145. }
  146. Future<void> _setupPrivacyScreen() async {
  147. if (!PlatformUtil.isMobile()) return;
  148. final brightness =
  149. SchedulerBinding.instance.platformDispatcher.platformBrightness;
  150. bool isInDarkMode = brightness == Brightness.dark;
  151. await PrivacyScreen.instance.enable(
  152. iosOptions: const PrivacyIosOptions(
  153. enablePrivacy: true,
  154. privacyImageName: "LaunchImage",
  155. lockTrigger: IosLockTrigger.didEnterBackground,
  156. ),
  157. androidOptions: const PrivacyAndroidOptions(
  158. enableSecure: true,
  159. ),
  160. backgroundColor: isInDarkMode ? Colors.black : Colors.white,
  161. blurEffect:
  162. isInDarkMode ? PrivacyBlurEffect.dark : PrivacyBlurEffect.extraLight,
  163. );
  164. }