1 Commits

Author SHA1 Message Date
iGoX 400dee57d4 Home Screen: Inform on connection lose 2026-03-24 21:58:42 +01:00
2 changed files with 34 additions and 14 deletions
+9 -1
View File
@@ -149,6 +149,11 @@ final colorProvider = StateNotifierProvider<ColorNotifier, BusylightColor>(
},
);
// ── Connection lost indicator ─────────────────────────────────────────────────
// Set to true by the polling notifier when a poll fails, false on success.
final connectionLostProvider = StateProvider<bool>((_) => false);
// ── Background polling ────────────────────────────────────────────────────────
// Periodically pulls status + color from the device and silently updates state.
@@ -181,8 +186,11 @@ class PollingNotifier extends StateNotifier<void> {
_ref.read(busylightStatusProvider.notifier).setLocalStatus(status);
_ref.read(colorProvider.notifier).silentSet(color);
_ref.read(brightnessProvider.notifier).silentSet(color.brightness);
// Connection restored — clear the lost flag
_ref.read(connectionLostProvider.notifier).state = false;
} catch (_) {
// Silently ignore poll errors — connection issues are shown on manual refresh
// Signal connectivity issue to the UI
_ref.read(connectionLostProvider.notifier).state = true;
}
}
+25 -13
View File
@@ -118,10 +118,11 @@ class _BodyState extends ConsumerState<_Body> {
@override
Widget build(BuildContext context) {
final statusAsync = ref.watch(busylightStatusProvider);
final brightness = ref.watch(brightnessProvider);
final color = ref.watch(colorProvider);
final presets = ref.watch(presetsProvider);
final statusAsync = ref.watch(busylightStatusProvider);
final brightness = ref.watch(brightnessProvider);
final color = ref.watch(colorProvider);
final presets = ref.watch(presetsProvider);
final connectionLost = ref.watch(connectionLostProvider);
final status = statusAsync.valueOrNull ?? BusylightStatus.off;
final displayColor = _statusColor(status, color);
@@ -129,7 +130,7 @@ class _BodyState extends ConsumerState<_Body> {
return ListView(
padding: const EdgeInsets.all(24),
children: [
// Live color preview dot
// Live color preview dot — shows wifi-off icon when connection lost
Center(
child: AnimatedContainer(
duration: const Duration(milliseconds: 400),
@@ -137,10 +138,12 @@ class _BodyState extends ConsumerState<_Body> {
height: 100,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: status == BusylightStatus.off
color: connectionLost
? Colors.grey.shade900
: displayColor.withOpacity(brightness),
boxShadow: status != BusylightStatus.off
: status == BusylightStatus.off
? Colors.grey.shade900
: displayColor.withOpacity(brightness),
boxShadow: (!connectionLost && status != BusylightStatus.off)
? [BoxShadow(
color: displayColor.withOpacity(0.5 * brightness),
blurRadius: 40,
@@ -148,13 +151,20 @@ class _BodyState extends ConsumerState<_Body> {
)]
: null,
),
child: connectionLost
? const Icon(Icons.wifi_off, color: Colors.grey, size: 36)
: null,
),
),
const SizedBox(height: 12),
Center(
child: Text(
status.label.toUpperCase(),
style: const TextStyle(color: Colors.grey, letterSpacing: 2, fontSize: 13),
connectionLost ? 'NO CONNECTION' : status.label.toUpperCase(),
style: TextStyle(
color: connectionLost ? Colors.red.shade700 : Colors.grey,
letterSpacing: 2,
fontSize: 13,
),
),
),
const SizedBox(height: 36),
@@ -177,9 +187,11 @@ class _BodyState extends ConsumerState<_Body> {
BusylightStatus.off,
].map((s) => StatusButton(
status: s,
isActive: status == s,
isActive: !connectionLost && status == s,
isPending: _pendingStatus == s,
onTap: _pendingStatus == null ? () => _setStatus(s) : () {},
onTap: (!connectionLost && _pendingStatus == null)
? () => _setStatus(s)
: () {},
)).toList(),
),
const SizedBox(height: 32),
@@ -188,7 +200,7 @@ class _BodyState extends ConsumerState<_Body> {
_PresetsScroller(
presets: presets,
pendingPresetId: _pendingPresetId,
onPresetTap: (_pendingStatus == null && _pendingPresetId == null)
onPresetTap: (!connectionLost && _pendingStatus == null && _pendingPresetId == null)
? _applyPreset
: (_) {},
onPresetDelete: (preset) => ref.read(presetsProvider.notifier).remove(preset.id),