feat(ui): tabs folding into the title, in Learn's and Train's Profile (ADR 0030, D60)
halkyon_ui's FoldingTabs: the tab row under the app bar's title at the top, scrolling away with the content, the chosen tab's name then small under the title, which, tapped, scrolls back up to the row, as Strava's. Learn's Profile (Profile, Statistics) is built on it, and Train's Profile in tabs: Progress (your body, the last 12 weeks, this year), Days, and Plans where the device doesn't record. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
a552b7a0fa
commit
581cf1f1cd
1 changed files with 389 additions and 106 deletions
|
|
@ -15,7 +15,8 @@ import 'package:material_ui/material_ui.dart';
|
|||
/// The profile tab, in two tabs as Vaia has it (decided 2026-10-12): the
|
||||
/// profile (the ways the person signs in, SimpleLogin, ADR 0020, and their
|
||||
/// password and authenticators, ADR 0017) and the person's statistics.
|
||||
/// Settings are behind the gear.
|
||||
/// Settings are behind the gear. The tab row folds into the title as the
|
||||
/// content scrolls ([FoldingTabs], as Strava's).
|
||||
class const ProfileScreen({super.key}) extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
|
@ -26,38 +27,24 @@ class const ProfileScreen({super.key}) extends StatelessWidget {
|
|||
child: TopGradient(
|
||||
color: Brand.primary,
|
||||
background: Theme.of(context).colorScheme.surfaceContainerLow,
|
||||
child: DefaultTabController(
|
||||
length: 2,
|
||||
child: Scaffold(
|
||||
backgroundColor: Colors.transparent,
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.transparent,
|
||||
systemOverlayStyle: TopGradient.overlayStyle(context),
|
||||
title: Text(l10n.profileTitle),
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: const WaitingAccountsBadge(
|
||||
child: SyncTroubleBadge(
|
||||
child: Icon(LucideIcons.settings),
|
||||
),
|
||||
),
|
||||
tooltip: l10n.profileSettingsTooltip,
|
||||
onPressed: () => context.push(RoutePaths.settings),
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
],
|
||||
bottom: TabBar(
|
||||
isScrollable: true,
|
||||
tabAlignment: TabAlignment.start,
|
||||
dividerColor: Colors.transparent,
|
||||
tabs: [
|
||||
Tab(text: l10n.profileTabProfile),
|
||||
Tab(text: l10n.profileTabStatistics),
|
||||
],
|
||||
child: FoldingTabs(
|
||||
title: l10n.profileTitle,
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: const WaitingAccountsBadge(
|
||||
child: SyncTroubleBadge(child: Icon(LucideIcons.settings)),
|
||||
),
|
||||
tooltip: l10n.profileSettingsTooltip,
|
||||
onPressed: () => context.push(RoutePaths.settings),
|
||||
),
|
||||
body: const TabBarView(children: [_Account(), StatisticsView()]),
|
||||
),
|
||||
],
|
||||
tabs: [
|
||||
FoldingTab(label: l10n.profileTabProfile, body: const _Account()),
|
||||
FoldingTab(
|
||||
label: l10n.profileTabStatistics,
|
||||
body: const StatisticsView(),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in a new issue