From 4c8d61ab8c5c110cf50e66a951d9b3ae8890a6b6 Mon Sep 17 00:00:00 2001 From: mathru Date: Sun, 5 Feb 2023 11:19:54 +0900 Subject: [PATCH] feat: Added MasamuneAdapter. --- packages/masamune/example/pubspec.lock | 28 +-- packages/masamune/lib/masamune.dart | 1 + .../masamune/lib/src/masamune_adapter.dart | 80 ++++++++ packages/masamune/lib/src/masamune_app.dart | 171 +++++++++++++++++- packages/masamune/pubspec.lock | 24 +-- packages/masamune_annotation/pubspec.lock | 4 +- packages/masamune_builder/pubspec.lock | 12 +- 7 files changed, 279 insertions(+), 41 deletions(-) create mode 100644 packages/masamune/lib/src/masamune_adapter.dart diff --git a/packages/masamune/example/pubspec.lock b/packages/masamune/example/pubspec.lock index 38fe40417..144861670 100644 --- a/packages/masamune/example/pubspec.lock +++ b/packages/masamune/example/pubspec.lock @@ -401,10 +401,10 @@ packages: dependency: transitive description: name: katana_form - sha256: "29d02abf2a2961a1cec48efa0901b398e8a6ec9621e1f865a8346201398a913e" + sha256: "0a9cf858d76331765ee6ca03a0a7e1c4b927da9ea21eb9944a4ff4b7222df402" url: "https://pub.dev" source: hosted - version: "1.3.8" + version: "1.3.10" katana_functions: dependency: transitive description: @@ -473,18 +473,18 @@ packages: dependency: transitive description: name: katana_model - sha256: "4d5db5f025bed98460e0deea908b56f10d65415a98ac58354f01baf85f2bb3c6" + sha256: aeabf0992fa9a35408f3fd10b6a9411d2f409eadb97d426164af7866eca27915 url: "https://pub.dev" source: hosted - version: "1.5.8" + version: "1.5.9" katana_prefs: dependency: transitive description: name: katana_prefs - sha256: dd45a8481abebf128bf6cb539ed39b7252b76e50544046eaa6417160e03410d1 + sha256: d67a1d185d72ebab7a21f78c71d16559c982034115266871cd13813914349dd9 url: "https://pub.dev" source: hosted - version: "1.1.14" + version: "1.1.16" katana_prefs_annotation: dependency: transitive description: @@ -497,10 +497,10 @@ packages: dependency: transitive description: name: katana_prefs_builder - sha256: "9180b29391a808cb7902f48769b1e4eb15f6b7f3d0ca48f3623dbac4e4b630ee" + sha256: "1876a45f1ce7f90d3f92d5bb8bf8f70861ad239371d9aa89f8d79d90c0d62807" url: "https://pub.dev" source: hosted - version: "1.1.17" + version: "1.1.19" katana_router: dependency: transitive description: @@ -603,22 +603,22 @@ packages: path: ".." relative: true source: path - version: "1.4.14" + version: "1.4.20" masamune_annotation: dependency: transitive description: name: masamune_annotation - sha256: "10366db8d1a6f8745b9b02bbce249b12d4e96dd11e6021c8756359974bf1f260" + sha256: deeab4150a3ceb2fac1005df4811112e68ad10ceada5457bccb602a289688def url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.2.1" masamune_builder: dependency: "direct dev" description: path: "../../masamune_builder" relative: true source: path - version: "1.2.7" + version: "1.2.10" matcher: dependency: transitive description: @@ -948,10 +948,10 @@ packages: dependency: transitive description: name: tint - sha256: d856019547532d4ea24171f554b319081c004c37741e7946eae30cb09f24e1c7 + sha256: "9652d9a589f4536d5e392cf790263d120474f15da3cf1bee7f1fdb31b4de5f46" url: "https://pub.dev" source: hosted - version: "2.0.0" + version: "2.0.1" typed_data: dependency: transitive description: diff --git a/packages/masamune/lib/masamune.dart b/packages/masamune/lib/masamune.dart index 9263c4f56..86f3d8c54 100644 --- a/packages/masamune/lib/masamune.dart +++ b/packages/masamune/lib/masamune.dart @@ -41,6 +41,7 @@ part 'model/model.dart'; part 'prefs/prefs.dart'; part 'scoped/controller.dart'; part 'src/masamune_app.dart'; +part 'src/masamune_adapter.dart'; part 'ui/grid_builder.dart'; part 'ui/list_builder.dart'; diff --git a/packages/masamune/lib/src/masamune_adapter.dart b/packages/masamune/lib/src/masamune_adapter.dart new file mode 100644 index 000000000..d0113efd2 --- /dev/null +++ b/packages/masamune/lib/src/masamune_adapter.dart @@ -0,0 +1,80 @@ +part of masamune; + +/// Adapter for easily adding functions to Masamune Framework. +/// +/// Setting [runZonedGuarded] to `true` allows wrapping [runApp] with [runZonedGuarded]. +/// At that time, [onPreRunApp] can be used to execute the process before [runApp], and [onError] can be used to describe the process in case of an error. +/// +/// You can set up observers to monitor transitions between pages at [navigatorObservers]. +/// +/// Widgets can be added during the build of [MasamuneApp] with [onBuildApp]. +/// +/// Masamune Frameworkに機能を手軽に追加するためのアダプター。 +/// +/// アプリ起動時と[MasamuneApp]に渡す処理を記述することができます。 +/// +/// [runZonedGuarded]を`true`にすると[runApp]を[runZonedGuarded]でラッピングすることができます。 +/// その際、[onPreRunApp]で[runApp]前の処理を実行することができ、[onError]でエラー時の処理を記述することができます。 +/// +/// [navigatorObservers]でページ間の遷移を監視するためのオブザーバーを設置することができます。 +/// +/// [onBuildApp]で[MasamuneApp]のビルド時にウィジェットを追加することが可能です。 +abstract class MasamuneAdapter { + /// Adapter for easily adding functions to Masamune Framework. + /// + /// Setting [runZonedGuarded] to `true` allows wrapping [runApp] with [runZonedGuarded]. + /// At that time, [onPreRunApp] can be used to execute the process before [runApp], and [onError] can be used to describe the process in case of an error. + /// + /// You can set up observers to monitor transitions between pages at [navigatorObservers]. + /// + /// Widgets can be added during the build of [MasamuneApp] with [onBuildApp]. + /// + /// Masamune Frameworkに機能を手軽に追加するためのアダプター。 + /// + /// アプリ起動時と[MasamuneApp]に渡す処理を記述することができます。 + /// + /// [runZonedGuarded]を`true`にすると[runApp]を[runZonedGuarded]でラッピングすることができます。 + /// その際、[onPreRunApp]で[runApp]前の処理を実行することができ、[onError]でエラー時の処理を記述することができます。 + /// + /// [navigatorObservers]でページ間の遷移を監視するためのオブザーバーを設置することができます。 + /// + /// [onBuildApp]で[MasamuneApp]のビルド時にウィジェットを追加することが可能です。 + const MasamuneAdapter(); + + /// If you set this to `true`, you can wrap [runApp] with [runZonedGuarded]. + /// + /// これを`true`にした場合、[runApp]を[runZonedGuarded]でラッピングすることができます。 + bool get runZonedGuarded; + + /// Observers can be set up to monitor transitions between pages. + /// + /// ページ間の遷移を監視するためのオブザーバーを設置することができます。 + List get navigatorObservers; + + /// Widgets can be added during the build of [MasamuneApp]. + /// + /// The widget generated in [MasamuneApp] is passed to [app]. + /// + /// Returning [Widget] will build the widget. + /// + /// [MasamuneApp]のビルド時にウィジェットを追加することが可能です。 + /// + /// [app]に[MasamuneApp]内で生成されたウィジェットが渡されます。 + /// + /// [Widget]を返すとそのウィジェットがビルドされます。 + Widget onBuildApp(BuildContext context, Widget app); + + /// You can describe the process before [runApp]. + /// + /// [runApp]前の処理を記述することができます。 + FutureOr? onPreRunApp(); + + /// You can describe the process when [runZonedGuarded] is set to `true`. + /// + /// The object in which the error occurred is passed to [error] and [stackTrace]. + /// + /// [runZonedGuarded]を`true`にした場合の処理を記述することができます。 + /// + /// [error]と[stackTrace]にエラーが起きた際のオブジェクトが渡されます。 + void onError(Object error, StackTrace stackTrace); +} diff --git a/packages/masamune/lib/src/masamune_app.dart b/packages/masamune/lib/src/masamune_app.dart index 44ec57d08..1994fb39c 100644 --- a/packages/masamune/lib/src/masamune_app.dart +++ b/packages/masamune/lib/src/masamune_app.dart @@ -5,9 +5,142 @@ part of masamune; /// デフォルトのロケール。 const kDefaultLocales = [Locale("en", "US")]; -/// MaterialApp] for Masamune Framework. +/// Function to run [MaterialApp] for Masamune Framework with [runApp]. +/// You may use this instead of [runApp]. /// -/// It encompasses the XXScope widget used in a series of katana packages. +/// Passing [masamuneAdapter] makes it easy to use additional plug-ins for the Masamune Framework. +/// +/// Wraps [runApp] with [runZonedGuarded] if [MasamuneAdapter.runZonedGuarded] is specified as `true` in [MasamuneAdapter]. +/// +/// It encapsulates the XXScope widget used in a series of katana packages. In addition, XXXScope can be specified by adding [onBuildAppFilters]. +/// +/// You can pass the [AppRef] used in `katana_scoped` in [appRef]. +/// +/// You can pass [AppThemeData] used in `katana_theme` in [theme]. You can also specify [ThemeMode] in [themeMode]. +/// +/// You can pass [AppLocalizeBase] used by `katana_localize` in [localize]. +/// +/// Other adapters for data and authentication such as [modelAdapter] and [authAdapter] can be passed. +/// +/// You can pass the [AppRouter] used by `katana_router` in [routerConfig]. +/// +/// If you do not pass [routerConfig], you can also use Flutter"s native routing functionality as you normally would with [MaterialApp], using [routes], [initialRoute], [onGenerateRoute], [onGenerateInitialRoutes], [onUnknownRoute ], [builder], [navigatorObservers], and [scaffoldMessengerKey] to take advantage of Flutter"s native routing capabilities. +/// +/// You can also use [home] to display a single widget. (available in Example, for example). +/// +/// The application title can be set with [title] and [onGenerateTitle]. +/// +/// The debug banner can be displayed with [debugShowCheckedModeBanner] and the performance overlay can be displayed with [showPerformanceOverlay]. +/// +/// Masamune Framework用の[MaterialApp]を[runApp]で実行するためのファンクション。 +/// [runApp]の代わりにこちらを用いても構いません。 +/// +/// [masamuneAdapter]を渡すことでMasamune Frameworkの追加プラグインを楽に利用することができます。 +/// +/// [MasamuneAdapter]内で[MasamuneAdapter.runZonedGuarded]が`true`で指定されていれば[runApp]を[runZonedGuarded]でラッピングします。 +/// +/// 一連のkatanaのパッケージで利用されているXXScopeのウィジェットを内包しています。さらに[onBuildAppFilters]を追加することでXXXScopeを指定することも可能です。 +/// +/// [appRef]で`katana_scoped`で使われている[AppRef]を渡すことができます。 +/// +/// [theme]で`katana_theme`で使われている[AppThemeData]を渡すことができます。また、[themeMode]で[ThemeMode]をあわせて指定できます。 +/// +/// [localize]で`katana_localize`で利用されている[AppLocalizeBase]を渡すことができます。 +/// +/// その他、[modelAdapter]や[authAdapter]といったデータや認証用のアダプターを渡すことが可能です。 +/// +/// [routerConfig]で`katana_router`で使われている[AppRouter]を渡すことができます。 +/// +/// [routerConfig]を渡さなかった場合、通常の[MaterialApp]と同じ様に[routes]や[initialRoute]、[onGenerateRoute]、[onGenerateInitialRoutes]、[onUnknownRoute]、[builder]、[navigatorObservers]、[scaffoldMessengerKey]を用いてFlutterネイティブのルーティング機能を利用することも可能です。 +/// +/// また、[home]を用いて単一のウィジェットを表示することができます。(Exampleなどで利用可能です) +/// +/// [title]、[onGenerateTitle]でアプリタイトルを設定することが可能です。 +/// +/// [debugShowCheckedModeBanner]でデバッグ用のバナーを表示することができ、[showPerformanceOverlay]でパフォーマンスのオーバーレイを表示することができます。 +Future runMasamuneApp({ + Key? key, + List masamuneAdapters = const [], + AppThemeData? theme, + AppLocalizeBase? localize, + AppRef? appRef, + AuthAdapter? authAdapter, + ModelAdapter? modelAdapter = const RuntimeModelAdapter(), + StorageAdapter? storageAdapter, + FunctionsAdapter? functionsAdapter, + RouterConfig? routerConfig, + GlobalKey? scaffoldMessengerKey, + bool debugShowCheckedModeBanner = true, + bool showPerformanceOverlay = false, + String title = "", + String Function(BuildContext)? onGenerateTitle, + ThemeMode? themeMode = ThemeMode.system, + Widget? home, + Map routes = + const {}, + String? initialRoute, + Route? Function(RouteSettings routeSettings)? onGenerateRoute, + List> Function(String routePath)? onGenerateInitialRoutes, + Route? Function(RouteSettings routeSettings)? onUnknownRoute, + List navigatorObservers = const [], + Widget Function(BuildContext context, Widget? child)? builder, + List? onBuildAppFilters, +}) async { + final useRunZonedGuarded = masamuneAdapters.any((e) => e.runZonedGuarded); + final app = MasamuneApp( + key: key, + theme: theme, + localize: localize, + appRef: appRef, + authAdapter: authAdapter, + modelAdapter: modelAdapter, + storageAdapter: storageAdapter, + functionsAdapter: functionsAdapter, + routerConfig: routerConfig, + scaffoldMessengerKey: scaffoldMessengerKey, + debugShowCheckedModeBanner: debugShowCheckedModeBanner, + showPerformanceOverlay: showPerformanceOverlay, + title: title, + onGenerateTitle: onGenerateTitle, + themeMode: themeMode, + home: home, + routes: routes, + initialRoute: initialRoute, + onGenerateRoute: onGenerateRoute, + onGenerateInitialRoutes: onGenerateInitialRoutes, + onUnknownRoute: onUnknownRoute, + navigatorObservers: [ + ...masamuneAdapters.expand((e) => e.navigatorObservers), + ...navigatorObservers, + ], + builder: builder, + onBuildAppFilters: [ + ...masamuneAdapters.map((e) => e.onBuildApp), + if (onBuildAppFilters != null) ...onBuildAppFilters, + ], + ); + if (useRunZonedGuarded) { + runZonedGuarded(() async { + for (final adapter in masamuneAdapters) { + await adapter.onPreRunApp(); + } + runApp(app); + }, (error, stack) { + for (final adapter in masamuneAdapters) { + adapter.onError(error, stack); + } + }); + } else { + for (final adapter in masamuneAdapters) { + await adapter.onPreRunApp(); + } + runApp(app); + } +} + +/// [MaterialApp] for Masamune Framework. +/// +/// It encapsulates the XXScope widget used in a series of katana packages. In addition, XXXScope can be specified by adding [onBuildAppFilters]. /// /// You can pass the [AppRef] used in `katana_scoped` in [appRef]. /// @@ -29,7 +162,7 @@ const kDefaultLocales = [Locale("en", "US")]; /// /// Masamune Framework用の[MaterialApp]。 /// -/// 一連のkatanaのパッケージで利用されているXXScopeのウィジェットを内包しています。 +/// 一連のkatanaのパッケージで利用されているXXScopeのウィジェットを内包しています。さらに[onBuildAppFilters]を追加することでXXXScopeを指定することも可能です。 /// /// [appRef]で`katana_scoped`で使われている[AppRef]を渡すことができます。 /// @@ -50,9 +183,9 @@ const kDefaultLocales = [Locale("en", "US")]; /// [debugShowCheckedModeBanner]でデバッグ用のバナーを表示することができ、[showPerformanceOverlay]でパフォーマンスのオーバーレイを表示することができます。 @immutable class MasamuneApp extends StatelessWidget { - /// MaterialApp] for Masamune Framework. + /// [MaterialApp] for Masamune Framework. /// - /// It encompasses the XXScope widget used in a series of katana packages. + /// It encapsulates the XXScope widget used in a series of katana packages. In addition, XXXScope can be specified by adding [onBuildAppFilters]. /// /// You can pass the [AppRef] used in `katana_scoped` in [appRef]. /// @@ -74,7 +207,7 @@ class MasamuneApp extends StatelessWidget { /// /// Masamune Framework用の[MaterialApp]。 /// - /// 一連のkatanaのパッケージで利用されているXXScopeのウィジェットを内包しています。 + /// 一連のkatanaのパッケージで利用されているXXScopeのウィジェットを内包しています。さらに[onBuildAppFilters]を追加することでXXXScopeを指定することも可能です。 /// /// [appRef]で`katana_scoped`で使われている[AppRef]を渡すことができます。 /// @@ -117,6 +250,7 @@ class MasamuneApp extends StatelessWidget { this.onGenerateInitialRoutes, this.onUnknownRoute, this.builder, + this.onBuildAppFilters, }); /// Theme data used by `katana_theme`. @@ -294,9 +428,25 @@ class MasamuneApp extends StatelessWidget { /// 戻り値に[child]をラッピングしたウィジェットを返してください。 final Widget Function(BuildContext context, Widget? child)? builder; + /// It is executed when the application is built. + /// + /// The widget generated by [build] of [MasamuneApp] is passed to [app]. + /// Wrap widgets to add functionality. + /// + /// Use it to add `Scope` widgets for other plug-ins, for example. + /// + /// アプリケーションをビルドする際に実行されます。 + /// + /// [app]に[MasamuneApp]の[build]で生成されたウィジェットが渡されます。 + /// ウィジェットをラップして機能を追加してください。 + /// + /// 他プラグインの`Scope`ウィジェットを追加する際などに用いてください。 + final List? + onBuildAppFilters; + @override Widget build(BuildContext context) { - return _buildAppFunctions( + var child = _buildAppFunctions( context, _buildAppStorage( context, @@ -318,6 +468,13 @@ class MasamuneApp extends StatelessWidget { ), ), ); + if (onBuildAppFilters == null) { + return child; + } + for (final builder in onBuildAppFilters!) { + child = builder.call(context, child); + } + return child; } Widget _buildAppModel(BuildContext context, Widget child) { diff --git a/packages/masamune/pubspec.lock b/packages/masamune/pubspec.lock index e00863385..b33b42c31 100644 --- a/packages/masamune/pubspec.lock +++ b/packages/masamune/pubspec.lock @@ -244,10 +244,10 @@ packages: dependency: "direct main" description: name: katana_form - sha256: "29d02abf2a2961a1cec48efa0901b398e8a6ec9621e1f865a8346201398a913e" + sha256: "0a9cf858d76331765ee6ca03a0a7e1c4b927da9ea21eb9944a4ff4b7222df402" url: "https://pub.dev" source: hosted - version: "1.3.8" + version: "1.3.10" katana_functions: dependency: "direct main" description: @@ -260,10 +260,10 @@ packages: dependency: "direct main" description: name: katana_indicator - sha256: "6d04cd7a4a3c689680e86e466ec987ed993a2e3ac2262c8aa9c99ec484f391d9" + sha256: e6ae1a233871ba744449d0bee0eacd43f0c8a309538cc4513e5676f28236e844 url: "https://pub.dev" source: hosted - version: "1.1.10" + version: "1.1.11" katana_listenables: dependency: "direct main" description: @@ -300,18 +300,18 @@ packages: dependency: "direct main" description: name: katana_model - sha256: "4d5db5f025bed98460e0deea908b56f10d65415a98ac58354f01baf85f2bb3c6" + sha256: "10fa4f40f70d9e3dbadc3fd57987087ce175ee6cfd5e22c9dfc95e0fa3393cdb" url: "https://pub.dev" source: hosted - version: "1.5.8" + version: "1.5.10" katana_prefs: dependency: "direct main" description: name: katana_prefs - sha256: dd45a8481abebf128bf6cb539ed39b7252b76e50544046eaa6417160e03410d1 + sha256: d67a1d185d72ebab7a21f78c71d16559c982034115266871cd13813914349dd9 url: "https://pub.dev" source: hosted - version: "1.1.14" + version: "1.1.16" katana_prefs_annotation: dependency: transitive description: @@ -404,10 +404,10 @@ packages: dependency: "direct main" description: name: masamune_annotation - sha256: "10366db8d1a6f8745b9b02bbce249b12d4e96dd11e6021c8756359974bf1f260" + sha256: deeab4150a3ceb2fac1005df4811112e68ad10ceada5457bccb602a289688def url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.2.1" matcher: dependency: transitive description: @@ -753,10 +753,10 @@ packages: dependency: transitive description: name: tint - sha256: d856019547532d4ea24171f554b319081c004c37741e7946eae30cb09f24e1c7 + sha256: "9652d9a589f4536d5e392cf790263d120474f15da3cf1bee7f1fdb31b4de5f46" url: "https://pub.dev" source: hosted - version: "2.0.0" + version: "2.0.1" typed_data: dependency: transitive description: diff --git a/packages/masamune_annotation/pubspec.lock b/packages/masamune_annotation/pubspec.lock index 472192dbb..20ae9496f 100644 --- a/packages/masamune_annotation/pubspec.lock +++ b/packages/masamune_annotation/pubspec.lock @@ -413,10 +413,10 @@ packages: dependency: transitive description: name: tint - sha256: d856019547532d4ea24171f554b319081c004c37741e7946eae30cb09f24e1c7 + sha256: "9652d9a589f4536d5e392cf790263d120474f15da3cf1bee7f1fdb31b4de5f46" url: "https://pub.dev" source: hosted - version: "2.0.0" + version: "2.0.1" typed_data: dependency: transitive description: diff --git a/packages/masamune_builder/pubspec.lock b/packages/masamune_builder/pubspec.lock index 0795fd78d..07b482b97 100644 --- a/packages/masamune_builder/pubspec.lock +++ b/packages/masamune_builder/pubspec.lock @@ -309,10 +309,10 @@ packages: dependency: "direct main" description: name: katana_prefs_builder - sha256: "9180b29391a808cb7902f48769b1e4eb15f6b7f3d0ca48f3623dbac4e4b630ee" + sha256: "1876a45f1ce7f90d3f92d5bb8bf8f70861ad239371d9aa89f8d79d90c0d62807" url: "https://pub.dev" source: hosted - version: "1.1.17" + version: "1.1.19" katana_router_annotation: dependency: "direct main" description: @@ -365,10 +365,10 @@ packages: dependency: "direct main" description: name: masamune_annotation - sha256: "10366db8d1a6f8745b9b02bbce249b12d4e96dd11e6021c8756359974bf1f260" + sha256: deeab4150a3ceb2fac1005df4811112e68ad10ceada5457bccb602a289688def url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.2.1" matcher: dependency: transitive description: @@ -581,10 +581,10 @@ packages: dependency: transitive description: name: tint - sha256: d856019547532d4ea24171f554b319081c004c37741e7946eae30cb09f24e1c7 + sha256: "9652d9a589f4536d5e392cf790263d120474f15da3cf1bee7f1fdb31b4de5f46" url: "https://pub.dev" source: hosted - version: "2.0.0" + version: "2.0.1" typed_data: dependency: transitive description: