feat: adopt smolmail protocol 1.1, adaptive nav shell, and server mail retention
This commit is contained in:
parent
eaaa3f2ede
commit
c693e6fcb9
27 changed files with 1190 additions and 592 deletions
86
lib/presentation/screens/home_screen.dart
Normal file
86
lib/presentation/screens/home_screen.dart
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
import "package:auto_route/auto_route.dart";
|
||||
import "package:flutter/material.dart";
|
||||
import "package:flutter_riverpod/flutter_riverpod.dart";
|
||||
|
||||
import "package:smol_mail/data/providers/providers.dart";
|
||||
import "package:smol_mail/presentation/routes/app_router.gr.dart";
|
||||
import "package:smol_mail/presentation/theme/app_colors.dart";
|
||||
import "package:smol_mail/presentation/theme/breakpoints.dart";
|
||||
import "package:smol_mail/shared/configs/flash_mail_icons.dart";
|
||||
|
||||
class _Destination {
|
||||
final Widget icon;
|
||||
final String label;
|
||||
|
||||
const _Destination({required this.icon, required this.label});
|
||||
}
|
||||
|
||||
/// The app's only persistent navigation surface: a bottom [NavigationBar] on
|
||||
/// phone-width screens, a side [NavigationRail] on desktop-width ones — no
|
||||
/// hamburger drawer at either width. Mail/Contacts/Settings are switched by
|
||||
/// tapping only, never by swipe, so a horizontal gesture inside a
|
||||
/// destination (e.g. the Inbox/Sent/Requests tab bar) never changes section.
|
||||
@RoutePage()
|
||||
class HomeScreen extends ConsumerWidget {
|
||||
const HomeScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final unread = ref.watch(unreadProvider) + ref.watch(requestsUnreadProvider);
|
||||
final appColors = Theme.of(context).extension<AppColors>()!;
|
||||
|
||||
final mailIcon = Icon(FlashMailIcons.inbox);
|
||||
final destinations = [
|
||||
_Destination(
|
||||
icon: unread > 0 ? Badge(label: Text("$unread"), child: mailIcon) : mailIcon,
|
||||
label: "Mail",
|
||||
),
|
||||
const _Destination(icon: Icon(Icons.contacts), label: "Contacts"),
|
||||
const _Destination(icon: Icon(Icons.settings), label: "Settings"),
|
||||
];
|
||||
|
||||
return AutoTabsRouter.builder(
|
||||
routes: const [InboxRoute(), ContactsRoute(), SettingsRoute()],
|
||||
builder: (context, children, tabsRouter) {
|
||||
final body = IndexedStack(index: tabsRouter.activeIndex, children: children);
|
||||
final wide = MediaQuery.sizeOf(context).width >= kDesktopBreakpoint;
|
||||
|
||||
if (!wide) {
|
||||
return Scaffold(
|
||||
body: body,
|
||||
bottomNavigationBar: NavigationBar(
|
||||
selectedIndex: tabsRouter.activeIndex,
|
||||
onDestinationSelected: tabsRouter.setActiveIndex,
|
||||
indicatorColor: appColors.highlight,
|
||||
destinations: [
|
||||
for (final d in destinations)
|
||||
NavigationDestination(icon: d.icon, label: d.label),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
body: Row(
|
||||
children: [
|
||||
NavigationRail(
|
||||
selectedIndex: tabsRouter.activeIndex,
|
||||
onDestinationSelected: tabsRouter.setActiveIndex,
|
||||
backgroundColor: appColors.cardFill,
|
||||
useIndicator: true,
|
||||
indicatorColor: appColors.highlight,
|
||||
labelType: NavigationRailLabelType.all,
|
||||
destinations: [
|
||||
for (final d in destinations)
|
||||
NavigationRailDestination(icon: d.icon, label: Text(d.label)),
|
||||
],
|
||||
),
|
||||
const VerticalDivider(width: 1),
|
||||
Expanded(child: body),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue