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 12aeaa88..c1e976ab 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 @@ -1,11 +1,13 @@ import 'dart:async'; -import 'package:bloc/bloc.dart'; import 'package:firebase_database/firebase_database.dart'; -import 'package:meta/meta.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter_bloc/flutter_bloc.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/one_g_glass_switch/models/once_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 'one_gang_glass_switch_event.dart'; @@ -13,13 +15,16 @@ part 'one_gang_glass_switch_state.dart'; class OneGangGlassSwitchBloc extends Bloc { - OneGangGlassStatusModel deviceStatus; - Timer? _timer; + late OneGangGlassStatusModel deviceStatus; + final String deviceId; + final ControlDeviceService controlDeviceService; + final BatchControlDevicesService batchControlDevicesService; - OneGangGlassSwitchBloc({required String deviceId}) - : deviceStatus = OneGangGlassStatusModel( - uuid: deviceId, switch1: false, countDown: 0), - super(OneGangGlassSwitchInitial()) { + OneGangGlassSwitchBloc({ + required this.deviceId, + required this.controlDeviceService, + required this.batchControlDevicesService, + }) : super(OneGangGlassSwitchInitial()) { on(_onFetchDeviceStatus); on(_onControl); on(_onBatchControl); @@ -28,160 +33,140 @@ class OneGangGlassSwitchBloc on(_onStatusUpdated); } - Future _onFetchDeviceStatus(OneGangGlassSwitchFetchDeviceEvent event, - Emitter emit) async { + Future _onFetchDeviceStatus( + OneGangGlassSwitchFetchDeviceEvent event, + Emitter emit, + ) async { emit(OneGangGlassSwitchLoading()); try { - final status = - await DevicesManagementApi().getDeviceStatus(event.deviceId); - _listenToChanges(event.deviceId); - deviceStatus = - OneGangGlassStatusModel.fromJson(event.deviceId, status.status); + final status = await DevicesManagementApi().getDeviceStatus(event.deviceId); + _listenToChanges(event.deviceId, emit); + deviceStatus = OneGangGlassStatusModel.fromJson(event.deviceId, status.status); emit(OneGangGlassSwitchStatusLoaded(deviceStatus)); } catch (e) { emit(OneGangGlassSwitchError(e.toString())); } } - _listenToChanges(deviceId) { + void _listenToChanges( + String deviceId, + Emitter emit, + ) { try { - DatabaseReference ref = - FirebaseDatabase.instance.ref('device-status/$deviceId'); - Stream stream = ref.onValue; + final ref = FirebaseDatabase.instance.ref('device-status/$deviceId'); + final stream = ref.onValue; stream.listen((DatabaseEvent event) { - Map usersMap = - event.snapshot.value as Map; + final data = event.snapshot.value as Map?; + if (data == null) return; - List statusList = []; - usersMap['status'].forEach((element) { - statusList - .add(Status(code: element['code'], value: element['value'])); - }); - - deviceStatus = OneGangGlassStatusModel.fromJson( - usersMap['productUuid'], statusList); - if (!isClosed) { - add(StatusUpdated(deviceStatus)); + 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)); + } + } } }); - } catch (_) {} + } catch (e) { + emit(OneGangGlassSwitchError('Failed to listen to changes: $e')); + } } void _onStatusUpdated( - StatusUpdated event, Emitter emit) { + StatusUpdated event, + Emitter emit, + ) { + emit(OneGangGlassSwitchLoading()); deviceStatus = event.deviceStatus; emit(OneGangGlassSwitchStatusLoaded(deviceStatus)); } - Future _onControl(OneGangGlassSwitchControl event, - Emitter emit) async { - final oldValue = _getValueByCode(event.code); - + Future _onControl( + OneGangGlassSwitchControl event, + Emitter emit, + ) async { + emit(OneGangGlassSwitchLoading()); _updateLocalValue(event.code, event.value); emit(OneGangGlassSwitchStatusLoaded(deviceStatus)); - await _runDebounce( - deviceId: event.deviceId, - code: event.code, - value: event.value, - oldValue: oldValue, - emit: emit, - isBatch: false, - ); - } - - Future _onFactoryReset(OneGangGlassFactoryResetEvent event, - Emitter emit) async { - emit(OneGangGlassSwitchLoading()); try { - final response = await DevicesManagementApi() - .factoryReset(event.factoryReset, event.deviceId); - if (!response) { - emit(OneGangGlassSwitchError('Failed to reset device')); - } else { - emit(OneGangGlassSwitchStatusLoaded(deviceStatus)); - } + await controlDeviceService.controlDevice( + deviceUuid: event.deviceId, + status: Status(code: event.code, value: event.value), + ); } catch (e) { + _updateLocalValue(event.code, !event.value); emit(OneGangGlassSwitchError(e.toString())); } } - Future _onBatchControl(OneGangGlassSwitchBatchControl event, - Emitter emit) async { - final oldValue = _getValueByCode(event.code); - + Future _onBatchControl( + OneGangGlassSwitchBatchControl event, + Emitter emit, + ) async { + emit(OneGangGlassSwitchLoading()); _updateLocalValue(event.code, event.value); emit(OneGangGlassSwitchStatusLoaded(deviceStatus)); - await _runDebounce( - deviceId: event.deviceIds, - code: event.code, - value: event.value, - oldValue: oldValue, - emit: emit, - isBatch: true, - ); + try { + await batchControlDevicesService.batchControlDevices( + uuids: event.deviceIds, + code: event.code, + value: event.value, + ); + } catch (e) { + _updateLocalValue(event.code, !event.value); + emit(OneGangGlassSwitchError(e.toString())); + } } Future _onFetchBatchStatus( - OneGangGlassSwitchFetchBatchStatusEvent event, - Emitter emit) async { + OneGangGlassSwitchFetchBatchStatusEvent event, + Emitter emit, + ) async { emit(OneGangGlassSwitchLoading()); try { - final status = - await DevicesManagementApi().getBatchStatus(event.deviceIds); - deviceStatus = OneGangGlassStatusModel.fromJson( - event.deviceIds.first, status.status); + final status = await DevicesManagementApi().getBatchStatus(event.deviceIds); + deviceStatus = + OneGangGlassStatusModel.fromJson(event.deviceIds.first, status.status); emit(OneGangGlassSwitchStatusLoaded(deviceStatus)); } catch (e) { emit(OneGangGlassSwitchError(e.toString())); } } - Future _runDebounce({ - required dynamic deviceId, - required String code, - required bool value, - required bool oldValue, - required Emitter emit, - required bool isBatch, - }) async { - late String id; - if (deviceId is List) { - id = deviceId.first; - } else { - id = deviceId; - } - - if (_timer != null) { - _timer!.cancel(); - } - - _timer = Timer(const Duration(milliseconds: 500), () async { - try { - late bool response; - if (isBatch) { - response = await DevicesManagementApi() - .deviceBatchControl(deviceId, code, value); - } else { - response = await DevicesManagementApi() - .deviceControl(deviceId, Status(code: code, value: value)); - } - - if (!response) { - _revertValueAndEmit(id, code, oldValue, emit); - } - } catch (e) { - _revertValueAndEmit(id, code, oldValue, emit); + Future _onFactoryReset( + OneGangGlassFactoryResetEvent event, + Emitter emit, + ) async { + emit(OneGangGlassSwitchLoading()); + try { + final response = await DevicesManagementApi().factoryReset( + event.factoryReset, + event.deviceId, + ); + if (!response) { + emit(OneGangGlassSwitchError('Failed to reset device')); + } else { + add(OneGangGlassSwitchFetchDeviceEvent(event.deviceId)); } - }); - } - - void _revertValueAndEmit(String deviceId, String code, bool oldValue, - Emitter emit) { - _updateLocalValue(code, oldValue); - emit(OneGangGlassSwitchStatusLoaded(deviceStatus)); + } catch (e) { + emit(OneGangGlassSwitchError(e.toString())); + } } void _updateLocalValue(String code, bool value) { @@ -189,19 +174,4 @@ class OneGangGlassSwitchBloc deviceStatus = deviceStatus.copyWith(switch1: value); } } - - bool _getValueByCode(String code) { - switch (code) { - case 'switch_1': - return deviceStatus.switch1; - default: - return false; - } - } - - @override - Future close() { - _timer?.cancel(); - return super.close(); - } } diff --git a/lib/pages/device_managment/one_g_glass_switch/factories/one_gang_glass_switch_bloc_factory.dart b/lib/pages/device_managment/one_g_glass_switch/factories/one_gang_glass_switch_bloc_factory.dart new file mode 100644 index 00000000..97bcab81 --- /dev/null +++ b/lib/pages/device_managment/one_g_glass_switch/factories/one_gang_glass_switch_bloc_factory.dart @@ -0,0 +1,18 @@ +import 'package:syncrow_web/pages/device_managment/factories/device_bloc_dependencies_factory.dart'; +import 'package:syncrow_web/pages/device_managment/one_g_glass_switch/bloc/one_gang_glass_switch_bloc.dart'; + +abstract final class OneGangGlassSwitchBlocFactory { + const OneGangGlassSwitchBlocFactory._(); + + static OneGangGlassSwitchBloc create({ + required String deviceId, + }) { + return OneGangGlassSwitchBloc( + deviceId: deviceId, + controlDeviceService: + DeviceBlocDependenciesFactory.createControlDeviceService(), + batchControlDevicesService: + DeviceBlocDependenciesFactory.createBatchControlDevicesService(), + ); + } +} diff --git a/lib/pages/device_managment/one_g_glass_switch/view/one_gang_glass_batch_control_view.dart b/lib/pages/device_managment/one_g_glass_switch/view/one_gang_glass_batch_control_view.dart index 9b89e876..307e61da 100644 --- a/lib/pages/device_managment/one_g_glass_switch/view/one_gang_glass_batch_control_view.dart +++ b/lib/pages/device_managment/one_g_glass_switch/view/one_gang_glass_batch_control_view.dart @@ -2,9 +2,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart'; import 'package:syncrow_web/pages/device_managment/one_g_glass_switch/bloc/one_gang_glass_switch_bloc.dart'; +import 'package:syncrow_web/pages/device_managment/one_g_glass_switch/factories/one_gang_glass_switch_bloc_factory.dart'; import 'package:syncrow_web/pages/device_managment/one_g_glass_switch/models/once_gang_glass_status_model.dart'; import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart'; -// import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart'; import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; @@ -16,7 +16,7 @@ class OneGangGlassSwitchBatchControlView extends StatelessWidget with HelperResp @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => OneGangGlassSwitchBloc(deviceId: deviceIds.first) + create: (context) => OneGangGlassSwitchBlocFactory.create(deviceId: deviceIds.first) ..add(OneGangGlassSwitchFetchBatchStatusEvent(deviceIds)), child: BlocBuilder( builder: (context, state) { diff --git a/lib/pages/device_managment/one_g_glass_switch/view/one_gang_glass_switch_control_view.dart b/lib/pages/device_managment/one_g_glass_switch/view/one_gang_glass_switch_control_view.dart index 8914b786..997be513 100644 --- a/lib/pages/device_managment/one_g_glass_switch/view/one_gang_glass_switch_control_view.dart +++ b/lib/pages/device_managment/one_g_glass_switch/view/one_gang_glass_switch_control_view.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/device_managment/one_g_glass_switch/bloc/one_gang_glass_switch_bloc.dart'; +import 'package:syncrow_web/pages/device_managment/one_g_glass_switch/factories/one_gang_glass_switch_bloc_factory.dart'; import 'package:syncrow_web/pages/device_managment/one_g_glass_switch/models/once_gang_glass_status_model.dart'; import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; @@ -9,13 +10,13 @@ import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_la class OneGangGlassSwitchControlView extends StatelessWidget with HelperResponsiveLayout { final String deviceId; - const OneGangGlassSwitchControlView({required this.deviceId, Key? key}) : super(key: key); + const OneGangGlassSwitchControlView({required this.deviceId, super.key}); @override Widget build(BuildContext context) { return BlocProvider( create: (context) => - OneGangGlassSwitchBloc(deviceId: deviceId)..add(OneGangGlassSwitchFetchDeviceEvent(deviceId)), + OneGangGlassSwitchBlocFactory.create(deviceId: deviceId)..add(OneGangGlassSwitchFetchDeviceEvent(deviceId)), child: BlocBuilder( builder: (context, state) { if (state is OneGangGlassSwitchLoading) {