From 15ad188296bc6177e2ad0e0318d35390a78dc444 Mon Sep 17 00:00:00 2001 From: Plague Fox Date: Mon, 18 Dec 2023 13:17:58 +0400 Subject: [PATCH] Add RouterStateMixin and ShopGuard --- .../src/common/router/router_state_mixin.dart | 49 +++++++++++++++++++ example/lib/src/common/router/shop_guard.dart | 20 ++++++++ example/lib/src/common/widget/app.dart | 47 +----------------- 3 files changed, 71 insertions(+), 45 deletions(-) create mode 100644 example/lib/src/common/router/router_state_mixin.dart create mode 100644 example/lib/src/common/router/shop_guard.dart diff --git a/example/lib/src/common/router/router_state_mixin.dart b/example/lib/src/common/router/router_state_mixin.dart new file mode 100644 index 0000000..1d974e2 --- /dev/null +++ b/example/lib/src/common/router/router_state_mixin.dart @@ -0,0 +1,49 @@ +import 'package:example/src/common/model/dependencies.dart'; +import 'package:example/src/common/router/authentication_guard.dart'; +import 'package:example/src/common/router/home_guard.dart'; +import 'package:example/src/common/router/routes.dart'; +import 'package:example/src/common/router/shop_guard.dart'; +import 'package:flutter/widgets.dart' show State, StatefulWidget, ValueNotifier; +import 'package:octopus/octopus.dart'; + +mixin RouterStateMixin on State { + late final Octopus router; + late final ValueNotifier> + errorsObserver; + + @override + void initState() { + final dependencies = Dependencies.of(context); + errorsObserver = + ValueNotifier>( + <({Object error, StackTrace stackTrace})>[], + ); + router = Octopus( + routes: Routes.values, + defaultRoute: Routes.home, + guards: [ + AuthenticationGuard( + getUser: () => dependencies.authenticationController.state.user, + routes: { + Routes.signin.name, + Routes.signup.name, + }, + signinNavigation: OctopusState.single(Routes.signin.node()), + homeNavigation: OctopusState.single(Routes.home.node()), + refresh: dependencies.authenticationController, + ), + HomeGuard(), + ShopGuard(), + ], + onError: (error, stackTrace) => + errorsObserver.value = <({Object error, StackTrace stackTrace})>[ + (error: error, stackTrace: stackTrace), + ...errorsObserver.value, + ], + /* observers: [ + HeroController(), + ], */ + ); + super.initState(); + } +} diff --git a/example/lib/src/common/router/shop_guard.dart b/example/lib/src/common/router/shop_guard.dart new file mode 100644 index 0000000..e955b58 --- /dev/null +++ b/example/lib/src/common/router/shop_guard.dart @@ -0,0 +1,20 @@ +import 'dart:async'; + +import 'package:example/src/common/router/routes.dart'; +import 'package:octopus/octopus.dart'; + +/// Do not allow any nested routes at `shop` inderectly except of `*-tab`. +class ShopGuard extends OctopusGuard { + ShopGuard(); + + @override + FutureOr call( + List history, + OctopusState state, + Map context, + ) => + state + ..find((node) => node.name == Routes.shop.name) + ?.children + .removeWhere((node) => !node.name.endsWith('-tab')); +} diff --git a/example/lib/src/common/widget/app.dart b/example/lib/src/common/widget/app.dart index 36b8c9c..720a2c2 100644 --- a/example/lib/src/common/widget/app.dart +++ b/example/lib/src/common/widget/app.dart @@ -1,15 +1,11 @@ import 'package:example/src/common/constant/config.dart'; import 'package:example/src/common/localization/localization.dart'; -import 'package:example/src/common/model/dependencies.dart'; -import 'package:example/src/common/router/authentication_guard.dart'; -import 'package:example/src/common/router/home_guard.dart'; -import 'package:example/src/common/router/routes.dart'; +import 'package:example/src/common/router/router_state_mixin.dart'; import 'package:example/src/common/widget/router_state_observer.dart'; import 'package:example/src/feature/authentication/widget/authentication_scope.dart'; import 'package:example/src/feature/shop/widget/shop_scope.dart'; import 'package:flutter/material.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; -import 'package:octopus/octopus.dart'; /// {@template app} /// App widget. @@ -22,46 +18,7 @@ class App extends StatefulWidget { State createState() => _AppState(); } -class _AppState extends State { - late final Octopus router; - late final ValueNotifier> - errorsObserver; - - @override - void initState() { - final dependencies = Dependencies.of(context); - errorsObserver = - ValueNotifier>( - <({Object error, StackTrace stackTrace})>[], - ); - router = Octopus( - routes: Routes.values, - defaultRoute: Routes.home, - guards: [ - AuthenticationGuard( - getUser: () => dependencies.authenticationController.state.user, - routes: { - Routes.signin.name, - Routes.signup.name, - }, - signinNavigation: OctopusState.single(Routes.signin.node()), - homeNavigation: OctopusState.single(Routes.home.node()), - refresh: dependencies.authenticationController, - ), - HomeGuard(), - ], - onError: (error, stackTrace) => - errorsObserver.value = <({Object error, StackTrace stackTrace})>[ - (error: error, stackTrace: stackTrace), - ...errorsObserver.value, - ], - /* observers: [ - HeroController(), - ], */ - ); - super.initState(); - } - +class _AppState extends State with RouterStateMixin { @override Widget build(BuildContext context) => MaterialApp.router( title: 'Octopus: example',