Browse Source

feat: optimize startup task and integrate supabase

Lucas.Xu 2 years ago
parent
commit
d01afab96e

+ 1 - 28
frontend/appflowy_flutter/lib/main.dart

@@ -1,37 +1,10 @@
-import 'package:appflowy_backend/log.dart';
-import 'package:easy_localization/easy_localization.dart';
-import 'package:flutter/foundation.dart';
+import 'package:appflowy/startup/entry_point.dart';
 import 'package:flutter/material.dart';
-import 'package:hotkey_manager/hotkey_manager.dart';
 
-import 'startup/launch_configuration.dart';
 import 'startup/startup.dart';
-import 'user/presentation/splash_screen.dart';
-import 'window/window.dart';
-
-class FlowyApp implements EntryPoint {
-  @override
-  Widget create(LaunchConfiguration config) {
-    return SplashScreen(
-      autoRegister: config.autoRegistrationSupported,
-    );
-  }
-}
 
 Future<void> main() async {
   WidgetsFlutterBinding.ensureInitialized();
 
-  // Handle platform errors not caught by Flutter.
-  // Reduces the likelihood of the app crashing, and logs the error.
-  PlatformDispatcher.instance.onError = (error, stack) {
-    Log.error('Uncaught platform error', error, stack);
-    return true;
-  };
-
-  await EasyLocalization.ensureInitialized();
-  await hotKeyManager.unregisterAll();
-
-  await AppWindow.initialize();
-
   await FlowyRunner.run(FlowyApp());
 }

+ 13 - 0
frontend/appflowy_flutter/lib/startup/entry_point.dart

@@ -0,0 +1,13 @@
+import 'package:appflowy/startup/launch_configuration.dart';
+import 'package:appflowy/startup/startup.dart';
+import 'package:appflowy/user/presentation/splash_screen.dart';
+import 'package:flutter/material.dart';
+
+class FlowyApp implements EntryPoint {
+  @override
+  Widget create(LaunchConfiguration config) {
+    return SplashScreen(
+      autoRegister: config.autoRegistrationSupported,
+    );
+  }
+}

+ 39 - 16
frontend/appflowy_flutter/lib/startup/startup.dart

