/* * Copyright (c) 2024-2026 Fabian Freund. * * This file is part of WebLibre * (see https://weblibre.eu). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ part of 'routes.dart'; @TypedGoRoute( name: BrowserRoute.name, path: '/browser', routes: [ TypedGoRoute( name: 'SearchRoute', path: 'search/:tabType/:searchText', ), TypedGoRoute(name: 'TabViewRoute', path: 'tab_view'), TypedGoRoute( name: 'ContextMenuRoute', path: 'context_menu', ), TypedGoRoute( name: 'ContainerDraftRoute', path: 'container_draft', ), TypedGoRoute( name: 'ContainerListRoute', path: 'containers', routes: [ TypedGoRoute( name: 'ContainerCreateRoute', path: 'create/:containerData', ), TypedGoRoute( name: 'ContainerEditRoute', path: 'edit/:containerData', ), ], ), TypedGoRoute( name: 'ContainerSelectionRoute', path: 'select_container', ), TypedGoRoute( name: 'TabTreeRoute', path: 'tab_tree/:rootTabId', ), TypedGoRoute( name: 'OpenSharedContentRoute', path: 'open_content', ), TypedGoRoute( name: 'SelectProfileRoute', path: 'profile', ), ], ) class BrowserRoute extends GoRouteData with $BrowserRoute { static const name = 'BrowserRoute'; const BrowserRoute(); @override Widget build(BuildContext context, GoRouterState state) { return const BrowserScreen(); } } enum TabType { regular, private, child, isolated } class SearchRoute extends GoRouteData with $SearchRoute { static const String emptySearchText = ' '; final TabType tabType; //This should be nullable but isnt allowed by go_router final String searchText; final bool launchedFromIntent; /// When provided, the search screen will load URLs into this existing tab /// instead of creating a new tab. This also changes the UI to show /// site-specific bangs instead of the tab type selector. final String? tabId; const SearchRoute({ required this.tabType, this.searchText = SearchRoute.emptySearchText, this.launchedFromIntent = false, this.tabId, }); @override Widget build(BuildContext context, GoRouterState state) { return SearchScreen( tabType: tabType, initialSearchText: (searchText.isEmpty || searchText == emptySearchText) ? null : searchText, launchedFromIntent: launchedFromIntent, tabId: tabId, ); } } bool _isContainerUiEnabled(BuildContext context) { final settings = ProviderScope.containerOf( context, listen: false, ).read(generalSettingsWithDefaultsProvider); return settings.showContainerUi; } class ContainerDraftRoute extends GoRouteData with $ContainerDraftRoute { const ContainerDraftRoute(); @override String? redirect(BuildContext context, GoRouterState state) { return _isContainerUiEnabled(context) ? null : const BrowserRoute().location; } @override Widget build(BuildContext context, GoRouterState state) { return const ContainerDraftSuggestionsScreen(); } } class ContainerListRoute extends GoRouteData with $ContainerListRoute { const ContainerListRoute(); @override String? redirect(BuildContext context, GoRouterState state) { return _isContainerUiEnabled(context) ? null : const BrowserRoute().location; } @override Widget build(BuildContext context, GoRouterState state) { return const ContainerListScreen(); } } class ContainerSelectionRoute extends GoRouteData with $ContainerSelectionRoute { const ContainerSelectionRoute(); @override String? redirect(BuildContext context, GoRouterState state) { return _isContainerUiEnabled(context) ? null : const BrowserRoute().location; } @override Widget build(BuildContext context, GoRouterState state) { return const ContainerSelectionScreen(); } } class ContainerEditRoute extends GoRouteData with $ContainerEditRoute { final String containerData; const ContainerEditRoute({required this.containerData}); @override String? redirect(BuildContext context, GoRouterState state) { return _isContainerUiEnabled(context) ? null : const BrowserRoute().location; } @override Widget build(BuildContext context, GoRouterState state) { return ContainerEditScreen.edit( initialContainer: ContainerDataWithCount.fromJson( jsonDecode(containerData) as Map, ), ); } } class ContainerCreateRoute extends GoRouteData with $ContainerCreateRoute { final String containerData; final String tabIds; ContainerCreateRoute({required this.containerData, this.tabIds = '[]'}); @override String? redirect(BuildContext context, GoRouterState state) { return _isContainerUiEnabled(context) ? null : const BrowserRoute().location; } @override Widget build(BuildContext context, GoRouterState state) { final tabIdsList = jsonDecode(tabIds) as List; final tabIdsSet = tabIdsList.cast().toSet(); return ContainerEditScreen.create( initialContainer: ContainerData.fromJson( jsonDecode(containerData) as Map, ), tabIds: tabIdsSet.isNotEmpty ? tabIdsSet : null, ); } } class ContextMenuRoute extends GoRouteData with $ContextMenuRoute { final String hitResult; const ContextMenuRoute({required this.hitResult}); @override Page buildPage(BuildContext context, GoRouterState state) { return DialogPage( builder: (_) => ContextMenuDialog(hitResult: HitResultJson.fromJson(hitResult)), ); } } class TabTreeRoute extends GoRouteData with $TabTreeRoute { final String rootTabId; const TabTreeRoute(this.rootTabId); @override Page buildPage(BuildContext context, GoRouterState state) { return DialogPage(builder: (_) => TabTreeDialog(rootTabId)); } } class OpenSharedContentRoute extends GoRouteData with $OpenSharedContentRoute { final String sharedUrl; const OpenSharedContentRoute({this.sharedUrl = 'about:blank'}); @override Page buildPage(BuildContext context, GoRouterState state) { return BottomSheetPage( builder: (_) => OpenSharedContent( sharedUrl: Uri.tryParse(sharedUrl) ?? Uri.parse('about:blank'), ), ); } } class TabViewRoute extends GoRouteData with $TabViewRoute { const TabViewRoute(); @override Page buildPage(BuildContext context, GoRouterState state) { return DialogPage(builder: (_) => const TabViewScreen()); } } class SelectProfileRoute extends GoRouteData with $SelectProfileRoute { const SelectProfileRoute(); @override Page buildPage(BuildContext context, GoRouterState state) { return BottomSheetPage(builder: (_) => const SelectProfileDialog()); } }