router function

  1. @riverpod
GoRouter router(
  1. Ref ref
)

Implementation

@riverpod
GoRouter router(Ref ref) {
  return GoRouter(
    initialLocation: '/scenes',
    redirect: (context, state) {
      final prefs = ref.read(sharedPreferencesProvider);
      final serverUrl = normalizeGraphqlServerUrl(
        prefs.getString('server_base_url')?.trim() ?? '',
      );
      final apiKey = prefs.getString('server_api_key')?.trim() ?? '';

      final isConfigured = serverUrl.isNotEmpty && apiKey.isNotEmpty;
      final isSettingsPath =
          state.uri.path == '/settings' ||
          state.uri.path.startsWith('/settings/');

      if (!isConfigured && !isSettingsPath) {
        return '/settings';
      }

      return null;
    },
    routes: [
      StatefulShellRoute.indexedStack(
        builder: (context, state, navigationShell) {
          return ShellPage(navigationShell: navigationShell);
        },
        branches: [
          StatefulShellBranch(
            routes: [
              GoRoute(
                path: '/scenes',
                builder: (context, state) => const ScenesPage(),
                routes: [
                  GoRoute(
                    path: 'scene/:id',
                    builder: (context, state) =>
                        SceneDetailsPage(sceneId: state.pathParameters['id']!),
                    routes: [
                      GoRoute(
                        path: 'fullscreen',
                        pageBuilder: (context, state) => CustomTransitionPage(
                          key: state.pageKey,
                          child: FullscreenPlayerPage(
                            sceneId: state.pathParameters['id']!,
                          ),
                          transitionsBuilder:
                              (context, animation, secondaryAnimation, child) =>
                                  FadeTransition(
                                      opacity: animation, child: child),
                          transitionDuration: const Duration(milliseconds: 200),
                        ),
                      ),
                    ],
                  ),
                  GoRoute(
                    path: 'fullscreen/:id',
                    pageBuilder: (context, state) => CustomTransitionPage(
                      key: state.pageKey,
                      child: FullscreenPlayerPage(
                        sceneId: state.pathParameters['id']!,
                      ),
                      transitionsBuilder:
                          (context, animation, secondaryAnimation, child) =>
                              FadeTransition(opacity: animation, child: child),
                      transitionDuration: const Duration(milliseconds: 200),
                    ),
                  ),
                ],
              ),
            ],
          ),
          StatefulShellBranch(
            routes: [
              GoRoute(
                path: '/performers',
                builder: (context, state) => const PerformersPage(),
                routes: [
                  GoRoute(
                    path: 'performer/:id',
                    builder: (context, state) => PerformerDetailsPage(
                      performerId: state.pathParameters['id']!,
                    ),
                    routes: [
                      GoRoute(
                        path: 'media',
                        builder: (context, state) => PerformerMediaGridPage(
                          performerId: state.pathParameters['id']!,
                        ),
                      ),
                    ],
                  ),
                ],
              ),
            ],
          ),
          StatefulShellBranch(
            routes: [
              GoRoute(
                path: '/studios',
                builder: (context, state) => const StudiosPage(),
                routes: [
                  GoRoute(
                    path: 'studio/:id',
                    builder: (context, state) => StudioDetailsPage(
                      studioId: state.pathParameters['id']!,
                    ),
                    routes: [
                      GoRoute(
                        path: 'media',
                        builder: (context, state) => StudioMediaGridPage(
                          studioId: state.pathParameters['id']!,
                        ),
                      ),
                    ],
                  ),
                ],
              ),
            ],
          ),
          StatefulShellBranch(
            routes: [
              GoRoute(
                path: '/tags',
                builder: (context, state) => const TagsPage(),
                routes: [
                  GoRoute(
                    path: 'tag/:id',
                    builder: (context, state) =>
                        TagDetailsPage(tagId: state.pathParameters['id']!),
                    routes: [
                      GoRoute(
                        path: 'media',
                        builder: (context, state) => TagMediaGridPage(
                          tagId: state.pathParameters['id']!,
                        ),
                      ),
                    ],
                  ),
                ],
              ),
            ],
          ),
          StatefulShellBranch(
            routes: [
              GoRoute(
                path: '/settings',
                builder: (context, state) => const SettingsPage(),
                routes: [
                  GoRoute(
                    path: 'logs',
                    builder: (context, state) => const DebugLogViewerPage(),
                  ),
                ],
              ),
            ],
          ),
        ],
      ),
      // Backward-compatible aliases for legacy absolute detail paths.
      GoRoute(
        path: '/scene/:id',
        builder: (context, state) =>
            SceneDetailsPage(sceneId: state.pathParameters['id']!),
      ),
      GoRoute(
        path: '/performer/:id',
        builder: (context, state) =>
            PerformerDetailsPage(performerId: state.pathParameters['id']!),
        routes: [
          GoRoute(
            path: 'media',
            builder: (context, state) => PerformerMediaGridPage(
              performerId: state.pathParameters['id']!,
            ),
          ),
        ],
      ),
      GoRoute(
        path: '/studio/:id',
        builder: (context, state) =>
            StudioDetailsPage(studioId: state.pathParameters['id']!),
        routes: [
          GoRoute(
            path: 'media',
            builder: (context, state) =>
                StudioMediaGridPage(studioId: state.pathParameters['id']!),
          ),
        ],
      ),
      GoRoute(
        path: '/tag/:id',
        builder: (context, state) =>
            TagDetailsPage(tagId: state.pathParameters['id']!),
        routes: [
          GoRoute(
            path: 'media',
            builder: (context, state) =>
                TagMediaGridPage(tagId: state.pathParameters['id']!),
          ),
        ],
      ),
    ],
  );
}