Merge FB-02: hide idle Speed panel

# Conflicts:
#	docs/feedback/FB-02-hide-idle-speed-panel.md
This commit is contained in:
2026-08-24 16:01:45 -05:00
3 changed files with 132 additions and 57 deletions

View File

@@ -173,7 +173,6 @@ class _RecordScreenState extends ConsumerState<RecordScreen> {
final engine = ref.watch(recordingEngineProvider);
final trip = ref.watch(activeTripProvider).valueOrNull;
final units = ref.watch(unitSystemProvider);
final (speedValue, speedUnit) = formatSpeedParts(_liveSpeed, unit: units);
final ui = RecordUiState(
trip: trip,
@@ -195,38 +194,17 @@ class _RecordScreenState extends ConsumerState<RecordScreen> {
body: SafeArea(
child: Stack(
children: [
if (ui.isIdle)
Center(
child: GlassPanel(
padding: const EdgeInsets.all(24),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
// Current speed, not max: a max figure only moves when you beat
// it, which reads as a frozen screen while riding steadily.
// This is the 2.0.1 fix and it must not regress.
BigStat(
key: const Key('speed'),
label: 'SPEED',
value: speedValue,
unit: speedUnit,
scale: mountedMode ? mountedTextScale : 1.0,
),
const SizedBox(height: 16),
// A resting state, not a zeroed ride -- otherwise the screen
// looks like a recording that is going nowhere.
const StatRow(label: 'Status', value: 'Ready'),
const StatRow(label: 'Last ride', value: 'See Rides'),
],
),
),
)
else
if (!ui.isIdle)
Positioned.fill(
bottom: _controlBarHeight(mountedMode),
child: HudEditOverlay(
metricBuilder: (context, metric) =>
_HudMetricValue(metric: metric, ui: ui, units: units),
metricBuilder: (context, metric) => _HudMetricValue(
metric: metric,
ui: ui,
units: units,
scale: mountedMode ? mountedTextScale : 1.0,
mountedMode: mountedMode,
),
),
),
if (ui.isPaused)
@@ -288,21 +266,50 @@ class _RecordScreenState extends ConsumerState<RecordScreen> {
/// same `RecordUiState`/units that powered the old fixed stats card. No new data
/// plumbing, only new presentation, per the ticket's own Implementation section.
class _HudMetricValue extends StatelessWidget {
const _HudMetricValue({required this.metric, required this.ui, required this.units});
const _HudMetricValue({
required this.metric,
required this.ui,
required this.units,
this.scale = 1.0,
this.mountedMode = false,
});
final HudMetric metric;
final RecordUiState ui;
final UnitSystem units;
/// V3-05: mounted mode reads bigger, at a glance, at speed. Same mechanism `BigStat`
/// used for the old idle Speed panel -- fixed pixel sizes below (not the ambient text
/// theme) are what a glove-and-visor readout actually is, so scaling has to happen
/// here rather than through `Theme.of(context).textTheme`.
final double scale;
/// FB-02: `_HudMetricValue` had no mounted-mode awareness at all before the idle
/// `BigStat` (which did) was removed as the idle panel's speed readout -- this
/// migration is what surfaced that gap. [scale] above covers the font-size half of
/// it; this covers the other half `BigStat` also handled by naming its headline
/// colour explicitly (`colors.onSurface`, never a metric accent) rather than trusting
/// the ambient theme: in the mounted theme specifically, `_valueColor`'s per-metric
/// accent colours (tuned for the dark theme's own contrast) fall a hair short of AA
/// (4.43:1, not 4.5:1) against `GlassPanel`'s mounted-theme surface. Reusing
/// `BigStat`'s own fallback -- plain, guaranteed-legible ink whenever mounted mode is
/// on -- fixes it without touching the accent colours the dark-theme HUD mockup
/// deliberately specifies.
final bool mountedMode;
/// Matches the Map HUD mockup's own colour choices for its default four metrics
/// exactly (Speed: primary, Avg Speed/Time: plain ink, Dist: secondary) rather than
/// this app's usual reference-vs-live convention -- this HUD is a new visual context
/// the mockup already specifies directly, colour by colour.
Color _valueColor(ColorScheme colors) => switch (metric) {
HudMetric.speed => colors.primary,
HudMetric.distance => colors.secondary,
_ => colors.onSurface,
};
/// the mockup already specifies directly, colour by colour. Mounted mode overrides
/// this with plain ink -- see [mountedMode] doc above.
Color _valueColor(ColorScheme colors) {
if (mountedMode) return colors.onSurface;
return switch (metric) {
HudMetric.speed => colors.primary,
HudMetric.distance => colors.secondary,
_ => colors.onSurface,
};
}
String get _value {
final trip = ui.trip;
@@ -326,7 +333,11 @@ class _HudMetricValue extends StatelessWidget {
children: [
Text(
metric.label.toUpperCase(),
style: TextStyle(fontSize: 10, letterSpacing: 1, color: colors.onSurfaceVariant),
style: TextStyle(
fontSize: 10 * scale,
letterSpacing: 1,
color: colors.onSurfaceVariant,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
@@ -334,7 +345,7 @@ class _HudMetricValue extends StatelessWidget {
Text(
_value,
style: monoDigits.copyWith(
fontSize: 18,
fontSize: 18 * scale,
fontWeight: FontWeight.bold,
color: _valueColor(colors),
),