Refactor router

This commit is contained in:
problematicconsumer
2023-11-26 21:59:57 +03:30
parent 829d58a1a2
commit 0c1768e05e
8 changed files with 383 additions and 461 deletions

View File

@@ -38,7 +38,9 @@ GoRouter router(RouterRef ref) {
navigatorKey: rootNavigatorKey,
initialLocation: initialLocation,
debugLogDiagnostics: true,
routes: useMobileRouter ? mobileRoutes : desktopRoutes,
routes: [
if (useMobileRouter) $mobileWrapperRoute else $desktopWrapperRoute,
],
refreshListenable: notifier,
redirect: notifier.redirect,
observers: [

View File

@@ -1,16 +1,380 @@
import 'package:hiddify/core/router/routes/desktop_routes.dart' as desktop;
import 'package:hiddify/core/router/routes/mobile_routes.dart' as mobile;
import 'package:hiddify/core/router/routes/shared_routes.dart' as shared;
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:hiddify/core/router/app_router.dart';
import 'package:hiddify/features/about/view/about_page.dart';
import 'package:hiddify/features/common/adaptive_root_scaffold.dart';
import 'package:hiddify/features/geo_asset/overview/geo_assets_overview_page.dart';
import 'package:hiddify/features/home/view/view.dart';
import 'package:hiddify/features/intro/intro_page.dart';
import 'package:hiddify/features/logs/view/logs_page.dart';
import 'package:hiddify/features/profile/add/add_profile_modal.dart';
import 'package:hiddify/features/profile/details/profile_details_page.dart';
import 'package:hiddify/features/profile/overview/profiles_overview_page.dart';
import 'package:hiddify/features/proxies/view/view.dart';
import 'package:hiddify/features/settings/view/config_options_page.dart';
import 'package:hiddify/features/settings/view/per_app_proxy_page.dart';
import 'package:hiddify/features/settings/view/settings_page.dart';
import 'package:hiddify/utils/utils.dart';
export 'routes/mobile_routes.dart';
export 'routes/shared_routes.dart' hide $appRoutes;
part 'routes.g.dart';
final mobileRoutes = [
...shared.$appRoutes,
...mobile.$appRoutes,
];
GlobalKey<NavigatorState>? _dynamicRootKey =
useMobileRouter ? rootNavigatorKey : null;
final desktopRoutes = [
...shared.$appRoutes,
...desktop.$appRoutes,
];
@TypedShellRoute<MobileWrapperRoute>(
routes: [
TypedGoRoute<IntroRoute>(path: "/intro", name: IntroRoute.name),
TypedGoRoute<HomeRoute>(
path: "/",
name: HomeRoute.name,
routes: [
TypedGoRoute<AddProfileRoute>(
path: "add",
name: AddProfileRoute.name,
),
TypedGoRoute<ProfilesOverviewRoute>(
path: "profiles",
name: ProfilesOverviewRoute.name,
),
TypedGoRoute<NewProfileRoute>(
path: "profiles/new",
name: NewProfileRoute.name,
),
TypedGoRoute<ProfileDetailsRoute>(
path: "profiles/:id",
name: ProfileDetailsRoute.name,
),
TypedGoRoute<LogsRoute>(
path: "logs",
name: LogsRoute.name,
),
TypedGoRoute<SettingsRoute>(
path: "settings",
name: SettingsRoute.name,
routes: [
TypedGoRoute<ConfigOptionsRoute>(
path: "config-options",
name: ConfigOptionsRoute.name,
),
TypedGoRoute<PerAppProxyRoute>(
path: "per-app-proxy",
name: PerAppProxyRoute.name,
),
TypedGoRoute<GeoAssetsRoute>(
path: "routing-assets",
name: GeoAssetsRoute.name,
),
],
),
TypedGoRoute<AboutRoute>(
path: "about",
name: AboutRoute.name,
),
],
),
TypedGoRoute<ProxiesRoute>(
path: "/proxies",
name: ProxiesRoute.name,
),
],
)
class MobileWrapperRoute extends ShellRouteData {
const MobileWrapperRoute();
@override
Widget builder(BuildContext context, GoRouterState state, Widget navigator) {
return AdaptiveRootScaffold(navigator);
}
}
@TypedShellRoute<DesktopWrapperRoute>(
routes: [
TypedGoRoute<IntroRoute>(path: "/intro", name: IntroRoute.name),
TypedGoRoute<HomeRoute>(
path: "/",
name: HomeRoute.name,
routes: [
TypedGoRoute<AddProfileRoute>(
path: "add",
name: AddProfileRoute.name,
),
TypedGoRoute<ProfilesOverviewRoute>(
path: "profiles",
name: ProfilesOverviewRoute.name,
),
TypedGoRoute<NewProfileRoute>(
path: "profiles/new",
name: NewProfileRoute.name,
),
TypedGoRoute<ProfileDetailsRoute>(
path: "profiles/:id",
name: ProfileDetailsRoute.name,
),
],
),
TypedGoRoute<ProxiesRoute>(
path: "/proxies",
name: ProxiesRoute.name,
),
TypedGoRoute<LogsRoute>(
path: "/logs",
name: LogsRoute.name,
),
TypedGoRoute<SettingsRoute>(
path: "/settings",
name: SettingsRoute.name,
routes: [
TypedGoRoute<ConfigOptionsRoute>(
path: "config-options",
name: ConfigOptionsRoute.name,
),
TypedGoRoute<GeoAssetsRoute>(
path: "routing-assets",
name: GeoAssetsRoute.name,
),
],
),
TypedGoRoute<AboutRoute>(
path: "/about",
name: AboutRoute.name,
),
],
)
class DesktopWrapperRoute extends ShellRouteData {
const DesktopWrapperRoute();
@override
Widget builder(BuildContext context, GoRouterState state, Widget navigator) {
return AdaptiveRootScaffold(navigator);
}
}
class IntroRoute extends GoRouteData {
const IntroRoute();
static const name = "Intro";
@override
Page<void> buildPage(BuildContext context, GoRouterState state) {
return const MaterialPage(
fullscreenDialog: true,
name: name,
child: IntroPage(),
);
}
}
class HomeRoute extends GoRouteData {
const HomeRoute();
static const name = "Home";
@override
Page<void> buildPage(BuildContext context, GoRouterState state) {
return const NoTransitionPage(
name: name,
child: HomePage(),
);
}
}
class ProxiesRoute extends GoRouteData {
const ProxiesRoute();
static const name = "Proxies";
@override
Page<void> buildPage(BuildContext context, GoRouterState state) {
return const NoTransitionPage(
name: name,
child: ProxiesPage(),
);
}
}
class AddProfileRoute extends GoRouteData {
const AddProfileRoute({this.url});
final String? url;
static const name = "Add Profile";
static final GlobalKey<NavigatorState> $parentNavigatorKey = rootNavigatorKey;
@override
Page<void> buildPage(BuildContext context, GoRouterState state) {
return BottomSheetPage(
fixed: true,
name: name,
builder: (controller) => AddProfileModal(
url: url,
scrollController: controller,
),
);
}
}
class ProfilesOverviewRoute extends GoRouteData {
const ProfilesOverviewRoute();
static const name = "Profiles";
static final GlobalKey<NavigatorState> $parentNavigatorKey = rootNavigatorKey;
@override
Page<void> buildPage(BuildContext context, GoRouterState state) {
return BottomSheetPage(
name: name,
builder: (controller) =>
ProfilesOverviewModal(scrollController: controller),
);
}
}
class NewProfileRoute extends GoRouteData {
const NewProfileRoute();
static const name = "New Profile";
static final GlobalKey<NavigatorState> $parentNavigatorKey = rootNavigatorKey;
@override
Page<void> buildPage(BuildContext context, GoRouterState state) {
return const MaterialPage(
fullscreenDialog: true,
name: name,
child: ProfileDetailsPage("new"),
);
}
}
class ProfileDetailsRoute extends GoRouteData {
const ProfileDetailsRoute(this.id);
final String id;
static const name = "Profile Details";
static final GlobalKey<NavigatorState> $parentNavigatorKey = rootNavigatorKey;
@override
Page<void> buildPage(BuildContext context, GoRouterState state) {
return MaterialPage(
fullscreenDialog: true,
name: name,
child: ProfileDetailsPage(id),
);
}
}
class LogsRoute extends GoRouteData {
const LogsRoute();
static const name = "Logs";
static final GlobalKey<NavigatorState>? $parentNavigatorKey = _dynamicRootKey;
@override
Page<void> buildPage(BuildContext context, GoRouterState state) {
if (useMobileRouter) {
return const MaterialPage(
fullscreenDialog: true,
name: name,
child: LogsPage(),
);
}
return const NoTransitionPage(name: name, child: LogsPage());
}
}
class SettingsRoute extends GoRouteData {
const SettingsRoute();
static const name = "Settings";
static final GlobalKey<NavigatorState>? $parentNavigatorKey = _dynamicRootKey;
@override
Page<void> buildPage(BuildContext context, GoRouterState state) {
if (useMobileRouter) {
return const MaterialPage(
fullscreenDialog: true,
name: name,
child: SettingsPage(),
);
}
return const NoTransitionPage(name: name, child: SettingsPage());
}
}
class ConfigOptionsRoute extends GoRouteData {
const ConfigOptionsRoute();
static const name = "Config Options";
static final GlobalKey<NavigatorState>? $parentNavigatorKey = _dynamicRootKey;
@override
Page<void> buildPage(BuildContext context, GoRouterState state) {
if (useMobileRouter) {
return const MaterialPage(
fullscreenDialog: true,
name: name,
child: ConfigOptionsPage(),
);
}
return const MaterialPage(
fullscreenDialog: true,
name: name,
child: ConfigOptionsPage(),
);
}
}
class PerAppProxyRoute extends GoRouteData {
const PerAppProxyRoute();
static const name = "Per-app Proxy";
static final GlobalKey<NavigatorState> $parentNavigatorKey = rootNavigatorKey;
@override
Page<void> buildPage(BuildContext context, GoRouterState state) {
return const MaterialPage(
fullscreenDialog: true,
name: name,
child: PerAppProxyPage(),
);
}
}
class GeoAssetsRoute extends GoRouteData {
const GeoAssetsRoute();
static const name = "Routing Assets";
static final GlobalKey<NavigatorState>? $parentNavigatorKey = _dynamicRootKey;
@override
Page<void> buildPage(BuildContext context, GoRouterState state) {
if (useMobileRouter) {
return const MaterialPage(
fullscreenDialog: true,
name: name,
child: GeoAssetsOverviewPage(),
);
}
return const MaterialPage(
fullscreenDialog: true,
name: name,
child: GeoAssetsOverviewPage(),
);
}
}
class AboutRoute extends GoRouteData {
const AboutRoute();
static const name = "About";
static final GlobalKey<NavigatorState>? $parentNavigatorKey = _dynamicRootKey;
@override
Page<void> buildPage(BuildContext context, GoRouterState state) {
if (useMobileRouter) {
return const MaterialPage(
fullscreenDialog: true,
name: name,
child: AboutPage(),
);
}
return const NoTransitionPage(name: name, child: AboutPage());
}
}

View File

@@ -1,137 +0,0 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:hiddify/core/router/routes/shared_routes.dart';
import 'package:hiddify/features/about/view/view.dart';
import 'package:hiddify/features/common/adaptive_root_scaffold.dart';
import 'package:hiddify/features/geo_asset/overview/geo_assets_overview_page.dart';
import 'package:hiddify/features/logs/view/view.dart';
import 'package:hiddify/features/settings/view/view.dart';
part 'desktop_routes.g.dart';
@TypedShellRoute<DesktopWrapperRoute>(
routes: [
TypedGoRoute<HomeRoute>(
path: HomeRoute.path,
name: HomeRoute.name,
routes: [
TypedGoRoute<AddProfileRoute>(
path: AddProfileRoute.path,
name: AddProfileRoute.name,
),
TypedGoRoute<ProfilesRoute>(
path: ProfilesRoute.path,
name: ProfilesRoute.name,
),
TypedGoRoute<NewProfileRoute>(
path: NewProfileRoute.path,
name: NewProfileRoute.name,
),
TypedGoRoute<ProfileDetailsRoute>(
path: ProfileDetailsRoute.path,
name: ProfileDetailsRoute.name,
),
],
),
TypedGoRoute<ProxiesRoute>(
path: ProxiesRoute.path,
name: ProxiesRoute.name,
),
TypedGoRoute<LogsRoute>(
path: LogsRoute.path,
name: LogsRoute.name,
),
TypedGoRoute<SettingsRoute>(
path: SettingsRoute.path,
name: SettingsRoute.name,
routes: [
TypedGoRoute<ConfigOptionsRoute>(
path: ConfigOptionsRoute.path,
name: ConfigOptionsRoute.name,
),
TypedGoRoute<GeoAssetsRoute>(
path: GeoAssetsRoute.path,
name: GeoAssetsRoute.name,
),
],
),
TypedGoRoute<AboutRoute>(
path: AboutRoute.path,
name: AboutRoute.name,
),
],
)
class DesktopWrapperRoute extends ShellRouteData {
const DesktopWrapperRoute();
@override
Widget builder(BuildContext context, GoRouterState state, Widget navigator) {
return AdaptiveRootScaffold(navigator);
}
}
class LogsRoute extends GoRouteData {
const LogsRoute();
static const path = '/logs';
static const name = 'Logs';
@override
Page<void> buildPage(BuildContext context, GoRouterState state) {
return const NoTransitionPage(name: name, child: LogsPage());
}
}
class SettingsRoute extends GoRouteData {
const SettingsRoute();
static const path = '/settings';
static const name = 'Settings';
@override
Page<void> buildPage(BuildContext context, GoRouterState state) {
return const NoTransitionPage(name: name, child: SettingsPage());
}
}
class ConfigOptionsRoute extends GoRouteData {
const ConfigOptionsRoute();
static const path = 'config-options';
static const name = 'Config Options';
@override
Page<void> buildPage(BuildContext context, GoRouterState state) {
return const MaterialPage(
fullscreenDialog: true,
name: name,
child: ConfigOptionsPage(),
);
}
}
class GeoAssetsRoute extends GoRouteData {
const GeoAssetsRoute();
static const path = 'routing-assets';
static const name = 'Routing Assets';
@override
Page<void> buildPage(BuildContext context, GoRouterState state) {
return const MaterialPage(
fullscreenDialog: true,
name: name,
child: GeoAssetsOverviewPage(),
);
}
}
class AboutRoute extends GoRouteData {
const AboutRoute();
static const path = '/about';
static const name = 'About';
@override
Page<void> buildPage(BuildContext context, GoRouterState state) {
return const NoTransitionPage(
name: name,
child: AboutPage(),
);
}
}

View File

@@ -1,178 +0,0 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:hiddify/core/router/app_router.dart';
import 'package:hiddify/core/router/routes/shared_routes.dart';
import 'package:hiddify/features/about/view/view.dart';
import 'package:hiddify/features/common/adaptive_root_scaffold.dart';
import 'package:hiddify/features/geo_asset/overview/geo_assets_overview_page.dart';
import 'package:hiddify/features/logs/view/view.dart';
import 'package:hiddify/features/settings/view/view.dart';
part 'mobile_routes.g.dart';
@TypedShellRoute<MobileWrapperRoute>(
routes: [
TypedGoRoute<HomeRoute>(
path: HomeRoute.path,
name: HomeRoute.name,
routes: [
TypedGoRoute<AddProfileRoute>(
path: AddProfileRoute.path,
name: AddProfileRoute.name,
),
TypedGoRoute<ProfilesRoute>(
path: ProfilesRoute.path,
name: ProfilesRoute.name,
),
TypedGoRoute<NewProfileRoute>(
path: NewProfileRoute.path,
name: NewProfileRoute.name,
),
TypedGoRoute<ProfileDetailsRoute>(
path: ProfileDetailsRoute.path,
name: ProfileDetailsRoute.name,
),
TypedGoRoute<LogsRoute>(
path: LogsRoute.path,
name: LogsRoute.name,
),
TypedGoRoute<SettingsRoute>(
path: SettingsRoute.path,
name: SettingsRoute.name,
routes: [
TypedGoRoute<ConfigOptionsRoute>(
path: ConfigOptionsRoute.path,
name: ConfigOptionsRoute.name,
),
TypedGoRoute<PerAppProxyRoute>(
path: PerAppProxyRoute.path,
name: PerAppProxyRoute.name,
),
TypedGoRoute<GeoAssetsRoute>(
path: GeoAssetsRoute.path,
name: GeoAssetsRoute.name,
),
],
),
TypedGoRoute<AboutRoute>(
path: AboutRoute.path,
name: AboutRoute.name,
),
],
),
TypedGoRoute<ProxiesRoute>(
path: ProxiesRoute.path,
name: ProxiesRoute.name,
),
],
)
class MobileWrapperRoute extends ShellRouteData {
const MobileWrapperRoute();
@override
Widget builder(BuildContext context, GoRouterState state, Widget navigator) {
return AdaptiveRootScaffold(navigator);
}
}
class LogsRoute extends GoRouteData {
const LogsRoute();
static const path = 'logs';
static const name = 'Logs';
static final GlobalKey<NavigatorState> $parentNavigatorKey = rootNavigatorKey;
@override
Page<void> buildPage(BuildContext context, GoRouterState state) {
return const MaterialPage(
fullscreenDialog: true,
name: name,
child: LogsPage(),
);
}
}
class SettingsRoute extends GoRouteData {
const SettingsRoute();
static const path = 'settings';
static const name = 'Settings';
static final GlobalKey<NavigatorState> $parentNavigatorKey = rootNavigatorKey;
@override
Page<void> buildPage(BuildContext context, GoRouterState state) {
return const MaterialPage(
fullscreenDialog: true,
name: name,
child: SettingsPage(),
);
}
}
class ConfigOptionsRoute extends GoRouteData {
const ConfigOptionsRoute();
static const path = 'config-options';
static const name = 'Config Options';
static final GlobalKey<NavigatorState> $parentNavigatorKey = rootNavigatorKey;
@override
Page<void> buildPage(BuildContext context, GoRouterState state) {
return const MaterialPage(
fullscreenDialog: true,
name: name,
child: ConfigOptionsPage(),
);
}
}
class PerAppProxyRoute extends GoRouteData {
const PerAppProxyRoute();
static const path = 'per-app-proxy';
static const name = 'Per-app Proxy';
static final GlobalKey<NavigatorState> $parentNavigatorKey = rootNavigatorKey;
@override
Page<void> buildPage(BuildContext context, GoRouterState state) {
return const MaterialPage(
fullscreenDialog: true,
name: name,
child: PerAppProxyPage(),
);
}
}
class GeoAssetsRoute extends GoRouteData {
const GeoAssetsRoute();
static const path = 'routing-assets';
static const name = 'Routing Assets';
static final GlobalKey<NavigatorState> $parentNavigatorKey = rootNavigatorKey;
@override
Page<void> buildPage(BuildContext context, GoRouterState state) {
return const MaterialPage(
fullscreenDialog: true,
name: name,
child: GeoAssetsOverviewPage(),
);
}
}
class AboutRoute extends GoRouteData {
const AboutRoute();
static const path = 'about';
static const name = 'About';
static final GlobalKey<NavigatorState> $parentNavigatorKey = rootNavigatorKey;
@override
Page<void> buildPage(BuildContext context, GoRouterState state) {
return const MaterialPage(
fullscreenDialog: true,
name: name,
child: AboutPage(),
);
}
}

View File

@@ -1,129 +0,0 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:hiddify/core/router/app_router.dart';
import 'package:hiddify/features/home/view/view.dart';
import 'package:hiddify/features/intro/intro_page.dart';
import 'package:hiddify/features/profile/add/add_profile_modal.dart';
import 'package:hiddify/features/profile/details/profile_details_page.dart';
import 'package:hiddify/features/profile/overview/profiles_overview_page.dart';
import 'package:hiddify/features/proxies/view/view.dart';
import 'package:hiddify/utils/utils.dart';
part 'shared_routes.g.dart';
class HomeRoute extends GoRouteData {
const HomeRoute();
static const path = '/';
static const name = 'Home';
@override
Page<void> buildPage(BuildContext context, GoRouterState state) {
return const NoTransitionPage(
name: name,
child: HomePage(),
);
}
}
class ProxiesRoute extends GoRouteData {
const ProxiesRoute();
static const path = '/proxies';
static const name = 'Proxies';
@override
Page<void> buildPage(BuildContext context, GoRouterState state) {
return const NoTransitionPage(
name: name,
child: ProxiesPage(),
);
}
}
class AddProfileRoute extends GoRouteData {
const AddProfileRoute({this.url});
static const path = 'add';
static const name = 'Add Profile';
final String? url;
static final GlobalKey<NavigatorState> $parentNavigatorKey = rootNavigatorKey;
@override
Page<void> buildPage(BuildContext context, GoRouterState state) {
return BottomSheetPage(
fixed: true,
name: name,
builder: (controller) => AddProfileModal(
url: url,
scrollController: controller,
),
);
}
}
@TypedGoRoute<IntroRoute>(path: IntroRoute.path, name: IntroRoute.name)
class IntroRoute extends GoRouteData {
const IntroRoute();
static const path = '/intro';
static const name = 'Intro';
@override
Page<void> buildPage(BuildContext context, GoRouterState state) {
return const MaterialPage(
fullscreenDialog: true,
name: name,
child: IntroPage(),
);
}
}
class ProfilesRoute extends GoRouteData {
const ProfilesRoute();
static const path = 'profiles';
static const name = 'Profiles';
static final GlobalKey<NavigatorState> $parentNavigatorKey = rootNavigatorKey;
@override
Page<void> buildPage(BuildContext context, GoRouterState state) {
return BottomSheetPage(
name: name,
builder: (controller) =>
ProfilesOverviewModal(scrollController: controller),
);
}
}
class NewProfileRoute extends GoRouteData {
const NewProfileRoute();
static const path = 'profiles/new';
static const name = 'New Profile';
static final GlobalKey<NavigatorState> $parentNavigatorKey = rootNavigatorKey;
@override
Page<void> buildPage(BuildContext context, GoRouterState state) {
return const MaterialPage(
fullscreenDialog: true,
name: name,
child: ProfileDetailsPage("new"),
);
}
}
class ProfileDetailsRoute extends GoRouteData {
const ProfileDetailsRoute(this.id);
final String id;
static const path = 'profiles/:id';
static const name = 'Profile Details';
static final GlobalKey<NavigatorState> $parentNavigatorKey = rootNavigatorKey;
@override
Page<void> buildPage(BuildContext context, GoRouterState state) {
return MaterialPage(
fullscreenDialog: true,
name: name,
child: ProfileDetailsPage(id),
);
}
}

View File

@@ -7,7 +7,7 @@ bool showDrawerButton(BuildContext context) {
if (!useMobileRouter) return true;
final String location = GoRouterState.of(context).uri.path;
if (location == const HomeRoute().location ||
location == const ProfilesRoute().location) return true;
location == const ProfilesOverviewRoute().location) return true;
if (location.startsWith(const ProxiesRoute().location)) return true;
return false;
}

View File

@@ -44,7 +44,7 @@ class EmptyActiveProfileHomeBody extends HookConsumerWidget {
Text(t.home.noActiveProfileMsg),
const Gap(16),
OutlinedButton(
onPressed: () => const ProfilesRoute().push(context),
onPressed: () => const ProfilesOverviewRoute().push(context),
child: Text(t.profile.overviewPageTitle),
),
],

View File

@@ -90,7 +90,7 @@ class ProfileTile extends HookConsumerWidget {
child: InkWell(
onTap: () {
if (isMain) {
const ProfilesRoute().go(context);
const ProfilesOverviewRoute().go(context);
} else {
if (selectActiveMutation.state.isInProgress) return;
if (profile.active) return;