diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..c169a71 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "cSpell.words": [ + "Scheduleapp" + ] +} \ No newline at end of file diff --git a/assets/icons/closed_garage_door.svg b/assets/icons/closed_garage_door.svg new file mode 100644 index 0000000..464aa07 --- /dev/null +++ b/assets/icons/closed_garage_door.svg @@ -0,0 +1,148 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/icons/curtainsIcon/verticalBlade.svg b/assets/icons/curtainsIcon/left_vertical_blade.svg similarity index 100% rename from assets/icons/curtainsIcon/verticalBlade.svg rename to assets/icons/curtainsIcon/left_vertical_blade.svg diff --git a/assets/icons/curtainsIcon/right_vertical_blade.svg b/assets/icons/curtainsIcon/right_vertical_blade.svg new file mode 100644 index 0000000..d7675aa --- /dev/null +++ b/assets/icons/curtainsIcon/right_vertical_blade.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/icons/garageIcon.svg b/assets/icons/garageIcon.svg new file mode 100644 index 0000000..0b044eb --- /dev/null +++ b/assets/icons/garageIcon.svg @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/icons/garage_countdown.svg b/assets/icons/garage_countdown.svg new file mode 100644 index 0000000..b2a3ead --- /dev/null +++ b/assets/icons/garage_countdown.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/icons/garage_preferences_icon.svg b/assets/icons/garage_preferences_icon.svg new file mode 100644 index 0000000..d0883b0 --- /dev/null +++ b/assets/icons/garage_preferences_icon.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/icons/garage_schedule.svg b/assets/icons/garage_schedule.svg new file mode 100644 index 0000000..04e7763 --- /dev/null +++ b/assets/icons/garage_schedule.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/icons/open_garage_door.svg b/assets/icons/open_garage_door.svg new file mode 100644 index 0000000..d55a690 --- /dev/null +++ b/assets/icons/open_garage_door.svg @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/Window.png b/assets/images/Window.png deleted file mode 100644 index be38a0b..0000000 Binary files a/assets/images/Window.png and /dev/null differ diff --git a/assets/images/window_img.svg b/assets/images/window_img.svg new file mode 100644 index 0000000..d908db4 --- /dev/null +++ b/assets/images/window_img.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/features/devices/bloc/curtain_bloc/curtain_bloc.dart b/lib/features/devices/bloc/curtain_bloc/curtain_bloc.dart index 1dea664..7e0ac56 100644 --- a/lib/features/devices/bloc/curtain_bloc/curtain_bloc.dart +++ b/lib/features/devices/bloc/curtain_bloc/curtain_bloc.dart @@ -24,9 +24,7 @@ class CurtainBloc extends Bloc { on(_onPauseCurtain); } - Future _onOpenCurtain( - OpenCurtain event, - Emitter emit) async { + Future _onOpenCurtain(OpenCurtain event, Emitter emit) async { isMoving = true; while (openPercentage < 100.0) { if (state is CurtainsClosing) { @@ -48,7 +46,7 @@ class CurtainBloc extends Bloc { _pauseCurtain(emit); } }); - if (openPercentage >=100.0) { + if (openPercentage >= 100.0) { await DevicesAPI.controlDevice( DeviceControlModel( deviceId: curtainId, @@ -73,8 +71,7 @@ class CurtainBloc extends Bloc { } } - Future _onCloseCurtain( - CloseCurtain event, Emitter emit) async { + Future _onCloseCurtain(CloseCurtain event, Emitter emit) async { isMoving = true; while (openPercentage > 0.0) { if (state is CurtainsOpening) { @@ -121,8 +118,7 @@ class CurtainBloc extends Bloc { } } - Future _onPauseCurtain( - PauseCurtain event, Emitter emit) async { + Future _onPauseCurtain(PauseCurtain event, Emitter emit) async { _pauseCurtain(emit); await DevicesAPI.controlDevice( DeviceControlModel( @@ -132,7 +128,7 @@ class CurtainBloc extends Bloc { ), curtainId, ); - await DevicesAPI.controlDevice( + await DevicesAPI.controlDevice( DeviceControlModel( deviceId: curtainId, code: 'percent_control', @@ -151,9 +147,6 @@ class CurtainBloc extends Bloc { )); } - - - void _fetchStatus(InitCurtain event, Emitter emit) async { try { emit(CurtainLoadingState()); @@ -166,10 +159,9 @@ class CurtainBloc extends Bloc { // Get the open percentage from the response openPercentage = double.tryParse(statusModelList[1].value.toString())!; // Calculate curtain width and blind height based on the open percentage - if (openPercentage != null) { - curtainWidth = 270 - (openPercentage / 100) * curtainOpeningSpace; - blindHeight = 310 - (openPercentage / 100) * blindOpeningSpace; - } + curtainWidth = 270 - (openPercentage / 100) * curtainOpeningSpace; + blindHeight = 310 - (openPercentage / 100) * blindOpeningSpace; + emit(CurtainsOpening( curtainWidth: curtainWidth, blindHeight: blindHeight, @@ -180,5 +172,4 @@ class CurtainBloc extends Bloc { return; } } - } diff --git a/lib/features/devices/bloc/garage_door_bloc/garage_door_bloc.dart b/lib/features/devices/bloc/garage_door_bloc/garage_door_bloc.dart new file mode 100644 index 0000000..995cd0c --- /dev/null +++ b/lib/features/devices/bloc/garage_door_bloc/garage_door_bloc.dart @@ -0,0 +1,564 @@ +import 'dart:async'; +import 'package:dio/dio.dart'; +import 'package:firebase_database/firebase_database.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart'; +import 'package:syncrow_app/features/devices/bloc/garage_door_bloc/garage_door_event.dart'; +import 'package:syncrow_app/features/devices/bloc/garage_door_bloc/garage_door_state.dart'; +import 'package:syncrow_app/features/devices/model/device_control_model.dart'; +import 'package:syncrow_app/features/devices/model/device_model.dart'; +import 'package:syncrow_app/features/devices/model/device_report_model.dart'; +import 'package:syncrow_app/features/devices/model/garage_door_model.dart'; +import 'package:syncrow_app/features/devices/model/group_garage_model.dart'; +import 'package:syncrow_app/features/devices/model/schedule_model.dart'; +import 'package:syncrow_app/features/devices/model/status_model.dart'; +import 'package:syncrow_app/services/api/devices_api.dart'; +import 'package:syncrow_app/utils/helpers/snack_bar.dart'; + +class GarageDoorBloc extends Bloc { + final String GDId; + GarageDoorBloc({ + required this.GDId, + }) : super(const GarageDoorSensorState()) { + on(_fetchStatus); + on(fetchLogsForLastMonth); + on(_toggleClosingReminder); + on(_toggleDoorAlarm); + on(toggleDaySelection); + on(saveSchedule); + on(getSchedule); + on(toggleChange); + on(toggleCreateSchedule); + on(_onClose); + on(selectSeconds); + on(openCloseGarageDoor); + on(_getCounterValue); + on(_setCounterValue); + on(_onTickTimer); + on(_fetchWizardStatus); + on(_groupAllOn); + on(_groupAllOff); + on(_changeFirstWizardSwitch); + } + void _onClose(OnClose event, Emitter emit) { + _timer?.cancel(); + } + + Timer? _timer; + bool lowBattery = false; + bool closingReminder = false; + bool doorAlarm = false; + + GarageDoorModel deviceStatus = GarageDoorModel( + tr_timecon: 0, + countdown1: 0, + countdownAlarm: 0, + doorContactState: false, + doorControl1: '', + doorState1: '', + switch1: false, + voiceControl1: false, + batteryPercentage: 0, + ); + + void _fetchStatus( + GarageDoorInitial event, Emitter emit) async { + emit(GarageDoorLoadingState()); + try { + var response = await DevicesAPI.getDeviceStatus(GDId); + List statusModelList = []; + for (var status in response['status']) { + statusModelList.add(StatusModel.fromJson(status)); + } + deviceStatus = GarageDoorModel.fromJson( + statusModelList, + ); + secondSelected = deviceStatus.tr_timecon; + toggleDoor = deviceStatus.switch1; + emit(UpdateState(garageSensor: deviceStatus)); + Future.delayed(const Duration(milliseconds: 500)); + _listenToChanges(); + } catch (e) { + emit(GarageDoorFailedState(errorMessage: e.toString())); + return; + } + } + + void _toggleClosingReminder(ToggleClosingReminderEvent event, + Emitter emit) async { + emit(LoadingNewSate(doorSensor: deviceStatus)); + try { + closingReminder = event.isClosingReminderEnabled; + emit(UpdateState(garageSensor: deviceStatus)); + await DevicesAPI.controlDevice( + DeviceControlModel( + deviceId: GDId, + code: 'closing_reminder', + value: closingReminder, + ), + GDId, + ); + } catch (e) { + emit(GarageDoorFailedState(errorMessage: e.toString())); + } + } + + void _toggleDoorAlarm( + ToggleDoorAlarmEvent event, Emitter emit) async { + emit(LoadingNewSate(doorSensor: deviceStatus)); + try { + doorAlarm = event.isDoorAlarmEnabled; + emit(UpdateState(garageSensor: deviceStatus)); + await DevicesAPI.controlDevice( + DeviceControlModel( + deviceId: GDId, + code: 'door_alarm', + value: doorAlarm, + ), + GDId, + ); + } catch (e) { + emit(GarageDoorFailedState(errorMessage: e.toString())); + } + } + + DeviceReport recordGroups = + DeviceReport(startTime: '0', endTime: '0', data: []); + + Future fetchLogsForLastMonth( + ReportLogsInitial event, Emitter emit) async { + DateTime now = DateTime.now(); + + DateTime lastMonth = DateTime(now.year, now.month - 1, now.day); + int startTime = lastMonth.millisecondsSinceEpoch; + int endTime = now.millisecondsSinceEpoch; + try { + emit(GarageDoorLoadingState()); + var response = await DevicesAPI.getReportLogs( + startTime: startTime.toString(), + endTime: endTime.toString(), + deviceUuid: GDId, + code: 'doorcontact_state', + ); + recordGroups = response; + emit(UpdateState(garageSensor: deviceStatus)); + } on DioException catch (e) { + final errorData = e.response!.data; + String errorMessage = errorData['message']; + emit(GarageDoorFailedState(errorMessage: errorMessage)); + } + } + + _listenToChanges() { + try { + DatabaseReference ref = + FirebaseDatabase.instance.ref('device-status/$GDId'); + Stream stream = ref.onValue; + + stream.listen((DatabaseEvent event) async { + if (_timer != null) { + await Future.delayed(const Duration(seconds: 2)); + } + Map usersMap = + event.snapshot.value as Map; + List statusList = []; + usersMap['status'].forEach((element) { + statusList.add(StatusModel(code: element['code'], value: true)); + }); + + deviceStatus = GarageDoorModel.fromJson(statusList); + if (!isClosed) { + // add( + // DoorSensorSwitch(switchD: deviceStatus.doorContactState), + // ); + } + }); + } catch (_) {} + } + + List> days = [ + {"day": "Sun", "key": "Sun"}, + {"day": "Mon", "key": "Mon"}, + {"day": "Tue", "key": "Tue"}, + {"day": "Wed", "key": "Wed"}, + {"day": "Thu", "key": "Thu"}, + {"day": "Fri", "key": "Fri"}, + {"day": "Sat", "key": "Sat"}, + ]; + + Future toggleDaySelection( + ToggleDaySelectionEvent event, + Emitter emit, + ) async { + emit(GarageDoorLoadingState()); + if (selectedDays.contains(event.key)) { + selectedDays.remove(event.key); + } else { + selectedDays.add(event.key); + } + emit(ChangeTimeState()); + } + + Future saveSchedule( + ScheduleSaveapp event, + Emitter emit, + ) async { + try { + if (selectedDays.isNotEmpty) { + emit(GarageDoorLoadingState()); + await DevicesAPI.postSchedule( + category: 'switch_1', + deviceId: GDId, + time: getTimeStampWithoutSeconds(selectedTime).toString(), + code: 'switch_1', + value: toggleSchedule, + days: selectedDays); + CustomSnackBar.displaySnackBar('Save Successfully'); + add(GetScheduleEvent()); + } else { + CustomSnackBar.displaySnackBar('Please select days'); + } + } catch (e) { + emit(GarageDoorFailedState(errorMessage: e.toString())); + } + } + + Future getSchedule( + GetScheduleEvent event, + Emitter emit, + ) async { + try { + emit(GarageDoorLoadingState()); + final response = await DevicesAPI.getSchedule( + category: 'switch_1', + deviceId: GDId, + ); + List jsonData = response; + listSchedule = + jsonData.map((item) => ScheduleModel.fromJson(item)).toList(); + } on DioException catch (e) { + final errorData = e.response!.data; + String errorMessage = errorData['message']; + emit(GarageDoorFailedState(errorMessage: errorMessage.toString())); + } + } + + int? getTimeStampWithoutSeconds(DateTime? dateTime) { + if (dateTime == null) return null; + DateTime dateTimeWithoutSeconds = DateTime(dateTime.year, dateTime.month, + dateTime.day, dateTime.hour, dateTime.minute); + return dateTimeWithoutSeconds.millisecondsSinceEpoch ~/ 1000; + } + + Future toggleChange( + ToggleScheduleEvent event, Emitter emit) async { + try { + emit(GarageDoorLoadingState()); + final response = await DevicesAPI.changeSchedule( + scheduleId: event.id, deviceUuid: GDId, enable: event.toggle); + if (response == true) { + add(GetScheduleEvent()); + toggleSchedule = event.toggle; + return toggleSchedule; + } + emit(IsToggleState(onOff: toggleSchedule)); + } on DioException catch (e) { + final errorData = e.response!.data; + String errorMessage = errorData['message']; + emit(GarageDoorFailedState(errorMessage: errorMessage.toString())); + } + } + + Future deleteSchedule( + DeleteScheduleEvent event, Emitter emit) async { + try { + emit(GarageDoorLoadingState()); + final response = await DevicesAPI.deleteSchedule( + scheduleId: event.id, + deviceUuid: GDId, + ); + if (response == true) { + add(GetScheduleEvent()); + return toggleSchedule; + } + emit(IsToggleState(onOff: toggleSchedule)); + } on DioException catch (e) { + final errorData = e.response!.data; + String errorMessage = errorData['message']; + emit(GarageDoorFailedState(errorMessage: errorMessage.toString())); + } + } + + void toggleSelectedIndex( + ToggleSelectedEvent event, Emitter emit) { + emit(GarageDoorLoadingState()); + selectedTabIndex = event.index; + emit(ChangeSlidingSegmentState(value: selectedTabIndex)); + } + + void toggleCreateSchedule( + ToggleCreateScheduleEvent event, Emitter emit) { + emit(GarageDoorLoadingState()); + createSchedule = !createSchedule; + selectedDays.clear(); + selectedTime = DateTime.now(); + emit(UpdateCreateScheduleState(createSchedule)); + } + + int selectedTabIndex = 0; + bool toggleSchedule = true; + List selectedDays = []; + bool createSchedule = false; + List listSchedule = []; + DateTime? selectedTime = DateTime.now(); + + int secondSelected = 0; + bool toggleDoor = false; + Future selectSeconds( + SelectSecondsEvent event, Emitter emit) async { + try { + emit(GarageDoorLoadingState()); + secondSelected = event.seconds; + + await DevicesAPI.controlDevice( + DeviceControlModel( + deviceId: GDId, code: 'tr_timecon', value: secondSelected), + GDId); + emit(UpdateState(garageSensor: deviceStatus)); + } on DioException catch (e) { + final errorData = e.response!.data; + String errorMessage = errorData['message']; + emit(GarageDoorFailedState(errorMessage: errorMessage.toString())); + } + } + + openCloseGarageDoor( + ToggleDoorEvent event, Emitter emit) async { + emit(GarageDoorLoadingState()); + try { + toggleDoor = !event.toggle; + await DevicesAPI.controlDevice( + DeviceControlModel( + deviceId: GDId, code: 'switch_1', value: toggleDoor), + GDId); + add(const GarageDoorInitial()); + emit(UpdateState(garageSensor: deviceStatus)); + } on DioException catch (e) { + final errorData = e.response!.data; + String errorMessage = errorData['message']; + emit(GarageDoorFailedState(errorMessage: errorMessage.toString())); + } + } + + void _setCounterValue( + SetCounterValue event, Emitter emit) async { + emit(LoadingNewSate(doorSensor: deviceStatus)); + int seconds = 0; + try { + seconds = event.duration.inSeconds; + final response = await DevicesAPI.controlDevice( + DeviceControlModel( + deviceId: GDId, code: 'countdown_1', value: seconds), + GDId); + + if (response['success'] ?? false) { + deviceStatus.countdown1 = seconds; + } else { + emit(const GarageDoorFailedState(errorMessage: 'Something went wrong')); + return; + } + } catch (e) { + emit(GarageDoorFailedState(errorMessage: e.toString())); + return; + } + if (seconds > 0) { + _onStartTimer(seconds); + } else { + _timer?.cancel(); + emit(TimerRunComplete()); + } + } + + void _getCounterValue( + GetCounterEvent event, Emitter emit) async { + emit(LoadingInitialState()); + try { + var response = await DevicesAPI.getDeviceStatus(GDId); + List statusModelList = []; + for (var status in response['status']) { + statusModelList.add(StatusModel.fromJson(status)); + } + deviceStatus = GarageDoorModel.fromJson(statusModelList); + if (event.deviceCode == 'countdown_1') { + deviceStatus.countdown1 > 0 + ? _onStartTimer(deviceStatus.countdown1) + : emit(UpdateTimerState(seconds: deviceStatus.countdown1)); + } + } catch (e) { + emit(GarageDoorFailedState(errorMessage: e.toString())); + return; + } + } + + void _onStartTimer(int seconds) { + _timer?.cancel(); + _timer = Timer.periodic(const Duration(seconds: 1), (timer) { + add(TickTimer(remainingTime: seconds - timer.tick)); + }); + } + + void _onTickTimer(TickTimer event, Emitter emit) { + if (event.remainingTime > 0) { + emit(TimerRunInProgress(event.remainingTime)); + } else { + _timer?.cancel(); + emit(TimerRunComplete()); + } + } + + bool oneGangGroup = false; + List devicesList = []; + List groupList = []; + bool allSwitchesOn = true; + + void _fetchWizardStatus( + InitialWizardEvent event, Emitter emit) async { + emit(LoadingInitialState()); + try { + devicesList = []; + groupList = []; + allSwitchesOn = true; + devicesList = await DevicesAPI.getDeviceByGroupName( + HomeCubit.getInstance().selectedSpace?.id ?? '', 'GD'); + + for (int i = 0; i < devicesList.length; i++) { + var response = + await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? ''); + List statusModelList = []; + for (var status in response['status']) { + statusModelList.add(StatusModel.fromJson(status)); + } + deviceStatus = GarageDoorModel.fromJson(statusModelList); + groupList.add(GroupGarageModel( + deviceId: devicesList[i].uuid ?? '', + deviceName: devicesList[i].name ?? '', + firstSwitch: deviceStatus.switch1, + )); + } + + if (groupList.isNotEmpty) { + groupList.firstWhere((element) { + if (!element.firstSwitch) { + allSwitchesOn = false; + } + return true; + }); + } + emit(UpdateGroupState(garageList: groupList, allSwitches: allSwitchesOn)); + } catch (e) { + emit(GarageDoorFailedState(errorMessage: e.toString())); + + return; + } + } + + void _groupAllOn( + GroupAllOnEvent event, Emitter emit) async { + emit(LoadingNewSate(doorSensor: deviceStatus)); + try { + // Set all switches (firstSwitch and secondSwitch) based on the event value (on/off) + for (int i = 0; i < groupList.length; i++) { + groupList[i].firstSwitch = true; + } + + // Emit the state with updated values + emit(UpdateGroupState(garageList: groupList, allSwitches: true)); + + // Get a list of all device IDs + List allDeviceIds = + groupList.map((device) => device.deviceId).toList(); + + // First call for switch_1 + final response = await DevicesAPI.deviceBatchController( + code: 'switch_1', // Controls first switch for all devices + devicesUuid: allDeviceIds, + value: true, // true (on) or false (off) depending on the event value + ); + // Check if either response is unsuccessful, then reset to initial state + if (response['failedResults'].toString() != '[]') { + await Future.delayed(const Duration(milliseconds: 500)); + add(const InitialEvent(groupScreen: true)); + } + } catch (_) { + // In case of an error, delay and reset the screen to initial state + await Future.delayed(const Duration(milliseconds: 500)); + add(const InitialEvent(groupScreen: true)); + } + } + + void _groupAllOff( + GroupAllOffEvent event, Emitter emit) async { + emit(LoadingNewSate(doorSensor: deviceStatus)); + try { + // Set all switches (firstSwitch and secondSwitch) based on the event value (on/off) + for (int i = 0; i < groupList.length; i++) { + groupList[i].firstSwitch = false; + } + + // Emit the state with updated values + emit(UpdateGroupState(garageList: groupList, allSwitches: false)); + + // Get a list of all device IDs + List allDeviceIds = + groupList.map((device) => device.deviceId).toList(); + + // First call for switch_1 + final response = await DevicesAPI.deviceBatchController( + code: 'switch_1', // Controls first switch for all devices + devicesUuid: allDeviceIds, + value: false, // true (on) or false (off) depending on the event value + ); + + // Check if either response is unsuccessful, then reset to initial state + if (response['failedResults'].toString() != '[]') { + await Future.delayed(const Duration(milliseconds: 500)); + add(const InitialEvent(groupScreen: true)); + } + } catch (_) { + // In case of an error, delay and reset the screen to initial state + await Future.delayed(const Duration(milliseconds: 500)); + add(const InitialEvent(groupScreen: true)); + } + } + + void _changeFirstWizardSwitch(ChangeFirstWizardSwitchStatusEvent event, + Emitter emit) async { + emit(LoadingNewSate(doorSensor: deviceStatus)); + try { + bool allSwitchesValue = true; + groupList.forEach((element) { + if (element.deviceId == event.deviceId) { + element.firstSwitch = !event.value; + } + if (!element.firstSwitch) { + allSwitchesValue = false; + } + }); + + emit(UpdateGroupState( + garageList: groupList, allSwitches: allSwitchesValue)); + + final response = await DevicesAPI.deviceBatchController( + code: 'switch_1', + devicesUuid: [event.deviceId], + value: !event.value, + ); + + if (response['failedResults'].toString() != '[]') { + add(InitialEvent(groupScreen: oneGangGroup)); + } + } catch (_) { + add(InitialEvent(groupScreen: oneGangGroup)); + } + } +} diff --git a/lib/features/devices/bloc/garage_door_bloc/garage_door_event.dart b/lib/features/devices/bloc/garage_door_bloc/garage_door_event.dart new file mode 100644 index 0000000..7114ce3 --- /dev/null +++ b/lib/features/devices/bloc/garage_door_bloc/garage_door_event.dart @@ -0,0 +1,175 @@ +import 'package:equatable/equatable.dart'; + +abstract class GarageDoorEvent extends Equatable { + const GarageDoorEvent(); + + @override + List get props => []; +} + +class GarageDoorLoading extends GarageDoorEvent {} + +class GarageDoorSwitch extends GarageDoorEvent { + final bool switchD; + final String deviceId; + final String productId; + const GarageDoorSwitch( + {required this.switchD, this.deviceId = '', this.productId = ''}); + + @override + List get props => [switchD, deviceId, productId]; +} + +class GarageDoorUpdated extends GarageDoorEvent {} + +class GarageDoorInitial extends GarageDoorEvent { + const GarageDoorInitial(); +} + +class ReportLogsInitial extends GarageDoorEvent { + const ReportLogsInitial(); +} + +class GarageDoorChangeStatus extends GarageDoorEvent {} + +class GetCounterEvent extends GarageDoorEvent { + final String deviceCode; + const GetCounterEvent({required this.deviceCode}); + @override + List get props => [deviceCode]; +} + +class ToggleLowBatteryEvent extends GarageDoorEvent { + final bool isLowBatteryEnabled; + + const ToggleLowBatteryEvent(this.isLowBatteryEnabled); + + @override + List get props => [isLowBatteryEnabled]; +} + +class ToggleClosingReminderEvent extends GarageDoorEvent { + final bool isClosingReminderEnabled; + + const ToggleClosingReminderEvent(this.isClosingReminderEnabled); + + @override + List get props => [isClosingReminderEnabled]; +} + +class ToggleDoorAlarmEvent extends GarageDoorEvent { + final bool isDoorAlarmEnabled; + + const ToggleDoorAlarmEvent(this.isDoorAlarmEnabled); + + @override + List get props => [isDoorAlarmEnabled]; +} + +class SetCounterValue extends GarageDoorEvent { + final Duration duration; + final String deviceCode; + const SetCounterValue({required this.duration, required this.deviceCode}); + @override + List get props => [duration, deviceCode]; +} + +class StartTimer extends GarageDoorEvent { + final int duration; + + const StartTimer(this.duration); + + @override + List get props => [duration]; +} + +class TickTimer extends GarageDoorEvent { + final int remainingTime; + + const TickTimer({required this.remainingTime}); + + @override + List get props => [remainingTime]; +} + +class StopTimer extends GarageDoorEvent {} + +class OnClose extends GarageDoorEvent {} + +//------------------- Schedule ----------=--------- +class GetScheduleEvent extends GarageDoorEvent {} + +class ScheduleSaveapp extends GarageDoorEvent {} + +class ToggleScheduleEvent extends GarageDoorEvent { + final String id; + final bool toggle; + const ToggleScheduleEvent({required this.toggle, required this.id}); + @override + List get props => [toggle, id]; +} + +class ToggleDaySelectionEvent extends GarageDoorEvent { + final String key; + + const ToggleDaySelectionEvent({required this.key}); + @override + List get props => [key]; +} + +class DeleteScheduleEvent extends GarageDoorEvent { + final String id; + const DeleteScheduleEvent({required this.id}); + @override + List get props => [id]; +} + +class ToggleSelectedEvent extends GarageDoorEvent { + final int index; + const ToggleSelectedEvent({required this.index}); + @override + List get props => [index]; +} + +class ToggleCreateScheduleEvent extends GarageDoorEvent { + final int index; + const ToggleCreateScheduleEvent({required this.index}); + @override + List get props => [index]; +} + +class ChangeFirstWizardSwitchStatusEvent extends GarageDoorEvent { + final bool value; + final String deviceId; + const ChangeFirstWizardSwitchStatusEvent( + {required this.value, this.deviceId = ''}); + @override + List get props => [value, deviceId]; +} + +class SelectSecondsEvent extends GarageDoorEvent { + final int seconds; + const SelectSecondsEvent({required this.seconds}); + @override + List get props => [seconds]; +} + +class ToggleDoorEvent extends GarageDoorEvent { + final bool toggle; + const ToggleDoorEvent({required this.toggle}); + @override + List get props => [toggle]; +} + +class InitialWizardEvent extends GarageDoorEvent {} + +class GroupAllOnEvent extends GarageDoorEvent {} + +class GroupAllOffEvent extends GarageDoorEvent {} + +class InitialEvent extends GarageDoorEvent { + final bool groupScreen; + const InitialEvent({required this.groupScreen}); + @override + List get props => [groupScreen]; +} diff --git a/lib/features/devices/bloc/garage_door_bloc/garage_door_state.dart b/lib/features/devices/bloc/garage_door_bloc/garage_door_state.dart new file mode 100644 index 0000000..d16f326 --- /dev/null +++ b/lib/features/devices/bloc/garage_door_bloc/garage_door_state.dart @@ -0,0 +1,94 @@ +import 'package:equatable/equatable.dart'; +import 'package:syncrow_app/features/devices/model/garage_door_model.dart'; +import 'package:syncrow_app/features/devices/model/group_garage_model.dart'; + +class GarageDoorSensorState extends Equatable { + const GarageDoorSensorState(); + + @override + List get props => []; +} + +class GarageDoorInitialState extends GarageDoorSensorState {} + +class GarageDoorLoadingState extends GarageDoorSensorState {} + +class GarageDoorFailedState extends GarageDoorSensorState { + final String errorMessage; + + const GarageDoorFailedState({required this.errorMessage}); + + @override + List get props => [errorMessage]; +} + +class UpdateState extends GarageDoorSensorState { + final GarageDoorModel garageSensor; + const UpdateState({required this.garageSensor}); + + @override + List get props => [garageSensor]; +} + +class LoadingNewSate extends GarageDoorSensorState { + final GarageDoorModel doorSensor; + const LoadingNewSate({required this.doorSensor}); + + @override + List get props => [doorSensor]; +} + +class ChangeSlidingSegmentState extends GarageDoorSensorState { + final int value; + + const ChangeSlidingSegmentState({required this.value}); + + @override + List get props => [value]; +} + +class UpdateTimerState extends GarageDoorSensorState { + final int seconds; + const UpdateTimerState({required this.seconds}); + + @override + List get props => [seconds]; +} + +class TimerRunInProgress extends GarageDoorSensorState { + final int remainingTime; + + const TimerRunInProgress(this.remainingTime); + + @override + List get props => [remainingTime]; +} + +class TimerRunComplete extends GarageDoorSensorState {} + +class SaveSchedule extends GarageDoorSensorState {} + +class IsToggleState extends GarageDoorSensorState { + final bool? onOff; + const IsToggleState({this.onOff}); +} + +class ChangeTimeState extends GarageDoorSensorState {} + +class LoadingInitialState extends GarageDoorSensorState {} + +class UpdateCreateScheduleState extends GarageDoorSensorState { + final bool createSchedule; + UpdateCreateScheduleState(this.createSchedule); +} + +class UpdateGroupState extends GarageDoorSensorState { + final List garageList; + final bool allSwitches; + + const UpdateGroupState( + {required this.garageList, required this.allSwitches}); + + @override + List get props => [garageList, allSwitches]; +} diff --git a/lib/features/devices/bloc/one_touch_bloc/one_touch_bloc.dart b/lib/features/devices/bloc/one_touch_bloc/one_touch_bloc.dart index 14d85f3..1d431e9 100644 --- a/lib/features/devices/bloc/one_touch_bloc/one_touch_bloc.dart +++ b/lib/features/devices/bloc/one_touch_bloc/one_touch_bloc.dart @@ -1,7 +1,6 @@ import 'dart:async'; import 'package:dio/dio.dart'; import 'package:firebase_database/firebase_database.dart'; -import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart'; import 'package:syncrow_app/features/devices/bloc/one_touch_bloc/one_touch_state.dart'; @@ -415,7 +414,7 @@ class OneTouchBloc extends Bloc { emit(UpdateGroupState( oneTouchList: groupOneTouchList, allSwitches: allSwitchesValue)); - if (!response['success']) { + if (response['success']) { add(InitialEvent(groupScreen: oneTouchGroup)); } } catch (_) { @@ -445,20 +444,12 @@ class OneTouchBloc extends Bloc { devicesUuid: allDeviceIds, value: true, // true (on) or false (off) depending on the event value ); - - // Second call for switch_2 - final response2 = await DevicesAPI.deviceBatchController( - code: 'switch_2', // Controls second switch for all devices - devicesUuid: allDeviceIds, - value: true, // true (on) or false (off) depending on the event value - ); - - // Check if either response is unsuccessful, then reset to initial state - if (!response1['success'] || !response2['success']) { + if (response1['failedResults'].toString() != '[]') { await Future.delayed(const Duration(milliseconds: 500)); add(const InitialEvent(groupScreen: true)); } } catch (_) { + emit(FailedState(error: _.toString())); // In case of an error, delay and reset the screen to initial state await Future.delayed(const Duration(milliseconds: 500)); add(const InitialEvent(groupScreen: true)); @@ -485,22 +476,16 @@ class OneTouchBloc extends Bloc { final response1 = await DevicesAPI.deviceBatchController( code: 'switch_1', // Controls first switch for all devices devicesUuid: allDeviceIds, - value: true, // true (on) or false (off) depending on the event value + value: false, // true (on) or false (off) depending on the event value ); - // Second call for switch_2 - final response2 = await DevicesAPI.deviceBatchController( - code: 'switch_2', // Controls second switch for all devices - devicesUuid: allDeviceIds, - value: true, // true (on) or false (off) depending on the event value - ); // Check if either response is unsuccessful, then reset to initial state - if (!response1['success'] || !response2['success']) { + if (response1['failedResults'].toString() != '[]') { await Future.delayed(const Duration(milliseconds: 500)); add(const InitialEvent(groupScreen: true)); } } catch (_) { - // In case of an error, delay and reset the screen to initial state + emit(FailedState(error: _.toString())); await Future.delayed(const Duration(milliseconds: 500)); add(const InitialEvent(groupScreen: true)); } @@ -511,38 +496,40 @@ class OneTouchBloc extends Bloc { Future _changeStatus( ChangeStatusEvent event, Emitter emit) async { - try { + try { emit(LoadingInitialState()); - final Map> controlMap = { - "relay_status": { - 'Power On': 'power_on', - 'Power Off': 'power_off', - 'Restart Memory': 'last', - }, - "light_mode": { - 'Off': 'none', - 'On/Off Status': 'relay', - 'Switch Position': 'pos', - }, - "relay_status_1": { - 'Power On': 'power_on', - 'Power Off': 'power_off', - 'Restart Memory': 'last', - }, - }; + final Map> controlMap = { + "relay_status": { + 'Power On': 'power_on', + 'Power Off': 'power_off', + 'Restart Memory': 'last', + }, + "light_mode": { + 'Off': 'none', + 'On/Off Status': 'relay', + 'Switch Position': 'pos', + }, + "relay_status_1": { + 'Power On': 'power_on', + 'Power Off': 'power_off', + 'Restart Memory': 'last', + }, + }; - final selectedControl = controlMap[optionSelected]?[statusSelected]; - if (selectedControl != null) { - await DevicesAPI.controlDevice( - DeviceControlModel( - deviceId: oneTouchId, code: optionSelected, value: selectedControl), - oneTouchId, - ); - } else { - print('Invalid statusSelected or optionSelected'); - } - } on DioException catch (e) { + final selectedControl = controlMap[optionSelected]?[statusSelected]; + if (selectedControl != null) { + await DevicesAPI.controlDevice( + DeviceControlModel( + deviceId: oneTouchId, + code: optionSelected, + value: selectedControl), + oneTouchId, + ); + } else { + print('Invalid statusSelected or optionSelected'); + } + } on DioException catch (e) { final errorData = e.response!.data; String errorMessage = errorData['message']; emit(FailedState(error: errorMessage.toString())); diff --git a/lib/features/devices/bloc/three_gang_bloc/three_gang_bloc.dart b/lib/features/devices/bloc/three_gang_bloc/three_gang_bloc.dart index 087d569..af74e8d 100644 --- a/lib/features/devices/bloc/three_gang_bloc/three_gang_bloc.dart +++ b/lib/features/devices/bloc/three_gang_bloc/three_gang_bloc.dart @@ -31,7 +31,8 @@ class ThreeGangBloc extends Bloc { List groupThreeGangList = []; bool allSwitchesOn = true; - ThreeGangBloc({required this.threeGangId, required this.switchCode}) : super(InitialState()) { + ThreeGangBloc({required this.threeGangId, required this.switchCode}) + : super(InitialState()) { on(_fetchThreeGangStatus); on(_threeGangUpdated); on(_changeFirstSwitch); @@ -57,7 +58,8 @@ class ThreeGangBloc extends Bloc { on(toggleCreateSchedule); } - void _fetchThreeGangStatus(InitialEvent event, Emitter emit) async { + void _fetchThreeGangStatus( + InitialEvent event, Emitter emit) async { emit(LoadingInitialState()); try { threeGangGroup = event.groupScreen; @@ -69,7 +71,8 @@ class ThreeGangBloc extends Bloc { HomeCubit.getInstance().selectedSpace?.id ?? '', '3G'); for (int i = 0; i < devicesList.length; i++) { - var response = await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? ''); + var response = + await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? ''); List statusModelList = []; for (var status in response['status']) { statusModelList.add(StatusModel.fromJson(status)); @@ -86,13 +89,16 @@ class ThreeGangBloc extends Bloc { if (groupThreeGangList.isNotEmpty) { groupThreeGangList.firstWhere((element) { - if (!element.firstSwitch || !element.secondSwitch || !element.thirdSwitch) { + if (!element.firstSwitch || + !element.secondSwitch || + !element.thirdSwitch) { allSwitchesOn = false; } return true; }); } - emit(UpdateGroupState(threeGangList: groupThreeGangList, allSwitches: allSwitchesOn)); + emit(UpdateGroupState( + threeGangList: groupThreeGangList, allSwitches: allSwitchesOn)); } else { var response = await DevicesAPI.getDeviceStatus(threeGangId); List statusModelList = []; @@ -101,7 +107,7 @@ class ThreeGangBloc extends Bloc { } deviceStatus = ThreeGangModel.fromJson(statusModelList); emit(UpdateState(threeGangModel: deviceStatus)); - _listenToChanges(); + // _listenToChanges(); } } catch (e) { emit(FailedState(error: e.toString())); @@ -111,18 +117,21 @@ class ThreeGangBloc extends Bloc { _listenToChanges() { try { - DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$threeGangId'); + DatabaseReference ref = + FirebaseDatabase.instance.ref('device-status/$threeGangId'); Stream stream = ref.onValue; - stream.listen((DatabaseEvent event) async { + stream.listen((DatabaseEvent event) async { if (_timer != null) { await Future.delayed(const Duration(seconds: 2)); } - Map usersMap = event.snapshot.value as Map; + Map usersMap = + event.snapshot.value as Map; List statusList = []; usersMap['status'].forEach((element) { - statusList.add(StatusModel(code: element['code'], value: element['value'])); + statusList + .add(StatusModel(code: element['code'], value: element['value'])); }); deviceStatus = ThreeGangModel.fromJson(statusList); @@ -137,7 +146,8 @@ class ThreeGangBloc extends Bloc { emit(UpdateState(threeGangModel: deviceStatus)); } - void _changeFirstSwitch(ChangeFirstSwitchStatusEvent event, Emitter emit) async { + void _changeFirstSwitch( + ChangeFirstSwitchStatusEvent event, Emitter emit) async { emit(LoadingNewSate(threeGangModel: deviceStatus)); try { if (threeGangGroup) { @@ -146,11 +156,14 @@ class ThreeGangBloc extends Bloc { if (element.deviceId == event.deviceId) { element.firstSwitch = !event.value; } - if (!element.firstSwitch || !element.secondSwitch || !element.thirdSwitch) { + if (!element.firstSwitch || + !element.secondSwitch || + !element.thirdSwitch) { allSwitchesValue = false; } }); - emit(UpdateGroupState(threeGangList: groupThreeGangList, allSwitches: allSwitchesValue)); + emit(UpdateGroupState( + threeGangList: groupThreeGangList, allSwitches: allSwitchesValue)); } else { deviceStatus.firstSwitch = !event.value; emit(UpdateState(threeGangModel: deviceStatus)); @@ -187,11 +200,14 @@ class ThreeGangBloc extends Bloc { if (element.deviceId == event.deviceId) { element.secondSwitch = !event.value; } - if (!element.firstSwitch || !element.secondSwitch || !element.thirdSwitch) { + if (!element.firstSwitch || + !element.secondSwitch || + !element.thirdSwitch) { allSwitchesValue = false; } }); - emit(UpdateGroupState(threeGangList: groupThreeGangList, allSwitches: allSwitchesValue)); + emit(UpdateGroupState( + threeGangList: groupThreeGangList, allSwitches: allSwitchesValue)); } else { deviceStatus.secondSwitch = !event.value; emit(UpdateState(threeGangModel: deviceStatus)); @@ -217,7 +233,8 @@ class ThreeGangBloc extends Bloc { } } - void _changeThirdSwitch(ChangeThirdSwitchStatusEvent event, Emitter emit) async { + void _changeThirdSwitch( + ChangeThirdSwitchStatusEvent event, Emitter emit) async { emit(LoadingNewSate(threeGangModel: deviceStatus)); try { if (threeGangGroup) { @@ -226,11 +243,14 @@ class ThreeGangBloc extends Bloc { if (element.deviceId == event.deviceId) { element.thirdSwitch = !event.value; } - if (!element.firstSwitch || !element.secondSwitch || !element.thirdSwitch) { + if (!element.firstSwitch || + !element.secondSwitch || + !element.thirdSwitch) { allSwitchesValue = false; } }); - emit(UpdateGroupState(threeGangList: groupThreeGangList, allSwitches: allSwitchesValue)); + emit(UpdateGroupState( + threeGangList: groupThreeGangList, allSwitches: allSwitchesValue)); } else { deviceStatus.thirdSwitch = !event.value; emit(UpdateState(threeGangModel: deviceStatus)); @@ -269,15 +289,21 @@ class ThreeGangBloc extends Bloc { final response = await Future.wait([ DevicesAPI.controlDevice( DeviceControlModel( - deviceId: threeGangId, code: 'switch_1', value: deviceStatus.firstSwitch), + deviceId: threeGangId, + code: 'switch_1', + value: deviceStatus.firstSwitch), threeGangId), DevicesAPI.controlDevice( DeviceControlModel( - deviceId: threeGangId, code: 'switch_2', value: deviceStatus.secondSwitch), + deviceId: threeGangId, + code: 'switch_2', + value: deviceStatus.secondSwitch), threeGangId), DevicesAPI.controlDevice( DeviceControlModel( - deviceId: threeGangId, code: 'switch_3', value: deviceStatus.thirdSwitch), + deviceId: threeGangId, + code: 'switch_3', + value: deviceStatus.thirdSwitch), threeGangId), ]); @@ -303,15 +329,21 @@ class ThreeGangBloc extends Bloc { final response = await Future.wait([ DevicesAPI.controlDevice( DeviceControlModel( - deviceId: threeGangId, code: 'switch_1', value: deviceStatus.firstSwitch), + deviceId: threeGangId, + code: 'switch_1', + value: deviceStatus.firstSwitch), threeGangId), DevicesAPI.controlDevice( DeviceControlModel( - deviceId: threeGangId, code: 'switch_2', value: deviceStatus.secondSwitch), + deviceId: threeGangId, + code: 'switch_2', + value: deviceStatus.secondSwitch), threeGangId), DevicesAPI.controlDevice( DeviceControlModel( - deviceId: threeGangId, code: 'switch_3', value: deviceStatus.thirdSwitch), + deviceId: threeGangId, + code: 'switch_3', + value: deviceStatus.thirdSwitch), threeGangId), ]); @@ -333,29 +365,33 @@ class ThreeGangBloc extends Bloc { groupThreeGangList[i].secondSwitch = true; groupThreeGangList[i].thirdSwitch = true; } - emit(UpdateGroupState(threeGangList: groupThreeGangList, allSwitches: true)); + emit(UpdateGroupState( + threeGangList: groupThreeGangList, allSwitches: true)); - for (int i = 0; i < groupThreeGangList.length; i++) { - final response = await Future.wait([ - DevicesAPI.controlDevice( - DeviceControlModel( - deviceId: groupThreeGangList[i].deviceId, code: 'switch_1', value: true), - groupThreeGangList[i].deviceId), - DevicesAPI.controlDevice( - DeviceControlModel( - deviceId: groupThreeGangList[i].deviceId, code: 'switch_2', value: true), - groupThreeGangList[i].deviceId), - DevicesAPI.controlDevice( - DeviceControlModel( - deviceId: groupThreeGangList[i].deviceId, code: 'switch_3', value: true), - groupThreeGangList[i].deviceId), - ]); + List allDeviceIds = + groupThreeGangList.map((device) => device.deviceId).toList(); - if (response.every((element) => !element['success'])) { - await Future.delayed(const Duration(milliseconds: 500)); - add(const InitialEvent(groupScreen: true)); - break; - } + final response1 = await DevicesAPI.deviceBatchController( + code: 'switch_1', + devicesUuid: allDeviceIds, + value: true, + ); + final response2 = await DevicesAPI.deviceBatchController( + code: 'switch_2', + devicesUuid: allDeviceIds, + value: true, + ); + final response3 = await DevicesAPI.deviceBatchController( + code: 'switch_3', + devicesUuid: allDeviceIds, + value: true, + ); + + if (response1['failedResults'].toString() != '[]' || + response2['failedResults'].toString() != '[]' || + response3['failedResults'].toString() != '[]') { + await Future.delayed(const Duration(milliseconds: 500)); + add(const InitialEvent(groupScreen: true)); } } catch (_) { await Future.delayed(const Duration(milliseconds: 500)); @@ -363,7 +399,8 @@ class ThreeGangBloc extends Bloc { } } - void _groupAllOff(GroupAllOffEvent event, Emitter emit) async { + void _groupAllOff( + GroupAllOffEvent event, Emitter emit) async { emit(LoadingNewSate(threeGangModel: deviceStatus)); try { for (int i = 0; i < groupThreeGangList.length; i++) { @@ -371,29 +408,32 @@ class ThreeGangBloc extends Bloc { groupThreeGangList[i].secondSwitch = false; groupThreeGangList[i].thirdSwitch = false; } - emit(UpdateGroupState(threeGangList: groupThreeGangList, allSwitches: false)); + emit(UpdateGroupState( + threeGangList: groupThreeGangList, allSwitches: false)); + List allDeviceIds = + groupThreeGangList.map((device) => device.deviceId).toList(); - for (int i = 0; i < groupThreeGangList.length; i++) { - final response = await Future.wait([ - DevicesAPI.controlDevice( - DeviceControlModel( - deviceId: groupThreeGangList[i].deviceId, code: 'switch_1', value: false), - groupThreeGangList[i].deviceId), - DevicesAPI.controlDevice( - DeviceControlModel( - deviceId: groupThreeGangList[i].deviceId, code: 'switch_2', value: false), - groupThreeGangList[i].deviceId), - DevicesAPI.controlDevice( - DeviceControlModel( - deviceId: groupThreeGangList[i].deviceId, code: 'switch_3', value: false), - groupThreeGangList[i].deviceId), - ]); + final response1 = await DevicesAPI.deviceBatchController( + code: 'switch_1', + devicesUuid: allDeviceIds, + value: false, + ); + final response2 = await DevicesAPI.deviceBatchController( + code: 'switch_2', + devicesUuid: allDeviceIds, + value: false, + ); + final response3 = await DevicesAPI.deviceBatchController( + code: 'switch_3', + devicesUuid: allDeviceIds, + value: false, + ); - if (response.every((element) => !element['success'])) { - await Future.delayed(const Duration(milliseconds: 500)); - add(const InitialEvent(groupScreen: true)); - break; - } + if (response1['failedResults'].toString() != '[]' || + response2['failedResults'].toString() != '[]' || + response3['failedResults'].toString() != '[]') { + await Future.delayed(const Duration(milliseconds: 500)); + add(const InitialEvent(groupScreen: true)); } } catch (_) { await Future.delayed(const Duration(milliseconds: 500)); @@ -401,17 +441,20 @@ class ThreeGangBloc extends Bloc { } } - void _changeSliding(ChangeSlidingSegment event, Emitter emit) async { + void _changeSliding( + ChangeSlidingSegment event, Emitter emit) async { emit(ChangeSlidingSegmentState(value: event.value)); } - void _setCounterValue(SetCounterValue event, Emitter emit) async { + void _setCounterValue( + SetCounterValue event, Emitter emit) async { emit(LoadingNewSate(threeGangModel: deviceStatus)); int seconds = 0; try { seconds = event.duration.inSeconds; final response = await DevicesAPI.controlDevice( - DeviceControlModel(deviceId: threeGangId, code: event.deviceCode, value: seconds), + DeviceControlModel( + deviceId: threeGangId, code: event.deviceCode, value: seconds), threeGangId); if (response['success'] ?? false) { @@ -438,7 +481,8 @@ class ThreeGangBloc extends Bloc { } } - void _getCounterValue(GetCounterEvent event, Emitter emit) async { + void _getCounterValue( + GetCounterEvent event, Emitter emit) async { emit(LoadingInitialState()); try { var response = await DevicesAPI.getDeviceStatus(threeGangId); @@ -548,7 +592,8 @@ class ThreeGangBloc extends Bloc { deviceId: threeGangId, ); List jsonData = response; - listSchedule = jsonData.map((item) => ScheduleModel.fromJson(item)).toList(); + listSchedule = + jsonData.map((item) => ScheduleModel.fromJson(item)).toList(); emit(InitialState()); } on DioException catch (e) { final errorData = e.response!.data; @@ -559,12 +604,13 @@ class ThreeGangBloc extends Bloc { int? getTimeStampWithoutSeconds(DateTime? dateTime) { if (dateTime == null) return null; - DateTime dateTimeWithoutSeconds = - DateTime(dateTime.year, dateTime.month, dateTime.day, dateTime.hour, dateTime.minute); + DateTime dateTimeWithoutSeconds = DateTime(dateTime.year, dateTime.month, + dateTime.day, dateTime.hour, dateTime.minute); return dateTimeWithoutSeconds.millisecondsSinceEpoch ~/ 1000; } - Future toggleChange(ToggleScheduleEvent event, Emitter emit) async { + Future toggleChange( + ToggleScheduleEvent event, Emitter emit) async { try { emit(LoadingInitialState()); final response = await DevicesAPI.changeSchedule( @@ -583,7 +629,8 @@ class ThreeGangBloc extends Bloc { } } - Future deleteSchedule(DeleteScheduleEvent event, Emitter emit) async { + Future deleteSchedule( + DeleteScheduleEvent event, Emitter emit) async { try { emit(LoadingInitialState()); final response = await DevicesAPI.deleteSchedule( @@ -603,13 +650,15 @@ class ThreeGangBloc extends Bloc { } } - void toggleSelectedIndex(ToggleSelectedEvent event, Emitter emit) { + void toggleSelectedIndex( + ToggleSelectedEvent event, Emitter emit) { emit(LoadingInitialState()); selectedTabIndex = event.index; emit(ChangeSlidingSegmentState(value: selectedTabIndex)); } - void toggleCreateSchedule(ToggleCreateScheduleEvent event, Emitter emit) { + void toggleCreateSchedule( + ToggleCreateScheduleEvent event, Emitter emit) { emit(LoadingInitialState()); createSchedule = !createSchedule; selectedDays.clear(); diff --git a/lib/features/devices/bloc/three_touch_bloc/three_touch_bloc.dart b/lib/features/devices/bloc/three_touch_bloc/three_touch_bloc.dart index da8a97e..8a4ac56 100644 --- a/lib/features/devices/bloc/three_touch_bloc/three_touch_bloc.dart +++ b/lib/features/devices/bloc/three_touch_bloc/three_touch_bloc.dart @@ -1,7 +1,6 @@ import 'dart:async'; import 'package:dio/dio.dart'; import 'package:firebase_database/firebase_database.dart'; -import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart'; import 'package:syncrow_app/features/devices/bloc/three_touch_bloc/three_touch_event.dart'; @@ -55,13 +54,11 @@ class ThreeTouchBloc extends Bloc { on(_onClose); on(_groupAllOn); on(_groupAllOff); - on(toggleDaySelection); on(saveSchedule); on(getSchedule); on(toggleChange); on(deleteSchedule); - on(toggleSelectedIndex); on(toggleCreateSchedule); on(_changeStatus); @@ -116,7 +113,7 @@ class ThreeTouchBloc extends Bloc { } deviceStatus = ThreeTouchModel.fromJson(statusModelList); emit(UpdateState(threeTouchModel: deviceStatus)); - _listenToChanges(); + // _listenToChanges(); } } catch (e) { emit(FailedState(error: e.toString())); @@ -379,34 +376,29 @@ class ThreeTouchBloc extends Bloc { } emit(UpdateGroupState( threeTouchList: groupThreeTouchList, allSwitches: true)); + List allDeviceIds = + groupThreeTouchList.map((device) => device.deviceId).toList(); + final response1 = await DevicesAPI.deviceBatchController( + code: 'switch_1', + devicesUuid: allDeviceIds, + value: true, + ); + final response2 = await DevicesAPI.deviceBatchController( + code: 'switch_2', + devicesUuid: allDeviceIds, + value: true, + ); + final response3 = await DevicesAPI.deviceBatchController( + code: 'switch_3', + devicesUuid: allDeviceIds, + value: true, + ); - for (int i = 0; i < groupThreeTouchList.length; i++) { - final response = await Future.wait([ - DevicesAPI.controlDevice( - DeviceControlModel( - deviceId: groupThreeTouchList[i].deviceId, - code: 'switch_1', - value: true), - groupThreeTouchList[i].deviceId), - DevicesAPI.controlDevice( - DeviceControlModel( - deviceId: groupThreeTouchList[i].deviceId, - code: 'switch_2', - value: true), - groupThreeTouchList[i].deviceId), - DevicesAPI.controlDevice( - DeviceControlModel( - deviceId: groupThreeTouchList[i].deviceId, - code: 'switch_3', - value: true), - groupThreeTouchList[i].deviceId), - ]); - - if (response.every((element) => !element['success'])) { - await Future.delayed(const Duration(milliseconds: 500)); - add(const InitialEvent(groupScreen: true)); - break; - } + if (response1['failedResults'].toString() != '[]' || + response2['failedResults'].toString() != '[]' || + response3['failedResults'].toString() != '[]') { + await Future.delayed(const Duration(milliseconds: 500)); + add(const InitialEvent(groupScreen: true)); } } catch (_) { await Future.delayed(const Duration(milliseconds: 500)); @@ -423,36 +415,31 @@ class ThreeTouchBloc extends Bloc { groupThreeTouchList[i].secondSwitch = false; groupThreeTouchList[i].thirdSwitch = false; } + List allDeviceIds = + groupThreeTouchList.map((device) => device.deviceId).toList(); emit(UpdateGroupState( threeTouchList: groupThreeTouchList, allSwitches: false)); + final response1 = await DevicesAPI.deviceBatchController( + code: 'switch_1', + devicesUuid: allDeviceIds, + value: false, + ); + final response2 = await DevicesAPI.deviceBatchController( + code: 'switch_2', + devicesUuid: allDeviceIds, + value: false, + ); + final response3 = await DevicesAPI.deviceBatchController( + code: 'switch_3', + devicesUuid: allDeviceIds, + value: false, + ); - for (int i = 0; i < groupThreeTouchList.length; i++) { - final response = await Future.wait([ - DevicesAPI.controlDevice( - DeviceControlModel( - deviceId: groupThreeTouchList[i].deviceId, - code: 'switch_1', - value: false), - groupThreeTouchList[i].deviceId), - DevicesAPI.controlDevice( - DeviceControlModel( - deviceId: groupThreeTouchList[i].deviceId, - code: 'switch_2', - value: false), - groupThreeTouchList[i].deviceId), - DevicesAPI.controlDevice( - DeviceControlModel( - deviceId: groupThreeTouchList[i].deviceId, - code: 'switch_3', - value: false), - groupThreeTouchList[i].deviceId), - ]); - - if (response.every((element) => !element['success'])) { - await Future.delayed(const Duration(milliseconds: 500)); - add(const InitialEvent(groupScreen: true)); - break; - } + if (response1['failedResults'].toString() != '[]' || + response2['failedResults'].toString() != '[]' || + response3['failedResults'].toString() != '[]') { + await Future.delayed(const Duration(milliseconds: 500)); + add(const InitialEvent(groupScreen: true)); } } catch (_) { await Future.delayed(const Duration(milliseconds: 500)); diff --git a/lib/features/devices/bloc/two_touch_bloc/two_touch_bloc.dart b/lib/features/devices/bloc/two_touch_bloc/two_touch_bloc.dart index 0f4c794..ff32edf 100644 --- a/lib/features/devices/bloc/two_touch_bloc/two_touch_bloc.dart +++ b/lib/features/devices/bloc/two_touch_bloc/two_touch_bloc.dart @@ -3,7 +3,6 @@ import 'package:dio/dio.dart'; import 'package:firebase_database/firebase_database.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart'; - import 'package:syncrow_app/features/devices/bloc/two_touch_bloc/two_touch_event.dart'; import 'package:syncrow_app/features/devices/bloc/two_touch_bloc/two_touch_state.dart'; import 'package:syncrow_app/features/devices/model/device_control_model.dart'; @@ -30,14 +29,14 @@ class TwoTouchBloc extends Bloc { relay_status_2: status.off, ); Timer? _timer; - + bool twoTouchGroup = false; List devicesList = []; List groupTwoTouchList = []; bool allSwitchesOn = true; bool toggleSchedule = true; List selectedDays = []; - + bool createSchedule = false; List listSchedule = []; @@ -586,12 +585,9 @@ class TwoTouchBloc extends Bloc { emit(UpdateGroupState( twoTouchList: groupTwoTouchList, allSwitches: allSwitchesValue)); - - List allDeviceIds = - groupTwoTouchList.map((device) => device.deviceId).toList(); final response = await DevicesAPI.deviceBatchController( code: 'switch_1', - devicesUuid: allDeviceIds, + devicesUuid: [event.deviceId], value: !event.value, ); @@ -616,15 +612,13 @@ class TwoTouchBloc extends Bloc { allSwitchesValue = false; } }); - List allDeviceIds = - groupTwoTouchList.map((device) => device.deviceId).toList(); emit(UpdateGroupState( twoTouchList: groupTwoTouchList, allSwitches: allSwitchesValue)); final response = await DevicesAPI.deviceBatchController( code: 'switch_2', - devicesUuid: allDeviceIds, + devicesUuid: [event.deviceId], value: !event.value, ); diff --git a/lib/features/devices/model/device_category_model.dart b/lib/features/devices/model/device_category_model.dart index 8ef4334..ccd2e0f 100644 --- a/lib/features/devices/model/device_category_model.dart +++ b/lib/features/devices/model/device_category_model.dart @@ -42,9 +42,7 @@ class DevicesCategoryModel { : name = json['groupName'], // id = json['groupId'], type = devicesTypesMap[json['groupName']] ?? DeviceType.Other, - icon = deviceTypeIconMap[ - devicesTypesMap[json['groupName']] ?? DeviceType.Other] ?? - '', + icon = deviceTypeIconMap[devicesTypesMap[json['groupName']] ?? DeviceType.Other] ?? '', devices = [], isSelected = false; @@ -70,4 +68,5 @@ Map deviceTypeIconMap = { DeviceType.OneTouch: Assets.oneGang, DeviceType.TowTouch: Assets.twoGang, DeviceType.ThreeTouch: Assets.assetsIconsGang, + DeviceType.GarageDoor: Assets.garageIcon }; diff --git a/lib/features/devices/model/device_model.dart b/lib/features/devices/model/device_model.dart index 2374198..44899e6 100644 --- a/lib/features/devices/model/device_model.dart +++ b/lib/features/devices/model/device_model.dart @@ -70,9 +70,12 @@ class DeviceModel { tempIcon = Assets.oneGang; } else if (type == DeviceType.TowTouch) { tempIcon = Assets.twoGang; + } else if (type == DeviceType.GarageDoor) { + tempIcon = Assets.garageIcon; } else if (type == DeviceType.ThreeTouch) { tempIcon = Assets.assetsIcons3GangSwitch; - } else { + } + else { tempIcon = Assets.assetsIconsLogo; } diff --git a/lib/features/devices/model/garage_door_model.dart b/lib/features/devices/model/garage_door_model.dart new file mode 100644 index 0000000..146523a --- /dev/null +++ b/lib/features/devices/model/garage_door_model.dart @@ -0,0 +1,81 @@ +import 'package:syncrow_app/features/devices/model/status_model.dart'; + +class GarageDoorModel { + bool switch1; + bool doorContactState; + int countdown1; + int countdownAlarm; + String doorControl1; + bool voiceControl1; + String doorState1; + int batteryPercentage; + int tr_timecon; + + GarageDoorModel({ + required this.switch1, + required this.doorContactState, + required this.countdown1, + required this.countdownAlarm, + required this.doorControl1, + required this.voiceControl1, + required this.doorState1, + required this.batteryPercentage, + required this.tr_timecon, + }); + + factory GarageDoorModel.fromJson(List jsonList) { + late bool _switch1 = false; + late bool _doorContactState = false; + late int _countdown1 = 0; + late int _countdownAlarm = 0; + late String _doorControl1 = "closed"; + late bool _voiceControl1 = false; + late String _doorState1 = "closed"; + late int _batteryPercentage = 0; + late int _tr_timecon = 0; + + for (var status in jsonList) { + switch (status.code) { + case 'tr_timecon': + _tr_timecon = status.value ?? "closed"; + break; + case 'switch_1': + _switch1 = status.value ?? false; + break; + case 'doorcontact_state': + _doorContactState = status.value ?? false; + break; + case 'countdown_1': + _countdown1 = status.value ?? 0; + break; + case 'countdown_alarm': + _countdownAlarm = status.value ?? 0; + break; + case 'door_control_1': + _doorControl1 = status.value ?? "closed"; + break; + + case 'voice_control_1': + _voiceControl1 = status.value ?? false; + break; + case 'door_state_1': + _doorState1 = status.value ?? "closed"; + break; + case 'battery_percentage': + _batteryPercentage = status.value ?? 0; + break; + } + } + + return GarageDoorModel( + switch1: _switch1, + doorContactState: _doorContactState, + countdown1: _countdown1, + countdownAlarm: _countdownAlarm, + doorControl1: _doorControl1, + voiceControl1: _voiceControl1, + doorState1: _doorState1, + batteryPercentage: _batteryPercentage, + tr_timecon: _tr_timecon); + } +} diff --git a/lib/features/devices/model/group_garage_model.dart b/lib/features/devices/model/group_garage_model.dart new file mode 100644 index 0000000..e4012ec --- /dev/null +++ b/lib/features/devices/model/group_garage_model.dart @@ -0,0 +1,11 @@ +class GroupGarageModel { + final String deviceId; + final String deviceName; + bool firstSwitch; + + GroupGarageModel({ + required this.deviceId, + required this.deviceName, + required this.firstSwitch, + }); +} diff --git a/lib/features/devices/view/widgets/curtains/curtain_buttons.dart b/lib/features/devices/view/widgets/curtains/curtain_buttons.dart index d1e0a06..91b919b 100644 --- a/lib/features/devices/view/widgets/curtains/curtain_buttons.dart +++ b/lib/features/devices/view/widgets/curtains/curtain_buttons.dart @@ -1,4 +1,3 @@ - import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/flutter_svg.dart'; @@ -17,8 +16,8 @@ class CurtainButtons extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ _buildButton( - onTap: () => context.read().add(OpenCurtain(curtain.productType!)), - iconPath: Assets.assetsIconsCurtainsIconOpenCurtain, + onTap: () => context.read().add(CloseCurtain(curtain.productType!)), + iconPath: Assets.assetsIconsCurtainsIconCloseCurtain, ), _buildButton( onTap: () => context.read().add(PauseCurtain()), @@ -26,8 +25,8 @@ class CurtainButtons extends StatelessWidget { isSvg: false, ), _buildButton( - onTap: () => context.read().add(CloseCurtain(curtain.productType!)), - iconPath: Assets.assetsIconsCurtainsIconCloseCurtain, + onTap: () => context.read().add(OpenCurtain(curtain.productType!)), + iconPath: Assets.assetsIconsCurtainsIconOpenCurtain, ), ], ); diff --git a/lib/features/devices/view/widgets/curtains/curtain_view.dart b/lib/features/devices/view/widgets/curtains/curtain_view.dart index 9f89aa2..6965008 100644 --- a/lib/features/devices/view/widgets/curtains/curtain_view.dart +++ b/lib/features/devices/view/widgets/curtains/curtain_view.dart @@ -6,6 +6,7 @@ import 'package:syncrow_app/features/devices/bloc/curtain_bloc/curtain_event.dar import 'package:syncrow_app/features/devices/bloc/curtain_bloc/curtain_state.dart'; import 'package:syncrow_app/features/devices/model/device_model.dart'; import 'package:syncrow_app/features/devices/view/widgets/curtains/curtain_buttons.dart'; +import 'package:syncrow_app/features/shared_widgets/default_container.dart'; import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart'; import 'package:syncrow_app/generated/assets.dart'; @@ -19,7 +20,7 @@ class CurtainView extends StatelessWidget { create: (context) => CurtainBloc(curtain.uuid!)..add(InitCurtain()), child: BlocBuilder( builder: (context, state) { - double curtainWidth = 270; + double curtainWidth = MediaQuery.sizeOf(context).width * 0.6; // double blindHeight = 310; if (state is CurtainsOpening) { curtainWidth = state.curtainWidth; @@ -33,66 +34,117 @@ class CurtainView extends StatelessWidget { } return DefaultScaffold( title: curtain.name, - child: Column( - children: [ - Stack( - alignment: Alignment.centerLeft, - children: [ - Container( - height: 340, - width: 365, - decoration: const BoxDecoration( - image: DecorationImage( - image: AssetImage( - Assets.assetsImagesWindow, - ), + child: state is CurtainLoadingState + ? const Center( + child: + DefaultContainer(width: 50, height: 50, child: CircularProgressIndicator()), + ) + : RefreshIndicator( + onRefresh: () async { + BlocProvider.of(context).add(InitCurtain()); + }, + child: ListView( + children: [ + const SizedBox( + height: 40, ), - ), - ), - Padding( - padding: const EdgeInsets.all(40), - child: AnimatedContainer( - duration: const Duration(milliseconds: 200), - curve: Curves.linear, - height: 310, - width: curtainWidth, - child: Stack( - children: List.generate( - 10, - (index) { - double spacing = curtainWidth / 9; - double leftMostPosition = index * spacing; - return AnimatedPositioned( - duration: const Duration(milliseconds: 200), - curve: Curves.linear, - left: leftMostPosition, - child: SizedBox( - height: 320, - width: 32, - child: SvgPicture.asset( - Assets.assetsIconsCurtainsIconVerticalBlade, - fit: BoxFit.fill, + Stack( + alignment: Alignment.center, + children: [ + SvgPicture.asset( + Assets.assetsImagesWindow, + width: MediaQuery.sizeOf(context).width * 0.85, + height: MediaQuery.sizeOf(context).height * 0.4, + ), + SizedBox( + height: MediaQuery.sizeOf(context).height * 0.4, + child: Column( + children: [ + SvgPicture.asset( + Assets.assetsIconsCurtainsIconCurtainHolder, + width: MediaQuery.sizeOf(context).width * 0.75, ), - ), - ); - }, - ), + SizedBox( + width: MediaQuery.sizeOf(context).width * 0.75, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + SizedBox( + width: MediaQuery.sizeOf(context).width * 0.025, + ), + AnimatedContainer( + duration: const Duration(milliseconds: 200), + curve: Curves.linear, + height: MediaQuery.sizeOf(context).height * 0.35, + width: MediaQuery.sizeOf(context).width * 0.35, + child: Stack( + children: List.generate( + 4, + (index) { + double spacing = curtainWidth / 7.5; + double leftMostPosition = index * spacing; + return AnimatedPositioned( + duration: const Duration(milliseconds: 200), + curve: Curves.linear, + left: leftMostPosition, + child: SizedBox( + height: + MediaQuery.sizeOf(context).height * 0.35, + width: MediaQuery.sizeOf(context).width * 0.08, + child: SvgPicture.asset( + Assets.assetsIconsCurtainsIconVerticalBlade, + fit: BoxFit.fill, + ), + ), + ); + }, + ), + ), + ), + AnimatedContainer( + duration: const Duration(milliseconds: 200), + curve: Curves.linear, + height: MediaQuery.sizeOf(context).height * 0.35, + width: MediaQuery.sizeOf(context).width * 0.35, + child: Stack( + children: List.generate( + 4, + (index) { + double spacing = curtainWidth / 7.5; + double rightMostPosition = index * spacing; + return AnimatedPositioned( + duration: const Duration(milliseconds: 200), + curve: Curves.linear, + right: rightMostPosition, + child: SizedBox( + height: MediaQuery.sizeOf(context).height * 0.35, + width: MediaQuery.sizeOf(context).width * 0.08, + child: SvgPicture.asset( + Assets.rightVerticalBlade, + fit: BoxFit.fill, + ), + ), + ); + }, + ), + ), + ), + SizedBox( + width: MediaQuery.sizeOf(context).width * 0.025, + ), + ], + ), + ), + ], + ), + ), + ], ), - ), + const SizedBox(height: 80), + CurtainButtons(curtain: curtain), + ], ), - Positioned( - top: 27, - left: 43, - child: SvgPicture.asset( - Assets.assetsIconsCurtainsIconCurtainHolder, - ), - ), - ], - ), - const SizedBox(height: 80), - CurtainButtons(curtain: curtain), - ], - ), + ), ); }, ), diff --git a/lib/features/devices/view/widgets/garage_door/create_schedule_garage.dart b/lib/features/devices/view/widgets/garage_door/create_schedule_garage.dart new file mode 100644 index 0000000..9410935 --- /dev/null +++ b/lib/features/devices/view/widgets/garage_door/create_schedule_garage.dart @@ -0,0 +1,204 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:syncrow_app/features/devices/view/widgets/garage_door/garagedialog.dart'; +import 'package:syncrow_app/features/shared_widgets/default_container.dart'; +import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +class CreateGarageSchedule extends StatefulWidget { + final List> days; + final void Function(List selectedDays)? + selectDays; + final Function(DateTime) onDateTimeChanged; + final void Function(bool isOn)? onToggleChanged; + + const CreateGarageSchedule({ + Key? key, + required this.days, + required this.selectDays, + required this.onDateTimeChanged, + this.onToggleChanged, + }) : super(key: key); + + @override + _CreateGarageScheduleState createState() => _CreateGarageScheduleState(); +} + +class _CreateGarageScheduleState extends State { + List selectedDays = []; + bool isOn = true; + String selectedControlOption = 'Open'; + + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 5), + child: Column( + children: [ + const Divider( + color: ColorsManager.greyColor, + ), + SizedBox( + height: 110, + child: CupertinoDatePicker( + mode: CupertinoDatePickerMode.time, + initialDateTime: DateTime.now(), + onDateTimeChanged: widget.onDateTimeChanged, + ), + ), + const Divider( + color: ColorsManager.greyColor, + ), + const SizedBox(height: 20), + SizedBox( + height: MediaQuery.of(context).size.height * 0.08, + child: ListView( + scrollDirection: Axis.horizontal, + children: widget.days.map((day) { + bool isSelected = selectedDays.contains(day['day']); + return Padding( + padding: const EdgeInsets.all(8.0), + child: InkWell( + onTap: () { + setState(() { + if (isSelected) { + selectedDays.remove(day['day']); + } else { + selectedDays.add(day['day']!); + } + if (widget.selectDays != null) { + widget.selectDays!(selectedDays); + } + }); + }, + child: Container( + width: 50, + padding: const EdgeInsets.symmetric( + vertical: 8, horizontal: 8), + decoration: BoxDecoration( + border: Border.all( + color: isSelected + ? Colors.black + : ColorsManager.grayColor, + ), + color: Colors.transparent, + borderRadius: BorderRadius.circular(30), + ), + child: Center( + child: Text( + day['day']!, + style: TextStyle( + fontSize: 13, + color: isSelected + ? Colors.black + : ColorsManager.grayColor, + ), + ), + ), + ), + ), + ); + }).toList(), + ), + ), + const SizedBox(height: 20), + DefaultContainer( + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + height: 50, + child: ListTile( + contentPadding: EdgeInsets.zero, + leading: const BodyMedium( + text: 'Notification', + fontWeight: FontWeight.normal, + ), + trailing: Transform.scale( + scale: .8, + child: CupertinoSwitch( + value: true, + onChanged: (value) { + }, + applyTheme: true, + )), + ), + ), + const Divider( + color: ColorsManager.graysColor, + ), + SizedBox( + height: 50, + child: InkWell( + onTap: () { + showDialog( + context: context, + builder: (context) { + return GarageDialog( + label2: 'Close', + initialSelectedLabel: selectedControlOption, + cancelTab: () { + Navigator.of(context).pop(); + }, + confirmTab: () { + setState(() {}); + if (selectedControlOption == "Open") { + widget.onToggleChanged!(true); + } else if (selectedControlOption == 'Close') { + widget.onToggleChanged!(false); + } + + Navigator.of(context).pop(); + }, + title: 'Control', + label1: 'Open', + onTapLabel1: (selected) { + setState(() { + selectedControlOption = 'Open'; + }); + }, + onTapLabel2: (selected) { + setState(() { + selectedControlOption = 'Close'; + }); + }, + ); + }, + ); + }, + child: ListTile( + contentPadding: EdgeInsets.zero, + leading: const BodyMedium( + text: 'Control', + fontWeight: FontWeight.normal, + ), + trailing: SizedBox( + width: 70, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + BodyMedium( + fontColor: ColorsManager.textGray, + text: selectedControlOption, + fontWeight: FontWeight.normal, + ), + const Icon( + Icons.arrow_forward_ios, + color: ColorsManager.textGray, + size: 17, + ) + ], + ), + )), + ), + ), + ], + ), + ), + ], + ), + ); + } +} diff --git a/lib/features/devices/view/widgets/garage_door/garage_door_screen.dart b/lib/features/devices/view/widgets/garage_door/garage_door_screen.dart new file mode 100644 index 0000000..ae1fe0d --- /dev/null +++ b/lib/features/devices/view/widgets/garage_door/garage_door_screen.dart @@ -0,0 +1,399 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:syncrow_app/features/devices/bloc/garage_door_bloc/garage_door_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/garage_door_bloc/garage_door_event.dart'; +import 'package:syncrow_app/features/devices/bloc/garage_door_bloc/garage_door_state.dart'; +import 'package:syncrow_app/features/devices/model/device_model.dart'; +import 'package:syncrow_app/features/devices/view/widgets/garage_door/garage_preferences_settings.dart'; +import 'package:syncrow_app/features/devices/view/widgets/garage_door/garage_records_screen.dart'; +import 'package:syncrow_app/features/devices/view/widgets/garage_door/schedule_garage_screen.dart'; +import 'package:syncrow_app/features/devices/view/widgets/garage_door/timer_page.dart'; +import 'package:syncrow_app/features/shared_widgets/default_container.dart'; +import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart'; +import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart'; +import 'package:syncrow_app/generated/assets.dart'; + +class GarageDoorScreen extends StatelessWidget { + final DeviceModel? device; + + const GarageDoorScreen({super.key, this.device}); + + @override + Widget build(BuildContext context) { + return DefaultScaffold( + title: 'Garage Door Opener', + child: BlocProvider( + create: (context) => + GarageDoorBloc(GDId: device?.uuid ?? '')..add(const GarageDoorInitial()), + child: BlocBuilder( + builder: (context, state) { + final garageBloc = BlocProvider.of(context); + // GarageDoorModel model = GarageDoorModel( + // tr_timecon: 0, + // countdown1: 0, + // countdownAlarm: 0, + // doorContactState: false, + // doorControl1: '', + // doorState1: '', + // switch1: false, + // voiceControl1: false, + // batteryPercentage: 0, + // ); + + // if (state is LoadingNewSate) { + // model = state.doorSensor; + // } else if (state is UpdateState) { + // model = state.garageSensor; + // } + return state is GarageDoorLoadingState + ? const Center( + child: + DefaultContainer(width: 50, height: 50, child: CircularProgressIndicator()), + ) + : RefreshIndicator( + onRefresh: () async { + garageBloc.add(const GarageDoorInitial()); + }, + child: ListView( + children: [ + SizedBox( + height: MediaQuery.sizeOf(context).height * 0.8, + child: Column( + children: [ + Expanded( + flex: 4, + child: InkWell( + overlayColor: WidgetStateProperty.all(Colors.transparent), + onTap: () {}, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(890), + boxShadow: [ + BoxShadow( + color: Colors.white.withOpacity(0.1), + blurRadius: 24, + offset: const Offset(-5, -5), + blurStyle: BlurStyle.outer, + ), + BoxShadow( + color: Colors.black.withOpacity(0.11), + blurRadius: 25, + offset: const Offset(5, 5), + blurStyle: BlurStyle.outer, + ), + BoxShadow( + color: Colors.black.withOpacity(0.13), + blurRadius: 30, + offset: const Offset(5, 5), + blurStyle: BlurStyle.inner, + ), + ], + ), + child: InkWell( + onTap: () { + garageBloc.add( + ToggleDoorEvent(toggle: garageBloc.toggleDoor)); + }, + child: GradientWidget( + doorStatus: garageBloc.toggleDoor, + seconds: garageBloc.secondSelected, + ), + )), + ], + ), + ), + ), + Flexible( + child: Row( + children: [ + Expanded( + child: DefaultContainer( + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => TimerScheduleScreen( + device: device!, + switchCode: 'switch_1', + deviceCode: 'countdown_1', + )), + ); + }, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + ConstrainedBox( + constraints: + const BoxConstraints(maxHeight: 46, maxWidth: 50), + child: SvgPicture.asset(Assets.garageSchedule), + ), + const SizedBox( + height: 15, + ), + const Flexible( + child: FittedBox( + child: BodySmall( + text: 'Schedule', + textAlign: TextAlign.center, + ), + ), + ), + ], + ), + ), + ), + const SizedBox( + width: 10, + ), + Expanded( + child: DefaultContainer( + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => TimerPage( + device: device!, + switchCode: 'switch_1', + deviceCode: 'countdown_1', + )), + ); + }, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + ConstrainedBox( + constraints: + const BoxConstraints(maxHeight: 46, maxWidth: 50), + child: SvgPicture.asset(Assets.garageCountdown), + ), + const SizedBox( + height: 15, + ), + const Flexible( + child: FittedBox( + child: BodySmall( + text: 'Countdown', + textAlign: TextAlign.center, + ), + ), + ), + ], + ), + ), + ), + ], + ), + ), + const SizedBox( + height: 10, + ), + Flexible( + child: Row( + children: [ + Expanded( + child: DefaultContainer( + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => + GarageRecordsScreen(GDId: device!.uuid!)), + ); + }, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + ConstrainedBox( + constraints: + const BoxConstraints(maxHeight: 46, maxWidth: 50), + child: SvgPicture.asset(Assets.doorRecordsIcon), + ), + const SizedBox( + height: 15, + ), + const Flexible( + child: FittedBox( + child: BodySmall( + text: 'Records', + textAlign: TextAlign.center, + ), + ), + ), + ], + ), + ), + ), + const SizedBox( + width: 10, + ), + Expanded( + child: DefaultContainer( + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => + PreferencesPage(GDId: device!.uuid!)), + ); + }, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + ConstrainedBox( + constraints: + const BoxConstraints(maxHeight: 46, maxWidth: 50), + child: SvgPicture.asset(Assets.garagePreferencesIcon), + ), + const SizedBox( + height: 15, + ), + const Flexible( + child: FittedBox( + child: BodySmall( + text: 'Preferences', + textAlign: TextAlign.center, + ), + ), + ), + ], + ), + ), + ), + ], + ), + ) + ], + ), + ), + ], + ), + ); + }, + ), + ), + ); + } +} + +class GradientWidget extends StatefulWidget { + const GradientWidget({required this.seconds, required this.doorStatus}); + final int seconds; + final bool doorStatus; + + @override + State createState() => _GradientWidgetState(); +} + +class _GradientWidgetState extends State with SingleTickerProviderStateMixin { + late ScrollController _scrollController; + late AnimationController _animationController; + late Animation _itemExtentAnimation; + + @override + void initState() { + super.initState(); + _scrollController = ScrollController(); + _animationController = AnimationController( + vsync: this, + duration: Duration(seconds: widget.seconds), + ); + _itemExtentAnimation = + Tween(begin: widget.doorStatus ? 0 : 15, end: widget.doorStatus ? 15 : 0).animate( + CurvedAnimation( + parent: _animationController, + curve: Curves.easeInOut, + ), + )..addListener(() { + setState(() {}); + }); + + WidgetsBinding.instance.addPostFrameCallback((_) { + if (widget.doorStatus) { + _openAnimation(); + } else { + _closeAnimation(); + } + }); + } + + void _openAnimation() { + _animationController.forward(); + } + + void _closeAnimation() { + _animationController.reverse(); + } + + @override + void dispose() { + _scrollController.dispose(); + _animationController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Container( + width: 300, + height: 300, + padding: EdgeInsets.only(right: 10), + child: Stack( + children: [ + SvgPicture.asset( + Assets.openGarageIcon, + fit: BoxFit.fill, + ), + Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Expanded(child: Container()), + Expanded( + flex: 2, + child: Center( + child: Container( + height: 104, + child: ListView.builder( + itemExtent: _itemExtentAnimation.value, + controller: _scrollController, + itemCount: 4, + itemBuilder: (context, index) { + return Center(child: GradientWidget1()); + }, + ), + ), + ), + ), + ], + ), + ], + ), + ); + } +} + +class GradientWidget1 extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Container( + width: 97, + height: 15, + decoration: const BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [ + Color(0xFF017297), + Color(0xFF024C67), + ], + stops: [0.0, 1.0], + ), + ), + ); + } +} diff --git a/lib/features/devices/view/widgets/garage_door/garage_list.dart b/lib/features/devices/view/widgets/garage_door/garage_list.dart new file mode 100644 index 0000000..b3d3f81 --- /dev/null +++ b/lib/features/devices/view/widgets/garage_door/garage_list.dart @@ -0,0 +1,70 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/garage_door_bloc/garage_door_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/garage_door_bloc/garage_door_event.dart'; +import 'package:syncrow_app/features/devices/bloc/garage_door_bloc/garage_door_state.dart'; +import 'package:syncrow_app/features/devices/model/group_garage_model.dart'; +import 'package:syncrow_app/features/shared_widgets/devices_default_switch.dart'; +import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart'; + +class GarageList extends StatelessWidget { + const GarageList( + {super.key, required this.garageList, required this.allSwitches}); + + final List garageList; + final bool allSwitches; + + @override + Widget build(BuildContext context) { + return BlocBuilder( + builder: (context, state) { + return SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + const SizedBox(height: 10), + const BodySmall(text: 'All Lights'), + const SizedBox(height: 5), + DevicesDefaultSwitch( + switchValue: allSwitches, + action: () { + BlocProvider.of(context) + .add(GroupAllOnEvent()); + }, + secondAction: () { + BlocProvider.of(context) + .add(GroupAllOffEvent()); + }, + ), + ListView.builder( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + padding: const EdgeInsets.all(0), + itemCount: garageList.length, + itemBuilder: (context, index) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 10), + BodySmall(text: garageList[index].deviceName), + const SizedBox(height: 5), + DevicesDefaultSwitch( + switchValue: garageList[index].firstSwitch, + action: () { + BlocProvider.of(context).add( + ChangeFirstWizardSwitchStatusEvent( + value: garageList[index].firstSwitch, + deviceId: garageList[index].deviceId)); + }, + ), + ], + ); + }, + ), + ], + ), + ); + }, + ); + } +} diff --git a/lib/features/devices/view/widgets/garage_door/garage_preferences_settings.dart b/lib/features/devices/view/widgets/garage_door/garage_preferences_settings.dart new file mode 100644 index 0000000..72ea127 --- /dev/null +++ b/lib/features/devices/view/widgets/garage_door/garage_preferences_settings.dart @@ -0,0 +1,328 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/garage_door_bloc/garage_door_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/garage_door_bloc/garage_door_event.dart'; +import 'package:syncrow_app/features/devices/bloc/garage_door_bloc/garage_door_state.dart'; +import 'package:syncrow_app/features/shared_widgets/default_container.dart'; +import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart'; +import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart'; +import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +class PreferencesPage extends StatelessWidget { + final String GDId; + const PreferencesPage({super.key, required this.GDId}); + @override + Widget build(BuildContext context) { + return DefaultScaffold( + title: 'Preferences', + child: BlocProvider( + create: (context) => GarageDoorBloc(GDId: GDId)..add(const GarageDoorInitial()), + child: BlocBuilder( + builder: (context, state) { + final garageDoorBloc = BlocProvider.of(context); + + return state is GarageDoorLoadingState + ? const Center( + child: DefaultContainer( + width: 50, height: 50, child: CircularProgressIndicator()), + ) + : Column( + children: [ + const Row( + children: [ + BodyMedium( + text: 'Warnings', + fontColor: ColorsManager.grayColor, + fontWeight: FontWeight.w700, + ), + ], + ), + DefaultContainer( + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + height: 50, + child: ListTile( + contentPadding: EdgeInsets.zero, + leading: const BodyMedium( + text: 'Alarm when door is open', + fontWeight: FontWeight.normal, + ), + trailing: Container( + width: 100, + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Container( + height: 30, + width: 1, + color: ColorsManager.graysColor, + ), + Transform.scale( + scale: .8, + child: CupertinoSwitch( + value: garageDoorBloc.lowBattery, + onChanged: (value) { + // context + // .read() + // .add( + // ToggleLowBatteryEvent( + // value)); + }, + applyTheme: true, + )), + ], + ), + )), + ), + ], + ), + ), + const SizedBox( + height: 10, + ), + const Row( + children: [ + BodyMedium( + text: 'Other Settings', + fontColor: ColorsManager.grayColor, + fontWeight: FontWeight.w700, + ), + ], + ), + DefaultContainer( + child: InkWell( + onTap: () { + showDialog( + context: context, + builder: (context) { + return SecondDialog( + label2: 'Close', + initialSelectedLabel: garageDoorBloc.secondSelected.toString(), + cancelTab: () { + Navigator.of(context).pop(); + }, + confirmTab: (v) { + garageDoorBloc.add(SelectSecondsEvent(seconds: v)); + Navigator.of(context).pop(); + }, + title: 'Control', + label1: 'Open', + onTapLabel1: (selected) {}, + ); + }, + ); + }, + child: SizedBox( + child: ListTile( + contentPadding: EdgeInsets.zero, + leading: const BodyMedium( + text: 'Opening and Closing Time', + fontWeight: FontWeight.normal, + ), + trailing: Container( + height: 90, + width: 120, + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + BodyMedium( + fontColor: ColorsManager.textGray, + text: + '${garageDoorBloc.secondSelected.toString()} Seconds', + fontWeight: FontWeight.normal, + ), + const Icon( + Icons.arrow_forward_ios, + size: 15, + color: ColorsManager.textGray, + ) + ], + ), + )), + ), + ), + ) + ], + ); + }, + ), + )); + } +} + +class SecondDialog extends StatefulWidget { + final String label1; + final String label2; + final String title; + + final Function(String)? onTapLabel1; + final Function()? cancelTab; + final Function(int selectedSecond)? confirmTab; + + final String? initialSelectedLabel; + + SecondDialog({ + required this.label1, + required this.label2, + required this.title, + this.onTapLabel1, + required this.cancelTab, + required this.confirmTab, + this.initialSelectedLabel, + }); + + @override + _SecondDialogState createState() => _SecondDialogState(); +} + +class _SecondDialogState extends State { + // late String _selectedOption; + late int selectedSecond; + + @override + void initState() { + super.initState(); + // Parse the initialSelectedLabel as an integer. Default to 10 if invalid or not provided. + selectedSecond = int.tryParse(widget.initialSelectedLabel ?? '10') ?? 10; + // _selectedOption = widget.initialSelectedLabel ?? ''; + } + + @override + Widget build(BuildContext context) { + return AlertDialog( + contentPadding: EdgeInsets.zero, + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const SizedBox( + height: 10, + ), + BodyLarge( + text: widget.title, + fontWeight: FontWeight.w700, + fontColor: ColorsManager.primaryColor, + fontSize: 16, + ), + const Padding( + padding: EdgeInsets.only(left: 15, right: 15), + child: Divider( + color: ColorsManager.textGray, + ), + ), + Padding( + padding: const EdgeInsets.only(left: 15, right: 15, bottom: 10), + child: Column( + children: [ + Center( + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Container( + width: 100, + child: CupertinoPicker( + itemExtent: 40.0, + scrollController: FixedExtentScrollController( + // Set the initial position based on selectedSecond + initialItem: selectedSecond - 10, + ), + onSelectedItemChanged: (int index) { + setState(() { + selectedSecond = index + 10; + }); + }, + children: List.generate(111, (int index) { + return Center( + child: BodyLarge( + text: (index + 10).toString().padLeft(2, '0'), + style: const TextStyle( + fontWeight: FontWeight.w400, fontSize: 30, color: Colors.blue), + ), + ); + }), + ), + ), + const Text('Sec'), + ], + ), + ) + ], + ), + ), + Row( + children: [ + Expanded( + child: Container( + decoration: const BoxDecoration( + border: Border( + right: BorderSide( + color: ColorsManager.textGray, + width: 0.5, + ), + top: BorderSide( + color: ColorsManager.textGray, + width: 1.0, + ), + )), + child: SizedBox( + child: InkWell( + onTap: widget.cancelTab, + child: const Padding( + padding: EdgeInsets.all(15), + child: Center( + child: Text( + 'Cancel', + style: TextStyle( + color: ColorsManager.textGray, + fontSize: 14, + fontWeight: FontWeight.w400), + ), + ), + ), + ), + ), + ), + ), + Expanded( + child: Container( + decoration: const BoxDecoration( + border: Border( + left: BorderSide( + color: ColorsManager.textGray, + width: 0.5, + ), + top: BorderSide( + color: ColorsManager.textGray, + width: 1.0, + ), + )), + child: InkWell( + onTap: () { + widget.confirmTab?.call(selectedSecond); + }, + child: const Padding( + padding: EdgeInsets.all(15), + child: Center( + child: Text( + 'Confirm', + style: TextStyle( + color: ColorsManager.primaryColor, + fontSize: 14, + fontWeight: FontWeight.w400), + ), + ), + )), + )) + ], + ) + ], + ), + ); + } +} diff --git a/lib/features/devices/view/widgets/garage_door/garage_records_screen.dart b/lib/features/devices/view/widgets/garage_door/garage_records_screen.dart new file mode 100644 index 0000000..f2389e1 --- /dev/null +++ b/lib/features/devices/view/widgets/garage_door/garage_records_screen.dart @@ -0,0 +1,122 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:intl/intl.dart'; +import 'package:syncrow_app/features/devices/bloc/garage_door_bloc/garage_door_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/garage_door_bloc/garage_door_event.dart'; +import 'package:syncrow_app/features/devices/bloc/garage_door_bloc/garage_door_state.dart'; +import 'package:syncrow_app/features/devices/model/device_report_model.dart'; +import 'package:syncrow_app/features/shared_widgets/default_container.dart'; +import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +class GarageRecordsScreen extends StatelessWidget { + final String GDId; + const GarageRecordsScreen({super.key, required this.GDId}); + + @override + Widget build(BuildContext context) { + return DefaultScaffold( + title: 'Records', + child: BlocProvider( + create: (context) => + GarageDoorBloc(GDId: GDId)..add(const ReportLogsInitial()), + child: BlocBuilder( + builder: (context, state) { + final garageDoorBloc = BlocProvider.of(context); + final Map> groupedRecords = {}; + + if (state is GarageDoorLoadingState) { + return const Center( + child: DefaultContainer( + width: 50, height: 50, child: CircularProgressIndicator()), + ); + } else if (state is UpdateState) { + for (var record in garageDoorBloc.recordGroups.data!) { + final DateTime eventDateTime = + DateTime.fromMillisecondsSinceEpoch(record.eventTime!); + final String formattedDate = + DateFormat('EEEE, dd/MM/yyyy').format(eventDateTime); + + // Group by formatted date + if (groupedRecords.containsKey(formattedDate)) { + groupedRecords[formattedDate]!.add(record); + } else { + groupedRecords[formattedDate] = [record]; + } + } + } + return ListView.builder( + itemCount: groupedRecords.length, + itemBuilder: (context, index) { + final String date = groupedRecords.keys.elementAt(index); + final List recordsForDate = groupedRecords[date]!; + + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(bottom: 5, top: 10), + child: Text( + date, + style: const TextStyle( + color: ColorsManager.grayColor, + fontSize: 13, + fontWeight: FontWeight.w700, + ), + ), + ), + DefaultContainer( + child: Column( + children: [ + ...recordsForDate.asMap().entries.map((entry) { + final int idx = entry.key; + final DeviceEvent record = entry.value; + final DateTime eventDateTime = + DateTime.fromMillisecondsSinceEpoch( + record.eventTime!); + final String formattedTime = + DateFormat('HH:mm:ss').format(eventDateTime); + + return Column( + children: [ + Container( + child: ListTile( + leading: Icon( + record.value == 'true' + ? Icons.radio_button_checked + : Icons.radio_button_unchecked, + color: record.value == 'true' + ? Colors.blue + : Colors.grey, + ), + title: Text( + record.value == 'true' + ? "Opened" + : "Closed", + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 18, + ), + ), + subtitle: Text('$formattedTime'), + ), + ), + if (idx != recordsForDate.length - 1) + const Divider( + color: ColorsManager.graysColor, + ), + ], + ); + }).toList(), + ], + ), + ), + ], + ); + }, + ); + }), + ), + ); + } +} diff --git a/lib/features/devices/view/widgets/garage_door/garage_wizard.dart b/lib/features/devices/view/widgets/garage_door/garage_wizard.dart new file mode 100644 index 0000000..4419139 --- /dev/null +++ b/lib/features/devices/view/widgets/garage_door/garage_wizard.dart @@ -0,0 +1,49 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/garage_door_bloc/garage_door_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/garage_door_bloc/garage_door_event.dart'; +import 'package:syncrow_app/features/devices/bloc/garage_door_bloc/garage_door_state.dart'; +import 'package:syncrow_app/features/devices/model/device_model.dart'; +import 'package:syncrow_app/features/devices/model/group_garage_model.dart'; +import 'package:syncrow_app/features/devices/view/widgets/garage_door/garage_list.dart'; +import 'package:syncrow_app/features/shared_widgets/default_container.dart'; +import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart'; + +class GarageWizard extends StatelessWidget { + const GarageWizard({super.key, this.device}); + + final DeviceModel? device; + + @override + Widget build(BuildContext context) { + List groupGarageModel = []; + + return DefaultScaffold( + title: 'Garage Door Opener', + child: BlocProvider( + create: (context) => GarageDoorBloc(GDId: device?.uuid ?? '') + ..add(InitialWizardEvent()), + child: BlocBuilder( + builder: (context, state) { + bool allSwitchesOn = false; + + if (state is UpdateGroupState) { + groupGarageModel = state.garageList; + allSwitchesOn = state.allSwitches; + } + return state is LoadingInitialState + ? const Center( + child: DefaultContainer( + width: 50, + height: 50, + child: CircularProgressIndicator()), + ) + : GarageList( + garageList: groupGarageModel, + allSwitches: allSwitchesOn, + ); + }, + ), + )); + } +} diff --git a/lib/features/devices/view/widgets/garage_door/garagedialog.dart b/lib/features/devices/view/widgets/garage_door/garagedialog.dart new file mode 100644 index 0000000..d002d0b --- /dev/null +++ b/lib/features/devices/view/widgets/garage_door/garagedialog.dart @@ -0,0 +1,221 @@ +import 'package:flutter/material.dart'; +import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart'; +import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +class GarageDialog extends StatefulWidget { + final String label1; + final String label2; + final String title; + + final Function(String)? onTapLabel1; + final Function(String)? onTapLabel2; + final Function()? cancelTab; + final Function()? confirmTab; + + final String? initialSelectedLabel; + + GarageDialog({ + required this.label1, + required this.label2, + required this.title, + this.onTapLabel1, + this.onTapLabel2, + required this.cancelTab, + required this.confirmTab, + this.initialSelectedLabel, + }); + + @override + _GarageDialogState createState() => _GarageDialogState(); +} + +class _GarageDialogState extends State { + late String _selectedOption; + + @override + void initState() { + super.initState(); + + _selectedOption = widget.initialSelectedLabel ?? ''; + } + + @override + Widget build(BuildContext context) { + return AlertDialog( + contentPadding: EdgeInsets.zero, + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const SizedBox( + height: 10, + ), + BodyLarge( + text: widget.title, + fontWeight: FontWeight.w700, + fontColor: ColorsManager.primaryColor, + fontSize: 16, + ), + const Padding( + padding: EdgeInsets.only(left: 15, right: 15), + child: Divider( + color: ColorsManager.textGray, + ), + ), + Padding( + padding: const EdgeInsets.only(left: 15, right: 15), + child: Column( + children: [ + _buildCheckboxOption( + label: widget.label1, + onTap: widget.onTapLabel1, + ), + _buildCheckboxOption( + label: widget.label2, + onTap: widget.onTapLabel2, + ), + ], + ), + ), + Row( + children: [ + Expanded( + child: Container( + decoration: const BoxDecoration( + border: Border( + right: BorderSide( + color: ColorsManager.textGray, + width: 0.5, + ), + top: BorderSide( + color: ColorsManager.textGray, + width: 1.0, + ), + )), + child: SizedBox( + child: InkWell( + onTap: widget.cancelTab, + child: const Padding( + padding: EdgeInsets.all(15), + child: Center( + child: Text( + 'Cancel', + style: TextStyle( + color: ColorsManager.textGray, + fontSize: 14, + fontWeight: FontWeight.w400), + ), + ), + ), + ), + ), + ), + ), + Expanded( + child: Container( + decoration: const BoxDecoration( + border: Border( + left: BorderSide( + color: ColorsManager.textGray, + width: 0.5, + ), + top: BorderSide( + color: ColorsManager.textGray, + width: 1.0, + ), + )), + child: InkWell( + onTap: widget.confirmTab, + child: const Padding( + padding: EdgeInsets.all(15), + child: Center( + child: Text( + 'Confirm', + style: TextStyle( + color: ColorsManager.primaryColor, + fontSize: 14, + fontWeight: FontWeight.w400), + ), + ), + )), + )) + ], + ) + ], + ), + ); + } + + Widget _buildCheckboxOption( + {required String label, Function(String)? onTap}) { + return Padding( + padding: const EdgeInsets.only(bottom: 10, top: 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + BodyMedium( + text: label, + style: const TextStyle(fontSize: 15, fontWeight: FontWeight.w400), + ), + CircularCheckbox( + value: _selectedOption == label, + onChanged: (bool? value) { + if (value == true) { + setState(() { + _selectedOption = label; + }); + if (onTap != null) { + onTap(label); + } + } + }, + ), + ], + ), + ); + } +} + +class CircularCheckbox extends StatefulWidget { + final bool value; + final ValueChanged onChanged; + + CircularCheckbox({required this.value, required this.onChanged}); + + @override + _CircularCheckboxState createState() => _CircularCheckboxState(); +} + +class _CircularCheckboxState extends State { + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: () { + widget.onChanged(!widget.value); + }, + child: Container( + decoration: BoxDecoration( + shape: BoxShape.circle, + border: Border.all( + color: widget.value + ? ColorsManager.primaryColorWithOpacity.withOpacity(0.01) + : Colors.grey, + width: 2.0, + ), + color: widget.value + ? ColorsManager.primaryColorWithOpacity + : Colors.transparent, + ), + width: 24.0, + height: 24.0, + child: widget.value + ? const Icon( + Icons.check, + color: Colors.white, + size: 16.0, + ) + : null, + ), + ); + } +} diff --git a/lib/features/devices/view/widgets/garage_door/schedule_garage_screen.dart b/lib/features/devices/view/widgets/garage_door/schedule_garage_screen.dart new file mode 100644 index 0000000..1a20804 --- /dev/null +++ b/lib/features/devices/view/widgets/garage_door/schedule_garage_screen.dart @@ -0,0 +1,142 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/garage_door_bloc/garage_door_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/garage_door_bloc/garage_door_event.dart'; +import 'package:syncrow_app/features/devices/bloc/garage_door_bloc/garage_door_state.dart'; +import 'package:syncrow_app/features/devices/model/device_model.dart'; +import 'package:syncrow_app/features/devices/view/widgets/garage_door/create_schedule_garage.dart'; +import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart'; +import 'package:syncrow_app/features/shared_widgets/schedule_list.dart'; +import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; +import 'package:syncrow_app/utils/resource_manager/font_manager.dart'; + +class TimerScheduleScreen extends StatelessWidget { + final DeviceModel device; + final String deviceCode; + final String switchCode; + const TimerScheduleScreen( + {required this.device, required this.deviceCode, required this.switchCode, super.key}); + + @override + Widget build(BuildContext context) { + return AnnotatedRegion( + value: SystemUiOverlayStyle( + statusBarColor: ColorsManager.primaryColor.withOpacity(0.5), + statusBarIconBrightness: Brightness.light, + ), + child: BlocProvider( + create: (context) => GarageDoorBloc(GDId: device.uuid ?? '')..add(GetScheduleEvent()), + child: BlocBuilder( + builder: (context, state) { + final garageBloc = BlocProvider.of(context); + // Duration duration = Duration.zero; + // int countNum = 0; + // if (state is UpdateTimerState) { + // countNum = state.seconds; + // } else if (state is TimerRunInProgress) { + // countNum = state.remainingTime; + // } else if (state is TimerRunComplete) { + // countNum = 0; + // } else if (state is LoadingNewSate) { + // countNum = 0; + // } + return PopScope( + canPop: false, + onPopInvoked: (didPop) { + if (!didPop) { + garageBloc.add(OnClose()); + Navigator.pop(context); + } + }, + child: DefaultTabController( + length: 2, + child: DefaultScaffold( + appBar: AppBar( + backgroundColor: Colors.transparent, + centerTitle: true, + title: const BodyLarge( + text: 'Schedule', + fontColor: ColorsManager.primaryColor, + fontWeight: FontsManager.bold, + ), + actions: [ + garageBloc.createSchedule == true + ? TextButton( + onPressed: () { + garageBloc.add(ScheduleSaveapp()); + }, + child: const Text('Save')) + : IconButton( + onPressed: () { + garageBloc.add(const ToggleCreateScheduleEvent(index: 1)); + }, + icon: const Icon(Icons.add), + ) + ], + ), + child: state is GarageDoorLoading + ? const Center(child: CircularProgressIndicator()) + : Column( + children: [ + Container( + width: MediaQuery.of(context).size.width, + decoration: const ShapeDecoration( + color: ColorsManager.onPrimaryColor, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(30)), + ), + ), + ), + Expanded( + child: SizedBox( + child: garageBloc.createSchedule == true + ? CreateGarageSchedule( + onToggleChanged: (bool value) { + garageBloc.toggleSchedule = value; + }, + onDateTimeChanged: (DateTime dateTime) { + garageBloc.selectedTime = dateTime; + }, + days: garageBloc.days, + selectDays: (List selectedDays) { + garageBloc.selectedDays = selectedDays; + }, + ) + : Padding( + padding: const EdgeInsets.only(top: 10), + child: ScheduleListView( + listSchedule: garageBloc.listSchedule, + onDismissed: (scheduleId) { + garageBloc.listSchedule.removeWhere((schedule) => + schedule.scheduleId == scheduleId); + garageBloc.add(DeleteScheduleEvent(id: scheduleId)); + }, + onToggleSchedule: (scheduleId, isEnabled) { + garageBloc.add(ToggleScheduleEvent( + id: scheduleId, + toggle: isEnabled, + )); + }, + ), + ), + ), + ), + ], + ), + ))); + }, + ), + ), + ); + } + + String _formatDuration(int seconds) { + final hours = (seconds ~/ 3600).toString().padLeft(2, '0'); + final minutes = ((seconds % 3600) ~/ 60).toString().padLeft(2, '0'); + final secs = (seconds % 60).toString().padLeft(2, '0'); + return '$hours:$minutes:$secs'; + } +} diff --git a/lib/features/devices/view/widgets/garage_door/timer_page.dart b/lib/features/devices/view/widgets/garage_door/timer_page.dart new file mode 100644 index 0000000..47c1b37 --- /dev/null +++ b/lib/features/devices/view/widgets/garage_door/timer_page.dart @@ -0,0 +1,148 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:syncrow_app/features/devices/bloc/garage_door_bloc/garage_door_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/garage_door_bloc/garage_door_event.dart'; +import 'package:syncrow_app/features/devices/bloc/garage_door_bloc/garage_door_state.dart'; +import 'package:syncrow_app/features/devices/model/device_model.dart'; +import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart'; +import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart'; +import 'package:syncrow_app/generated/assets.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; +import 'package:syncrow_app/utils/resource_manager/font_manager.dart'; + +class TimerPage extends StatelessWidget { + final DeviceModel device; + final String deviceCode; + final String switchCode; + const TimerPage( + {required this.device, + required this.deviceCode, + required this.switchCode, + super.key}); + + @override + Widget build(BuildContext context) { + return AnnotatedRegion( + value: SystemUiOverlayStyle( + statusBarColor: ColorsManager.primaryColor.withOpacity(0.5), + statusBarIconBrightness: Brightness.light, + ), + child: BlocProvider( + create: (context) => GarageDoorBloc(GDId: device.uuid ?? '') + ..add(GetCounterEvent(deviceCode: deviceCode)), + child: BlocBuilder( + builder: (context, state) { + final oneGangBloc = BlocProvider.of(context); + Duration duration = Duration.zero; + int countNum = 0; + if (state is UpdateTimerState) { + countNum = state.seconds; + } else if (state is TimerRunInProgress) { + countNum = state.remainingTime; + } else if (state is TimerRunComplete) { + countNum = 0; + } else if (state is LoadingNewSate) { + countNum = 0; + } + return PopScope( + canPop: false, + onPopInvoked: (didPop) { + if (!didPop) { + oneGangBloc.add(OnClose()); + Navigator.pop(context); + } + }, + child: DefaultTabController( + length: 2, + child: DefaultScaffold( + appBar: AppBar( + backgroundColor: Colors.transparent, + centerTitle: true, + title: const BodyLarge( + text: 'Countdown', + fontColor: ColorsManager.primaryColor, + fontWeight: FontsManager.bold, + ), + ), + child: state is GarageDoorLoadingState + ? const Center(child: CircularProgressIndicator()) + : Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Container( + width: MediaQuery.of(context).size.width, + decoration: const ShapeDecoration( + color: ColorsManager.onPrimaryColor, + shape: RoundedRectangleBorder( + borderRadius: + BorderRadius.all(Radius.circular(30)), + ), + ), + ), + Center( + child: Container( + child: Column( + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + countNum > 0 + ? BodyLarge( + text: _formatDuration(countNum), + fontColor: ColorsManager + .slidingBlueColor, + fontSize: 40, + ) + : CupertinoTimerPicker( + mode: + CupertinoTimerPickerMode.hm, + onTimerDurationChanged: + (Duration newDuration) { + duration = newDuration; + }, + ), + GestureDetector( + onTap: () { + if (state is LoadingNewSate) { + return; + } + if (countNum > 0) { + oneGangBloc.add( + const SetCounterValue( + deviceCode: + 'countdown_1', + duration: + Duration.zero)); + } else if (duration != + Duration.zero) { + oneGangBloc.add(SetCounterValue( + deviceCode: 'countdown_1', + duration: duration)); + } + }, + child: SvgPicture.asset(countNum > 0 + ? Assets.pauseIcon + : Assets.playIcon)), + ], + ), + ), + ), + ], + ), + ))); + }, + ), + ), + ); + } + + String _formatDuration(int seconds) { + final hours = (seconds ~/ 3600).toString().padLeft(2, '0'); + final minutes = ((seconds % 3600) ~/ 60).toString().padLeft(2, '0'); + final secs = (seconds % 60).toString().padLeft(2, '0'); + return '$hours:$minutes:$secs'; + } +} diff --git a/lib/features/devices/view/widgets/one_touch/one_touch_screen.dart b/lib/features/devices/view/widgets/one_touch/one_touch_screen.dart index 383e7d0..853469c 100644 --- a/lib/features/devices/view/widgets/one_touch/one_touch_screen.dart +++ b/lib/features/devices/view/widgets/one_touch/one_touch_screen.dart @@ -5,7 +5,6 @@ import 'package:syncrow_app/features/devices/bloc/one_touch_bloc/one_touch_bloc. import 'package:syncrow_app/features/devices/bloc/one_touch_bloc/one_touch_event.dart'; import 'package:syncrow_app/features/devices/bloc/one_touch_bloc/one_touch_state.dart'; import 'package:syncrow_app/features/devices/model/device_model.dart'; -import 'package:syncrow_app/features/devices/model/group_one_touch_model.dart'; import 'package:syncrow_app/features/devices/model/one_touch_model.dart'; import 'package:syncrow_app/features/devices/view/widgets/circular_button.dart'; import 'package:syncrow_app/features/devices/view/widgets/device_appbar.dart'; @@ -69,9 +68,9 @@ class OneTouchScreen extends StatelessWidget { bottom: Constants.bottomNavBarHeight, ), child: BlocProvider( - create: (context) => OneTouchBloc( - switchCode: 'switch_1', oneTouchId: device?.uuid ?? '') - ..add(const InitialEvent(groupScreen: false)), + create: (context) => + OneTouchBloc(switchCode: 'switch_1', oneTouchId: device?.uuid ?? '') + ..add(const InitialEvent(groupScreen: false)), child: BlocBuilder( builder: (context, state) { OneTouchModel oneTouchModel = OneTouchModel( @@ -81,30 +80,27 @@ class OneTouchScreen extends StatelessWidget { relay: status.off, relay_status_1: status.off); - List groupOneTouchModel = []; - bool allSwitchesOn = false; + // List groupOneTouchModel = []; + // bool allSwitchesOn = false; if (state is LoadingNewSate) { oneTouchModel = state.oneTouchModel; } else if (state is UpdateState) { oneTouchModel = state.oneTouchModel; - } else if (state is UpdateGroupState) { - groupOneTouchModel = state.oneTouchList; - allSwitchesOn = state.allSwitches; } + // else if (state is UpdateGroupState) { + // groupOneTouchModel = state.oneTouchList; + // allSwitchesOn = state.allSwitches; + // } return state is LoadingInitialState ? const Center( child: DefaultContainer( - width: 50, - height: 50, - child: CircularProgressIndicator()), + width: 50, height: 50, child: CircularProgressIndicator()), ) : RefreshIndicator( onRefresh: () async { - BlocProvider.of(context).add( - InitialEvent( - groupScreen: - device != null ? false : true)); + BlocProvider.of(context) + .add(InitialEvent(groupScreen: device != null ? false : true)); }, child: ListView( children: [ @@ -112,30 +108,23 @@ class OneTouchScreen extends StatelessWidget { height: MediaQuery.of(context).size.height, child: Column( mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: - CrossAxisAlignment.stretch, + crossAxisAlignment: CrossAxisAlignment.stretch, children: [ const Expanded(child: SizedBox.shrink()), Expanded( child: Row( - mainAxisAlignment: - MainAxisAlignment.spaceAround, - crossAxisAlignment: - CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceAround, + crossAxisAlignment: CrossAxisAlignment.center, children: [ Column( children: [ GangSwitch( threeGangSwitch: device!, - value: - oneTouchModel.firstSwitch, + value: oneTouchModel.firstSwitch, action: () { - BlocProvider.of< - OneTouchBloc>( - context) - .add(ChangeFirstSwitchStatusEvent( - value: oneTouchModel - .firstSwitch)); + BlocProvider.of(context).add( + ChangeFirstSwitchStatusEvent( + value: oneTouchModel.firstSwitch)); }, ), const SizedBox(height: 20), @@ -143,8 +132,7 @@ class OneTouchScreen extends StatelessWidget { width: 70, child: BodySmall( text: " Entrance Light", - fontColor: ColorsManager - .textPrimaryColor, + fontColor: ColorsManager.textPrimaryColor, textAlign: TextAlign.center, ), ), @@ -155,10 +143,8 @@ class OneTouchScreen extends StatelessWidget { ), Center( child: Row( - mainAxisAlignment: - MainAxisAlignment.center, - crossAxisAlignment: - CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, children: [ CircularButton( device: device, @@ -168,16 +154,13 @@ class OneTouchScreen extends StatelessWidget { Navigator.push( context, PageRouteBuilder( - pageBuilder: (context, - animation1, - animation2) => - TimerScheduleScreen( - switchCode: - 'switch_1', - device: device!, - deviceCode: - 'countdown_1', - ))); + pageBuilder: + (context, animation1, animation2) => + TimerScheduleScreen( + switchCode: 'switch_1', + device: device!, + deviceCode: 'countdown_1', + ))); }, ), const SizedBox( @@ -191,12 +174,11 @@ class OneTouchScreen extends StatelessWidget { Navigator.push( context, PageRouteBuilder( - pageBuilder: (context, - animation1, - animation2) => - OneTouchSetting( - device: device, - ))); + pageBuilder: + (context, animation1, animation2) => + OneTouchSetting( + device: device, + ))); }, ), ], diff --git a/lib/features/devices/view/widgets/one_touch/one_touch_setting.dart b/lib/features/devices/view/widgets/one_touch/one_touch_setting.dart index 52be48f..38eda41 100644 --- a/lib/features/devices/view/widgets/one_touch/one_touch_setting.dart +++ b/lib/features/devices/view/widgets/one_touch/one_touch_setting.dart @@ -142,8 +142,7 @@ class OneTouchSetting extends StatelessWidget { bottom: 10, top: 10), child: InkWell( onTap: () async { - oneTouchBloc.optionSelected = - 'light_mode'; + oneTouchBloc.optionSelected = 'light_mode'; final result = await showDialog( context: context, builder: (context) { diff --git a/lib/features/devices/view/widgets/room_page_switch.dart b/lib/features/devices/view/widgets/room_page_switch.dart index 851aabf..3eb0d6c 100644 --- a/lib/features/devices/view/widgets/room_page_switch.dart +++ b/lib/features/devices/view/widgets/room_page_switch.dart @@ -10,6 +10,7 @@ import 'package:syncrow_app/features/devices/model/device_model.dart'; import 'package:syncrow_app/features/devices/view/widgets/ACs/acs_view.dart'; import 'package:syncrow_app/features/devices/view/widgets/curtains/curtain_view.dart'; import 'package:syncrow_app/features/devices/view/widgets/door_sensor/door_sensor_screen.dart'; +import 'package:syncrow_app/features/devices/view/widgets/garage_door/garage_door_screen.dart'; import 'package:syncrow_app/features/devices/view/widgets/gateway/gateway_view.dart'; import 'package:syncrow_app/features/devices/view/widgets/lights/light_interface.dart'; import 'package:syncrow_app/features/devices/view/widgets/one_gang/one_gang_Interface.dart'; @@ -187,6 +188,14 @@ void showDeviceInterface(DeviceModel device, BuildContext context) { PageRouteBuilder( pageBuilder: (context, animation1, animation2) => ThreeTouchInterface(touchSwitch: device))); + + case DeviceType.GarageDoor: + Navigator.push( + context, + PageRouteBuilder( + pageBuilder: (context, animation1, animation2) => + GarageDoorScreen(device: device))); + break; default: } diff --git a/lib/features/devices/view/widgets/three_touch/three_touch_setting.dart b/lib/features/devices/view/widgets/three_touch/three_touch_setting.dart index 21ef6b3..f61d0d9 100644 --- a/lib/features/devices/view/widgets/three_touch/three_touch_setting.dart +++ b/lib/features/devices/view/widgets/three_touch/three_touch_setting.dart @@ -4,7 +4,6 @@ import 'package:syncrow_app/features/devices/bloc/three_touch_bloc/three_touch_b import 'package:syncrow_app/features/devices/bloc/three_touch_bloc/three_touch_event.dart'; import 'package:syncrow_app/features/devices/bloc/three_touch_bloc/three_touch_state.dart'; import 'package:syncrow_app/features/devices/model/device_model.dart'; -import 'package:syncrow_app/features/devices/model/three_touch_model.dart'; import 'package:syncrow_app/features/devices/view/widgets/restart_status_dialog.dart'; import 'package:syncrow_app/features/shared_widgets/default_container.dart'; import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart'; @@ -23,41 +22,15 @@ class ThreeTouchSetting extends StatelessWidget { return DefaultScaffold( title: 'Setting', child: BlocProvider( - create: (context) => - ThreeTouchBloc(switchCode: '', threeTouchId: device?.uuid ?? '') - ..add(InitialEvent(groupScreen: false)), + create: (context) => ThreeTouchBloc(switchCode: '', threeTouchId: device?.uuid ?? '') + ..add(InitialEvent(groupScreen: false)), child: BlocBuilder( builder: (context, state) { final threeTouchBloc = BlocProvider.of(context); - ThreeTouchModel deviceStatus = ThreeTouchModel( - firstSwitch: false, - secondSwitch: false, - thirdSwitch: false, - firstCountDown: 0, - secondCountDown: 0, - thirdCountDown: 0, - light_mode: lightStatus.off, - relay: status.off, - relay_status_1: status.off, - relay_status_2: status.off, - relay_status_3: status.off, - ); - if (state is LoadingNewSate) { - deviceStatus = state.threeTouchModel; - } else if (state is UpdateState) { - deviceStatus = state.threeTouchModel; - } - // if (state is ChangeStateSetting) { - // // Navigator.of(context).pop(true); - // threeTouchBloc - // .add(InitialSettingDevises(id: device?.uuid ?? '')); - // } return state is LoadingInitialState ? const Center( child: DefaultContainer( - width: 50, - height: 50, - child: CircularProgressIndicator()), + width: 50, height: 50, child: CircularProgressIndicator()), ) : Column( children: [ @@ -70,22 +43,19 @@ class ThreeTouchSetting extends StatelessWidget { children: [ InkWell( onTap: () async { - threeTouchBloc.optionSelected = - 'relay_status'; + threeTouchBloc.optionSelected = 'relay_status'; final result = await showDialog( context: context, builder: (context) { return RestartStatusDialog( - initialSelectedLabel: threeTouchBloc - .deviceStatus.relay.value, + initialSelectedLabel: + threeTouchBloc.deviceStatus.relay.value, cancelTab: () { Navigator.of(context).pop(); }, confirmTab: () { - threeTouchBloc.add( - ChangeStatusEvent( - deviceId: device!.uuid!, - context: context)); + threeTouchBloc.add(ChangeStatusEvent( + deviceId: device!.uuid!, context: context)); Navigator.of(context).pop(true); }, title: 'Restart Status', @@ -93,34 +63,27 @@ class ThreeTouchSetting extends StatelessWidget { label2: 'Power On', label3: 'Restart Memory', onTapLabel1: (selected) { - threeTouchBloc.statusSelected = - selected; + threeTouchBloc.statusSelected = selected; }, onTapLabel2: (selected) { - threeTouchBloc.statusSelected = - selected; + threeTouchBloc.statusSelected = selected; }, onTapLabel3: (selected) { - threeTouchBloc.statusSelected = - selected; + threeTouchBloc.statusSelected = selected; }, ); }, ); if (result == true) { - Future.delayed(const Duration(seconds: 2), - () async { - threeTouchBloc.add( - InitialEvent(groupScreen: false)); + Future.delayed(const Duration(seconds: 2), () async { + threeTouchBloc.add(InitialEvent(groupScreen: false)); }); } }, child: Container( - padding: const EdgeInsets.only( - bottom: 10, top: 10), + padding: const EdgeInsets.only(bottom: 10, top: 10), child: Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ const BodyLarge( fontSize: 15, @@ -131,10 +94,8 @@ class ThreeTouchSetting extends StatelessWidget { children: [ BodyMedium( fontSize: 13, - text: threeTouchBloc - .deviceStatus.relay.value, - fontColor: - ColorsManager.textGray, + text: threeTouchBloc.deviceStatus.relay.value, + fontColor: ColorsManager.textGray, ), const Icon( Icons.keyboard_arrow_right, @@ -149,26 +110,22 @@ class ThreeTouchSetting extends StatelessWidget { color: ColorsManager.graysColor, ), Padding( - padding: const EdgeInsets.only( - bottom: 10, top: 10), + padding: const EdgeInsets.only(bottom: 10, top: 10), child: InkWell( onTap: () async { - threeTouchBloc.optionSelected = - 'light_mode'; + threeTouchBloc.optionSelected = 'light_mode'; final result = await showDialog( context: context, builder: (context) { return RestartStatusDialog( - initialSelectedLabel: threeTouchBloc - .deviceStatus.light_mode.value, + initialSelectedLabel: + threeTouchBloc.deviceStatus.light_mode.value, cancelTab: () { Navigator.of(context).pop(); }, confirmTab: () { - threeTouchBloc.add( - ChangeStatusEvent( - deviceId: device!.uuid!, - context: context)); + threeTouchBloc.add(ChangeStatusEvent( + deviceId: device!.uuid!, context: context)); Navigator.of(context).pop(true); }, title: 'Indicator Status', @@ -176,33 +133,26 @@ class ThreeTouchSetting extends StatelessWidget { label2: 'On/Off Status', label3: 'Switch Position', onTapLabel1: (selected) { - threeTouchBloc.statusSelected = - selected; + threeTouchBloc.statusSelected = selected; }, onTapLabel2: (selected) { - threeTouchBloc.statusSelected = - selected; + threeTouchBloc.statusSelected = selected; }, onTapLabel3: (selected) { - threeTouchBloc.statusSelected = - selected; + threeTouchBloc.statusSelected = selected; }, ); }, ); if (result == true) { - Future.delayed( - const Duration(seconds: 2), - () async { - threeTouchBloc.add( - InitialEvent(groupScreen: false)); + Future.delayed(const Duration(seconds: 2), () async { + threeTouchBloc.add(InitialEvent(groupScreen: false)); }); } }, child: SizedBox( child: Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ const BodyLarge( fontSize: 15, @@ -213,8 +163,7 @@ class ThreeTouchSetting extends StatelessWidget { children: [ BodyMedium( fontSize: 13, - text: threeTouchBloc.deviceStatus - .light_mode.value, + text: threeTouchBloc.deviceStatus.light_mode.value, fontColor: ColorsManager.textGray, ), const Icon( @@ -231,27 +180,22 @@ class ThreeTouchSetting extends StatelessWidget { color: ColorsManager.graysColor, ), Container( - padding: const EdgeInsets.only( - bottom: 10, top: 10), + padding: const EdgeInsets.only(bottom: 10, top: 10), child: InkWell( onTap: () async { - threeTouchBloc.optionSelected = - 'relay_status_1'; + threeTouchBloc.optionSelected = 'relay_status_1'; final result = await showDialog( context: context, builder: (context) { return RestartStatusDialog( initialSelectedLabel: - threeTouchBloc.deviceStatus - .relay_status_1.value, + threeTouchBloc.deviceStatus.relay_status_1.value, cancelTab: () { Navigator.of(context).pop(); }, confirmTab: () { - threeTouchBloc.add( - ChangeStatusEvent( - deviceId: device!.uuid!, - context: context)); + threeTouchBloc.add(ChangeStatusEvent( + deviceId: device!.uuid!, context: context)); Navigator.of(context).pop(true); }, title: 'Restart Status 1', @@ -259,33 +203,26 @@ class ThreeTouchSetting extends StatelessWidget { label2: 'Power On', label3: 'Restart Memory', onTapLabel1: (selected) { - threeTouchBloc.statusSelected = - selected; + threeTouchBloc.statusSelected = selected; }, onTapLabel2: (selected) { - threeTouchBloc.statusSelected = - selected; + threeTouchBloc.statusSelected = selected; }, onTapLabel3: (selected) { - threeTouchBloc.statusSelected = - selected; + threeTouchBloc.statusSelected = selected; }, ); }, ); if (result == true) { - Future.delayed( - const Duration(seconds: 2), - () async { - threeTouchBloc.add( - const InitialEvent( - groupScreen: false)); + Future.delayed(const Duration(seconds: 2), () async { + threeTouchBloc + .add(const InitialEvent(groupScreen: false)); }); } }, child: Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ const BodyLarge( fontSize: 15, @@ -297,11 +234,8 @@ class ThreeTouchSetting extends StatelessWidget { BodyMedium( fontSize: 13, text: threeTouchBloc - .deviceStatus - .relay_status_1 - .value, - fontColor: - ColorsManager.textGray, + .deviceStatus.relay_status_1.value, + fontColor: ColorsManager.textGray, ), const Icon( Icons.keyboard_arrow_right, @@ -316,27 +250,22 @@ class ThreeTouchSetting extends StatelessWidget { color: ColorsManager.graysColor, ), Container( - padding: const EdgeInsets.only( - bottom: 10, top: 10), + padding: const EdgeInsets.only(bottom: 10, top: 10), child: InkWell( onTap: () async { - threeTouchBloc.optionSelected = - 'relay_status_2'; + threeTouchBloc.optionSelected = 'relay_status_2'; final result = await showDialog( context: context, builder: (context) { return RestartStatusDialog( initialSelectedLabel: - threeTouchBloc.deviceStatus - .relay_status_2.value, + threeTouchBloc.deviceStatus.relay_status_2.value, cancelTab: () { Navigator.of(context).pop(); }, confirmTab: () { - threeTouchBloc.add( - ChangeStatusEvent( - deviceId: device!.uuid!, - context: context)); + threeTouchBloc.add(ChangeStatusEvent( + deviceId: device!.uuid!, context: context)); Navigator.of(context).pop(true); }, title: 'Restart Status 2', @@ -344,36 +273,28 @@ class ThreeTouchSetting extends StatelessWidget { label2: 'Power On', label3: 'Restart Memory', onTapLabel1: (selected) { - threeTouchBloc.statusSelected = - selected; + threeTouchBloc.statusSelected = selected; }, onTapLabel2: (selected) { - threeTouchBloc.statusSelected = - selected; + threeTouchBloc.statusSelected = selected; }, onTapLabel3: (selected) { - threeTouchBloc.statusSelected = - selected; + threeTouchBloc.statusSelected = selected; }, ); }, ); if (result == true) { - Future.delayed( - const Duration(seconds: 2), - () async { - threeTouchBloc.add( - const InitialEvent( - groupScreen: false)); - threeTouchBloc.add( - const InitialEvent( - groupScreen: false)); + Future.delayed(const Duration(seconds: 2), () async { + threeTouchBloc + .add(const InitialEvent(groupScreen: false)); + threeTouchBloc + .add(const InitialEvent(groupScreen: false)); }); } }, child: Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ const BodyLarge( fontSize: 15, @@ -385,11 +306,8 @@ class ThreeTouchSetting extends StatelessWidget { BodyMedium( fontSize: 13, text: threeTouchBloc - .deviceStatus - .relay_status_2 - .value, - fontColor: - ColorsManager.textGray, + .deviceStatus.relay_status_2.value, + fontColor: ColorsManager.textGray, ), const Icon( Icons.keyboard_arrow_right, @@ -404,27 +322,22 @@ class ThreeTouchSetting extends StatelessWidget { color: ColorsManager.graysColor, ), Container( - padding: const EdgeInsets.only( - bottom: 10, top: 10), + padding: const EdgeInsets.only(bottom: 10, top: 10), child: InkWell( onTap: () async { - threeTouchBloc.optionSelected = - 'relay_status_3'; + threeTouchBloc.optionSelected = 'relay_status_3'; final result = await showDialog( context: context, builder: (context) { return RestartStatusDialog( initialSelectedLabel: - threeTouchBloc.deviceStatus - .relay_status_3.value, + threeTouchBloc.deviceStatus.relay_status_3.value, cancelTab: () { Navigator.of(context).pop(); }, confirmTab: () { - threeTouchBloc.add( - ChangeStatusEvent( - deviceId: device!.uuid!, - context: context)); + threeTouchBloc.add(ChangeStatusEvent( + deviceId: device!.uuid!, context: context)); Navigator.of(context).pop(true); }, title: 'Restart Status 3', @@ -432,36 +345,28 @@ class ThreeTouchSetting extends StatelessWidget { label2: 'Power On', label3: 'Restart Memory', onTapLabel1: (selected) { - threeTouchBloc.statusSelected = - selected; + threeTouchBloc.statusSelected = selected; }, onTapLabel2: (selected) { - threeTouchBloc.statusSelected = - selected; + threeTouchBloc.statusSelected = selected; }, onTapLabel3: (selected) { - threeTouchBloc.statusSelected = - selected; + threeTouchBloc.statusSelected = selected; }, ); }, ); if (result == true) { - Future.delayed( - const Duration(seconds: 2), - () async { - threeTouchBloc.add( - const InitialEvent( - groupScreen: false)); - threeTouchBloc.add( - const InitialEvent( - groupScreen: false)); + Future.delayed(const Duration(seconds: 2), () async { + threeTouchBloc + .add(const InitialEvent(groupScreen: false)); + threeTouchBloc + .add(const InitialEvent(groupScreen: false)); }); } }, child: Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ const BodyLarge( fontSize: 15, @@ -473,11 +378,8 @@ class ThreeTouchSetting extends StatelessWidget { BodyMedium( fontSize: 13, text: threeTouchBloc - .deviceStatus - .relay_status_3 - .value, - fontColor: - ColorsManager.textGray, + .deviceStatus.relay_status_3.value, + fontColor: ColorsManager.textGray, ), const Icon( Icons.keyboard_arrow_right, diff --git a/lib/features/devices/view/widgets/water_heater/wh_wizard.dart b/lib/features/devices/view/widgets/water_heater/wh_wizard.dart index c27fd55..c8ce572 100644 --- a/lib/features/devices/view/widgets/water_heater/wh_wizard.dart +++ b/lib/features/devices/view/widgets/water_heater/wh_wizard.dart @@ -19,28 +19,29 @@ class WHWizard extends StatelessWidget { List groupModel = []; return DefaultScaffold( + title: 'Water Heater', child: BlocProvider( - create: (context) => - WaterHeaterBloc(switchCode: '', whId: device?.uuid ?? '')..add(InitialWizardEvent()), - child: BlocBuilder( - builder: (context, state) { - bool allSwitchesOn = false; + create: (context) => + WaterHeaterBloc(switchCode: '', whId: device?.uuid ?? '')..add(InitialWizardEvent()), + child: BlocBuilder( + builder: (context, state) { + bool allSwitchesOn = false; - if (state is UpdateGroupState) { - groupModel = state.twoGangList; - allSwitchesOn = state.allSwitches; - } - return state is WHLoadingState - ? const Center( - child: - DefaultContainer(width: 50, height: 50, child: CircularProgressIndicator()), - ) - : WHList( - whList: groupModel, - allSwitches: allSwitchesOn, - ); - }, - ), - )); + if (state is UpdateGroupState) { + groupModel = state.twoGangList; + allSwitchesOn = state.allSwitches; + } + return state is WHLoadingState + ? const Center( + child: DefaultContainer( + width: 50, height: 50, child: CircularProgressIndicator()), + ) + : WHList( + whList: groupModel, + allSwitches: allSwitchesOn, + ); + }, + ), + )); } } diff --git a/lib/features/devices/view/widgets/wizard_page.dart b/lib/features/devices/view/widgets/wizard_page.dart index d617bad..3b62d1c 100644 --- a/lib/features/devices/view/widgets/wizard_page.dart +++ b/lib/features/devices/view/widgets/wizard_page.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; import 'package:syncrow_app/features/devices/model/device_category_model.dart'; import 'package:syncrow_app/features/devices/view/widgets/ACs/acs_view.dart'; +import 'package:syncrow_app/features/devices/view/widgets/garage_door/garage_wizard.dart'; import 'package:syncrow_app/features/devices/view/widgets/one_gang/one_gang_wizard.dart'; import 'package:syncrow_app/features/devices/view/widgets/one_touch/one_touch_wizard.dart'; import 'package:syncrow_app/features/devices/view/widgets/three_gang/three_gang_wizard.dart'; @@ -91,6 +92,14 @@ class WizardPage extends StatelessWidget { pageBuilder: (context, animation1, animation2) => const ThreeTouchWizard())); } + + if (groupsList[index].name == 'GD') { + Navigator.push( + context, + PageRouteBuilder( + pageBuilder: (context, animation1, animation2) => + const GarageWizard())); + } }, child: DefaultContainer( padding: const EdgeInsets.all(15), diff --git a/lib/features/menu/view/menu_view.dart b/lib/features/menu/view/menu_view.dart index bba2896..aa1ae86 100644 --- a/lib/features/menu/view/menu_view.dart +++ b/lib/features/menu/view/menu_view.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:syncrow_app/features/auth/bloc/auth_cubit.dart'; import 'package:syncrow_app/features/menu/bloc/menu_cubit.dart'; import 'package:syncrow_app/features/menu/view/widgets/menu_list.dart'; @@ -7,7 +8,6 @@ import 'package:syncrow_app/features/menu/view/widgets/profile/profile_tab.dart' import 'package:syncrow_app/features/shared_widgets/default_container.dart'; import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart'; import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart'; -import 'package:syncrow_app/services/locator.dart'; import 'package:syncrow_app/utils/context_extension.dart'; import 'package:syncrow_app/utils/resource_manager/constants.dart'; @@ -34,7 +34,7 @@ class MenuView extends StatelessWidget { const SizedBox( height: 15, ), - BodyMedium(text: serviceLocator.get()), + BodyMedium(text: dotenv.env['ENV_NAME'] ?? ''), const SizedBox( height: 15, ), diff --git a/lib/features/shared_widgets/create_schedule.dart b/lib/features/shared_widgets/create_schedule.dart index c8b298a..310b97d 100644 --- a/lib/features/shared_widgets/create_schedule.dart +++ b/lib/features/shared_widgets/create_schedule.dart @@ -137,3 +137,5 @@ class _CreateScheduleState extends State { ); } } + + diff --git a/lib/generated/assets.dart b/lib/generated/assets.dart index 2699f62..68575b6 100644 --- a/lib/generated/assets.dart +++ b/lib/generated/assets.dart @@ -3,8 +3,7 @@ class Assets { /// Assets for assetsFontsAftikaRegular /// assets/fonts/AftikaRegular.ttf - static const String assetsFontsAftikaRegular = - "assets/fonts/AftikaRegular.ttf"; + static const String assetsFontsAftikaRegular = "assets/fonts/AftikaRegular.ttf"; /// Assets for assetsIcons3GangSwitch /// assets/icons/3GangSwitch.svg @@ -20,98 +19,82 @@ class Assets { /// Assets for assetsIconsAutomatedClock /// assets/icons/automated_clock.svg - static const String assetsIconsAutomatedClock = - "assets/icons/automated_clock.svg"; + static const String assetsIconsAutomatedClock = "assets/icons/automated_clock.svg"; static const String acSwitchIcon = "assets/icons/ac_switch_ic.svg"; /// Assets for assetsIconsBatteryDmOffPerOffchargOfflowOffpmOffstChargeddmOff /// assets/icons/battery/dmOff/perOffchargOfflowOffpmOffstChargeddmOff.svg - static const String - assetsIconsBatteryDmOffPerOffchargOfflowOffpmOffstChargeddmOff = + static const String assetsIconsBatteryDmOffPerOffchargOfflowOffpmOffstChargeddmOff = "assets/icons/battery/dmOff/perOffchargOfflowOffpmOffstChargeddmOff.svg"; /// Assets for assetsIconsBatteryDmOffPerOffchargOfflowOffpmOffstDefaultdmOff /// assets/icons/battery/dmOff/perOffchargOfflowOffpmOffstDefaultdmOff.svg - static const String - assetsIconsBatteryDmOffPerOffchargOfflowOffpmOffstDefaultdmOff = + static const String assetsIconsBatteryDmOffPerOffchargOfflowOffpmOffstDefaultdmOff = "assets/icons/battery/dmOff/perOffchargOfflowOffpmOffstDefaultdmOff.svg"; /// Assets for assetsIconsBatteryDmOffPerOffchargOfflowOffpmOnstChargeddmOff /// assets/icons/battery/dmOff/perOffchargOfflowOffpmOnstChargeddmOff.svg - static const String - assetsIconsBatteryDmOffPerOffchargOfflowOffpmOnstChargeddmOff = + static const String assetsIconsBatteryDmOffPerOffchargOfflowOffpmOnstChargeddmOff = "assets/icons/battery/dmOff/perOffchargOfflowOffpmOnstChargeddmOff.svg"; /// Assets for assetsIconsBatteryDmOffPerOffchargOfflowOnpmOffstDefaultdmOff /// assets/icons/battery/dmOff/perOffchargOfflowOnpmOffstDefaultdmOff.svg - static const String - assetsIconsBatteryDmOffPerOffchargOfflowOnpmOffstDefaultdmOff = + static const String assetsIconsBatteryDmOffPerOffchargOfflowOnpmOffstDefaultdmOff = "assets/icons/battery/dmOff/perOffchargOfflowOnpmOffstDefaultdmOff.svg"; /// Assets for assetsIconsBatteryDmOffPerOffchargOfflowOnpmOnstDefaultdmOff /// assets/icons/battery/dmOff/perOffchargOfflowOnpmOnstDefaultdmOff.svg - static const String - assetsIconsBatteryDmOffPerOffchargOfflowOnpmOnstDefaultdmOff = + static const String assetsIconsBatteryDmOffPerOffchargOfflowOnpmOnstDefaultdmOff = "assets/icons/battery/dmOff/perOffchargOfflowOnpmOnstDefaultdmOff.svg"; /// Assets for assetsIconsBatteryDmOffPerOffchargOnlowOffpmOffstChargeddmOff /// assets/icons/battery/dmOff/perOffchargOnlowOffpmOffstChargeddmOff.svg - static const String - assetsIconsBatteryDmOffPerOffchargOnlowOffpmOffstChargeddmOff = + static const String assetsIconsBatteryDmOffPerOffchargOnlowOffpmOffstChargeddmOff = "assets/icons/battery/dmOff/perOffchargOnlowOffpmOffstChargeddmOff.svg"; /// Assets for assetsIconsBatteryDmOffPerOffchargOnlowOnpmOffstlowBatterydmOff /// assets/icons/battery/dmOff/perOffchargOnlowOnpmOffstlowBatterydmOff.svg - static const String - assetsIconsBatteryDmOffPerOffchargOnlowOnpmOffstlowBatterydmOff = + static const String assetsIconsBatteryDmOffPerOffchargOnlowOnpmOffstlowBatterydmOff = "assets/icons/battery/dmOff/perOffchargOnlowOnpmOffstlowBatterydmOff.svg"; /// Assets for assetsIconsBatteryDmOffPerOffchargOnlowOnpmOnstlowpmdmOff /// assets/icons/battery/dmOff/perOffchargOnlowOnpmOnstlowpmdmOff.svg - static const String - assetsIconsBatteryDmOffPerOffchargOnlowOnpmOnstlowpmdmOff = + static const String assetsIconsBatteryDmOffPerOffchargOnlowOnpmOnstlowpmdmOff = "assets/icons/battery/dmOff/perOffchargOnlowOnpmOnstlowpmdmOff.svg"; /// Assets for assetsIconsBatteryDmOffPerOnchargOfflowOffpmOffstChargeddmOff /// assets/icons/battery/dmOff/perOnchargOfflowOffpmOffstChargeddmOff.svg - static const String - assetsIconsBatteryDmOffPerOnchargOfflowOffpmOffstChargeddmOff = + static const String assetsIconsBatteryDmOffPerOnchargOfflowOffpmOffstChargeddmOff = "assets/icons/battery/dmOff/perOnchargOfflowOffpmOffstChargeddmOff.svg"; /// Assets for assetsIconsBatteryDmOffPerOnchargOfflowOffpmOffstDefaultdmOff /// assets/icons/battery/dmOff/perOnchargOfflowOffpmOffstDefaultdmOff.svg - static const String - assetsIconsBatteryDmOffPerOnchargOfflowOffpmOffstDefaultdmOff = + static const String assetsIconsBatteryDmOffPerOnchargOfflowOffpmOffstDefaultdmOff = "assets/icons/battery/dmOff/perOnchargOfflowOffpmOffstDefaultdmOff.svg"; /// Assets for assetsIconsBatteryDmOffPerOnchargOfflowOffpmOnstChargeddmOff /// assets/icons/battery/dmOff/perOnchargOfflowOffpmOnstChargeddmOff.svg - static const String - assetsIconsBatteryDmOffPerOnchargOfflowOffpmOnstChargeddmOff = + static const String assetsIconsBatteryDmOffPerOnchargOfflowOffpmOnstChargeddmOff = "assets/icons/battery/dmOff/perOnchargOfflowOffpmOnstChargeddmOff.svg"; /// Assets for assetsIconsBatteryDmOffPerOnchargOfflowOnpmOffstDefaultdmOff /// assets/icons/battery/dmOff/perOnchargOfflowOnpmOffstDefaultdmOff.svg - static const String - assetsIconsBatteryDmOffPerOnchargOfflowOnpmOffstDefaultdmOff = + static const String assetsIconsBatteryDmOffPerOnchargOfflowOnpmOffstDefaultdmOff = "assets/icons/battery/dmOff/perOnchargOfflowOnpmOffstDefaultdmOff.svg"; /// Assets for assetsIconsBatteryDmOffPerOnchargOfflowOnpmOnstDefaultdmOff /// assets/icons/battery/dmOff/perOnchargOfflowOnpmOnstDefaultdmOff.svg - static const String - assetsIconsBatteryDmOffPerOnchargOfflowOnpmOnstDefaultdmOff = + static const String assetsIconsBatteryDmOffPerOnchargOfflowOnpmOnstDefaultdmOff = "assets/icons/battery/dmOff/perOnchargOfflowOnpmOnstDefaultdmOff.svg"; /// Assets for assetsIconsBatteryDmOffPerOnchargOnlowOffpmOffstChargeddmOff /// assets/icons/battery/dmOff/perOnchargOnlowOffpmOffstChargeddmOff.svg - static const String - assetsIconsBatteryDmOffPerOnchargOnlowOffpmOffstChargeddmOff = + static const String assetsIconsBatteryDmOffPerOnchargOnlowOffpmOffstChargeddmOff = "assets/icons/battery/dmOff/perOnchargOnlowOffpmOffstChargeddmOff.svg"; /// Assets for assetsIconsBatteryDmOffPerOnchargOnlowOnpmOffstlowBatterydmOff /// assets/icons/battery/dmOff/perOnchargOnlowOnpmOffstlowBatterydmOff.svg - static const String - assetsIconsBatteryDmOffPerOnchargOnlowOnpmOffstlowBatterydmOff = + static const String assetsIconsBatteryDmOffPerOnchargOnlowOnpmOffstlowBatterydmOff = "assets/icons/battery/dmOff/perOnchargOnlowOnpmOffstlowBatterydmOff.svg"; /// Assets for assetsIconsBatteryDmOffPerOnchargOnlowOnpmOnstlowpmdmOff @@ -121,44 +104,37 @@ class Assets { /// Assets for assetsIconsBatteryDmOnPerOffchargOfflowOffpmOffstChargeddmOn /// assets/icons/battery/dmOn/perOffchargOfflowOffpmOffstChargeddmOn.svg - static const String - assetsIconsBatteryDmOnPerOffchargOfflowOffpmOffstChargeddmOn = + static const String assetsIconsBatteryDmOnPerOffchargOfflowOffpmOffstChargeddmOn = "assets/icons/battery/dmOn/perOffchargOfflowOffpmOffstChargeddmOn.svg"; /// Assets for assetsIconsBatteryDmOnPerOffchargOfflowOffpmOffstDefaultdmOn /// assets/icons/battery/dmOn/perOffchargOfflowOffpmOffstDefaultdmOn.svg - static const String - assetsIconsBatteryDmOnPerOffchargOfflowOffpmOffstDefaultdmOn = + static const String assetsIconsBatteryDmOnPerOffchargOfflowOffpmOffstDefaultdmOn = "assets/icons/battery/dmOn/perOffchargOfflowOffpmOffstDefaultdmOn.svg"; /// Assets for assetsIconsBatteryDmOnPerOffchargOfflowOffpmOnstChargeddmOn /// assets/icons/battery/dmOn/perOffchargOfflowOffpmOnstChargeddmOn.svg - static const String - assetsIconsBatteryDmOnPerOffchargOfflowOffpmOnstChargeddmOn = + static const String assetsIconsBatteryDmOnPerOffchargOfflowOffpmOnstChargeddmOn = "assets/icons/battery/dmOn/perOffchargOfflowOffpmOnstChargeddmOn.svg"; /// Assets for assetsIconsBatteryDmOnPerOffchargOfflowOnpmOffstDefaultdmOn /// assets/icons/battery/dmOn/perOffchargOfflowOnpmOffstDefaultdmOn.svg - static const String - assetsIconsBatteryDmOnPerOffchargOfflowOnpmOffstDefaultdmOn = + static const String assetsIconsBatteryDmOnPerOffchargOfflowOnpmOffstDefaultdmOn = "assets/icons/battery/dmOn/perOffchargOfflowOnpmOffstDefaultdmOn.svg"; /// Assets for assetsIconsBatteryDmOnPerOffchargOfflowOnpmOnstDefaultdmOn /// assets/icons/battery/dmOn/perOffchargOfflowOnpmOnstDefaultdmOn.svg - static const String - assetsIconsBatteryDmOnPerOffchargOfflowOnpmOnstDefaultdmOn = + static const String assetsIconsBatteryDmOnPerOffchargOfflowOnpmOnstDefaultdmOn = "assets/icons/battery/dmOn/perOffchargOfflowOnpmOnstDefaultdmOn.svg"; /// Assets for assetsIconsBatteryDmOnPerOffchargOnlowOffpmOffstChargeddmOn /// assets/icons/battery/dmOn/perOffchargOnlowOffpmOffstChargeddmOn.svg - static const String - assetsIconsBatteryDmOnPerOffchargOnlowOffpmOffstChargeddmOn = + static const String assetsIconsBatteryDmOnPerOffchargOnlowOffpmOffstChargeddmOn = "assets/icons/battery/dmOn/perOffchargOnlowOffpmOffstChargeddmOn.svg"; /// Assets for assetsIconsBatteryDmOnPerOffchargOnlowOnpmOffstlowBatterydmOn /// assets/icons/battery/dmOn/perOffchargOnlowOnpmOffstlowBatterydmOn.svg - static const String - assetsIconsBatteryDmOnPerOffchargOnlowOnpmOffstlowBatterydmOn = + static const String assetsIconsBatteryDmOnPerOffchargOnlowOnpmOffstlowBatterydmOn = "assets/icons/battery/dmOn/perOffchargOnlowOnpmOffstlowBatterydmOn.svg"; /// Assets for assetsIconsBatteryDmOnPerOffchargOnlowOnpmOnstlowpmdmOn @@ -168,44 +144,37 @@ class Assets { /// Assets for assetsIconsBatteryDmOnPerOnchargOfflowOffpmOffstChargeddmOn /// assets/icons/battery/dmOn/perOnchargOfflowOffpmOffstChargeddmOn.svg - static const String - assetsIconsBatteryDmOnPerOnchargOfflowOffpmOffstChargeddmOn = + static const String assetsIconsBatteryDmOnPerOnchargOfflowOffpmOffstChargeddmOn = "assets/icons/battery/dmOn/perOnchargOfflowOffpmOffstChargeddmOn.svg"; /// Assets for assetsIconsBatteryDmOnPerOnchargOfflowOffpmOffstDefaultdmOn /// assets/icons/battery/dmOn/perOnchargOfflowOffpmOffstDefaultdmOn.svg - static const String - assetsIconsBatteryDmOnPerOnchargOfflowOffpmOffstDefaultdmOn = + static const String assetsIconsBatteryDmOnPerOnchargOfflowOffpmOffstDefaultdmOn = "assets/icons/battery/dmOn/perOnchargOfflowOffpmOffstDefaultdmOn.svg"; /// Assets for assetsIconsBatteryDmOnPerOnchargOfflowOffpmOnstChargeddmOn /// assets/icons/battery/dmOn/perOnchargOfflowOffpmOnstChargeddmOn.svg - static const String - assetsIconsBatteryDmOnPerOnchargOfflowOffpmOnstChargeddmOn = + static const String assetsIconsBatteryDmOnPerOnchargOfflowOffpmOnstChargeddmOn = "assets/icons/battery/dmOn/perOnchargOfflowOffpmOnstChargeddmOn.svg"; /// Assets for assetsIconsBatteryDmOnPerOnchargOfflowOnpmOffstDefaultdmOn /// assets/icons/battery/dmOn/perOnchargOfflowOnpmOffstDefaultdmOn.svg - static const String - assetsIconsBatteryDmOnPerOnchargOfflowOnpmOffstDefaultdmOn = + static const String assetsIconsBatteryDmOnPerOnchargOfflowOnpmOffstDefaultdmOn = "assets/icons/battery/dmOn/perOnchargOfflowOnpmOffstDefaultdmOn.svg"; /// Assets for assetsIconsBatteryDmOnPerOnchargOfflowOnpmOnstDefaultdmOn /// assets/icons/battery/dmOn/perOnchargOfflowOnpmOnstDefaultdmOn.svg - static const String - assetsIconsBatteryDmOnPerOnchargOfflowOnpmOnstDefaultdmOn = + static const String assetsIconsBatteryDmOnPerOnchargOfflowOnpmOnstDefaultdmOn = "assets/icons/battery/dmOn/perOnchargOfflowOnpmOnstDefaultdmOn.svg"; /// Assets for assetsIconsBatteryDmOnPerOnchargOnlowOffpmOffstChargeddmOn /// assets/icons/battery/dmOn/perOnchargOnlowOffpmOffstChargeddmOn.svg - static const String - assetsIconsBatteryDmOnPerOnchargOnlowOffpmOffstChargeddmOn = + static const String assetsIconsBatteryDmOnPerOnchargOnlowOffpmOffstChargeddmOn = "assets/icons/battery/dmOn/perOnchargOnlowOffpmOffstChargeddmOn.svg"; /// Assets for assetsIconsBatteryDmOnPerOnchargOnlowOnpmOffstlowBatterydmOn /// assets/icons/battery/dmOn/perOnchargOnlowOnpmOffstlowBatterydmOn.svg - static const String - assetsIconsBatteryDmOnPerOnchargOnlowOnpmOffstlowBatterydmOn = + static const String assetsIconsBatteryDmOnPerOnchargOnlowOnpmOffstlowBatterydmOn = "assets/icons/battery/dmOn/perOnchargOnlowOnpmOffstlowBatterydmOn.svg"; /// Assets for assetsIconsBatteryDmOnPerOnchargOnlowOnpmOnstlowpmdmOn @@ -247,7 +216,9 @@ class Assets { /// Assets for assetsIconsCurtainsIconVerticalBlade /// assets/icons/curtainsIcon/verticalBlade.svg static const String assetsIconsCurtainsIconVerticalBlade = - "assets/icons/curtainsIcon/verticalBlade.svg"; + "assets/icons/curtainsIcon/left_vertical_blade.svg"; + + static const String rightVerticalBlade = "assets/icons/curtainsIcon/right_vertical_blade.svg"; /// Assets for assetsIconsDashboard /// assets/icons/dashboard.svg @@ -257,8 +228,7 @@ class Assets { /// Assets for assetsIconsDashboardFill /// assets/icons/dashboard-fill.svg - static const String assetsIconsDashboardFill = - "assets/icons/dashboard-fill.svg"; + static const String assetsIconsDashboardFill = "assets/icons/dashboard-fill.svg"; /// Assets for assetsIconsDevices /// assets/icons/Devices.svg @@ -274,8 +244,7 @@ class Assets { /// Assets for assetsIconsDoorLockLinkage /// assets/icons/DoorLockLinkage.svg - static const String assetsIconsDoorLockLinkage = - "assets/icons/DoorLockLinkage.svg"; + static const String assetsIconsDoorLockLinkage = "assets/icons/DoorLockLinkage.svg"; /// Assets for assetsIconsDoorLockLock /// assets/icons/DoorLockLock.svg @@ -283,18 +252,15 @@ class Assets { /// Assets for assetsIconsDoorLockMembers /// assets/icons/DoorLockMembers.svg - static const String assetsIconsDoorLockMembers = - "assets/icons/DoorLockMembers.svg"; + static const String assetsIconsDoorLockMembers = "assets/icons/DoorLockMembers.svg"; /// Assets for assetsIconsDoorLockPassword /// assets/icons/DoorLockPassword.svg - static const String assetsIconsDoorLockPassword = - "assets/icons/DoorLockPassword.svg"; + static const String assetsIconsDoorLockPassword = "assets/icons/DoorLockPassword.svg"; /// Assets for assetsIconsDoorLockRecords /// assets/icons/DoorLockRecords.svg - static const String assetsIconsDoorLockRecords = - "assets/icons/DoorLockRecords.svg"; + static const String assetsIconsDoorLockRecords = "assets/icons/DoorLockRecords.svg"; /// Assets for assetsIconsDoorlockAssetsBatteryIndicator /// assets/icons/doorlock-assets/BatteryIndicator.svg @@ -315,8 +281,7 @@ class Assets { /// assets/icons/doorlock-assets/lockIcon.svg static const String assetsIconsDoorlockAssetsLockIcon = "assets/icons/doorlock-assets/lockIcon.svg"; - static const String doorUnlockIcon = - "assets/icons/doorlock-assets/door_un_look_ic.svg"; + static const String doorUnlockIcon = "assets/icons/doorlock-assets/door_un_look_ic.svg"; /// Assets for assetsIconsDoorlockAssetsMembersManagement /// assets/icons/doorlock-assets/members-management.svg @@ -404,13 +369,11 @@ class Assets { /// Assets for assetsIconsLightSwitchOff /// assets/icons/lightSwitchOff.svg - static const String assetsIconsLightSwitchOff = - "assets/icons/lightSwitchOff.svg"; + static const String assetsIconsLightSwitchOff = "assets/icons/lightSwitchOff.svg"; /// Assets for assetsIconsLightSwitchOn /// assets/icons/lightSwitchOn.svg - static const String assetsIconsLightSwitchOn = - "assets/icons/lightSwitchOn.svg"; + static const String assetsIconsLightSwitchOn = "assets/icons/lightSwitchOn.svg"; /// Assets for assetsIconsLinkageIconsDoorLockAlarm /// assets/icons/linkageIcons/doorLockAlarm.svg @@ -419,8 +382,7 @@ class Assets { /// Assets for assetsIconsLinkTimeLimitedPasswordIcon /// assets/icons/timeLimitedPasswordIcon.svg - static const String timeLimitedPasswordIcon = - "assets/icons/timeLimitedPasswordIcon.svg"; + static const String timeLimitedPasswordIcon = "assets/icons/timeLimitedPasswordIcon.svg"; /// Assets for assetsIconsoneTimePassword /// assets/icons/oneTimePassword.svg @@ -428,8 +390,7 @@ class Assets { /// Assets for assetsIconsTimeLimitedPassword /// assets/icons/timeLimitedPassword.svg - static const String timeLimitedPassword = - "assets/icons/timeLimitedPassword.svg"; + static const String timeLimitedPassword = "assets/icons/timeLimitedPassword.svg"; /// Assets for assetsIconsNoValidPasswords /// assets/icons/noValidPasswords.svg @@ -598,13 +559,11 @@ class Assets { /// Assets for assetsIconsPresenceSensorAssetsParameterSettings /// assets/icons/presence-sensor-assets/space_type_icon.svg - static const String spaceTypeIcon = - "assets/icons/presence-sensor-assets/space_type_icon.svg"; + static const String spaceTypeIcon = "assets/icons/presence-sensor-assets/space_type_icon.svg"; /// Assets for assetsIconsPresenceSensorAssetsParameterSettings /// assets/icons/presence-sensor-assets/space_type_icon.svg - static const String sensitivityIcon = - "assets/icons/presence-sensor-assets/Sensitivity.svg"; + static const String sensitivityIcon = "assets/icons/presence-sensor-assets/Sensitivity.svg"; /// Assets for assetsIconsPresenceSensorAssetsParameterSettings /// assets/icons/presence-sensor-assets/maximum_distance.svg @@ -637,8 +596,7 @@ class Assets { /// Assets for assetsIconsRoutinesFill /// assets/icons/Routines-fill.svg - static const String assetsIconsRoutinesFill = - "assets/icons/Routines-fill.svg"; + static const String assetsIconsRoutinesFill = "assets/icons/Routines-fill.svg"; /// Assets for assetsIconsScan /// assets/icons/Scan.svg @@ -670,8 +628,7 @@ class Assets { /// Assets for assetsIconsSustainability /// assets/icons/sustainability.svg - static const String assetsIconsSustainability = - "assets/icons/sustainability.svg"; + static const String assetsIconsSustainability = "assets/icons/sustainability.svg"; /// Assets for assetsIconsUnlockingMethodsIconsFace /// assets/icons/unlockingMethodsIcons/face.svg @@ -767,8 +724,7 @@ class Assets { /// Assets for assetsImagesHorizintalBlade /// assets/images/HorizintalBlade.png - static const String assetsImagesHorizintalBlade = - "assets/images/HorizintalBlade.png"; + static const String assetsImagesHorizintalBlade = "assets/images/HorizintalBlade.png"; /// Assets for assetsImagesLogo /// assets/images/Logo.svg @@ -776,8 +732,7 @@ class Assets { /// Assets for assetsImagesLogoHorizontal /// assets/images/logo_horizontal.png - static const String assetsImagesLogoHorizontal = - "assets/images/logo_horizontal.png"; + static const String assetsImagesLogoHorizontal = "assets/images/logo_horizontal.png"; /// Assets for assetsImagesPause /// assets/images/Pause.png @@ -805,10 +760,9 @@ class Assets { /// Assets for assetsImagesWindow /// assets/images/Window.png - static const String assetsImagesWindow = "assets/images/Window.png"; + static const String assetsImagesWindow = "assets/images/window_img.svg"; - static const String assetsSensitivityFunction = - "assets/icons/functions_icons/sensitivity.svg"; + static const String assetsSensitivityFunction = "assets/icons/functions_icons/sensitivity.svg"; //assets/icons/functions_icons/sesitivity_operation_icon.svg static const String assetsSensitivityOperationIcon = @@ -816,73 +770,59 @@ class Assets { //assets/icons/functions_icons/ac_power.svg - static const String assetsAcPower = - "assets/icons/functions_icons/ac_power.svg"; + static const String assetsAcPower = "assets/icons/functions_icons/ac_power.svg"; //assets/icons/functions_icons/ac_power_off.svg - static const String assetsAcPowerOFF = - "assets/icons/functions_icons/ac_power_off.svg"; + static const String assetsAcPowerOFF = "assets/icons/functions_icons/ac_power_off.svg"; //assets/icons/functions_icons/child_lock.svg - static const String assetsChildLock = - "assets/icons/functions_icons/child_lock.svg"; + static const String assetsChildLock = "assets/icons/functions_icons/child_lock.svg"; //assets/icons/functions_icons/cooling.svg - static const String assetsFreezing = - "assets/icons/functions_icons/freezing.svg"; + static const String assetsFreezing = "assets/icons/functions_icons/freezing.svg"; //assets/icons/functions_icons/fan_speed.svg - static const String assetsFanSpeed = - "assets/icons/functions_icons/fan_speed.svg"; + static const String assetsFanSpeed = "assets/icons/functions_icons/fan_speed.svg"; //assets/icons/functions_icons/ac_cooling.svg - static const String assetsAcCooling = - "assets/icons/functions_icons/ac_cooling.svg"; + static const String assetsAcCooling = "assets/icons/functions_icons/ac_cooling.svg"; //assets/icons/functions_icons/ac_heating.svg - static const String assetsAcHeating = - "assets/icons/functions_icons/ac_heating.svg"; + static const String assetsAcHeating = "assets/icons/functions_icons/ac_heating.svg"; //assets/icons/functions_icons/celsius_degrees.svg - static const String assetsCelsiusDegrees = - "assets/icons/functions_icons/celsius_degrees.svg"; + static const String assetsCelsiusDegrees = "assets/icons/functions_icons/celsius_degrees.svg"; //assets/icons/functions_icons/tempreture.svg - static const String assetsTempreture = - "assets/icons/functions_icons/tempreture.svg"; + static const String assetsTempreture = "assets/icons/functions_icons/tempreture.svg"; //assets/icons/functions_icons/ac_fan_low.svg - static const String assetsAcFanLow = - "assets/icons/functions_icons/ac_fan_low.svg"; + static const String assetsAcFanLow = "assets/icons/functions_icons/ac_fan_low.svg"; //assets/icons/functions_icons/ac_fan_middle.svg - static const String assetsAcFanMiddle = - "assets/icons/functions_icons/ac_fan_middle.svg"; + static const String assetsAcFanMiddle = "assets/icons/functions_icons/ac_fan_middle.svg"; //assets/icons/functions_icons/ac_fan_high.svg - static const String assetsAcFanHigh = - "assets/icons/functions_icons/ac_fan_high.svg"; + static const String assetsAcFanHigh = "assets/icons/functions_icons/ac_fan_high.svg"; //assets/icons/functions_icons/ac_fan_auto.svg - static const String assetsAcFanAuto = - "assets/icons/functions_icons/ac_fan_auto.svg"; + static const String assetsAcFanAuto = "assets/icons/functions_icons/ac_fan_auto.svg"; //assets/icons/functions_icons/scene_child_lock.svg - static const String assetsSceneChildLock = - "assets/icons/functions_icons/scene_child_lock.svg"; + static const String assetsSceneChildLock = "assets/icons/functions_icons/scene_child_lock.svg"; //assets/icons/functions_icons/scene_child_unlock.svg @@ -891,18 +831,15 @@ class Assets { //assets/icons/functions_icons/scene_refresh.svg - static const String assetsSceneRefresh = - "assets/icons/functions_icons/scene_refresh.svg"; + static const String assetsSceneRefresh = "assets/icons/functions_icons/scene_refresh.svg"; //assets/icons/functions_icons/light_countdown.svg - static const String assetsLightCountdown = - "assets/icons/functions_icons/light_countdown.svg"; + static const String assetsLightCountdown = "assets/icons/functions_icons/light_countdown.svg"; //assets/icons/functions_icons/far_detection.svg - static const String assetsFarDetection = - "assets/icons/functions_icons/far_detection.svg"; + static const String assetsFarDetection = "assets/icons/functions_icons/far_detection.svg"; //assets/icons/functions_icons/far_detection_function.svg @@ -911,13 +848,11 @@ class Assets { //assets/icons/functions_icons/indicator.svg - static const String assetsIndicator = - "assets/icons/functions_icons/indicator.svg"; + static const String assetsIndicator = "assets/icons/functions_icons/indicator.svg"; //assets/icons/functions_icons/motion_detection.svg - static const String assetsMotionDetection = - "assets/icons/functions_icons/motion_detection.svg"; + static const String assetsMotionDetection = "assets/icons/functions_icons/motion_detection.svg"; //assets/icons/functions_icons/motionless_detection.svg @@ -926,18 +861,15 @@ class Assets { //assets/icons/functions_icons/nobody_time.svg - static const String assetsNobodyTime = - "assets/icons/functions_icons/nobody_time.svg"; + static const String assetsNobodyTime = "assets/icons/functions_icons/nobody_time.svg"; //assets/icons/functions_icons/factory_reset.svg - static const String assetsFactoryReset = - "assets/icons/functions_icons/factory_reset.svg"; + static const String assetsFactoryReset = "assets/icons/functions_icons/factory_reset.svg"; //assets/icons/functions_icons/master_state.svg - static const String assetsMasterState = - "assets/icons/functions_icons/master_state.svg"; + static const String assetsMasterState = "assets/icons/functions_icons/master_state.svg"; //assets/icons/functions_icons/switch_alarm_sound.svg @@ -946,8 +878,7 @@ class Assets { //assets/icons/functions_icons/reset_off.svg - static const String assetsResetOff = - "assets/icons/functions_icons/reset_off.svg"; + static const String assetsResetOff = "assets/icons/functions_icons/reset_off.svg"; //assets/icons/functions_icons/automation_functions/card_unlock.svg @@ -1021,8 +952,7 @@ class Assets { //assets/icons/functions_icons/automation_functions/motion.svg - static const String assetsMotion = - "assets/icons/functions_icons/automation_functions/motion.svg"; + static const String assetsMotion = "assets/icons/functions_icons/automation_functions/motion.svg"; //assets/icons/functions_icons/automation_functions/current_temp.svg @@ -1044,19 +974,22 @@ class Assets { static const String waterHeaterOn = "assets/icons/water_heater_on.svg"; static const String waterHeaterOff = "assets/icons/water_heater_off.svg"; - static const String scheduleCelenderIcon = - "assets/icons/schedule_celender_icon.svg"; - static const String scheduleCirculateIcon = - "assets/icons/schedule_circulate_icon.svg"; - static const String scheduleInchingIcon = - "assets/icons/schedule_Inching_icon.svg"; + static const String scheduleCelenderIcon = "assets/icons/schedule_celender_icon.svg"; + static const String scheduleCirculateIcon = "assets/icons/schedule_circulate_icon.svg"; + static const String scheduleInchingIcon = "assets/icons/schedule_Inching_icon.svg"; static const String scheduleTimeIcon = "assets/icons/schedule_time_icon.svg"; static const String waterHeaterIcon = "assets/icons/water_heater_icon.svg"; static const String doorOpen = "assets/icons/opened_door.svg"; static const String doorClose = "assets/icons/closed_door.svg"; - static const String doorNotificationSetting = - "assets/icons/door_notification_setting_icon.svg"; + static const String doorNotificationSetting = "assets/icons/door_notification_setting_icon.svg"; static const String doorRecordsIcon = "assets/icons/door_records_icon.svg"; static const String doorSensorIcon = "assets/icons/door_sensor_icon.svg"; + static const String closedGarageIcon = "assets/icons/closed_garage_door.svg"; + static const String openGarageIcon = "assets/icons/open_garage_door.svg"; + static const String garageCountdown = "assets/icons/garage_countdown.svg"; + static const String garagePreferencesIcon = "assets/icons/garage_preferences_icon.svg"; + static const String garageSchedule = "assets/icons/garage_schedule.svg"; + + static const String garageIcon = "assets/icons/garageIcon.svg"; } diff --git a/lib/main.dart b/lib/main.dart index 1a6c5a6..4f1f904 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -30,7 +30,7 @@ void main() { // }); //to initialize the locator - initialSetup(envName: 'prod'); + initialSetup(); await Firebase.initializeApp( options: DefaultFirebaseOptionsStaging.currentPlatform, diff --git a/lib/main_dev.dart b/lib/main_dev.dart index 9e53a7e..5f13c0a 100644 --- a/lib/main_dev.dart +++ b/lib/main_dev.dart @@ -30,7 +30,7 @@ void main() { // }); //to initialize the locator - initialSetup(envName: 'dev'); + initialSetup(); await Firebase.initializeApp( options: DefaultFirebaseOptionsDev.currentPlatform, diff --git a/lib/services/api/devices_api.dart b/lib/services/api/devices_api.dart index c7305db..e277df4 100644 --- a/lib/services/api/devices_api.dart +++ b/lib/services/api/devices_api.dart @@ -385,11 +385,13 @@ class DevicesAPI { String? code, bool? value, }) async { + print({"devicesUuid": devicesUuid, "code": code, "value": value}); final response = await _httpService.post( path: ApiEndpoints.controlBatch, body: {"devicesUuid": devicesUuid, "code": code, "value": value}, showServerMessage: true, expectedResponseModel: (json) { + print('json===$json'); return json; }, ); diff --git a/lib/services/locator.dart b/lib/services/locator.dart index 97a9ae8..0fef6d7 100644 --- a/lib/services/locator.dart +++ b/lib/services/locator.dart @@ -5,9 +5,8 @@ import 'package:syncrow_app/services/api/http_service.dart'; final GetIt serviceLocator = GetIt.instance; // setupLocator() // to search for dependency injection in flutter -initialSetup({required String envName}) { +initialSetup() { serviceLocator.registerSingleton(HTTPInterceptor()); //Base classes serviceLocator.registerSingleton(HTTPService.setupDioClient()); - serviceLocator.registerSingleton(envName); } diff --git a/lib/utils/resource_manager/constants.dart b/lib/utils/resource_manager/constants.dart index 7b7114d..5bd1667 100644 --- a/lib/utils/resource_manager/constants.dart +++ b/lib/utils/resource_manager/constants.dart @@ -53,6 +53,7 @@ enum DeviceType { OneTouch, TowTouch, ThreeTouch, + GarageDoor, Other, } @@ -83,6 +84,7 @@ Map devicesTypesMap = { "1GT": DeviceType.OneTouch, "2GT": DeviceType.TowTouch, "3GT": DeviceType.ThreeTouch, + "GD": DeviceType.GarageDoor, }; Map> devicesFunctionsMap = { DeviceType.AC: [ @@ -370,7 +372,6 @@ Map> devicesFunctionsMap = { "range": ['power_off', 'power_on', 'last'] })), ], - DeviceType.ThreeTouch: [ FunctionModel( code: 'switch_1', @@ -430,6 +431,43 @@ Map> devicesFunctionsMap = { "range": ['power_off', 'power_on', 'last'] })), ], + DeviceType.GarageDoor: [ + FunctionModel( + code: 'switch_1', + type: functionTypesMap['Boolean'], + values: ValueModel.fromJson({})), + FunctionModel( + code: 'countdown_1', + type: functionTypesMap['Integer'], + values: ValueModel.fromJson( + {"unit": "s", "min": 0, "max": 86400, "scale": 0, "step": 1})), + FunctionModel( + code: 'tr_timecon', + type: functionTypesMap['Integer'], + values: ValueModel.fromJson( + {"unit": "s", "min": 0, "max": 120, "scale": 0, "step": 1})), + FunctionModel( + code: 'countdown_alarm', + type: functionTypesMap['Integer'], + values: ValueModel.fromJson( + {"unit": "s", "min": 0, "max": 86400, "scale": 0, "step": 1})), + FunctionModel( + code: 'door_control_1', + type: functionTypesMap['Enum'], + values: ValueModel.fromJson({ + "range": ['open', 'open'] + })), + FunctionModel( + code: 'voice_control_1', + type: functionTypesMap['Boolean'], + values: ValueModel.fromJson({})), + FunctionModel( + code: 'door_state_1', + type: functionTypesMap['Enum'], + values: ValueModel.fromJson({ + "range": ["unclosed_time", "close_time_alarm", "none"] + })), + ], }; enum TempModes { hot, cold, wind } diff --git a/pubspec.yaml b/pubspec.yaml index d2fab73..1a9b3e5 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -5,7 +5,7 @@ description: This is the mobile application project, developed with Flutter for # pub.dev using `flutter pub publish`. This is preferred for private packages. publish_to: "none" # Remove this line if you wish to publish to pub.dev -version: 1.0.3+22 +version: 1.0.3+25 environment: sdk: ">=3.0.6 <4.0.0"