feat: tablet landscape improvements
Shell: move Projects/News/Calendar into ShellRoute so the NavigationRail persists across all screens. Show all 6 nav destinations on tablet instead of 3+More overflow. Phone bottom nav unchanged. Chat: master-detail layout on tablet — conversations list (320px) with inline chat panel. Tapping a conversation updates state instead of pushing a new route. Knowledge: responsive grid (2 cols portrait, 3 cols landscape) with card layout showing icon, title, body preview, and tags. Fix snippet data — read json['snippet'] which the API actually sends. Bump snippet length from 120 to 200 chars. Tasks now show description as snippet. News: responsive grid with the same breakpoints. Larger snippet (5 lines) in grid mode via snippetMaxLines parameter. Briefing: centered reading column (maxWidth 700) on wide screens, matching the web UI layout. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+35
-29
@@ -159,20 +159,20 @@ final routerProvider = Provider<GoRouter>((ref) {
|
||||
path: Routes.conversations,
|
||||
builder: (_, _) => const ConversationsTabScreen(),
|
||||
),
|
||||
GoRoute(
|
||||
path: Routes.projects,
|
||||
builder: (_, _) => const ProjectsScreen(),
|
||||
),
|
||||
GoRoute(
|
||||
path: Routes.news,
|
||||
builder: (_, _) => const NewsScreen(),
|
||||
),
|
||||
GoRoute(
|
||||
path: Routes.calendar,
|
||||
builder: (_, _) => const CalendarScreen(),
|
||||
),
|
||||
],
|
||||
),
|
||||
GoRoute(
|
||||
path: Routes.projects,
|
||||
builder: (_, _) => const ProjectsScreen(),
|
||||
),
|
||||
GoRoute(
|
||||
path: Routes.news,
|
||||
builder: (_, _) => const NewsScreen(),
|
||||
),
|
||||
GoRoute(
|
||||
path: Routes.calendar,
|
||||
builder: (_, _) => const CalendarScreen(),
|
||||
),
|
||||
],
|
||||
);
|
||||
});
|
||||
@@ -190,6 +190,9 @@ class _ShellState extends ConsumerState<_Shell> with WidgetsBindingObserver {
|
||||
Routes.briefing,
|
||||
Routes.knowledge,
|
||||
Routes.conversations,
|
||||
Routes.projects,
|
||||
Routes.news,
|
||||
Routes.calendar,
|
||||
];
|
||||
|
||||
// Minimum gap between app-resume refreshes to avoid hammering the server.
|
||||
@@ -255,6 +258,10 @@ class _ShellState extends ConsumerState<_Shell> with WidgetsBindingObserver {
|
||||
ref.read(knowledgeProvider.notifier).refresh();
|
||||
case 2:
|
||||
ref.read(conversationsProvider.notifier).refresh();
|
||||
case 4:
|
||||
ref.read(newsProvider.notifier).refresh();
|
||||
case 5:
|
||||
ref.read(calendarProvider.notifier).refresh();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -271,11 +278,6 @@ class _ShellState extends ConsumerState<_Shell> with WidgetsBindingObserver {
|
||||
for (var i = 0; i < _tabs.length; i++) {
|
||||
if (location.startsWith(_tabs[i])) return i;
|
||||
}
|
||||
if (location.startsWith(Routes.projects) ||
|
||||
location.startsWith(Routes.news) ||
|
||||
location.startsWith(Routes.calendar)) {
|
||||
return 3;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -394,7 +396,7 @@ class _ShellState extends ConsumerState<_Shell> with WidgetsBindingObserver {
|
||||
final index = _tabIndex(location);
|
||||
|
||||
// Refresh the incoming tab's data when switching between shell tabs.
|
||||
if (_prevTabIndex != null && _prevTabIndex != index && index < 3) {
|
||||
if (_prevTabIndex != null && _prevTabIndex != index) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) => _refreshTab(index));
|
||||
}
|
||||
_prevTabIndex = index;
|
||||
@@ -413,13 +415,7 @@ class _ShellState extends ConsumerState<_Shell> with WidgetsBindingObserver {
|
||||
children: [
|
||||
NavigationRail(
|
||||
selectedIndex: index,
|
||||
onDestinationSelected: (i) {
|
||||
if (i == 3) {
|
||||
_showMoreSheet(context);
|
||||
} else {
|
||||
context.go(_tabs[i]);
|
||||
}
|
||||
},
|
||||
onDestinationSelected: (i) => context.go(_tabs[i]),
|
||||
labelType: NavigationRailLabelType.all,
|
||||
destinations: const [
|
||||
NavigationRailDestination(
|
||||
@@ -438,9 +434,19 @@ class _ShellState extends ConsumerState<_Shell> with WidgetsBindingObserver {
|
||||
label: Text('Chat'),
|
||||
),
|
||||
NavigationRailDestination(
|
||||
icon: Icon(Icons.more_horiz_outlined),
|
||||
selectedIcon: Icon(Icons.more_horiz),
|
||||
label: Text('More'),
|
||||
icon: Icon(Icons.folder_outlined),
|
||||
selectedIcon: Icon(Icons.folder),
|
||||
label: Text('Projects'),
|
||||
),
|
||||
NavigationRailDestination(
|
||||
icon: Icon(Icons.newspaper_outlined),
|
||||
selectedIcon: Icon(Icons.newspaper),
|
||||
label: Text('News'),
|
||||
),
|
||||
NavigationRailDestination(
|
||||
icon: Icon(Icons.calendar_month_outlined),
|
||||
selectedIcon: Icon(Icons.calendar_month),
|
||||
label: Text('Calendar'),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -469,7 +475,7 @@ class _ShellState extends ConsumerState<_Shell> with WidgetsBindingObserver {
|
||||
],
|
||||
),
|
||||
bottomNavigationBar: NavigationBar(
|
||||
selectedIndex: index,
|
||||
selectedIndex: index >= 3 ? 3 : index,
|
||||
onDestinationSelected: (i) {
|
||||
if (i == 3) {
|
||||
_showMoreSheet(context);
|
||||
|
||||
Reference in New Issue
Block a user