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:
Tizian 「ティツィアーン」 2026-10-31 19:12:11 +01:00
commit 581cf1f1cd
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64

View file

@ -355,14 +355,33 @@ void main() {
expect(startFor(), findsOneWidget);
});
testWidgets("a phone's Profile has the tabs Progress and Days (D60)", (
tester,
) async {
await start(tester, usedBefore: true, recording: phone());
await goTab(tester, 'Profile');
final profileTabs = find.descendant(
of: find.byType(FoldingTabs),
matching: find.byType(Tab),
);
expect(
[for (final tab in tester.widgetList<Tab>(profileTabs)) tab.text],
['Progress', 'Days'],
);
expect(find.byType(WeeksCard), findsOneWidget);
});
testWidgets("a device that doesn't record has no Record tab, and its "
'plans beside the days in Profile', (tester) async {
await start(tester, usedBefore: true);
expect(tabs(tester), ['Home', 'Maps', 'Groups', 'Profile']);
await goTab(tester, 'Profile');
expect(find.text('Days'), findsOneWidget);
expect(find.text('Plans'), findsOneWidget);
expect(find.widgetWithText(Tab, 'Progress'), findsOneWidget);
expect(find.widgetWithText(Tab, 'Days'), findsOneWidget);
expect(find.widgetWithText(Tab, 'Plans'), findsOneWidget);
});
testWidgets('Groups says they come later', (tester) async {
@ -2281,12 +2300,19 @@ void main() {
),
);
/// Profile's Days tab.
Future<void> openDays(WidgetTester tester) async {
await goTab(tester, 'Profile');
await tester.tap(find.widgetWithText(Tab, 'Days'));
await tester.pumpAndSettle();
}
testWidgets('without a band, the days tab says where days come from', (
tester,
) async {
await start(tester, usedBefore: true, days: days);
await goTab(tester, 'Profile');
await openDays(tester);
expect(find.text('No days yet'), findsOneWidget);
});
@ -2296,7 +2322,7 @@ void main() {
await keepTuesday(tester);
await start(tester, usedBefore: true, days: days);
await goTab(tester, 'Profile');
await openDays(tester);
expect(find.text('Tuesday, October 27'), findsOneWidget);
expect(find.text('9876 steps'), findsOneWidget);