From bd9a74b3804e8ed1c747915388c0c336b4d94cb2 Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Mon, 30 Jun 2025 13:58:10 +0300 Subject: [PATCH] fix touch gangs realtime. --- .../bloc/one_gang_glass_switch_bloc.dart | 54 ++- .../bloc/three_gang_glass_switch_bloc.dart | 54 ++- .../bloc/two_gang_glass_switch_bloc.dart | 322 +++++++++--------- 3 files changed, 209 insertions(+), 221 deletions(-) diff --git a/lib/pages/device_managment/one_g_glass_switch/bloc/one_gang_glass_switch_bloc.dart b/lib/pages/device_managment/one_g_glass_switch/bloc/one_gang_glass_switch_bloc.dart index c1e976ab..bb6f8e29 100644 --- a/lib/pages/device_managment/one_g_glass_switch/bloc/one_gang_glass_switch_bloc.dart +++ b/lib/pages/device_managment/one_g_glass_switch/bloc/one_gang_glass_switch_bloc.dart @@ -40,7 +40,7 @@ class OneGangGlassSwitchBloc emit(OneGangGlassSwitchLoading()); try { final status = await DevicesManagementApi().getDeviceStatus(event.deviceId); - _listenToChanges(event.deviceId, emit); + _listenToChanges(event.deviceId); deviceStatus = OneGangGlassStatusModel.fromJson(event.deviceId, status.status); emit(OneGangGlassSwitchStatusLoaded(deviceStatus)); } catch (e) { @@ -48,42 +48,28 @@ class OneGangGlassSwitchBloc } } - void _listenToChanges( - String deviceId, - Emitter emit, - ) { + StreamSubscription? _deviceStatusSubscription; + + void _listenToChanges(String deviceId) { try { final ref = FirebaseDatabase.instance.ref('device-status/$deviceId'); - final stream = ref.onValue; + _deviceStatusSubscription = ref.onValue.listen((DatabaseEvent event) async { + if (event.snapshot.value == null) return; - stream.listen((DatabaseEvent event) { - final data = event.snapshot.value as Map?; - if (data == null) return; + final usersMap = event.snapshot.value! as Map; final statusList = []; - if (data['status'] != null) { - for (var element in data['status']) { - statusList.add( - Status( - code: element['code'].toString(), - value: element['value'].toString(), - ), - ); - } - } - if (statusList.isNotEmpty) { - final newStatus = OneGangGlassStatusModel.fromJson(deviceId, statusList); - if (newStatus != deviceStatus) { - deviceStatus = newStatus; - if (!isClosed) { - add(StatusUpdated(deviceStatus)); - } - } - } + + usersMap['status'].forEach((element) { + statusList.add(Status(code: element['code'], value: element['value'])); + }); + + deviceStatus = + OneGangGlassStatusModel.fromJson(usersMap['productUuid'], statusList); + + add(StatusUpdated(deviceStatus)); }); - } catch (e) { - emit(OneGangGlassSwitchError('Failed to listen to changes: $e')); - } + } catch (_) {} } void _onStatusUpdated( @@ -174,4 +160,10 @@ class OneGangGlassSwitchBloc deviceStatus = deviceStatus.copyWith(switch1: value); } } + + @override + Future close() { + _deviceStatusSubscription?.cancel(); + return super.close(); + } } diff --git a/lib/pages/device_managment/three_g_glass_switch/bloc/three_gang_glass_switch_bloc.dart b/lib/pages/device_managment/three_g_glass_switch/bloc/three_gang_glass_switch_bloc.dart index 766c3163..4a122345 100644 --- a/lib/pages/device_managment/three_g_glass_switch/bloc/three_gang_glass_switch_bloc.dart +++ b/lib/pages/device_managment/three_g_glass_switch/bloc/three_gang_glass_switch_bloc.dart @@ -41,7 +41,7 @@ class ThreeGangGlassSwitchBloc emit(ThreeGangGlassSwitchLoading()); try { final status = await DevicesManagementApi().getDeviceStatus(event.deviceId); - _listenToChanges(event.deviceId, emit); + _listenToChanges(event.deviceId); deviceStatus = ThreeGangGlassStatusModel.fromJson(event.deviceId, status.status); emit(ThreeGangGlassSwitchStatusLoaded(deviceStatus)); @@ -50,42 +50,28 @@ class ThreeGangGlassSwitchBloc } } - void _listenToChanges( - String deviceId, - Emitter emit, - ) { + StreamSubscription? _deviceStatusSubscription; + + void _listenToChanges(String deviceId) { try { final ref = FirebaseDatabase.instance.ref('device-status/$deviceId'); - final stream = ref.onValue; + _deviceStatusSubscription = ref.onValue.listen((DatabaseEvent event) async { + if (event.snapshot.value == null) return; - stream.listen((DatabaseEvent event) { - final data = event.snapshot.value as Map?; - if (data == null) return; + final usersMap = event.snapshot.value! as Map; final statusList = []; - if (data['status'] != null) { - for (var element in data['status']) { - statusList.add( - Status( - code: element['code'].toString(), - value: element['value'].toString(), - ), - ); - } - } - if (statusList.isNotEmpty) { - final newStatus = ThreeGangGlassStatusModel.fromJson(deviceId, statusList); - if (newStatus != deviceStatus) { - deviceStatus = newStatus; - if (!isClosed) { - add(StatusUpdated(deviceStatus)); - } - } - } + + usersMap['status'].forEach((element) { + statusList.add(Status(code: element['code'], value: element['value'])); + }); + + deviceStatus = + ThreeGangGlassStatusModel.fromJson(usersMap['productUuid'], statusList); + + add(StatusUpdated(deviceStatus)); }); - } catch (e) { - emit(ThreeGangGlassSwitchError('Failed to listen to changes: $e')); - } + } catch (_) {} } void _onStatusUpdated( @@ -184,4 +170,10 @@ class ThreeGangGlassSwitchBloc break; } } + + @override + Future close() { + _deviceStatusSubscription?.cancel(); + return super.close(); + } } diff --git a/lib/pages/device_managment/two_g_glass_switch/bloc/two_gang_glass_switch_bloc.dart b/lib/pages/device_managment/two_g_glass_switch/bloc/two_gang_glass_switch_bloc.dart index 8f82c198..08b40362 100644 --- a/lib/pages/device_managment/two_g_glass_switch/bloc/two_gang_glass_switch_bloc.dart +++ b/lib/pages/device_managment/two_g_glass_switch/bloc/two_gang_glass_switch_bloc.dart @@ -1,173 +1,177 @@ -import 'dart:async'; -import 'dart:developer'; + import 'dart:async'; -import 'package:bloc/bloc.dart'; -import 'package:equatable/equatable.dart'; -import 'package:firebase_database/firebase_database.dart'; -import 'package:flutter/foundation.dart'; -import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart'; -import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart'; -import 'package:syncrow_web/pages/device_managment/two_g_glass_switch/models/two_gang_glass_status_model.dart'; -import 'package:syncrow_web/services/batch_control_devices_service.dart'; -import 'package:syncrow_web/services/control_device_service.dart'; -import 'package:syncrow_web/services/devices_mang_api.dart'; + import 'package:bloc/bloc.dart'; + import 'package:equatable/equatable.dart'; + import 'package:firebase_database/firebase_database.dart'; + import 'package:flutter/foundation.dart'; + import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart'; + import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart'; + import 'package:syncrow_web/pages/device_managment/two_g_glass_switch/models/two_gang_glass_status_model.dart'; + import 'package:syncrow_web/services/batch_control_devices_service.dart'; + import 'package:syncrow_web/services/control_device_service.dart'; + import 'package:syncrow_web/services/devices_mang_api.dart'; -part 'two_gang_glass_switch_event.dart'; -part 'two_gang_glass_switch_state.dart'; + part 'two_gang_glass_switch_event.dart'; + part 'two_gang_glass_switch_state.dart'; -class TwoGangGlassSwitchBloc - extends Bloc { - final String deviceId; - final ControlDeviceService controlDeviceService; - final BatchControlDevicesService batchControlDevicesService; + class TwoGangGlassSwitchBloc + extends Bloc { + final String deviceId; + final ControlDeviceService controlDeviceService; + final BatchControlDevicesService batchControlDevicesService; - late TwoGangGlassStatusModel deviceStatus; + late TwoGangGlassStatusModel deviceStatus; - TwoGangGlassSwitchBloc({ - required this.deviceId, - required this.controlDeviceService, - required this.batchControlDevicesService, - }) : super(TwoGangGlassSwitchInitial()) { - on(_onFetchDeviceStatus); - on(_onControl); - on(_onBatchControl); - on(_onFetchBatchStatus); - on(_onFactoryReset); - on(_onStatusUpdated); - } - - Future _onFetchDeviceStatus( - TwoGangGlassSwitchFetchDeviceEvent event, - Emitter emit, - ) async { - emit(TwoGangGlassSwitchLoading()); - try { - final status = await DevicesManagementApi().getDeviceStatus(event.deviceId); - deviceStatus = TwoGangGlassStatusModel.fromJson(event.deviceId, status.status); - _listenToChanges(event.deviceId); - emit(TwoGangGlassSwitchStatusLoaded(deviceStatus)); - } catch (e) { - emit(TwoGangGlassSwitchError(e.toString())); + TwoGangGlassSwitchBloc({ + required this.deviceId, + required this.controlDeviceService, + required this.batchControlDevicesService, + }) : super(TwoGangGlassSwitchInitial()) { + on(_onFetchDeviceStatus); + on(_onControl); + on(_onBatchControl); + on(_onFetchBatchStatus); + on(_onFactoryReset); + on(_onStatusUpdated); } - } - void _listenToChanges(String deviceId) { - try { - final ref = FirebaseDatabase.instance.ref( - 'device-status/$deviceId', - ); - - ref.onValue.listen((event) { - final eventsMap = event.snapshot.value as Map; - - List statusList = []; - eventsMap['status'].forEach((element) { - statusList.add(Status(code: element['code'], value: element['value'])); - }); - - deviceStatus = TwoGangGlassStatusModel.fromJson(deviceId, statusList); - add(StatusUpdated(deviceStatus)); - }); - } catch (_) { - log( - 'Error listening to changes', - name: 'TwoGangGlassSwitchBloc._listenToChanges', - ); - } - } - - Future _onControl( - TwoGangGlassSwitchControl event, - Emitter emit, - ) async { - emit(TwoGangGlassSwitchLoading()); - _updateLocalValue(event.code, event.value); - emit(TwoGangGlassSwitchStatusLoaded(deviceStatus)); - - try { - await controlDeviceService.controlDevice( - deviceUuid: event.deviceId, - status: Status(code: event.code, value: event.value), - ); - } catch (e) { - _updateLocalValue(event.code, !event.value); - emit(TwoGangGlassSwitchError(e.toString())); - } - } - - Future _onBatchControl( - TwoGangGlassSwitchBatchControl event, - Emitter emit, - ) async { - emit(TwoGangGlassSwitchLoading()); - _updateLocalValue(event.code, event.value); - emit(TwoGangGlassSwitchBatchStatusLoaded(deviceStatus)); - - try { - await batchControlDevicesService.batchControlDevices( - uuids: event.deviceIds, - code: event.code, - value: event.value, - ); - } catch (e) { - _updateLocalValue(event.code, !event.value); - emit(TwoGangGlassSwitchError(e.toString())); - } - } - - Future _onFetchBatchStatus( - TwoGangGlassSwitchFetchBatchStatusEvent event, - Emitter emit, - ) async { - emit(TwoGangGlassSwitchLoading()); - try { - final status = await DevicesManagementApi().getBatchStatus(event.deviceIds); - deviceStatus = TwoGangGlassStatusModel.fromJson( - event.deviceIds.first, - status.status, - ); - emit(TwoGangGlassSwitchBatchStatusLoaded(deviceStatus)); - } catch (e) { - emit(TwoGangGlassSwitchError(e.toString())); - } - } - - Future _onFactoryReset( - TwoGangGlassFactoryReset event, - Emitter emit, - ) async { - emit(TwoGangGlassSwitchLoading()); - try { - final response = await DevicesManagementApi().factoryReset( - event.factoryReset, - event.deviceId, - ); - if (!response) { - emit(TwoGangGlassSwitchError('Failed to reset device')); - } else { - add(TwoGangGlassSwitchFetchDeviceEvent(event.deviceId)); + Future _onFetchDeviceStatus( + TwoGangGlassSwitchFetchDeviceEvent event, + Emitter emit, + ) async { + emit(TwoGangGlassSwitchLoading()); + try { + final status = await DevicesManagementApi().getDeviceStatus(event.deviceId); + deviceStatus = TwoGangGlassStatusModel.fromJson(event.deviceId, status.status); + _listenToChanges(event.deviceId); + emit(TwoGangGlassSwitchStatusLoaded(deviceStatus)); + } catch (e) { + emit(TwoGangGlassSwitchError(e.toString())); } - } catch (e) { - emit(TwoGangGlassSwitchError(e.toString())); } - } - void _onStatusUpdated( - StatusUpdated event, - Emitter emit, - ) { - deviceStatus = event.deviceStatus; - emit(TwoGangGlassSwitchStatusLoaded(deviceStatus)); - } + StreamSubscription? _deviceStatusSubscription; - void _updateLocalValue(String code, bool value) { - switch (code) { - case 'switch_1': - deviceStatus = deviceStatus.copyWith(switch1: value); - break; - case 'switch_2': - deviceStatus = deviceStatus.copyWith(switch2: value); - break; + void _listenToChanges(String deviceId) { + try { + final ref = FirebaseDatabase.instance.ref('device-status/$deviceId'); + _deviceStatusSubscription = ref.onValue.listen((DatabaseEvent event) async { + if (event.snapshot.value == null) return; + + final usersMap = event.snapshot.value! as Map; + + final statusList = []; + + usersMap['status'].forEach((element) { + statusList.add(Status(code: element['code'], value: element['value'])); + }); + + deviceStatus = + TwoGangGlassStatusModel.fromJson(usersMap['productUuid'], statusList); + + add(StatusUpdated(deviceStatus)); + }); + } catch (_) {} } + + Future _onControl( + TwoGangGlassSwitchControl event, + Emitter emit, + ) async { + emit(TwoGangGlassSwitchLoading()); + _updateLocalValue(event.code, event.value); + emit(TwoGangGlassSwitchStatusLoaded(deviceStatus)); + + try { + await controlDeviceService.controlDevice( + deviceUuid: event.deviceId, + status: Status(code: event.code, value: event.value), + ); + } catch (e) { + _updateLocalValue(event.code, !event.value); + emit(TwoGangGlassSwitchError(e.toString())); + } + } + + Future _onBatchControl( + TwoGangGlassSwitchBatchControl event, + Emitter emit, + ) async { + emit(TwoGangGlassSwitchLoading()); + _updateLocalValue(event.code, event.value); + emit(TwoGangGlassSwitchBatchStatusLoaded(deviceStatus)); + + try { + await batchControlDevicesService.batchControlDevices( + uuids: event.deviceIds, + code: event.code, + value: event.value, + ); + } catch (e) { + _updateLocalValue(event.code, !event.value); + emit(TwoGangGlassSwitchError(e.toString())); + } + } + + Future _onFetchBatchStatus( + TwoGangGlassSwitchFetchBatchStatusEvent event, + Emitter emit, + ) async { + emit(TwoGangGlassSwitchLoading()); + try { + final status = await DevicesManagementApi().getBatchStatus(event.deviceIds); + deviceStatus = TwoGangGlassStatusModel.fromJson( + event.deviceIds.first, + status.status, + ); + emit(TwoGangGlassSwitchBatchStatusLoaded(deviceStatus)); + } catch (e) { + emit(TwoGangGlassSwitchError(e.toString())); + } + } + + Future _onFactoryReset( + TwoGangGlassFactoryReset event, + Emitter emit, + ) async { + emit(TwoGangGlassSwitchLoading()); + try { + final response = await DevicesManagementApi().factoryReset( + event.factoryReset, + event.deviceId, + ); + if (!response) { + emit(TwoGangGlassSwitchError('Failed to reset device')); + } else { + add(TwoGangGlassSwitchFetchDeviceEvent(event.deviceId)); + } + } catch (e) { + emit(TwoGangGlassSwitchError(e.toString())); + } + } + + void _onStatusUpdated( + StatusUpdated event, + Emitter emit, + ) { + deviceStatus = event.deviceStatus; + emit(TwoGangGlassSwitchStatusLoaded(deviceStatus)); + } + + void _updateLocalValue(String code, bool value) { + switch (code) { + case 'switch_1': + deviceStatus = deviceStatus.copyWith(switch1: value); + break; + case 'switch_2': + deviceStatus = deviceStatus.copyWith(switch2: value); + break; + } + } + + @override + Future close() { + _deviceStatusSubscription?.cancel(); + return super.close(); } }