@@ -37,8 +37,9 @@ abstract class EntryPoint {
 class FlowyRunner {
   static Future<void> run(
     EntryPoint f, {
-    LaunchConfiguration config =
-        const LaunchConfiguration(autoRegistrationSupported: false),
+    LaunchConfiguration config = const LaunchConfiguration(
+      autoRegistrationSupported: false,
+    ),
   }) async {
     // Clear all the states in case of rebuilding.
     await getIt.reset();
@@ -52,16 +53,30 @@ class FlowyRunner {
         .then((value) => Directory(value));
 
     // add task
-    getIt<AppLauncher>().addTask(InitRustSDKTask(directory: directory));
-    getIt<AppLauncher>().addTask(PluginLoadTask());
-
-    if (!env.isTest()) {
-      getIt<AppLauncher>().addTask(InitAppWidgetTask());
-      getIt<AppLauncher>().addTask(InitPlatformServiceTask());
-    }
-
-    // execute the tasks
-    await getIt<AppLauncher>().launch();
+    final launcher = getIt<AppLauncher>();
+    launcher.addTasks(
+      [
+        // handle platform errors.
+        const PlatformErrorCatcherTask(),
+        // localization
+        const InitLocalizationTask(),
+        // init the app window
+        const InitAppWindowTask(),
+        // Init Rust SDK
+        InitRustSDKTask(directory: directory),
+        // Load Plugins, like document, grid ...
+        const PluginLoadTask(),
+
+        // init the app widget
+        // ignore in test mode
+        if (!env.isTest()) ...[
+          const HotKeyTask(),
+          const InitAppWidgetTask(),
+          const InitPlatformServiceTask()
+        ],
+      ],
+    );
+    await launcher.launch(); // execute the tasks
   }
 }
 
@@ -104,23 +119,31 @@ enum LaunchTaskType {
 /// The interface of an app launch task, which will trigger
 /// some nonresident indispensable task in app launching task.
 abstract class LaunchTask {
+  const LaunchTask();
+
   LaunchTaskType get type => LaunchTaskType.dataProcessing;
+
   Future<void> initialize(LaunchContext context);
 }
 
 class AppLauncher {
-  List<LaunchTask> tasks;
+  AppLauncher({
+    required this.context,
+  });
 
   final LaunchContext context;
-
-  AppLauncher({required this.context}) : tasks = List.from([]);
+  final List<LaunchTask> tasks = [];
 
   void addTask(LaunchTask task) {
     tasks.add(task);
   }
 
+  void addTasks(Iterable<LaunchTask> tasks) {
+    this.tasks.addAll(tasks);
+  }
+
   Future<void> launch() async {
-    for (var task in tasks) {
+    for (final task in tasks) {
       await task.initialize(context);
     }
   }

+ 2 - 0
frontend/appflowy_flutter/lib/startup/tasks/app_widget.dart

@@ -11,6 +11,8 @@ import '../../workspace/application/appearance.dart';
 import '../startup.dart';
 
 class InitAppWidgetTask extends LaunchTask {
+  const InitAppWidgetTask();
+
   @override
   LaunchTaskType get type => LaunchTaskType.appLauncher;
 

+ 12 - 0
frontend/appflowy_flutter/lib/startup/tasks/hot_key.dart

@@ -0,0 +1,12 @@
+import 'package:hotkey_manager/hotkey_manager.dart';
+
+import '../startup.dart';
+
+class HotKeyTask extends LaunchTask {
+  const HotKeyTask();
+
+  @override
+  Future<void> initialize(LaunchContext context) async {
+    await hotKeyManager.unregisterAll();
+  }
+}

+ 2 - 0
frontend/appflowy_flutter/lib/startup/tasks/load_plugin.dart

@@ -8,6 +8,8 @@ import 'package:appflowy/plugins/document/document.dart';
 import 'package:appflowy/plugins/trash/trash.dart';
 
 class PluginLoadTask extends LaunchTask {
+  const PluginLoadTask();
+
   @override
   LaunchTaskType get type => LaunchTaskType.dataProcessing;
 

+ 12 - 0
frontend/appflowy_flutter/lib/startup/tasks/localization.dart

@@ -0,0 +1,12 @@
+import 'package:easy_localization/easy_localization.dart';
+
+import '../startup.dart';
+
+class InitLocalizationTask extends LaunchTask {
+  const InitLocalizationTask();
+
+  @override
+  Future<void> initialize(LaunchContext context) async {
+    await EasyLocalization.ensureInitialized();
+  }
+}

+ 21 - 0
frontend/appflowy_flutter/lib/startup/tasks/platform_error_catcher.dart

@@ -0,0 +1,21 @@
+import 'package:appflowy_backend/log.dart';
+import 'package:flutter/foundation.dart';
+
+import '../startup.dart';
+
+class PlatformErrorCatcherTask extends LaunchTask {
+  const PlatformErrorCatcherTask();
+
+  @override
+  Future<void> initialize(LaunchContext context) async {
+    // Handle platform errors not caught by Flutter.
+    // Reduces the likelihood of the app crashing, and logs the error.
+    // only active in non debug mode.
+    if (!kDebugMode) {
+      PlatformDispatcher.instance.onError = (error, stack) {
+        Log.error('Uncaught platform error', error, stack);
+        return true;
+      };
+    }
+  }
+}

+ 2 - 0
frontend/appflowy_flutter/lib/startup/tasks/platform_service.dart

@@ -2,6 +2,8 @@ import 'package:appflowy/core/network_monitor.dart';
 import '../startup.dart';
 
 class InitPlatformServiceTask extends LaunchTask {
+  const InitPlatformServiceTask();
+
   @override
   LaunchTaskType get type => LaunchTaskType.dataProcessing;
 

+ 4 - 0
frontend/appflowy_flutter/lib/startup/tasks/prelude.dart

@@ -2,3 +2,7 @@ export 'app_widget.dart';
 export 'rust_sdk.dart';
 export 'platform_service.dart';
 export 'load_plugin.dart';
+export 'hot_key.dart';
+export 'platform_error_catcher.dart';
+export 'windows.dart';
+export 'localization.dart';

+ 1 - 1
frontend/appflowy_flutter/lib/startup/tasks/rust_sdk.dart

@@ -7,7 +7,7 @@ import 'package:path/path.dart' as path;
 import '../startup.dart';
 
 class InitRustSDKTask extends LaunchTask {
-  InitRustSDKTask({
+  const InitRustSDKTask({
     this.directory,
   });
 

+ 14 - 15
frontend/appflowy_flutter/lib/window/app_window.dart → frontend/appflowy_flutter/lib/startup/tasks/windows.dart

@@ -1,37 +1,36 @@
 import 'dart:ui';
 
 import 'package:appflowy/core/helpers/helpers.dart';
+import 'package:appflowy/startup/startup.dart';
 import 'package:flutter/foundation.dart';
 import 'package:window_manager/window_manager.dart';
 
-/// Represents the main window of the app.
-class AppWindow {
-  /// The singleton instance of the window.
-  static late AppWindow instance;
+class InitAppWindowTask extends LaunchTask {
+  const InitAppWindowTask({
+    this.minimumSize = const Size(600, 400),
+    this.title = 'AppFlowy',
+  });
 
-  AppWindow._() {
-    instance = this;
-  }
+  final Size minimumSize;
+  final String title;
 
-  /// Initializes the window.
-  static Future<AppWindow?> initialize() async {
+  @override
+  Future<void> initialize(LaunchContext context) async {
     // Don't initialize on mobile or web.
     if (!defaultTargetPlatform.isDesktop) {
-      return null;
+      return;
     }
 
     await windowManager.ensureInitialized();
 
-    WindowOptions windowOptions = const WindowOptions(
-      minimumSize: Size(600, 400),
-      title: 'AppFlowy',
+    WindowOptions windowOptions = WindowOptions(
+      minimumSize: minimumSize,
+      title: title,
     );
 
     await windowManager.waitUntilReadyToShow(windowOptions, () async {
       await windowManager.show();
       await windowManager.focus();
     });
-
-    return AppWindow._();
   }
 }

+ 1 - 1
frontend/appflowy_flutter/lib/user/presentation/skip_log_in_screen.dart

@@ -1,4 +1,5 @@
 import 'package:appflowy/core/frameless_window.dart';
+import 'package:appflowy/startup/entry_point.dart';
 import 'package:dartz/dartz.dart' as dartz;
 import 'package:easy_localization/easy_localization.dart';
 import 'package:flowy_infra/size.dart';
@@ -12,7 +13,6 @@ import 'package:flutter/material.dart';
 import 'package:url_launcher/url_launcher.dart';
 
 import '../../generated/locale_keys.g.dart';
-import '../../main.dart';
 import '../../startup/launch_configuration.dart';
 import '../../startup/startup.dart';
 import '../application/auth_service.dart';

+ 0 - 1
frontend/appflowy_flutter/lib/window/window.dart

@@ -1 +0,0 @@
-export 'app_window.dart';

+ 1 - 1
frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_file_customize_location_view.dart

@@ -1,3 +1,4 @@
+import 'package:appflowy/startup/entry_point.dart';
 import 'package:appflowy/util/file_picker/file_picker_service.dart';
 import 'package:appflowy/workspace/application/settings/settings_location_cubit.dart';
 import 'package:flutter/material.dart';
@@ -7,7 +8,6 @@ import 'package:flowy_infra_ui/flowy_infra_ui.dart';
 import 'package:flutter/services.dart';
 
 import '../../../../generated/locale_keys.g.dart';
-import '../../../../main.dart';
 import '../../../../startup/launch_configuration.dart';
 import '../../../../startup/startup.dart';
 import '../../../../startup/tasks/prelude.dart';

+ 176 - 0
frontend/appflowy_flutter/pubspec.lock

@@ -25,6 +25,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "2.0.7"
+  app_links:
+    dependency: transitive
+    description:
+      name: app_links
+      sha256: d572dcdff49c4cfcfa6f315e2683e518ec6eb54e084d01e51d9631a4dcc1b5e8
+      url: "https://pub.dev"
+    source: hosted
+    version: "3.4.2"
   appflowy_backend:
     dependency: "direct main"
     description:
@@ -580,6 +588,14 @@ packages:
     description: flutter
     source: sdk
     version: "0.0.0"
+  functions_client:
+    dependency: transitive
+    description:
+      name: functions_client
+      sha256: "26059c5fb000ffd0986ae3144d43c2a6f54931610fd61c2584e18e308c7eaa52"
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.2.1"
   get_it:
     dependency: "direct main"
     description:
@@ -604,6 +620,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "4.0.3"
+  gotrue:
+    dependency: transitive
+    description:
+      name: gotrue
+      sha256: c08f5ac76dcae2dd06cc7f8e80a8ede12c66454fef06caac3b191c8c7a603811
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.7.1"
   graphs:
     dependency: transitive
     description:
@@ -620,6 +644,22 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "0.7.0"
+  hive:
+    dependency: transitive
+    description:
+      name: hive
+      sha256: "8dcf6db979d7933da8217edcec84e9df1bdb4e4edc7fc77dbd5aa74356d6d941"
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.2.3"
+  hive_flutter:
+    dependency: transitive
+    description:
+      name: hive_flutter
+      sha256: dca1da446b1d808a51689fb5d0c6c9510c0a2ba01e22805d492c73b68e33eecc
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.1.0"
   hotkey_manager:
     dependency: "direct main"
     description:
@@ -721,6 +761,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "6.5.4"
+  jwt_decode:
+    dependency: transitive
+    description:
+      name: jwt_decode
+      sha256: d2e9f68c052b2225130977429d30f187aa1981d789c76ad104a32243cfdebfbb
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.3.1"
   linked_scroll_controller:
     dependency: "direct main"
     description:
@@ -1009,6 +1057,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.5.1"
+  postgrest:
+    dependency: transitive
+    description:
+      name: postgrest
+      sha256: "7b91eb7b40621d07aaae687f47f3032f30e1b86a9ccebfcfca52d001223f8b6e"
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.2.4"
   process:
     dependency: transitive
     description:
@@ -1049,6 +1105,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.2.1"
+  realtime_client:
+    dependency: transitive
+    description:
+      name: realtime_client
+      sha256: "0f2614f72e5639ddd7abc3dede336f23554f9f744d0b064d41009f9ca94a53d2"
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.0.4"
   reorderables:
     dependency: "direct main"
     description:
@@ -1057,6 +1121,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "0.6.0"
+  retry:
+    dependency: transitive
+    description:
+      name: retry
+      sha256: a8a1e475a100a0bdc73f529ca8ea1e9c9c76bec8ad86a1f47780139a34ce7aea
+      url: "https://pub.dev"
+    source: hosted
+    version: "3.1.1"
   rich_clipboard:
     dependency: transitive
     description:
@@ -1121,6 +1193,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.0.2"
+  rxdart:
+    dependency: transitive
+    description:
+      name: rxdart
+      sha256: "0c7c0cedd93788d996e33041ffecda924cc54389199cde4e6a34b440f50044cb"
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.27.7"
   screen_retriever:
     dependency: transitive
     description:
@@ -1217,6 +1297,30 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.0.3"
+  sign_in_with_apple:
+    dependency: transitive
+    description:
+      name: sign_in_with_apple
+      sha256: ac3b113767dfdd765078c507dad9d4d9fe96b669cc7bd88fc36fc15376fb3400
+      url: "https://pub.dev"
+    source: hosted
+    version: "4.3.0"
+  sign_in_with_apple_platform_interface:
+    dependency: transitive
+    description:
+      name: sign_in_with_apple_platform_interface
+      sha256: a5883edee09ed6be19de19e7d9f618a617fe41a6fa03f76d082dfb787e9ea18d
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.0.0"
+  sign_in_with_apple_web:
+    dependency: transitive
+    description:
+      name: sign_in_with_apple_web
+      sha256: "44b66528f576e77847c14999d5e881e17e7223b7b0625a185417829e5306f47a"
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.0.1"
   simple_gesture_detector:
     dependency: transitive
     description:
@@ -1286,6 +1390,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.11.0"
+  storage_client:
+    dependency: transitive
+    description:
+      name: storage_client
+      sha256: "4ed4dc8a990d178c96962319d6d8c267c3e206fca2c2b98660bad6e001220ffc"
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.3.1"
   stream_channel:
     dependency: transitive
     description:
@@ -1318,6 +1430,22 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "0.3.1+2"
+  supabase:
+    dependency: transitive
+    description:
+      name: supabase
+      sha256: "403739cdfea48ba633450e5b191ceeaae81ac10ec89166c0e109235b3e1532f3"
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.8.1"
+  supabase_flutter:
+    dependency: "direct main"
+    description:
+      name: supabase_flutter
+      sha256: "7cbdd9a7264dd5b7ab5a6e2da63346054b8e5ddf358467c7f2bc23d5c14d732c"
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.9.1"
   sync_http:
     dependency: transitive
     description:
@@ -1414,6 +1542,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.3.1"
+  universal_io:
+    dependency: transitive
+    description:
+      name: universal_io
+      sha256: "06866290206d196064fd61df4c7aea1ffe9a4e7c4ccaa8fcded42dd41948005d"
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.2.0"
   universal_platform:
     dependency: transitive
     description:
@@ -1566,6 +1702,38 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.2.0"
+  webview_flutter:
+    dependency: transitive
+    description:
+      name: webview_flutter
+      sha256: "1a37bdbaaf5fbe09ad8579ab09ecfd473284ce482f900b5aea27cf834386a567"
+      url: "https://pub.dev"
+    source: hosted
+    version: "4.2.0"
+  webview_flutter_android:
+    dependency: transitive
+    description:
+      name: webview_flutter_android
+      sha256: "1acea8def62592123e2fbbca164ed8681a98a890bdcbb88f916d5b4a22687759"
+      url: "https://pub.dev"
+    source: hosted
+    version: "3.7.0"
+  webview_flutter_platform_interface:
+    dependency: transitive
+    description:
+      name: webview_flutter_platform_interface
+      sha256: "78715dc442b7849dbde74e92bb67de1cecf5addf95531c5fb474e72f5fe9a507"
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.3.0"
+  webview_flutter_wkwebview:
+    dependency: transitive
+    description:
+      name: webview_flutter_wkwebview
+      sha256: "4646bb68297803bdbb96d46853e8fcb560d6cb5e04153fa64581535767875dfe"
+      url: "https://pub.dev"
+    source: hosted
+    version: "3.4.3"
   win32:
     dependency: transitive
     description:
@@ -1606,6 +1774,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "3.1.1"
+  yet_another_json_isolate:
+    dependency: transitive
+    description:
+      name: yet_another_json_isolate
+      sha256: "94ba4947ac1ce44bd6a1634d9df712e07b9b5025ba12abd6750be77ba5c08f18"
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.0.4"
 sdks:
   dart: ">=2.19.0 <3.0.0"
   flutter: ">=3.7.0"

+ 1 - 0
frontend/appflowy_flutter/pubspec.yaml

@@ -107,6 +107,7 @@ dependencies:
   archive: ^3.3.0
   flutter_svg: ^2.0.5
   nanoid: ^1.0.0
+  supabase_flutter: ^1.9.1
 
 dev_dependencies:
   flutter_lints: ^2.0.1

+ 0 - 2
frontend/appflowy_flutter/test/util.dart

@@ -4,7 +4,6 @@ import 'package:appflowy/user/application/auth_service.dart';
 import 'package:appflowy/user/application/user_service.dart';
 import 'package:appflowy/workspace/application/workspace/workspace_service.dart';
 import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart';
-import 'package:easy_localization/easy_localization.dart';
 import 'package:flowy_infra/uuid.dart';
 import 'package:appflowy_backend/protobuf/flowy-folder2/workspace.pb.dart';
 import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart';
@@ -35,7 +34,6 @@ class AppFlowyUnitTest {
     SharedPreferences.setMockInitialValues({});
     _pathProviderInitialized();
 
-    await EasyLocalization.ensureInitialized();
     await FlowyRunner.run(FlowyTestApp());
 
     final test = AppFlowyUnitTest();