fix(train): the Record sheet's music choice on a row of its own, each label on one line

The segmented choice of Music, Metronome and Off sat in the music
tile's subtitle, beside its icon, where a phone of 360 dp wrapped
"Metronome" into "Metronom/e". It takes the list's whole width now,
under its title, each label on one line and scaled down where larger
text still leaves too little room. ADR 0030, D65.

Whats-New: The Record sheet's Music, Metronome and Off each fit on one line.
Whats-New-De: Musik, Metronom und Aus passen im Aufzeichnen-Blatt jeweils auf eine Zeile.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
Tizian 「ティツィアーン」 2026-11-04 20:40:17 +01:00
commit 0c2d4ffecc
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64

View file

@ -3,6 +3,7 @@ import 'dart:io';
import 'package:clock/clock.dart';
import 'package:flutter/gestures.dart' show kLongPressTimeout;
import 'package:flutter/rendering.dart' show RenderParagraph;
import 'package:flutter_map/flutter_map.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:halkyon_app/halkyon_app.dart';
@ -69,6 +70,7 @@ import 'package:halkyon_ui/halkyon_ui.dart';
import 'package:http/http.dart' as http;
import 'package:http/testing.dart';
import 'package:latlong2/latlong.dart';
import 'package:lucide_icons_flutter/lucide_icons.dart';
import 'package:material_ui/material_ui.dart';
import '../support/fake_firmware_relay.dart';
@ -2193,6 +2195,43 @@ void main() {
});
});
testWidgets("the music's choice keeps each label on one line on a phone, "
'its text larger (D65)', (tester) async {
await withClock(Clock(() => at), () async {
await startRecording(tester);
tester.view.physicalSize = const Size(360, 800);
tester.platformDispatcher.textScaleFactorTestValue = 1.3;
addTearDown(tester.platformDispatcher.clearTextScaleFactorTestValue);
await tester.pumpAndSettle();
await tester.tap(startFor());
await tester.pumpAndSettle();
await tester.ensureVisible(find.text('Metronome'));
await tester.pumpAndSettle();
for (final label in ['Music', 'Metronome', 'Off']) {
final text = find.descendant(
of: find.byType(SegmentedButton<MusicChoice>),
matching: find.text(label),
);
final paragraph = tester.renderObject<RenderParagraph>(text);
final tops = paragraph
.getBoxesForSelection(
TextSelection(baseOffset: 0, extentOffset: label.length),
)
.map((box) => box.top)
.toSet();
expect(tops, hasLength(1), reason: '$label on one line');
}
// On a row of its own, as wide as the sheet's list less its margins.
final segments = tester.getRect(
find.byType(SegmentedButton<MusicChoice>),
);
final icon = tester.getRect(find.byIcon(LucideIcons.music));
expect(segments.left, lessThanOrEqualTo(icon.left));
expect(segments.top, greaterThan(icon.bottom));
});
});
testWidgets("a ride offers the bike's sensors, found nearby and chosen; "
"a run doesn't (D49)", (tester) async {
platform.nearbyBike = [