feat: optimize startup task and integrate supabase

This commit is contained in:
Lucas.Xu 2023-05-17 11:03:33 +08:00
parent 19ee0ea44d
commit d01afab96e
18 changed files with 301 additions and 64 deletions

View File

@ -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());
}

View File

@ -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,
);
}
}

View File

@ -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());
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(),
if (!env.isTest()) {
getIt<AppLauncher>().addTask(InitAppWidgetTask());
getIt<AppLauncher>().addTask(InitPlatformServiceTask());
}
// execute the tasks
await getIt<AppLauncher>().launch();
// 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);
}
}

View File

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

View File

@ -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();
}
}

View File

@ -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;

View File

@ -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();
}
}

View File

@ -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;
};
}
}
}

View File

@ -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;

View File

@ -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';

View File

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

View File

@ -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._();
}
}

View File

@ -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';

View File

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

View File

@ -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';

View File

@ -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"

View File

@ -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

View File

@ -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();