import 'package:flutter/material.dart'; import 'package:worldhopper/l10n/app_localizations.dart'; import 'package:go_router/go_router.dart'; import 'package:worldhopper/config/constants.dart'; import 'package:worldhopper/screens/servers/server_list_screen.dart'; import 'package:worldhopper/screens/servers/add_server_screen.dart'; import 'package:worldhopper/screens/servers/edit_server_screen.dart'; import 'package:worldhopper/screens/browse/library_browser_screen.dart'; import 'package:worldhopper/screens/browse/feed_screen.dart'; import 'package:worldhopper/screens/publication/publication_detail_screen.dart'; import 'package:worldhopper/screens/reader/reader_screen.dart'; import 'package:worldhopper/screens/reader/epub_reader_screen.dart'; import 'package:worldhopper/screens/library/library_screen.dart'; import 'package:worldhopper/screens/settings/settings_screen.dart'; import 'package:worldhopper/screens/shell/main_shell_screen.dart'; import 'package:worldhopper/models/opds_entry.dart'; /// Application router configuration using GoRouter class AppRouter { AppRouter._(); static final GlobalKey _libraryNavigatorKey = GlobalKey(debugLabel: 'library'); static final GlobalKey _serversNavigatorKey = GlobalKey(debugLabel: 'servers'); static final GlobalKey _settingsNavigatorKey = GlobalKey(debugLabel: 'settings'); /// Navigator keys for each bottom navigation branch, indexed by tab position. static final List> branchNavigatorKeys = [ _libraryNavigatorKey, _serversNavigatorKey, _settingsNavigatorKey, ]; static final GoRouter router = GoRouter( initialLocation: AppConstants.routeLibrary, routes: [ // StatefulShellRoute for bottom navigation StatefulShellRoute.indexedStack( builder: (context, state, navigationShell) { return MainShellScreen(navigationShell: navigationShell); }, branches: [ // Branch 1: Library StatefulShellBranch( navigatorKey: _libraryNavigatorKey, routes: [ GoRoute( path: AppConstants.routeLibrary, name: 'library', builder: (context, state) => const LibraryScreen(), ), ], ), // Branch 2: Servers (home) StatefulShellBranch( navigatorKey: _serversNavigatorKey, routes: [ GoRoute( path: AppConstants.routeServerList, name: 'server-list', builder: (context, state) => const ServerListScreen(), routes: [ // Nested browse routes GoRoute( path: 'browse/:serverId', name: 'browse-library', builder: (context, state) { final serverId = state.pathParameters['serverId']!; return LibraryBrowserScreen(serverId: serverId); }, routes: [ GoRoute( path: 'feed', name: 'browse-feed', builder: (context, state) { final serverId = state.pathParameters['serverId']!; final extra = state.extra as Map; return FeedScreen( serverId: serverId, feedUrl: extra['feedUrl'] as String, feedTitle: extra['feedTitle'] as String, ); }, ), ], ), ], ), ], ), // Branch 3: Settings StatefulShellBranch( navigatorKey: _settingsNavigatorKey, routes: [ GoRoute( path: AppConstants.routeSettings, name: 'settings', builder: (context, state) => const SettingsScreen(), ), ], ), ], ), // Standalone routes (full-screen, no bottom navigation) GoRoute( path: AppConstants.routeAddServer, name: 'add-server', builder: (context, state) => const AddServerScreen(), ), GoRoute( path: '${AppConstants.routeEditServer}/:id', name: 'edit-server', builder: (context, state) { final serverId = state.pathParameters['id']!; return EditServerScreen(serverId: serverId); }, ), GoRoute( path: AppConstants.routePublicationDetail, name: 'publication-detail', builder: (context, state) { final entry = state.extra as Map; return PublicationDetailScreen( entry: entry['entry'] as OPDSEntry, serverId: entry['serverId'] as String, feedUrl: entry['feedUrl'] as String?, ); }, ), GoRoute( path: AppConstants.routeReader, name: 'reader', builder: (context, state) { final data = state.extra as Map; return ReaderScreen( entry: data['entry'] as OPDSEntry, serverId: data['serverId'] as String, initialPage: data['initialPage'] as int? ?? 0, feedUrl: data['feedUrl'] as String?, ); }, ), GoRoute( path: AppConstants.routeEpubReader, name: 'epub-reader', builder: (context, state) { final data = state.extra as Map; return EpubReaderScreen( entry: data['entry'] as OPDSEntry, serverId: data['serverId'] as String, feedUrl: data['feedUrl'] as String?, ); }, ), ], errorBuilder: (context, state) => Scaffold( body: Center( child: Text( AppLocalizations.of(context).routeNotFound(state.uri.toString())), ), ), ); }