From c3d8e6a52ed419293612a1a029cf4c745c7b0af8 Mon Sep 17 00:00:00 2001 From: ashrafzarkanisala Date: Wed, 11 Sep 2024 00:27:51 +0300 Subject: [PATCH] add batch controll box selection logic --- .../ac/view/ac_device_control.dart | 6 +- .../bloc/device_managment_bloc.dart | 31 +++++-- .../bloc/device_managment_state.dart | 14 +++- .../helper/route_controls_based_code.dart | 41 +++++++++- .../all_devices/models/devices_model.dart | 62 ++++++++++++++ .../widgets/device_managment_body.dart | 49 ++++++++--- .../curtain/view/curtain_status_view.dart | 5 +- .../door_lock/view/door_lock_status_view.dart | 4 +- .../shared/device_batch_control_dialog.dart | 81 +++++++++++++++++++ .../bloc/living_room_bloc.dart | 34 ++++++-- .../bloc/living_room_event.dart | 10 +++ .../view/living_room_batch_controls.dart | 67 +++++++++++++++ .../view/living_room_device_control.dart | 15 ++-- pubspec.lock | 24 +++--- 14 files changed, 383 insertions(+), 60 deletions(-) create mode 100644 lib/pages/device_managment/shared/device_batch_control_dialog.dart create mode 100644 lib/pages/device_managment/three_gang_switch/view/living_room_batch_controls.dart diff --git a/lib/pages/device_managment/ac/view/ac_device_control.dart b/lib/pages/device_managment/ac/view/ac_device_control.dart index c2b554b9..123ffdfd 100644 --- a/lib/pages/device_managment/ac/view/ac_device_control.dart +++ b/lib/pages/device_managment/ac/view/ac_device_control.dart @@ -11,8 +11,8 @@ import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_mo import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; -class AcDeviceControl extends StatelessWidget with HelperResponsiveLayout { - const AcDeviceControl({super.key, required this.device}); +class AcDeviceControls extends StatelessWidget with HelperResponsiveLayout { + const AcDeviceControls({super.key, required this.device}); final AllDevicesModel device; @@ -69,7 +69,7 @@ class AcDeviceControl extends StatelessWidget with HelperResponsiveLayout { deviceId: device.uuid!, description: 'Child Lock', icon: - state.status.childLock ? Assets.childLock:Assets.unlock , + state.status.childLock ? Assets.childLock : Assets.unlock, ), ], ); diff --git a/lib/pages/device_managment/all_devices/bloc/device_managment_bloc.dart b/lib/pages/device_managment/all_devices/bloc/device_managment_bloc.dart index 37447cc3..1919cb49 100644 --- a/lib/pages/device_managment/all_devices/bloc/device_managment_bloc.dart +++ b/lib/pages/device_managment/all_devices/bloc/device_managment_bloc.dart @@ -41,6 +41,7 @@ class DeviceManagementBloc offlineCount: _offlineCount, lowBatteryCount: _lowBatteryCount, selectedDevice: null, + isControlButtonEnabled: false, )); } catch (e) { emit(DeviceManagementInitial()); @@ -69,8 +70,8 @@ class DeviceManagementBloc onlineCount: _onlineCount, offlineCount: _offlineCount, lowBatteryCount: _lowBatteryCount, - selectedDevice: - _selectedDevices.isNotEmpty ? _selectedDevices.first : null, + selectedDevice: _selectedDevices.isNotEmpty ? _selectedDevices : null, + isControlButtonEnabled: _selectedDevices.isNotEmpty, )); if (productName.isNotEmpty) { @@ -92,6 +93,7 @@ class DeviceManagementBloc offlineCount: _offlineCount, lowBatteryCount: _lowBatteryCount, selectedDevice: null, + isControlButtonEnabled: false, )); } @@ -111,7 +113,19 @@ class DeviceManagementBloc _selectedDevices.add(event.selectedDevice); } - bool isControlButtonEnabled = _selectedDevices.length == 1; + List clonedSelectedDevices = List.from(_selectedDevices); + + bool isControlButtonEnabled = false; + + if (clonedSelectedDevices.length == 1) { + isControlButtonEnabled = true; + } else if (clonedSelectedDevices.length > 1) { + + final productTypes = + clonedSelectedDevices.map((device) => device.productType).toSet(); + isControlButtonEnabled = productTypes.length == + 1; + } if (state is DeviceManagementLoaded) { emit(DeviceManagementLoaded( @@ -120,7 +134,9 @@ class DeviceManagementBloc onlineCount: _onlineCount, offlineCount: _offlineCount, lowBatteryCount: _lowBatteryCount, - selectedDevice: isControlButtonEnabled ? _selectedDevices.first : null, + selectedDevice: + clonedSelectedDevices.isNotEmpty ? clonedSelectedDevices : null, + isControlButtonEnabled: isControlButtonEnabled, )); } else if (state is DeviceManagementFiltered) { emit(DeviceManagementFiltered( @@ -129,7 +145,9 @@ class DeviceManagementBloc onlineCount: _onlineCount, offlineCount: _offlineCount, lowBatteryCount: _lowBatteryCount, - selectedDevice: isControlButtonEnabled ? _selectedDevices.first : null, + selectedDevice: + clonedSelectedDevices.isNotEmpty ? clonedSelectedDevices : null, + isControlButtonEnabled: isControlButtonEnabled, )); } } @@ -158,12 +176,10 @@ class DeviceManagementBloc void _onSearchDevices( SearchDevices event, Emitter emit) { - // If the search fields are all empty, restore the last filtered devices if ((event.community == null || event.community!.isEmpty) && (event.unitName == null || event.unitName!.isEmpty) && (event.productName == null || event.productName!.isEmpty)) { productName = ''; - // If the current state is filtered, re-emit the filtered state if (state is DeviceManagementFiltered) { add(FilterDevices(_getFilterFromIndex(_selectedIndex))); } @@ -214,6 +230,7 @@ class DeviceManagementBloc offlineCount: _offlineCount, lowBatteryCount: _lowBatteryCount, selectedDevice: null, + isControlButtonEnabled: false, )); } } diff --git a/lib/pages/device_managment/all_devices/bloc/device_managment_state.dart b/lib/pages/device_managment/all_devices/bloc/device_managment_state.dart index 9a6e2f41..f7513890 100644 --- a/lib/pages/device_managment/all_devices/bloc/device_managment_state.dart +++ b/lib/pages/device_managment/all_devices/bloc/device_managment_state.dart @@ -17,7 +17,8 @@ class DeviceManagementLoaded extends DeviceManagementState { final int onlineCount; final int offlineCount; final int lowBatteryCount; - final AllDevicesModel? selectedDevice; + final List? selectedDevice; + final bool isControlButtonEnabled; const DeviceManagementLoaded({ required this.devices, @@ -26,6 +27,7 @@ class DeviceManagementLoaded extends DeviceManagementState { required this.offlineCount, required this.lowBatteryCount, this.selectedDevice, + required this.isControlButtonEnabled, }); @override @@ -35,7 +37,8 @@ class DeviceManagementLoaded extends DeviceManagementState { onlineCount, offlineCount, lowBatteryCount, - selectedDevice + selectedDevice, + isControlButtonEnabled ]; } @@ -45,7 +48,8 @@ class DeviceManagementFiltered extends DeviceManagementState { final int onlineCount; final int offlineCount; final int lowBatteryCount; - final AllDevicesModel? selectedDevice; + final List? selectedDevice; + final bool isControlButtonEnabled; const DeviceManagementFiltered({ required this.filteredDevices, @@ -54,6 +58,7 @@ class DeviceManagementFiltered extends DeviceManagementState { required this.offlineCount, required this.lowBatteryCount, this.selectedDevice, + required this.isControlButtonEnabled, }); @override @@ -63,7 +68,8 @@ class DeviceManagementFiltered extends DeviceManagementState { onlineCount, offlineCount, lowBatteryCount, - selectedDevice + selectedDevice, + isControlButtonEnabled ]; } diff --git a/lib/pages/device_managment/all_devices/helper/route_controls_based_code.dart b/lib/pages/device_managment/all_devices/helper/route_controls_based_code.dart index 3b228192..5df77b2b 100644 --- a/lib/pages/device_managment/all_devices/helper/route_controls_based_code.dart +++ b/lib/pages/device_managment/all_devices/helper/route_controls_based_code.dart @@ -6,6 +6,7 @@ import 'package:syncrow_web/pages/device_managment/ceiling_sensor/view/ceiling_s import 'package:syncrow_web/pages/device_managment/curtain/view/curtain_status_view.dart'; import 'package:syncrow_web/pages/device_managment/door_lock/view/door_lock_status_view.dart'; import 'package:syncrow_web/pages/device_managment/gateway/view/gateway_view.dart'; +import 'package:syncrow_web/pages/device_managment/three_gang_switch/view/living_room_batch_controls.dart'; import 'package:syncrow_web/pages/device_managment/three_gang_switch/view/living_room_device_control.dart'; import 'package:syncrow_web/pages/device_managment/wall_sensor/view/wall_sensor_conrtols.dart'; @@ -13,7 +14,7 @@ mixin RouteControlsBasedCode { Widget routeControlsWidgets({required AllDevicesModel device}) { switch (device.productType) { case '3G': - return LivingRoomDeviceControl( + return LivingRoomDeviceControls( deviceId: device.uuid!, ); case 'GW': @@ -21,7 +22,7 @@ mixin RouteControlsBasedCode { gatewayId: device.uuid!, ); case 'DL': - return DoorLockView(device: device); + return DoorLockControls(device: device); case 'WPS': return WallSensorControls(device: device); case 'CPS': @@ -29,11 +30,43 @@ mixin RouteControlsBasedCode { device: device, ); case 'CUR': - return CurtainStatusView( + return CurtainStatusControls( deviceId: device.uuid!, ); case 'AC': - return AcDeviceControl(device: device); + return AcDeviceControls(device: device); + default: + return const SizedBox(); + } + } + + Widget routeBatchControlsWidgets({required List devices}) { + switch (devices.first.productType) { + case '3G': + return LivingRoomBatchControls( + deviceIds: devices + .where((e) => e.productType == '3G') + .map((e) => e.uuid!) + .toList(), + ); + // case 'GW': + // return GateWayControls( + // gatewayId: device.first.uuid!, + // ); + // case 'DL': + // return DoorLockControls(device: device.first); + // case 'WPS': + // return WallSensorControls(device: device.first); + // case 'CPS': + // return CeilingSensorControls( + // device: device.first, + // ); + // case 'CUR': + // return CurtainStatusControls( + // deviceId: device.first.uuid!, + // ); + // case 'AC': + // return AcDeviceControls(device: device.first); default: return const SizedBox(); } diff --git a/lib/pages/device_managment/all_devices/models/devices_model.dart b/lib/pages/device_managment/all_devices/models/devices_model.dart index 13d3dd2e..a814a8b1 100644 --- a/lib/pages/device_managment/all_devices/models/devices_model.dart +++ b/lib/pages/device_managment/all_devices/models/devices_model.dart @@ -1,3 +1,4 @@ + import 'package:syncrow_web/pages/device_managment/all_devices/models/room.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/unit.dart'; @@ -154,4 +155,65 @@ class AllDevicesModel { data['battery'] = batteryLevel; return data; } + + @override + bool operator ==(Object other) { + if (identical(this, other)) return true; + + return other is AllDevicesModel && + other.room == room && + other.unit == unit && + other.productUuid == productUuid && + other.productType == productType && + other.permissionType == permissionType && + other.activeTime == activeTime && + other.category == category && + other.categoryName == categoryName && + other.createTime == createTime && + other.gatewayId == gatewayId && + other.icon == icon && + other.ip == ip && + other.lat == lat && + other.localKey == localKey && + other.lon == lon && + other.model == model && + other.name == name && + other.nodeId == nodeId && + other.online == online && + other.ownerId == ownerId && + other.sub == sub && + other.timeZone == timeZone && + other.updateTime == updateTime && + other.uuid == uuid && + other.batteryLevel == batteryLevel; + } + + @override + int get hashCode { + return room.hashCode ^ + unit.hashCode ^ + productUuid.hashCode ^ + productType.hashCode ^ + permissionType.hashCode ^ + activeTime.hashCode ^ + category.hashCode ^ + categoryName.hashCode ^ + createTime.hashCode ^ + gatewayId.hashCode ^ + icon.hashCode ^ + ip.hashCode ^ + lat.hashCode ^ + localKey.hashCode ^ + lon.hashCode ^ + model.hashCode ^ + name.hashCode ^ + nodeId.hashCode ^ + online.hashCode ^ + ownerId.hashCode ^ + sub.hashCode ^ + timeZone.hashCode ^ + updateTime.hashCode ^ + uuid.hashCode ^ + batteryLevel.hashCode; + } } diff --git a/lib/pages/device_managment/all_devices/widgets/device_managment_body.dart b/lib/pages/device_managment/all_devices/widgets/device_managment_body.dart index ab2f07fc..936234cf 100644 --- a/lib/pages/device_managment/all_devices/widgets/device_managment_body.dart +++ b/lib/pages/device_managment/all_devices/widgets/device_managment_body.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_web/pages/device_managment/shared/device_batch_control_dialog.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart'; import 'package:syncrow_web/pages/common/buttons/default_button.dart'; import 'package:syncrow_web/pages/common/custom_table.dart'; @@ -27,6 +28,7 @@ class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout { int offlineCount = 0; int lowBatteryCount = 0; bool isControlButtonEnabled = false; + List selectedDevices = []; if (state is DeviceManagementLoaded) { devicesToShow = state.devices; @@ -34,14 +36,18 @@ class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout { onlineCount = state.onlineCount; offlineCount = state.offlineCount; lowBatteryCount = state.lowBatteryCount; - isControlButtonEnabled = state.selectedDevice != null; + isControlButtonEnabled = state.isControlButtonEnabled; + selectedDevices = state.selectedDevice ?? + context.read().selectedDevices; } else if (state is DeviceManagementFiltered) { devicesToShow = state.filteredDevices; selectedIndex = state.selectedIndex; onlineCount = state.onlineCount; offlineCount = state.offlineCount; lowBatteryCount = state.lowBatteryCount; - isControlButtonEnabled = state.selectedDevice != null; + isControlButtonEnabled = state.isControlButtonEnabled; + selectedDevices = state.selectedDevice ?? + context.read().selectedDevices; } else if (state is DeviceManagementInitial) { devicesToShow = []; selectedIndex = 0; @@ -55,8 +61,11 @@ class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout { 'Low Battery ($lowBatteryCount)', ]; + final buttonLabel = + (selectedDevices.length > 1) ? 'Batch Control' : 'Control'; + return Column( - children: [ + children: [ Container( padding: isLargeScreenSize(context) ? const EdgeInsets.all(30) @@ -69,7 +78,8 @@ class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout { tabs: tabs, selectedIndex: selectedIndex, onTabChanged: (index) { - context.read() + context + .read() .add(SelectedFilterChanged(index)); }, ), @@ -84,19 +94,32 @@ class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout { child: DefaultButton( onPressed: isControlButtonEnabled ? () { - final selectedDevice = context - .read() - .selectedDevices.first; - showDialog( - context: context, - builder: (context) => DeviceControlDialog( - device: selectedDevice), - ); + if (selectedDevices.length == 1) { + showDialog( + context: context, + builder: (context) => DeviceControlDialog( + device: selectedDevices.first, + ), + ); + } else if (selectedDevices.length > 1) { + final productTypes = selectedDevices + .map((device) => device.productType) + .toSet(); + if (productTypes.length == 1) { + showDialog( + context: context, + builder: (context) => + DeviceBatchControlDialog( + devices: selectedDevices, + ), + ); + } + } } : null, borderRadius: 9, child: Text( - 'Control', + buttonLabel, style: TextStyle( fontSize: 12, color: isControlButtonEnabled diff --git a/lib/pages/device_managment/curtain/view/curtain_status_view.dart b/lib/pages/device_managment/curtain/view/curtain_status_view.dart index c9af04fb..1de7fa83 100644 --- a/lib/pages/device_managment/curtain/view/curtain_status_view.dart +++ b/lib/pages/device_managment/curtain/view/curtain_status_view.dart @@ -6,10 +6,11 @@ import 'package:syncrow_web/pages/device_managment/curtain/bloc/curtain_event.da import 'package:syncrow_web/pages/device_managment/curtain/bloc/curtain_state.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; -class CurtainStatusView extends StatelessWidget with HelperResponsiveLayout { +class CurtainStatusControls extends StatelessWidget + with HelperResponsiveLayout { final String deviceId; - const CurtainStatusView({super.key, required this.deviceId}); + const CurtainStatusControls({super.key, required this.deviceId}); @override Widget build(BuildContext context) { diff --git a/lib/pages/device_managment/door_lock/view/door_lock_status_view.dart b/lib/pages/device_managment/door_lock/view/door_lock_status_view.dart index 536b0d97..6e24907a 100644 --- a/lib/pages/device_managment/door_lock/view/door_lock_status_view.dart +++ b/lib/pages/device_managment/door_lock/view/door_lock_status_view.dart @@ -7,10 +7,10 @@ import 'package:syncrow_web/pages/device_managment/door_lock/bloc/door_lock_stat import 'package:syncrow_web/pages/device_managment/door_lock/models/door_lock_status_model.dart'; import 'package:syncrow_web/pages/device_managment/door_lock/widget/door_button.dart'; -class DoorLockView extends StatelessWidget { +class DoorLockControls extends StatelessWidget { final AllDevicesModel device; - const DoorLockView({super.key, required this.device}); + const DoorLockControls({super.key, required this.device}); @override Widget build(BuildContext context) { diff --git a/lib/pages/device_managment/shared/device_batch_control_dialog.dart b/lib/pages/device_managment/shared/device_batch_control_dialog.dart new file mode 100644 index 00000000..18397253 --- /dev/null +++ b/lib/pages/device_managment/shared/device_batch_control_dialog.dart @@ -0,0 +1,81 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +import 'package:syncrow_web/utils/extension/build_context_x.dart'; +import 'package:syncrow_web/pages/device_managment/all_devices/helper/route_controls_based_code.dart'; + +import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart'; +import 'package:syncrow_web/utils/color_manager.dart'; + +class DeviceBatchControlDialog extends StatelessWidget + with RouteControlsBasedCode { + final List devices; + + const DeviceBatchControlDialog({super.key, required this.devices}); + + @override + Widget build(BuildContext context) { + return Dialog( + backgroundColor: Colors.white, + insetPadding: const EdgeInsets.all(20), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(20), + ), + child: SizedBox( + width: 798, + height: context.screenHeight * 0.7, + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.all(20.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + const SizedBox(), + Text( + devices.first.categoryName ?? 'Device Control', + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 22, + color: ColorsManager.dialogBlueTitle, + ), + ), + Container( + width: 25, + decoration: BoxDecoration( + color: Colors.transparent, + shape: BoxShape.circle, + border: Border.all( + color: Colors.grey, + width: 1.0, + ), + ), + child: IconButton( + padding: EdgeInsets.all(1), + icon: const Icon( + Icons.close, + color: Colors.grey, + size: 18, + ), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + ), + ], + ), + const SizedBox(height: 20), + //// BUILD DEVICE CONTROLS + /// + //// ROUTE TO SPECIFIC CONTROL VIEW BASED ON DEVICE CATEGORY + routeBatchControlsWidgets(devices: devices), + ], + ), + ), + ), + ), + ); + } +} diff --git a/lib/pages/device_managment/three_gang_switch/bloc/living_room_bloc.dart b/lib/pages/device_managment/three_gang_switch/bloc/living_room_bloc.dart index de06248b..3bbe428c 100644 --- a/lib/pages/device_managment/three_gang_switch/bloc/living_room_bloc.dart +++ b/lib/pages/device_managment/three_gang_switch/bloc/living_room_bloc.dart @@ -18,21 +18,25 @@ class LivingRoomBloc extends Bloc { LivingRoomBloc({required this.deviceId}) : super(LivingRoomInitial()) { on(_onFetchDeviceStatus); on(_livingRoomControl); + on(_livingRoomBatchControl); } FutureOr _onFetchDeviceStatus( LivingRoomFetchDeviceStatus event, Emitter emit) async { emit(LivingRoomDeviceStatusLoading()); try { - final status = await DevicesManagementApi().getDeviceStatus(event.deviceId); - deviceStatus = LivingRoomStatusModel.fromJson(event.deviceId, status.status); + final status = + await DevicesManagementApi().getDeviceStatus(event.deviceId); + deviceStatus = + LivingRoomStatusModel.fromJson(event.deviceId, status.status); emit(LivingRoomDeviceStatusLoaded(deviceStatus)); } catch (e) { emit(LivingRoomDeviceManagementError(e.toString())); } } - FutureOr _livingRoomControl(LivingRoomControl event, Emitter emit) async { + FutureOr _livingRoomControl( + LivingRoomControl event, Emitter emit) async { final oldValue = _getValueByCode(event.code); _updateLocalValue(event.code, event.value); @@ -60,8 +64,8 @@ class LivingRoomBloc extends Bloc { } _timer = Timer(const Duration(seconds: 1), () async { try { - final response = - await DevicesManagementApi().deviceControl(deviceId, Status(code: code, value: value)); + final response = await DevicesManagementApi() + .deviceControl(deviceId, Status(code: code, value: value)); if (!response) { _revertValueAndEmit(deviceId, code, oldValue, emit); } @@ -71,8 +75,8 @@ class LivingRoomBloc extends Bloc { }); } - void _revertValueAndEmit( - String deviceId, String code, dynamic oldValue, Emitter emit) { + void _revertValueAndEmit(String deviceId, String code, dynamic oldValue, + Emitter emit) { _updateLocalValue(code, oldValue); emit(LivingRoomDeviceStatusLoaded(deviceStatus)); emit(const LivingRoomControlError('Failed to control the device.')); @@ -113,4 +117,20 @@ class LivingRoomBloc extends Bloc { return null; } } + + FutureOr _livingRoomBatchControl( + LivingRoomFetchBatchStatus event, Emitter emit) async { + emit(LivingRoomDeviceStatusLoading()); + try { + //TODO: get batch status from api + /// for now sending one id and getting the same value from fetch status + final status = + await DevicesManagementApi().getDeviceStatus(event.deviceId); + deviceStatus = + LivingRoomStatusModel.fromJson(event.deviceId, status.status); + emit(LivingRoomDeviceStatusLoaded(deviceStatus)); + } catch (e) { + emit(LivingRoomDeviceManagementError(e.toString())); + } + } } diff --git a/lib/pages/device_managment/three_gang_switch/bloc/living_room_event.dart b/lib/pages/device_managment/three_gang_switch/bloc/living_room_event.dart index f7b57cde..39cf84f1 100644 --- a/lib/pages/device_managment/three_gang_switch/bloc/living_room_event.dart +++ b/lib/pages/device_managment/three_gang_switch/bloc/living_room_event.dart @@ -16,6 +16,16 @@ class LivingRoomFetchDeviceStatus extends LivingRoomEvent { List get props => [deviceId]; } +//LivingRoomFetchBatchStatus +class LivingRoomFetchBatchStatus extends LivingRoomEvent { + final String deviceId; + + const LivingRoomFetchBatchStatus(this.deviceId); + + @override + List get props => [deviceId]; +} + class LivingRoomControl extends LivingRoomEvent { final String deviceId; final String code; diff --git a/lib/pages/device_managment/three_gang_switch/view/living_room_batch_controls.dart b/lib/pages/device_managment/three_gang_switch/view/living_room_batch_controls.dart new file mode 100644 index 00000000..7712cc02 --- /dev/null +++ b/lib/pages/device_managment/three_gang_switch/view/living_room_batch_controls.dart @@ -0,0 +1,67 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_web/pages/device_managment/three_gang_switch/bloc/living_room_bloc.dart'; +import 'package:syncrow_web/pages/device_managment/three_gang_switch/models/living_room_model.dart'; +import 'package:syncrow_web/pages/device_managment/three_gang_switch/widgets/living_toggle_widget.dart'; +import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; + +class LivingRoomBatchControls extends StatelessWidget + with HelperResponsiveLayout { + const LivingRoomBatchControls({super.key, required this.deviceIds}); + + final List deviceIds; + + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (context) => LivingRoomBloc(deviceId: deviceIds.first) + ..add(LivingRoomFetchBatchStatus(deviceIds.first)), + child: BlocBuilder( + builder: (context, state) { + if (state is LivingRoomDeviceStatusLoading) { + return const Center(child: CircularProgressIndicator()); + } else if (state is LivingRoomDeviceStatusLoaded) { + return _buildStatusControls(context, state.status); + } else if (state is LivingRoomDeviceManagementError || + state is LivingRoomControlError) { + return const Center(child: Text('Error fetching status')); + } else { + return const Center(child: CircularProgressIndicator()); + } + }, + ), + ); + } + + Widget _buildStatusControls( + BuildContext context, LivingRoomStatusModel status) { + final isExtraLarge = isExtraLargeScreenSize(context); + final isLarge = isLargeScreenSize(context); + final isMedium = isMediumScreenSize(context); + return SizedBox( + child: GridView( + padding: const EdgeInsets.symmetric(horizontal: 50), + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: isLarge || isExtraLarge + ? 3 + : isMedium + ? 2 + : 1, + mainAxisExtent: 140, + crossAxisSpacing: 12, + mainAxisSpacing: 12, + ), + children: [ + ToggleWidget( + value: status.switch1, + code: 'switch_1', + deviceId: deviceIds.first, + label: 'Wall Light', + ), + ], + ), + ); + } +} diff --git a/lib/pages/device_managment/three_gang_switch/view/living_room_device_control.dart b/lib/pages/device_managment/three_gang_switch/view/living_room_device_control.dart index 0cf7ffa9..a0588d8d 100644 --- a/lib/pages/device_managment/three_gang_switch/view/living_room_device_control.dart +++ b/lib/pages/device_managment/three_gang_switch/view/living_room_device_control.dart @@ -5,23 +5,25 @@ import 'package:syncrow_web/pages/device_managment/three_gang_switch/models/livi import 'package:syncrow_web/pages/device_managment/three_gang_switch/widgets/living_toggle_widget.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; -class LivingRoomDeviceControl extends StatelessWidget with HelperResponsiveLayout { +class LivingRoomDeviceControls extends StatelessWidget + with HelperResponsiveLayout { final String deviceId; - const LivingRoomDeviceControl({super.key, required this.deviceId}); + const LivingRoomDeviceControls({super.key, required this.deviceId}); @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => - LivingRoomBloc(deviceId: deviceId)..add(LivingRoomFetchDeviceStatus(deviceId)), + create: (context) => LivingRoomBloc(deviceId: deviceId) + ..add(LivingRoomFetchDeviceStatus(deviceId)), child: BlocBuilder( builder: (context, state) { if (state is LivingRoomDeviceStatusLoading) { return const Center(child: CircularProgressIndicator()); } else if (state is LivingRoomDeviceStatusLoaded) { return _buildStatusControls(context, state.status); - } else if (state is LivingRoomDeviceManagementError || state is LivingRoomControlError) { + } else if (state is LivingRoomDeviceManagementError || + state is LivingRoomControlError) { return const Center(child: Text('Error fetching status')); } else { return const Center(child: CircularProgressIndicator()); @@ -31,7 +33,8 @@ class LivingRoomDeviceControl extends StatelessWidget with HelperResponsiveLayou ); } - Widget _buildStatusControls(BuildContext context, LivingRoomStatusModel status) { + Widget _buildStatusControls( + BuildContext context, LivingRoomStatusModel status) { final isExtraLarge = isExtraLargeScreenSize(context); final isLarge = isLargeScreenSize(context); final isMedium = isMediumScreenSize(context); diff --git a/pubspec.lock b/pubspec.lock index 8b9df6d6..2c9cb88c 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -292,18 +292,18 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a" + sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" url: "https://pub.dev" source: hosted - version: "10.0.4" + version: "10.0.5" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8" + sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" url: "https://pub.dev" source: hosted - version: "3.0.3" + version: "3.0.5" leak_tracker_testing: dependency: transitive description: @@ -340,18 +340,18 @@ packages: dependency: transitive description: name: material_color_utilities - sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec url: "https://pub.dev" source: hosted - version: "0.8.0" + version: "0.11.1" meta: dependency: transitive description: name: meta - sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136" + sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 url: "https://pub.dev" source: hosted - version: "1.12.0" + version: "1.15.0" nested: dependency: transitive description: @@ -561,10 +561,10 @@ packages: dependency: transitive description: name: test_api - sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f" + sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" url: "https://pub.dev" source: hosted - version: "0.7.0" + version: "0.7.2" typed_data: dependency: transitive description: @@ -609,10 +609,10 @@ packages: dependency: transitive description: name: vm_service - sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec" + sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" url: "https://pub.dev" source: hosted - version: "14.2.1" + version: "14.2.5" web: dependency: transitive description: