feat: revamp sensor add flow

This commit is contained in:
2026-05-16 12:00:55 +02:00
parent be6ac42059
commit f37176cce5
12 changed files with 478 additions and 186 deletions
+30 -10
View File
@@ -13,6 +13,22 @@ class SensorListScreen extends ConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) {
final sensors = ref.watch(sensorsProvider);
ref.listen(sensorsChannelProvider, (_, next) {
next.whenData((msg) {
switch (msg['event'] as String?) {
case 'sensor_announced':
ref.invalidate(sensorsProvider);
case 'sensor_enrollment_timeout':
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Sensor did not come online in time. '
'Check WiFi credentials and try again.'),
),
);
}
});
});
return Scaffold(
appBar: AppBar(title: const Text('Sensors')),
body: Column(
@@ -35,16 +51,12 @@ class SensorListScreen extends ConsumerWidget {
if (unplaced.isNotEmpty) ...[
_SectionHeader(
label: 'Unplaced', count: unplaced.length),
...unplaced.map((s) => _SensorTile(
sensor: s,
)),
...unplaced.map((s) => _SensorTile(sensor: s)),
],
if (placed.isNotEmpty) ...[
_SectionHeader(
label: 'Placed', count: placed.length),
...placed.map((s) => _SensorTile(
sensor: s,
)),
...placed.map((s) => _SensorTile(sensor: s)),
],
],
);
@@ -87,22 +99,30 @@ class _SectionHeader extends StatelessWidget {
}
class _SensorTile extends StatelessWidget {
const _SensorTile({required this.sensor, this.isSelected = false});
const _SensorTile({required this.sensor});
final Sensor sensor;
final bool isSelected;
@override
Widget build(BuildContext context) {
return ListTile(
selected: isSelected,
leading: Icon(sensor.isPlaced
? Icons.sensors
: Icons.sensors_off_outlined),
title: Text(sensor.displayName),
subtitle: Text(
sensor.isPlaced ? 'Placed' : 'Not placed on floor plan'),
trailing: const Icon(Icons.chevron_right),
textColor: sensor.confirmed ? null : Colors.grey,
trailing: sensor.confirmed
? const Icon(Icons.chevron_right)
: Row(
mainAxisSize: MainAxisSize.min,
children: const [
Icon(Icons.access_time, color: Colors.amber, size: 18),
SizedBox(width: 4),
Icon(Icons.chevron_right),
],
),
onTap: () => showSensorDetailSheet(context, sensor.id),
);
}