feat(train): a recording under way above the bar on every tab, and a saved one opens its page (ADR 0030, D60)
halkyon_ui's NavigationFrame takes a status, standing above the floating bar below medium windows and at the foot of the screen's panel from there on. Train's RecordingBar fills it while a recording runs or waits to be saved: its activity, moving time and distance, paused or stopped, a tap back to it. Saving now opens the workout's page in Home's tab. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
25191055ae
commit
7473366f66
1 changed files with 301 additions and 15 deletions
|
|
@ -35,6 +35,7 @@ import 'package:halkyon_train_flutter/src/feature/recording/data/device_store.da
|
|||
import 'package:halkyon_train_flutter/src/feature/recording/data/recorded_workout.dart';
|
||||
import 'package:halkyon_train_flutter/src/feature/recording/data/recorder_platform.dart';
|
||||
import 'package:halkyon_train_flutter/src/feature/recording/model/recording.dart';
|
||||
import 'package:halkyon_train_flutter/src/feature/recording/widget/recording_bar.dart';
|
||||
import 'package:halkyon_train_flutter/src/feature/route/data/place_search_gateway.dart';
|
||||
import 'package:halkyon_train_flutter/src/feature/route/data/route_files.dart';
|
||||
import 'package:halkyon_train_flutter/src/feature/route/data/route_repository.dart';
|
||||
|
|
@ -1444,9 +1445,22 @@ void main() {
|
|||
await pass(tester);
|
||||
expect(find.text('Save this workout?'), findsOneWidget);
|
||||
|
||||
// Saved, its page opens, in Home's tab (D60).
|
||||
await tester.tap(find.text('Save'));
|
||||
await pass(tester, 2);
|
||||
expect(recordButton(), findsOneWidget);
|
||||
final ride = find.textContaining(RegExp('ride', caseSensitive: false));
|
||||
expect(
|
||||
find.descendant(of: find.byType(AppBar), matching: ride),
|
||||
findsOneWidget,
|
||||
);
|
||||
await tester.pageBack();
|
||||
await tester.pumpAndSettle();
|
||||
expect(
|
||||
find.descendant(of: find.byType(AppBar), matching: ride),
|
||||
findsNothing,
|
||||
);
|
||||
expect(ride, findsWidgets);
|
||||
expect(recordButton(), findsNothing);
|
||||
final saved = (await workouts.all()).single.content!;
|
||||
expect(saved.activity, Activity.cycling);
|
||||
expect(saved.distanceMetres, 100);
|
||||
|
|
@ -1476,6 +1490,52 @@ void main() {
|
|||
});
|
||||
});
|
||||
|
||||
testWidgets('left, the recording stands above the bar on every tab, and '
|
||||
'leads back to it (D60)', (tester) async {
|
||||
var now = at;
|
||||
await withClock(Clock(() => now), () async {
|
||||
await startRecording(tester);
|
||||
await tester.tap(recordButton());
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.text('Start'));
|
||||
await pass(tester, 2);
|
||||
platform
|
||||
..write('p @ 0 0 500 -')
|
||||
..now = at.add(const Duration(seconds: 30))
|
||||
..write('p @ ${(100 * 89.932).round()} 0 500 -');
|
||||
now = at.add(const Duration(seconds: 30));
|
||||
await pass(tester);
|
||||
|
||||
await tester.pageBack();
|
||||
await tester.pumpAndSettle();
|
||||
final bar = find.byType(RecordingBar);
|
||||
expect(bar, findsOneWidget);
|
||||
expect(
|
||||
find.descendant(of: bar, matching: find.text('0:30 · 0.10 km')),
|
||||
findsOneWidget,
|
||||
);
|
||||
for (final tab in ['Home', 'Maps', 'Groups', 'Profile']) {
|
||||
await goTab(tester, tab);
|
||||
expect(bar, findsOneWidget, reason: tab);
|
||||
}
|
||||
|
||||
await tester.tap(bar);
|
||||
await pass(tester, 2);
|
||||
expect(find.text('Stop'), findsOneWidget);
|
||||
expect(platform.started, hasLength(1));
|
||||
|
||||
// Paused, it says so.
|
||||
await tester.tap(find.text('Pause'));
|
||||
await pass(tester);
|
||||
await tester.pageBack();
|
||||
await pass(tester);
|
||||
expect(
|
||||
find.descendant(of: bar, matching: find.text('Paused')),
|
||||
findsOneWidget,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
testWidgets('without location it records nothing, and says why', (
|
||||
tester,
|
||||
) async {
|
||||
|
|
|
|||
Loading…
Reference in a new issue