Skip to content

Commit 12ea253

Browse files
committed
feat: Enhance device availability handling and UI updates
- Added DeviceAvailabilityGuard to manage device availability state in the UI. - Updated SettingsScreen to use DeviceAvailabilityGuard for better state management. - Improved handling of device status in BaseBorneoDeviceViewModel, ensuring proper availability checks. - Refactored LyfiBusyIndicatorSliver to reflect loading states based on editor status. - Enhanced LyfiTimeLineChart with dashed lines for better visual distinction. - Updated device OTA screen to use a new danger button style for critical actions. - Improved error handling and user feedback in GroupedDevicesViewModel and DeviceDiscoveryViewModel. - Added tests for BaseDeviceViewModel to ensure correct behavior on device deletion. - Updated pubspec.yaml for version bump to 0.5.9.
1 parent 31b1626 commit 12ea253

34 files changed

+2067
-2280
lines changed

client/assets/i18n/de.po

Lines changed: 267 additions & 493 deletions
Large diffs are not rendered by default.

client/assets/i18n/en_US.po

Lines changed: 252 additions & 253 deletions
Large diffs are not rendered by default.

client/assets/i18n/es.po

Lines changed: 266 additions & 490 deletions
Large diffs are not rendered by default.

client/assets/i18n/messages.pot

Lines changed: 249 additions & 253 deletions
Large diffs are not rendered by default.

client/assets/i18n/zh_CN.po

Lines changed: 267 additions & 490 deletions
Large diffs are not rendered by default.

client/lib/app/app.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ class _BorneoAppState extends State<BorneoApp> {
219219
context.read<ISceneManager>(),
220220
context.read<IGroupManager>(),
221221
context.read<IDeviceModuleRegistry>(),
222+
gettext: gt,
222223
logger: context.read<Logger>(),
223224
),
224225
dispose: (context, dm) => dm.dispose(),

client/lib/core/services/devices/device_manager_impl.dart

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import 'dart:core';
44
import 'package:borneo_common/exceptions.dart';
55
import 'package:cancellation_token/cancellation_token.dart';
66
import 'package:event_bus/event_bus.dart';
7+
import 'package:flutter_gettext/flutter_gettext.dart';
78
import 'package:logger/logger.dart';
89
import 'package:sembast/sembast.dart';
910
import 'package:synchronized/synchronized.dart';
@@ -22,6 +23,7 @@ import 'package:borneo_app/shared/models/base_entity.dart';
2223
import 'package:borneo_app/core/services/devices/device_manager.dart';
2324

