startup.dart 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. import 'dart:io';
  2. import 'package:appflowy/env/env.dart';
  3. import 'package:appflowy/workspace/application/settings/settings_location_cubit.dart';
  4. import 'package:appflowy_backend/appflowy_backend.dart';
  5. import 'package:flutter/foundation.dart';
  6. import 'package:flutter/material.dart';
  7. import 'package:get_it/get_it.dart';
  8. import 'deps_resolver.dart';
  9. import 'launch_configuration.dart';
  10. import 'plugin/plugin.dart';
  11. import 'tasks/prelude.dart';
  12. final getIt = GetIt.instance;
  13. abstract class EntryPoint {
  14. Widget create(LaunchConfiguration config);
  15. }
  16. class FlowyRunner {
  17. static Future<void> run(
  18. EntryPoint f, {
  19. LaunchConfiguration config = const LaunchConfiguration(
  20. autoRegistrationSupported: false,
  21. ),
  22. }) async {
  23. // Clear all the states in case of rebuilding.
  24. await getIt.reset();
  25. // Specify the env
  26. final env = integrationEnv();
  27. initGetIt(getIt, env, f, config);
  28. final directory = await getIt<LocalFileStorage>()
  29. .getPath()
  30. .then((value) => Directory(value));
  31. // final directory = await appFlowyDocumentDirectory();
  32. // add task
  33. final launcher = getIt<AppLauncher>();
  34. launcher.addTasks(
  35. [
  36. // handle platform errors.
  37. const PlatformErrorCatcherTask(),
  38. // localization
  39. const InitLocalizationTask(),
  40. // init the app window
  41. const InitAppWindowTask(),
  42. // Init Rust SDK
  43. InitRustSDKTask(directory: directory),
  44. // Load Plugins, like document, grid ...
  45. const PluginLoadTask(),
  46. // init the app widget
  47. // ignore in test mode
  48. if (!env.isTest()) ...[
  49. const HotKeyTask(),
  50. InitSupabaseTask(
  51. url: Env.supabaseUrl,
  52. anonKey: Env.supabaseAnonKey,
  53. key: Env.supabaseKey,
  54. jwtSecret: Env.supabaseJwtSecret,
  55. collabTable: Env.supabaseCollabTable,
  56. ),
  57. const InitAppWidgetTask(),
  58. const InitPlatformServiceTask()
  59. ],
  60. ],
  61. );
  62. await launcher.launch(); // execute the tasks
  63. }
  64. }
  65. Future<void> initGetIt(
  66. GetIt getIt,
  67. IntegrationMode env,
  68. EntryPoint f,
  69. LaunchConfiguration config,
  70. ) async {
  71. getIt.registerFactory<EntryPoint>(() => f);
  72. getIt.registerLazySingleton<FlowySDK>(() {
  73. return FlowySDK();
  74. });
  75. getIt.registerLazySingleton<AppLauncher>(
  76. () => AppLauncher(
  77. context: LaunchContext(
  78. getIt,
  79. env,
  80. config,
  81. ),
  82. ),
  83. );
  84. getIt.registerSingleton<PluginSandbox>(PluginSandbox());
  85. await DependencyResolver.resolve(getIt);
  86. }
  87. class LaunchContext {
  88. GetIt getIt;
  89. IntegrationMode env;
  90. LaunchConfiguration config;
  91. LaunchContext(this.getIt, this.env, this.config);
  92. }
  93. enum LaunchTaskType {
  94. dataProcessing,
  95. appLauncher,
  96. }
  97. /// The interface of an app launch task, which will trigger
  98. /// some nonresident indispensable task in app launching task.
  99. abstract class LaunchTask {
  100. const LaunchTask();
  101. LaunchTaskType get type => LaunchTaskType.dataProcessing;
  102. Future<void> initialize(LaunchContext context);
  103. }
  104. class AppLauncher {
  105. AppLauncher({
  106. required this.context,
  107. });
  108. final LaunchContext context;
  109. final List<LaunchTask> tasks = [];
  110. void addTask(LaunchTask task) {
  111. tasks.add(task);
  112. }
  113. void addTasks(Iterable<LaunchTask> tasks) {
  114. this.tasks.addAll(tasks);
  115. }
  116. Future<void> launch() async {
  117. for (final task in tasks) {
  118. await task.initialize(context);
  119. }
  120. }
  121. }
  122. enum IntegrationMode {
  123. develop,
  124. release,
  125. test,
  126. }
  127. extension IntegrationEnvExt on IntegrationMode {
  128. bool isTest() {
  129. return this == IntegrationMode.test;
  130. }
  131. }
  132. IntegrationMode integrationEnv() {
  133. if (Platform.environment.containsKey('FLUTTER_TEST')) {
  134. return IntegrationMode.test;
  135. }
  136. if (kReleaseMode) {
  137. return IntegrationMode.release;
  138. }
  139. return IntegrationMode.develop;
  140. }