From a124e3d9f22304ee0f3ff91f471ab613fe35fa4c Mon Sep 17 00:00:00 2001 From: Janez T Date: Sun, 15 Mar 2026 10:48:48 +0100 Subject: [PATCH] Improve sensor settings UI --- lib/screens/sensors_tab.dart | 94 ++++++++++++------- .../sensor_metric_selector_item_test.dart | 42 +++++++++ 2 files changed, 101 insertions(+), 35 deletions(-) diff --git a/lib/screens/sensors_tab.dart b/lib/screens/sensors_tab.dart index f22c7e4..0e59edd 100644 --- a/lib/screens/sensors_tab.dart +++ b/lib/screens/sensors_tab.dart @@ -627,6 +627,7 @@ class SensorMetricSelectorItem extends StatelessWidget { Widget build(BuildContext context) { final theme = Theme.of(context); final colorScheme = theme.colorScheme; + final showChannelChip = option.channel != null && option.channel != 1; final previewCardData = option.previewCardData ?? SensorMetricCardData( @@ -667,15 +668,68 @@ class SensorMetricSelectorItem extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( + crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded( - child: Text( - option.defaultLabel, - style: theme.textTheme.titleSmall?.copyWith( - fontWeight: FontWeight.w700, - ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + option.defaultLabel, + style: theme.textTheme.titleSmall?.copyWith( + fontWeight: FontWeight.w700, + ), + ), + const SizedBox(height: 6), + Wrap( + spacing: 8, + runSpacing: 8, + crossAxisAlignment: WrapCrossAlignment.center, + children: [ + TextButton.icon( + onPressed: onRename, + style: TextButton.styleFrom( + padding: const EdgeInsets.symmetric( + horizontal: 12, + vertical: 8, + ), + foregroundColor: colorScheme.primary, + textStyle: theme.textTheme.labelLarge?.copyWith( + fontWeight: FontWeight.w700, + ), + ), + icon: const Icon(Icons.edit_outlined, size: 18), + label: const Text('Rename'), + ), + if (showChannelChip) + Container( + key: ValueKey( + 'sensor_selector_channel_${option.key}', + ), + padding: const EdgeInsets.symmetric( + horizontal: 10, + vertical: 8, + ), + decoration: BoxDecoration( + color: previewCardData.accent.withValues( + alpha: 0.10, + ), + borderRadius: BorderRadius.circular(999), + ), + child: Text( + 'Channel ${option.channel}', + style: theme.textTheme.labelMedium?.copyWith( + color: previewCardData.accent, + fontWeight: FontWeight.w700, + ), + ), + ), + ], + ), + ], ), ), + const SizedBox(width: 12), Container( padding: const EdgeInsets.symmetric( horizontal: 10, @@ -723,36 +777,6 @@ class SensorMetricSelectorItem extends StatelessWidget { Switch.adaptive(value: visible, onChanged: onToggle), ], ), - Wrap( - spacing: 8, - runSpacing: 8, - children: [ - OutlinedButton.icon( - onPressed: onRename, - icon: const Icon(Icons.edit_outlined), - label: const Text('Rename'), - ), - if (option.channel != null) - Container( - key: ValueKey('sensor_selector_channel_${option.key}'), - padding: const EdgeInsets.symmetric( - horizontal: 10, - vertical: 10, - ), - decoration: BoxDecoration( - color: previewCardData.accent.withValues(alpha: 0.10), - borderRadius: BorderRadius.circular(999), - ), - child: Text( - 'Channel ${option.channel}', - style: theme.textTheme.labelMedium?.copyWith( - color: previewCardData.accent, - fontWeight: FontWeight.w700, - ), - ), - ), - ], - ), const SizedBox(height: 12), Row( children: [ diff --git a/test/widgets/sensor_metric_selector_item_test.dart b/test/widgets/sensor_metric_selector_item_test.dart index 56a52b3..dfb816d 100644 --- a/test/widgets/sensor_metric_selector_item_test.dart +++ b/test/widgets/sensor_metric_selector_item_test.dart @@ -46,4 +46,46 @@ void main() { ); expect(find.text('Channel 2'), findsOneWidget); }); + + testWidgets('omits duplicate channel chip for channel 1', (tester) async { + await tester.pumpWidget( + MaterialApp( + home: Scaffold( + body: SensorMetricSelectorItem( + option: const SensorMetricOption( + key: 'battery', + label: 'Battery', + defaultLabel: 'Battery', + channel: 1, + valuePreview: '84%', + previewCardData: SensorMetricCardData( + fieldKey: 'battery', + icon: Icons.battery_5_bar, + label: 'Battery', + value: '84%', + accent: Color(0xFF4B8E2F), + channel: 1, + ), + ), + visible: true, + span: 1, + canMoveUp: true, + canMoveDown: true, + onToggle: (_) {}, + onRename: () {}, + onMoveUp: () {}, + onMoveDown: () {}, + onSpanChanged: (_) {}, + ), + ), + ), + ); + + expect(find.text('Rename'), findsOneWidget); + expect( + find.byKey(const ValueKey('sensor_selector_channel_battery')), + findsNothing, + ); + expect(find.text('Channel 1'), findsNothing); + }); }