2425
final class DeviceManagerImpl extends IDeviceManager {
26+
final GettextLocalizations gettext;
2527
final Logger? logger;
2628
bool _isDisposed = false;
2729
final Database _db;
@@ -53,6 +55,7 @@ final class DeviceManagerImpl extends IDeviceManager {
5355
this._sceneManager,
5456
this._groupManager,
5557
this._deviceModuleRegistry, {
58+
required this.gettext,
5659
this.logger,
5760
}) {
5861
logger?.i("Creating DeviceManagerImpl...");
@@ -355,7 +358,10 @@ final class DeviceManagerImpl extends IDeviceManager {
355358
} else {
356359
final store = stringMapStoreFactory.store(StoreNames.devices);
357360
final record = await store.record(id).get(tx);
358-
final device = DeviceEntity.fromMap(id, record!);
361+
if (record == null) {
362+
throw KeyNotFoundException(message: 'Cannot find device with ID `$id`', key: id);
363+
}
364+
final device = DeviceEntity.fromMap(id, record);
359365
return device;
360366
}
361367
}

client/lib/devices/borneo/lyfi/view_models/base_lyfi_device_view_model.dart

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,22 @@ abstract class BaseLyfiDeviceViewModel extends BaseBorneoDeviceViewModel {
99
ILyfiDeviceApi get lyfiDeviceApi => super.boundDevice!.driver as ILyfiDeviceApi;
1010
LyfiDeviceInfo get lyfiDeviceInfo => lyfiThing.getProperty<LyfiDeviceInfo>('lyfiDeviceInfo')!;
1111

12-
LyfiDeviceStatus? get lyfiDeviceStatus => lyfiThing.getProperty<LyfiDeviceStatus>('lyfiStatus');
12+
LyfiDeviceStatus? get lyfiDeviceStatus => isAvailable ? lyfiThing.getProperty<LyfiDeviceStatus>('lyfiStatus') : null;
13+
14+
AcclimationSettings? get acclimationSettings =>
15+
isAvailable ? lyfiThing.getProperty<AcclimationSettings>('acclimation') : null;
16+
17+
bool get acclimationEnabled => isAvailable && (lyfiThing.getProperty<bool>('acclimationEnabled') ?? false);
18+
19+
bool get acclimationActivated => isAvailable && (lyfiThing.getProperty<bool>('acclimationActivated') ?? false);
20+
21+
MoonConfig? get moonConfig => isAvailable ? lyfiThing.getProperty<MoonConfig>('moonConfig') : null;
22+
23+
MoonStatus? get moonStatus => isAvailable ? lyfiThing.getProperty<MoonStatus>('moonStatus') : null;
24+
25+
bool get cloudActivated => isAvailable && (lyfiThing.getProperty<bool>('cloudActivated') ?? false);
26+
27+
DateTime? get deviceTimestamp => isAvailable ? lyfiThing.getProperty<DateTime>('timestamp') : null;
1328

1429
LyfiThing get lyfiThing => wotThing as LyfiThing;
1530

@@ -36,22 +51,22 @@ abstract class BaseLyfiDeviceViewModel extends BaseBorneoDeviceViewModel {
3651
void _subscribeToLyfiThing() {
3752
_stateSubscription =
3853
lyfiThing.findProperty('state')?.value.onUpdate.listen((stateName) {
39-
if (!isDisposed) {
54+
if (isAvailable && !isDisposed) {
4055
notifyListeners();
4156
}
4257
})
4358
as StreamSubscription<String>?;
4459
_modeSubscription =
4560
lyfiThing.findProperty('mode')?.value.onUpdate.listen((modeName) {
46-
if (!isDisposed) {
61+
if (isAvailable && !isDisposed) {
4762
notifyListeners();
4863
}
4964
})
5065
as StreamSubscription<String>?;
5166

5267
_statusSubscription =
5368
lyfiThing.findProperty('lyfiStatus')?.value.onUpdate.listen((status) {
54-
if (!isDisposed) {
69+
if (isAvailable && !isDisposed) {
5570
notifyListeners();
5671
}
5772
})
@@ -61,13 +76,20 @@ abstract class BaseLyfiDeviceViewModel extends BaseBorneoDeviceViewModel {
6176
@override
6277
void onDeviceBound() {
6378
super.onDeviceBound();
79+
_unsubscribeFromLyfiThing();
6480
_subscribeToLyfiThing();
6581
}
6682

6783
@override
6884
void onDeviceRemoved() {
85+
_unsubscribeFromLyfiThing();
6986
super.onDeviceRemoved();
87+
}
88+
89+
@override
90+
void onDeviceDeleted() {
7091
_unsubscribeFromLyfiThing();
92+
super.onDeviceDeleted();
7193
}
7294

7395
void _unsubscribeFromLyfiThing() {

client/lib/devices/borneo/lyfi/view_models/lyfi_view_model.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,13 @@ class LyfiViewModel extends BaseLyfiDeviceViewModel {
446446
void onDeviceRemoved() {
447447
super.onDeviceRemoved();
448448

449+
_rapidProbeTask = null;
450+
}
451+
452+
@override
453+
void onDeviceDeleted() {
454+
super.onDeviceDeleted();
455+
449456
for (final cvn in _channels) {
450457
cvn.dispose();
451458
}

client/lib/devices/borneo/lyfi/view_models/settings_view_model.dart

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,8 @@ class SettingsViewModel extends BaseLyfiDeviceViewModel {
254254
notifyListeners();
255255
try {
256256
await api.factoryReset(boundDevice!.device);
257-
notification.showSuccess(_gt.translate("Device restored to factory settings"));
257+
await deviceManager.delete(this.deviceID, cancelToken: masterCancellation);
258+
await Future.delayed(const Duration(milliseconds: 100)).asCancellable(masterCancellation);
258259
} catch (e) {
259260
notification.showError(_gt.translate("Failed to restore device to factory settings: $e"));
260261
} finally {
@@ -268,7 +269,8 @@ class SettingsViewModel extends BaseLyfiDeviceViewModel {
268269
notifyListeners();
269270
try {
270271
await api.networkReset(boundDevice!.device, cancelToken: masterCancellation);
271-
notification.showSuccess(_gt.translate("Device network settings reset"));
272+
await deviceManager.delete(this.deviceID, cancelToken: masterCancellation);
273+
await Future.delayed(const Duration(milliseconds: 100)).asCancellable(masterCancellation);
272274
} catch (e) {
273275
notification.showError(_gt.translate("Failed to reset device network settings: $e"));
274276
} finally {

0 commit comments

Comments
 (0)