Skip to content

Commit 859c255

Browse files
committed
feat(router): Add global article details route
- Allow access from outside shell - Avoids navigator context issues - Provides a direct path to details
1 parent 87bc809 commit 859c255

File tree

1 file changed

+61
-0
lines changed

1 file changed

+61
-0
lines changed

lib/router/router.dart

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ GoRouter createRouter({
191191
isGoingToAccount ||
192192
currentLocation == Routes.categoryDetails ||
193193
currentLocation == Routes.sourceDetails ||
194+
currentLocation.startsWith(Routes.globalArticleDetails.split('/:id').first) || // Allow global article details
194195
currentLocation.startsWith('${Routes.feed}/${Routes.articleDetailsName.split('/:id').first}') ||
195196
currentLocation.startsWith('${Routes.search}/${Routes.searchArticleDetailsName.split('/:id').first}') ||
196197
currentLocation.startsWith('${Routes.account}/${Routes.accountSavedHeadlines}/${Routes.accountArticleDetailsName.split('/:id').first}')) {
@@ -337,6 +338,66 @@ GoRouter createRouter({
337338
);
338339
},
339340
),
341+
// --- Global Article Details Route (Top Level) ---
342+
// This GoRoute provides a top-level, globally accessible way to view the
343+
// HeadlineDetailsPage.
344+
//
345+
// Purpose:
346+
// It is specifically designed for navigating to article details from contexts
347+
// that are *outside* the main StatefulShellRoute's branches (e.g., from
348+
// EntityDetailsPage, which is itself a top-level route, or potentially
349+
// from other future top-level pages or deep links).
350+
//
351+
// Why it's necessary:
352+
// Attempting to push a route that is deeply nested within a specific shell
353+
// branch (like '/feed/article/:id') from a BuildContext outside of that
354+
// shell can lead to navigator context issues and assertion failures.
355+
// This global route avoids such problems by providing a clean, direct path
356+
// to the HeadlineDetailsPage.
357+
//
358+
// How it differs:
359+
// This route is distinct from the article detail routes nested within the
360+
// StatefulShellRoute branches (e.g., Routes.articleDetailsName under /feed,
361+
// Routes.searchArticleDetailsName under /search). Those nested routes are
362+
// intended for navigation *within* their respective shell branches,
363+
// preserving the shell's UI (like the bottom navigation bar).
364+
// This global route, being top-level, will typically cover the entire screen.
365+
GoRoute(
366+
path: Routes.globalArticleDetails, // Use new path: '/article/:id'
367+
name: Routes.globalArticleDetailsName, // Use new name
368+
builder: (context, state) {
369+
final headlineFromExtra = state.extra as Headline?;
370+
final headlineIdFromPath = state.pathParameters['id'];
371+
372+
// Ensure accountBloc is available if needed by HeadlineDetailsPage
373+
// or its descendants for actions like saving.
374+
// If AccountBloc is already provided higher up (e.g., in AppShell or App),
375+
// this specific BlocProvider.value might not be strictly necessary here,
376+
// but it's safer to ensure it's available for this top-level route.
377+
// We are using the `accountBloc` instance created at the top of `createRouter`.
378+
return MultiBlocProvider(
379+
providers: [
380+
BlocProvider.value(value: accountBloc),
381+
BlocProvider(
382+
create: (context) => HeadlineDetailsBloc(
383+
headlinesRepository:
384+
context.read<HtDataRepository<Headline>>(),
385+
),
386+
),
387+
BlocProvider(
388+
create: (context) => SimilarHeadlinesBloc(
389+
headlinesRepository:
390+
context.read<HtDataRepository<Headline>>(),
391+
),
392+
),
393+
],
394+
child: HeadlineDetailsPage(
395+
initialHeadline: headlineFromExtra,
396+
headlineId: headlineFromExtra?.id ?? headlineIdFromPath,
397+
),
398+
);
399+
},
400+
),
340401
// --- Main App Shell ---
341402
StatefulShellRoute.indexedStack(
342403
builder: (context, state, navigationShell) {

0 commit comments

Comments
 (0)