diff --git a/open_wearable/lib/widgets/devices/device_detail/power_saving_mode_widget.dart b/open_wearable/lib/widgets/devices/device_detail/power_saving_mode_widget.dart index 9c414ee9..d13fd617 100644 --- a/open_wearable/lib/widgets/devices/device_detail/power_saving_mode_widget.dart +++ b/open_wearable/lib/widgets/devices/device_detail/power_saving_mode_widget.dart @@ -121,7 +121,8 @@ class _PowerSavingModeWidgetState extends State { data.modes.any((candidate) => _modesEqualById(candidate, mode)), equalsSelection: _modesEqualById, optionLabel: (mode) => mode.name, - optionIcon: (_) => Icons.battery_saver_rounded, + optionSubtitle: _subtitleForMode, + optionIcon: _iconForMode, loadErrorText: (error) => 'Failed to load power saving mode: ${_describeError(error)}', applyErrorText: ( @@ -207,6 +208,48 @@ bool _modesEqualById(PowerSavingMode? a, PowerSavingMode b) { return a != null && a.id == b.id; } +String _subtitleForMode(PowerSavingMode mode) { + return switch (mode.id) { + 0 => 'Auto-off disabled', + 1 => 'Off after 30 min idle (audio/sensors prevent)', + 2 => 'Off after 15 min idle (audio/sensors prevent)', + 3 => 'Off after 5 min idle (only audio prevents)', + _ => _subtitleForModeName(mode.name), + }; +} + +String _subtitleForModeName(String name) { + final normalized = name.toLowerCase().replaceAll(RegExp(r'[^a-z]'), ''); + return switch (normalized) { + 'off' => 'Auto-off disabled', + 'minimal' => 'Off after 30 min idle (audio/sensors prevent)', + 'balanced' => 'Off after 15 min idle (audio/sensors prevent)', + 'aggressive' || 'agressive' => 'Off after 5 min idle (only audio prevents)', + _ => 'Firmware-defined auto-off behavior', + }; +} + +IconData _iconForMode(PowerSavingMode mode) { + return switch (mode.id) { + 0 => Icons.power_settings_new_rounded, + 1 => Icons.schedule_rounded, + 2 => Icons.battery_saver_rounded, + 3 => Icons.speed_rounded, + _ => _iconForModeName(mode.name), + }; +} + +IconData _iconForModeName(String name) { + final normalized = name.toLowerCase().replaceAll(RegExp(r'[^a-z]'), ''); + return switch (normalized) { + 'off' => Icons.power_settings_new_rounded, + 'minimal' => Icons.schedule_rounded, + 'balanced' => Icons.battery_saver_rounded, + 'aggressive' || 'agressive' => Icons.speed_rounded, + _ => Icons.battery_saver_rounded, + }; +} + String _describeError(Object error) { final text = error.toString().trim(); if (text.startsWith('Exception: ')) { diff --git a/open_wearable/lib/widgets/devices/devices_page.dart b/open_wearable/lib/widgets/devices/devices_page.dart index e47973ca..5225485e 100644 --- a/open_wearable/lib/widgets/devices/devices_page.dart +++ b/open_wearable/lib/widgets/devices/devices_page.dart @@ -819,14 +819,6 @@ class _PairedDeviceSheet extends StatelessWidget { device: powerSavingModeDevice, applyScope: StereoPairApplyScope.pairOnly, ), - ] else ...[ - const SizedBox(height: 10), - Text( - 'Power saving mode is not available for this stereo pair.', - style: theme.textTheme.bodySmall?.copyWith( - color: theme.colorScheme.onSurfaceVariant, - ), - ), ], ], ), diff --git a/open_wearable/test/widgets/connector_activity_indicator_test.dart b/open_wearable/test/widgets/connector_activity_indicator_test.dart index e081a2f5..9db08d0f 100644 --- a/open_wearable/test/widgets/connector_activity_indicator_test.dart +++ b/open_wearable/test/widgets/connector_activity_indicator_test.dart @@ -77,7 +77,7 @@ void main() { ); expect( - find.byTooltip('Connector active, Wi-Fi unavailable'), + find.byTooltip('Connector active, network unavailable'), findsOneWidget, ); });