From ec7b351a824f0f27124581a121b1f821799081c6 Mon Sep 17 00:00:00 2001 From: mohammad Date: Mon, 18 Nov 2024 09:09:47 +0300 Subject: [PATCH 01/29] 4_scene&6_scene --- assets/icons/add_devices_icon.svg | 5 + assets/icons/add_scene_icon.svg | 5 + assets/icons/add_switch_icon.svg | 10 + assets/icons/backlight_icon.svg | 10 + assets/icons/check_update_icon.svg | 22 + assets/icons/create_group_icon.svg | 3 + assets/icons/edit_sos_icon.svg | 4 + assets/icons/empty_log.svg | 16 + assets/icons/empty_update_icon.svg | 9 + assets/icons/faq_icon.svg | 3 + assets/icons/green_sos.svg | 38 ++ assets/icons/info.svg | 10 + assets/icons/minus_icon.svg | 4 + assets/icons/notification_icon.svg | 3 + assets/icons/red_sos.svg | 38 ++ assets/icons/remove_scene_icon.svg | 3 + assets/icons/share_icon.svg | 3 + assets/icons/six_scene_icon.svg | 34 ++ assets/icons/sos_profile_icon.svg | 6 + assets/icons/switch_off.svg | 4 + assets/icons/switch_on.svg | 4 + assets/icons/tap_run_icon.svg | 3 + assets/icons/thumb_down.svg | 10 + assets/icons/thumb_up.svg | 10 + assets/icons/update_icon.svg | 3 + .../6_scene_switch_bloc/6_scene_bloc.dart | 314 +++++++++++ .../6_scene_switch_bloc/6_scene_event.dart | 173 ++++++ .../6_scene_switch_bloc/6_scene_state.dart | 113 ++++ .../bloc/four_scene_bloc/four_scene_bloc.dart | 370 ++++++++++++ .../four_scene_bloc/four_scene_event.dart | 174 ++++++ .../four_scene_bloc/four_scene_state.dart | 123 ++++ .../devices/model/four_scene_model.dart | 52 ++ .../model/four_scene_question_model.dart | 11 + .../devices/model/group_devices_model.dart | 6 + .../devices/model/scene_switch_model.dart | 149 +++++ .../model/sex_scene_question_model.dart | 11 + .../devices/model/six_scene_model.dart | 28 + .../6_scene_setting/faq_six_scene_page.dart | 151 +++++ .../6_scene_setting/location_setting.dart | 197 +++++++ .../6_scene_setting/question_page.dart | 144 +++++ .../6_scene_setting/share_six_scene_page.dart | 101 ++++ .../six_scene_create_group.dart | 208 +++++++ .../six_scene_delete_dialog.dart | 227 ++++++++ .../6_scene_setting/six_scene_info_page.dart | 132 +++++ .../six_scene_profile_page.dart | 171 ++++++ .../6_scene_setting/six_scene_settings.dart | 520 +++++++++++++++++ .../six_scene_update_dialog.dart | 118 ++++ .../six_scene_update_note.dart | 118 ++++ .../six_scene_update_page.dart | 345 ++++++++++++ .../6_scene_switch/select_scene_page.dart | 286 ++++++++++ .../6_scene_switch/select_switch_dialog.dart | 146 +++++ .../6_scene_switch/six_scene_screen.dart | 200 +++++++ .../widgets/6_scene_switch/switches_card.dart | 135 +++++ .../four_scene_switch/four_scene_screen.dart | 204 +++++++ .../faq_four_scene_page.dart | 151 +++++ .../four_scene_create_group.dart | 213 +++++++ .../four_scene_delete_dialog.dart | 227 ++++++++ .../four_scene_info_page.dart | 132 +++++ .../four_scene_profile_page.dart | 175 ++++++ .../four_scene_settings.dart | 526 ++++++++++++++++++ .../four_scene_update_dialog.dart | 118 ++++ .../four_scene_update_note.dart | 118 ++++ .../four_scene_update_page.dart | 345 ++++++++++++ .../location_setting_four_scene.dart | 202 +++++++ .../question_page_four_scene.dart | 149 +++++ .../share_four_scene_page.dart | 103 ++++ .../four_select_scene_page.dart | 286 ++++++++++ .../four_select_switch_dialog.dart | 145 +++++ .../four_scene_switch/four_switches_card.dart | 131 +++++ .../view/widgets/room_page_switch.dart | 9 +- lib/generated/assets.dart | 264 ++++++--- lib/services/api/devices_api.dart | 13 +- lib/utils/resource_manager/color_manager.dart | 3 + lib/utils/resource_manager/constants.dart | 208 +++++-- pubspec.lock | 8 + pubspec.yaml | 1 + 76 files changed, 8584 insertions(+), 130 deletions(-) create mode 100644 assets/icons/add_devices_icon.svg create mode 100644 assets/icons/add_scene_icon.svg create mode 100644 assets/icons/add_switch_icon.svg create mode 100644 assets/icons/backlight_icon.svg create mode 100644 assets/icons/check_update_icon.svg create mode 100644 assets/icons/create_group_icon.svg create mode 100644 assets/icons/edit_sos_icon.svg create mode 100644 assets/icons/empty_log.svg create mode 100644 assets/icons/empty_update_icon.svg create mode 100644 assets/icons/faq_icon.svg create mode 100644 assets/icons/green_sos.svg create mode 100644 assets/icons/info.svg create mode 100644 assets/icons/minus_icon.svg create mode 100644 assets/icons/notification_icon.svg create mode 100644 assets/icons/red_sos.svg create mode 100644 assets/icons/remove_scene_icon.svg create mode 100644 assets/icons/share_icon.svg create mode 100644 assets/icons/six_scene_icon.svg create mode 100644 assets/icons/sos_profile_icon.svg create mode 100644 assets/icons/switch_off.svg create mode 100644 assets/icons/switch_on.svg create mode 100644 assets/icons/tap_run_icon.svg create mode 100644 assets/icons/thumb_down.svg create mode 100644 assets/icons/thumb_up.svg create mode 100644 assets/icons/update_icon.svg create mode 100644 lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart create mode 100644 lib/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart create mode 100644 lib/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart create mode 100644 lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart create mode 100644 lib/features/devices/bloc/four_scene_bloc/four_scene_event.dart create mode 100644 lib/features/devices/bloc/four_scene_bloc/four_scene_state.dart create mode 100644 lib/features/devices/model/four_scene_model.dart create mode 100644 lib/features/devices/model/four_scene_question_model.dart create mode 100644 lib/features/devices/model/group_devices_model.dart create mode 100644 lib/features/devices/model/scene_switch_model.dart create mode 100644 lib/features/devices/model/sex_scene_question_model.dart create mode 100644 lib/features/devices/model/six_scene_model.dart create mode 100644 lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/faq_six_scene_page.dart create mode 100644 lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/location_setting.dart create mode 100644 lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/question_page.dart create mode 100644 lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/share_six_scene_page.dart create mode 100644 lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_create_group.dart create mode 100644 lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_delete_dialog.dart create mode 100644 lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_info_page.dart create mode 100644 lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_profile_page.dart create mode 100644 lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_settings.dart create mode 100644 lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_update_dialog.dart create mode 100644 lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_update_note.dart create mode 100644 lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_update_page.dart create mode 100644 lib/features/devices/view/widgets/6_scene_switch/select_scene_page.dart create mode 100644 lib/features/devices/view/widgets/6_scene_switch/select_switch_dialog.dart create mode 100644 lib/features/devices/view/widgets/6_scene_switch/six_scene_screen.dart create mode 100644 lib/features/devices/view/widgets/6_scene_switch/switches_card.dart create mode 100644 lib/features/devices/view/widgets/four_scene_switch/four_scene_screen.dart create mode 100644 lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/faq_four_scene_page.dart create mode 100644 lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_create_group.dart create mode 100644 lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_delete_dialog.dart create mode 100644 lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_info_page.dart create mode 100644 lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_profile_page.dart create mode 100644 lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart create mode 100644 lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_update_dialog.dart create mode 100644 lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_update_note.dart create mode 100644 lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_update_page.dart create mode 100644 lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/location_setting_four_scene.dart create mode 100644 lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/question_page_four_scene.dart create mode 100644 lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/share_four_scene_page.dart create mode 100644 lib/features/devices/view/widgets/four_scene_switch/four_select_scene_page.dart create mode 100644 lib/features/devices/view/widgets/four_scene_switch/four_select_switch_dialog.dart create mode 100644 lib/features/devices/view/widgets/four_scene_switch/four_switches_card.dart diff --git a/assets/icons/add_devices_icon.svg b/assets/icons/add_devices_icon.svg new file mode 100644 index 0000000..b7f0243 --- /dev/null +++ b/assets/icons/add_devices_icon.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/icons/add_scene_icon.svg b/assets/icons/add_scene_icon.svg new file mode 100644 index 0000000..0fb0b4a --- /dev/null +++ b/assets/icons/add_scene_icon.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/icons/add_switch_icon.svg b/assets/icons/add_switch_icon.svg new file mode 100644 index 0000000..7b39523 --- /dev/null +++ b/assets/icons/add_switch_icon.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/icons/backlight_icon.svg b/assets/icons/backlight_icon.svg new file mode 100644 index 0000000..b4f5d91 --- /dev/null +++ b/assets/icons/backlight_icon.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/icons/check_update_icon.svg b/assets/icons/check_update_icon.svg new file mode 100644 index 0000000..46527d3 --- /dev/null +++ b/assets/icons/check_update_icon.svg @@ -0,0 +1,22 @@ + + + +Created with Fabric.js 5.2.4 + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/icons/create_group_icon.svg b/assets/icons/create_group_icon.svg new file mode 100644 index 0000000..00a8668 --- /dev/null +++ b/assets/icons/create_group_icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/icons/edit_sos_icon.svg b/assets/icons/edit_sos_icon.svg new file mode 100644 index 0000000..c9e6a9e --- /dev/null +++ b/assets/icons/edit_sos_icon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/icons/empty_log.svg b/assets/icons/empty_log.svg new file mode 100644 index 0000000..8e847ac --- /dev/null +++ b/assets/icons/empty_log.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/assets/icons/empty_update_icon.svg b/assets/icons/empty_update_icon.svg new file mode 100644 index 0000000..3cf26c9 --- /dev/null +++ b/assets/icons/empty_update_icon.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/icons/faq_icon.svg b/assets/icons/faq_icon.svg new file mode 100644 index 0000000..394f26c --- /dev/null +++ b/assets/icons/faq_icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/icons/green_sos.svg b/assets/icons/green_sos.svg new file mode 100644 index 0000000..da225aa --- /dev/null +++ b/assets/icons/green_sos.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/icons/info.svg b/assets/icons/info.svg new file mode 100644 index 0000000..8aafa02 --- /dev/null +++ b/assets/icons/info.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/icons/minus_icon.svg b/assets/icons/minus_icon.svg new file mode 100644 index 0000000..5eb5323 --- /dev/null +++ b/assets/icons/minus_icon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/icons/notification_icon.svg b/assets/icons/notification_icon.svg new file mode 100644 index 0000000..ed3d9d0 --- /dev/null +++ b/assets/icons/notification_icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/icons/red_sos.svg b/assets/icons/red_sos.svg new file mode 100644 index 0000000..c2f6966 --- /dev/null +++ b/assets/icons/red_sos.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/icons/remove_scene_icon.svg b/assets/icons/remove_scene_icon.svg new file mode 100644 index 0000000..f190e01 --- /dev/null +++ b/assets/icons/remove_scene_icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/icons/share_icon.svg b/assets/icons/share_icon.svg new file mode 100644 index 0000000..a4b908f --- /dev/null +++ b/assets/icons/share_icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/icons/six_scene_icon.svg b/assets/icons/six_scene_icon.svg new file mode 100644 index 0000000..386e615 --- /dev/null +++ b/assets/icons/six_scene_icon.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/icons/sos_profile_icon.svg b/assets/icons/sos_profile_icon.svg new file mode 100644 index 0000000..f99ec5b --- /dev/null +++ b/assets/icons/sos_profile_icon.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/icons/switch_off.svg b/assets/icons/switch_off.svg new file mode 100644 index 0000000..0615df3 --- /dev/null +++ b/assets/icons/switch_off.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/icons/switch_on.svg b/assets/icons/switch_on.svg new file mode 100644 index 0000000..d3b24ed --- /dev/null +++ b/assets/icons/switch_on.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/icons/tap_run_icon.svg b/assets/icons/tap_run_icon.svg new file mode 100644 index 0000000..3518ace --- /dev/null +++ b/assets/icons/tap_run_icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/icons/thumb_down.svg b/assets/icons/thumb_down.svg new file mode 100644 index 0000000..4d22f00 --- /dev/null +++ b/assets/icons/thumb_down.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/icons/thumb_up.svg b/assets/icons/thumb_up.svg new file mode 100644 index 0000000..5670b79 --- /dev/null +++ b/assets/icons/thumb_up.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/icons/update_icon.svg b/assets/icons/update_icon.svg new file mode 100644 index 0000000..cf3e305 --- /dev/null +++ b/assets/icons/update_icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart new file mode 100644 index 0000000..dfb11d4 --- /dev/null +++ b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart @@ -0,0 +1,314 @@ +import 'dart:async'; +import 'package:dio/dio.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart'; +import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_state.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/group_devices_model.dart'; +import 'package:syncrow_app/features/devices/model/sex_scene_question_model.dart'; +import 'package:syncrow_app/features/devices/model/six_scene_model.dart'; +import 'package:syncrow_app/features/devices/model/status_model.dart'; +import 'package:syncrow_app/features/scene/model/scenes_model.dart'; +import 'package:syncrow_app/generated/assets.dart'; +import 'package:syncrow_app/services/api/devices_api.dart'; +import 'package:syncrow_app/services/api/scene_api.dart'; +import 'package:syncrow_app/services/api/spaces_api.dart'; + +class SixSceneBloc extends Bloc { + final String sixSceneId; + SixSceneBloc({ + required this.sixSceneId, + }) : super(const SixSceneState()) { + on(_fetchStatus); + on(fetchLogsForLastMonth); + on(_toggleNotification); + on(_changeName); + on(_onSearchFaq); + on(_fetchRoomsAndDevices); + on(changeSwitchStatus); + on(_onLoadScenes); + on(_selectScene); + on(searchScene); + on(_onSaveSelection); + on(_onOptionSelected); + on(_addDeviceToGroup); // Register handler here + on(_removeDeviceFromGroup); + } + + final TextEditingController nameController = + TextEditingController(text: '${'firstName'}'); + bool isSaving = false; + bool editName = false; + final FocusNode focusNode = FocusNode(); + bool closingReminder = false; + bool waterAlarm = false; + + SixSceneModel deviceStatus = + SixSceneModel(waterContactState: 'normal', batteryPercentage: 0); + + void _fetchStatus(SixSceneInitial event, Emitter emit) async { + emit(SixSceneLoadingState()); + try { + var response = await DevicesAPI.getDeviceStatus(sixSceneId); + List statusModelList = []; + for (var status in response['status']) { + statusModelList.add(StatusModel.fromJson(status)); + } + deviceStatus = SixSceneModel.fromJson( + statusModelList, + ); + emit(UpdateState(sensor: deviceStatus)); + + Future.delayed(const Duration(milliseconds: 500)); + // _listenToChanges(); + } catch (e) { + emit(SixSceneFailedState(errorMessage: e.toString())); + return; + } + } + + void _onSearchFaq(SearchFaqEvent event, Emitter emit) { + emit(SixSceneLoadingState()); + // Filter FAQ questions based on search query + List _faqQuestions = faqQuestions.where((question) { + return question.question + .toLowerCase() + .contains(event.query.toLowerCase()); + }).toList(); + + print(_faqQuestions); + emit(FaqSearchState(filteredFaqQuestions: _faqQuestions)); + } + + void _changeName(ChangeNameEvent event, Emitter emit) { + emit(SixSceneLoadingState()); + editName = event.value!; + if (editName) { + Future.delayed(const Duration(milliseconds: 500), () { + focusNode.requestFocus(); + }); + } else { + focusNode.unfocus(); + } + emit(NameEditingState(editName: editName)); + } + + void _toggleNotification( + ToggleNotificationEvent event, Emitter emit) async { + emit(LoadingNewSate(sosSensor: deviceStatus)); + try { + closingReminder = event.isClosingEnabled; + emit(UpdateState(sensor: deviceStatus)); + + // API call to update the state, if necessary + // await DevicesAPI.controlDevice( + // DeviceControlModel( + // deviceId: sosId, + // code: 'closing_reminder', + // value: closingReminder, + // ), + // sosId, + // ); + } catch (e) { + emit(SixSceneFailedState(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(SixSceneLoadingState()); + var response = await DevicesAPI.getReportLogs( + startTime: startTime.toString(), + endTime: endTime.toString(), + deviceUuid: sixSceneId, + code: 'sossensor_state', + ); + recordGroups = response; + emit(UpdateState(sensor: deviceStatus)); + } on DioException catch (e) { + final errorData = e.response!.data; + String errorMessage = errorData['message']; + emit(SixSceneFailedState(errorMessage: e.toString())); + } + } + + final List faqQuestions = [ + SixSceneQuestionModel( + id: 1, + question: 'How does an SOS emergency button work?', + answer: + 'The SOS emergency button sends an alert to your contacts when pressed.', + ), + SixSceneQuestionModel( + id: 2, + question: 'How long will an SOS alarm persist?', + answer: + 'The SOS alarm will persist until it is manually turned off or after a set time.', + ), + SixSceneQuestionModel( + id: 3, + question: 'What should I do if the SOS button is unresponsive?', + answer: 'Try restarting the device. If it persists, contact support.', + ), + SixSceneQuestionModel( + id: 4, + question: 'Can I use the SOS feature without a network connection?', + answer: + 'No, a network connection is required to send the alert to your contacts.', + ), + SixSceneQuestionModel( + id: 5, + question: 'How often should I check the SOS battery?', + answer: + 'Check the SOS battery at least once a month to ensure it is operational.', + ), + ]; + + Future _onSixSceneInitial( + SixSceneInitialQuestion event, Emitter emit) async { + emit(SixSceneLoadingState()); + emit(FaqLoadedState(filteredFaqQuestions: faqQuestions)); + } + + List allDevices = []; + + void _fetchRoomsAndDevices( + FetchRoomsEvent event, Emitter emit) async { + try { + emit(SixSceneLoadingState()); + final roomsList = await SpacesAPI.getSubSpaceBySpaceId( + event.unit.community.uuid, event.unit.id); + emit(FetchRoomsState(devicesList: allDevices, roomsList: roomsList)); + } catch (e) { + emit(const SixSceneFailedState(errorMessage: 'Something went wrong')); + return; + } + } + + bool switchStatus = true; + void changeSwitchStatus( + ChangeSwitchStatusEvent event, Emitter emit) { + emit(SixSceneLoadingState()); + switchStatus = !switchStatus; + emit(ChangeSwitchState(isEnable: switchStatus)); + } + + // List allScenes = []; + + Future _onLoadScenes( + LoadScenes event, Emitter emit) async { + emit(SixSceneLoadingState()); + try { + if (event.unitId.isNotEmpty) { + allScenes = await SceneApi.getScenesByUnitId( + event.unitId, event.unit.community.uuid, + showInDevice: event.showInDevice); + emit(SceneLoaded( + allScenes, + )); + filteredScenes = allScenes; + } else { + emit(const SixSceneFailedState(errorMessage: 'Unit ID is empty')); + } + } catch (e) { + emit(const SixSceneFailedState(errorMessage: 'Something went wrong')); + } + } + + bool selecedScene = false; + String selectedSceneId = ''; + _selectScene(SelectSceneEvent event, Emitter emit) { + emit(SixSceneLoadingState()); + selecedScene = !selecedScene; + emit(SelectedSceneState()); + } + + List allScenes = []; + List filteredScenes = []; + + void searchScene(SearchScenesEvent event, Emitter emit) { + emit(SixSceneLoadingState()); + filteredScenes = event.query.isEmpty + ? allScenes + : allScenes.where((scene) { + final sceneName = scene.name?.toLowerCase() ?? ''; + return sceneName.contains(event.query.toLowerCase()); + }).toList(); + emit(SearchResultsState()); + } + + String _selectedOption = ''; + bool _hasSelectionChanged = false; + + void _onOptionSelected(SelectOptionEvent event, Emitter emit) { + emit(SixSceneLoadingState()); + _selectedOption = event.selectedOption; + _hasSelectionChanged = true; + emit(OptionSelectedState( + selectedOption: _selectedOption, + hasSelectionChanged: _hasSelectionChanged)); + } + + void _onSaveSelection(SaveSelectionEvent event, Emitter emit) { + if (_hasSelectionChanged) { + print('Save button clicked with selected option: $_selectedOption'); + _hasSelectionChanged = false; + emit(SaveSelectionSuccessState()); + } + } + +//addDevicesIcon + List groupDevices = [ + GroupDevicesModel( + dec: 'Syncroom', icon: Assets.minusIcon, name: '6 Scene Switch') + ]; + + List devices = [ + GroupDevicesModel( + dec: 'Syncroom', icon: Assets.addDevicesIcon, name: '6 Scene Switch') + ]; + + // @override + // Stream mapEventToState(SixSceneEvent event) async* { + // if (event is AddDeviceToGroup) { + // devices.remove(event.device); + // groupDevices.add(event.device); + // yield UpdateStateList(groupDevices: groupDevices, devices: devices); + // } else if (event is RemoveDeviceFromGroup) { + // groupDevices.remove(event.device); + // devices.add(event.device); + // yield UpdateStateList(groupDevices: groupDevices, devices: devices); + // } + // } + + // Handler for AddDeviceToGroup + void _addDeviceToGroup(AddDeviceToGroup event, Emitter emit) { + devices.remove(event.device); + groupDevices.add(event.device); + for (var device in groupDevices) { + device.icon = event.icon; + } + emit(UpdateStateList(groupDevices: groupDevices, devices: devices)); + } + + // Handler for RemoveDeviceFromGroup + void _removeDeviceFromGroup( + RemoveDeviceFromGroup event, Emitter emit) { + groupDevices.remove(event.device); + devices.add(event.device); + for (var device in groupDevices) { + device.icon = event.icon; + } + emit(UpdateStateList(groupDevices: groupDevices, devices: devices)); + } +} diff --git a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart new file mode 100644 index 0000000..52b5ed3 --- /dev/null +++ b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart @@ -0,0 +1,173 @@ +import 'package:equatable/equatable.dart'; +import 'package:syncrow_app/features/app_layout/model/space_model.dart'; +import 'package:syncrow_app/features/devices/model/group_devices_model.dart'; + +abstract class SixSceneEvent extends Equatable { + const SixSceneEvent(); + + @override + List get props => []; +} + +class SixSceneLoading extends SixSceneEvent {} + +class SixSceneSwitch extends SixSceneEvent { + final String switchD; + final String deviceId; + final String productId; + const SixSceneSwitch( + {required this.switchD, this.deviceId = '', this.productId = ''}); + + @override + List get props => [switchD, deviceId, productId]; +} + +class SixSceneUpdated extends SixSceneEvent {} + +class SixSceneInitial extends SixSceneEvent { + const SixSceneInitial(); +} + +class ReportLogsInitial extends SixSceneEvent { + const ReportLogsInitial(); +} + +class SixSceneChangeStatus extends SixSceneEvent {} + +class GetCounterEvent extends SixSceneEvent { + final String deviceCode; + const GetCounterEvent({required this.deviceCode}); + @override + List get props => [deviceCode]; +} + +class ToggleEnableAlarmEvent extends SixSceneEvent { + final bool isLowBatteryEnabled; + + const ToggleEnableAlarmEvent(this.isLowBatteryEnabled); + + @override + List get props => [isLowBatteryEnabled]; +} + +class ToggleNotificationEvent extends SixSceneEvent { + final bool isClosingEnabled; + + const ToggleNotificationEvent(this.isClosingEnabled); + + @override + List get props => [isClosingEnabled]; +} + +class ToggleSixSceneAlarmEvent extends SixSceneEvent { + final bool isSixSceneAlarmEnabled; + + const ToggleSixSceneAlarmEvent(this.isSixSceneAlarmEnabled); + + @override + List get props => [isSixSceneAlarmEnabled]; +} + +class SetCounterValue extends SixSceneEvent { + final Duration duration; + final String deviceCode; + const SetCounterValue({required this.duration, required this.deviceCode}); + @override + List get props => [duration, deviceCode]; +} + +class StartTimer extends SixSceneEvent { + final int duration; + + const StartTimer(this.duration); + + @override + List get props => [duration]; +} + +class TickTimer extends SixSceneEvent { + final int remainingTime; + + const TickTimer(this.remainingTime); + + @override + List get props => [remainingTime]; +} + +class StopTimer extends SixSceneEvent {} + +class OnClose extends SixSceneEvent {} + +class ChangeNameEvent extends SixSceneEvent { + final bool? value; + const ChangeNameEvent({this.value}); +} + +class SearchFaqEvent extends SixSceneEvent { + final String query; + + const SearchFaqEvent(this.query); +} + +class SixSceneInitialQuestion extends SixSceneEvent { + const SixSceneInitialQuestion(); +} + +class ChangeSwitchStatusEvent extends SixSceneEvent {} + +class FetchRoomsEvent extends SixSceneEvent { + final SpaceModel unit; + + const FetchRoomsEvent({required this.unit}); + + @override + List get props => [unit]; +} + +class LoadScenes extends SixSceneEvent { + final String unitId; + final bool showInDevice; + final SpaceModel unit; + + const LoadScenes( + {required this.unitId, required this.unit, this.showInDevice = false}); + + @override + List get props => [unitId, showInDevice]; +} + +class SelectSceneEvent extends SixSceneEvent { + final String unitId; + const SelectSceneEvent({ + required this.unitId, + }); +} + +class SearchScenesEvent extends SixSceneEvent { + final String query; + const SearchScenesEvent({ + required this.query, + }); +} + +class SaveSelectionEvent extends SixSceneEvent {} + +class SelectOptionEvent extends SixSceneEvent { + dynamic selectedOption; + SelectOptionEvent({ + this.selectedOption, + }); +} + +class AddDeviceToGroup extends SixSceneEvent { + final GroupDevicesModel device; + final String icon; + AddDeviceToGroup(this.device, this.icon); +} + +class RemoveDeviceFromGroup extends SixSceneEvent { + final GroupDevicesModel device; + final String icon; + + RemoveDeviceFromGroup(this.device, this.icon); +} diff --git a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart new file mode 100644 index 0000000..de478df --- /dev/null +++ b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart @@ -0,0 +1,113 @@ +import 'package:equatable/equatable.dart'; +import 'package:syncrow_app/features/devices/model/device_model.dart'; +import 'package:syncrow_app/features/devices/model/group_devices_model.dart'; +import 'package:syncrow_app/features/devices/model/sex_scene_question_model.dart'; +import 'package:syncrow_app/features/devices/model/six_scene_model.dart'; +import 'package:syncrow_app/features/devices/model/subspace_model.dart'; +import 'package:syncrow_app/features/scene/model/scenes_model.dart'; + +class SixSceneState extends Equatable { + const SixSceneState(); + + @override + List get props => []; +} + +class SixSceneInitialState extends SixSceneState {} + +class SixSceneLoadingState extends SixSceneState {} + +class SixSceState extends SixSceneState {} + +class UpdateStateList extends SixSceneState { + final List groupDevices; + final List devices; + const UpdateStateList({required this.groupDevices, required this.devices}); +} + +class SixSceneFailedState extends SixSceneState { + final String errorMessage; + + const SixSceneFailedState({required this.errorMessage}); + + @override + List get props => [errorMessage]; +} + +class UpdateState extends SixSceneState { + final SixSceneModel sensor; + const UpdateState({required this.sensor}); + + @override + List get props => [sensor]; +} + +class LoadingNewSate extends SixSceneState { + final SixSceneModel sosSensor; + const LoadingNewSate({required this.sosSensor}); + + @override + List get props => [sosSensor]; +} + +class NameEditingState extends SixSceneState { + final bool editName; + + NameEditingState({required this.editName}); +} + +class FaqLoadedState extends SixSceneState { + final List filteredFaqQuestions; + + FaqLoadedState({this.filteredFaqQuestions = const []}); +} + +class FaqSearchState extends SixSceneState { + final List filteredFaqQuestions; + + const FaqSearchState({this.filteredFaqQuestions = const []}); +} + +class FetchRoomsState extends SixSceneState { + final List roomsList; + final List devicesList; + + const FetchRoomsState({required this.devicesList, required this.roomsList}); + + @override + List get props => [devicesList]; +} + +class ChangeSwitchState extends SixSceneState { + final bool isEnable; + + const ChangeSwitchState({required this.isEnable}); +} + +class SceneLoaded extends SixSceneState { + final List scenes; + final String? loadingSceneId; + final Map loadingStates; + + const SceneLoaded(this.scenes, + {this.loadingSceneId, this.loadingStates = const {}}); +} + +class SelectedSceneState extends SixSceneState {} + +class SearchResultsState extends SixSceneState {} + +class SaveSelectionSuccessState extends SixSceneState {} + +class OptionSelectedState extends SixSceneState { + final String selectedOption; + final bool hasSelectionChanged; + + OptionSelectedState({ + required this.selectedOption, + required this.hasSelectionChanged, + }); + + @override + List get props => [selectedOption, hasSelectionChanged]; +} diff --git a/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart b/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart new file mode 100644 index 0000000..c74b990 --- /dev/null +++ b/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart @@ -0,0 +1,370 @@ +import 'dart:async'; +import 'dart:convert'; +import 'package:dio/dio.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_event.dart'; +import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_state.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/four_scene_model.dart'; +import 'package:syncrow_app/features/devices/model/four_scene_question_model.dart'; +import 'package:syncrow_app/features/devices/model/group_devices_model.dart'; +import 'package:syncrow_app/features/devices/model/scene_switch_model.dart'; +import 'package:syncrow_app/features/devices/model/status_model.dart'; +import 'package:syncrow_app/features/scene/model/scenes_model.dart'; +import 'package:syncrow_app/generated/assets.dart'; +import 'package:syncrow_app/services/api/devices_api.dart'; +import 'package:syncrow_app/services/api/scene_api.dart'; +import 'package:syncrow_app/services/api/spaces_api.dart'; + +class FourSceneBloc extends Bloc { + final String fourSceneId; + FourSceneBloc({ + required this.fourSceneId, + }) : super(const FourSceneState()) { + on(_fetchStatus); + on(fetchDeviceData); + on(fetchLogsForLastMonth); + on(_toggleNotification); + on(_changeName); + on(_onSearchFaq); + on(_fetchRoomsAndDevices); + on(changeSwitchStatus); + on(_onLoadScenes); + on(_selectScene); + on(searchScene); + on(_onSaveSelection); + on(_onOptionSelected); + on(_addDeviceToGroup); // Register handler here + on(_removeDeviceFromGroup); + } + + final TextEditingController nameController = + TextEditingController(text: '${'firstName'}'); + bool isSaving = false; + bool editName = false; + final FocusNode focusNode = FocusNode(); + bool closingReminder = false; + bool waterAlarm = false; + + FourSceneModel deviceStatus = FourSceneModel( + scene_1: '', + scene_2: '', + scene_3: '', + scene_4: '', + scene_id_group_id: '', + switch_backlight: false); + + SceneSwitch sceneInfo = SceneSwitch( + activeTime: 1728118263, + category: "", + categoryName: "", + createTime: 1728118263, + gatewayId: "", + icon: "", + ip: "", + lat: "", + localKey: "", + lon: "", + model: "", + name: "", + nodeId: "", + online: true, + ownerId: "", + productName: "", + sub: true, + timeZone: "", + updateTime: 0, + uuid: "", + productUuid: "", + productType: "", + permissionType: "", + macAddress: "", + subspace: Subspace( + uuid: "", + createdAt: "", + updatedAt: "", + subspaceName: "", + ), + ); + + void _fetchStatus( + FourSceneInitial event, Emitter emit) async { + emit(FourSceneLoadingState()); + try { + var response = await DevicesAPI.getDeviceStatus(fourSceneId); + List statusModelList = []; + for (var status in response['status']) { + statusModelList.add(StatusModel.fromJson(status)); + } + deviceStatus = FourSceneModel.fromJson( + statusModelList, + ); + emit(UpdateState(sensor: deviceStatus)); + + Future.delayed(const Duration(milliseconds: 500)); + // _listenToChanges(); + } catch (e) { + emit(FourSceneFailedState(errorMessage: e.toString())); + return; + } + } + + Future fetchDeviceData( + FourSceneInitialInfo event, Emitter emit) async { + emit(FourSceneLoadingState()); + var response = await DevicesAPI.getDeviceInfo(fourSceneId); + if (response.statusCode == 200) { + Map jsonData = jsonDecode(response.body); + sceneInfo = SceneSwitch.fromJson(jsonData); + emit(LoadingDeviceInfo(sosSensor: sceneInfo)); + } else { + throw Exception('Failed to load device data: ${response.reasonPhrase}'); + } + } + + void _onSearchFaq(SearchFaqEvent event, Emitter emit) { + emit(FourSceneLoadingState()); + List _faqQuestions = faqQuestions.where((question) { + return question.question + .toLowerCase() + .contains(event.query.toLowerCase()); + }).toList(); + + print(_faqQuestions); + emit(FaqSearchState(filteredFaqQuestions: _faqQuestions)); + } + + void _changeName(ChangeNameEvent event, Emitter emit) { + emit(FourSceneLoadingState()); + editName = event.value!; + if (editName) { + Future.delayed(const Duration(milliseconds: 500), () { + focusNode.requestFocus(); + }); + } else { + focusNode.unfocus(); + } + emit(NameEditingState(editName: editName)); + } + + void _toggleNotification( + ToggleNotificationEvent event, Emitter emit) async { + emit(LoadingNewSate(sosSensor: deviceStatus)); + try { + closingReminder = event.isClosingEnabled; + emit(UpdateState(sensor: deviceStatus)); + + // API call to update the state, if necessary + // await DevicesAPI.controlDevice( + // DeviceControlModel( + // deviceId: sosId, + // code: 'closing_reminder', + // value: closingReminder, + // ), + // sosId, + // ); + } catch (e) { + emit(FourSceneFailedState(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(FourSceneLoadingState()); + var response = await DevicesAPI.getReportLogs( + startTime: startTime.toString(), + endTime: endTime.toString(), + deviceUuid: fourSceneId, + code: 'sossensor_state', + ); + recordGroups = response; + emit(UpdateState(sensor: deviceStatus)); + } on DioException catch (e) { + final errorData = e.response!.data; + String errorMessage = errorData['message']; + emit(FourSceneFailedState(errorMessage: e.toString())); + } + } + + final List faqQuestions = [ + FourSceneQuestionModel( + id: 1, + question: 'How does an SOS emergency button work?', + answer: + 'The SOS emergency button sends an alert to your contacts when pressed.', + ), + FourSceneQuestionModel( + id: 2, + question: 'How long will an SOS alarm persist?', + answer: + 'The SOS alarm will persist until it is manually turned off or after a set time.', + ), + FourSceneQuestionModel( + id: 3, + question: 'What should I do if the SOS button is unresponsive?', + answer: 'Try restarting the device. If it persists, contact support.', + ), + FourSceneQuestionModel( + id: 4, + question: 'Can I use the SOS feature without a network connection?', + answer: + 'No, a network connection is required to send the alert to your contacts.', + ), + FourSceneQuestionModel( + id: 5, + question: 'How often should I check the SOS battery?', + answer: + 'Check the SOS battery at least once a month to ensure it is operational.', + ), + ]; + + Future _onFourSceneInitial( + FourSceneInitialQuestion event, Emitter emit) async { + emit(FourSceneLoadingState()); + emit(FaqLoadedState(filteredFaqQuestions: faqQuestions)); + } + + List allDevices = []; + + void _fetchRoomsAndDevices( + FetchRoomsEvent event, Emitter emit) async { + try { + emit(FourSceneLoadingState()); + final roomsList = await SpacesAPI.getSubSpaceBySpaceId( + event.unit.community.uuid, event.unit.id); + emit(FetchRoomsState(devicesList: allDevices, roomsList: roomsList)); + } catch (e) { + emit(const FourSceneFailedState(errorMessage: 'Something went wrong')); + return; + } + } + + bool switchStatus = true; + void changeSwitchStatus( + ChangeSwitchStatusEvent event, Emitter emit) { + emit(FourSceneLoadingState()); + switchStatus = !switchStatus; + emit(ChangeSwitchState(isEnable: switchStatus)); + } + + // List allScenes = []; + + Future _onLoadScenes( + LoadScenes event, Emitter emit) async { + emit(FourSceneLoadingState()); + try { + if (event.unitId.isNotEmpty) { + allScenes = await SceneApi.getScenesByUnitId( + event.unitId, event.unit.community.uuid, + showInDevice: event.showInDevice); + emit(SceneLoaded( + allScenes, + )); + filteredScenes = allScenes; + } else { + emit(const FourSceneFailedState(errorMessage: 'Unit ID is empty')); + } + } catch (e) { + emit(const FourSceneFailedState(errorMessage: 'Something went wrong')); + } + } + + bool selecedScene = false; + String selectedSceneId = ''; + _selectScene(SelectSceneEvent event, Emitter emit) { + emit(FourSceneLoadingState()); + selecedScene = !selecedScene; + emit(SelectedSceneState()); + } + + List allScenes = []; + List filteredScenes = []; + + void searchScene(SearchScenesEvent event, Emitter emit) { + emit(FourSceneLoadingState()); + filteredScenes = event.query.isEmpty + ? allScenes + : allScenes.where((scene) { + final sceneName = scene.name?.toLowerCase() ?? ''; + return sceneName.contains(event.query.toLowerCase()); + }).toList(); + emit(SearchResultsState()); + } + + String _selectedOption = ''; + bool _hasSelectionChanged = false; + + void _onOptionSelected( + SelectOptionEvent event, Emitter emit) { + emit(FourSceneLoadingState()); + _selectedOption = event.selectedOption; + _hasSelectionChanged = true; + emit(OptionSelectedState( + selectedOption: _selectedOption, + hasSelectionChanged: _hasSelectionChanged)); + } + + void _onSaveSelection( + SaveSelectionEvent event, Emitter emit) { + if (_hasSelectionChanged) { + print('Save button clicked with selected option: $_selectedOption'); + _hasSelectionChanged = false; + emit(SaveSelectionSuccessState()); + } + } + +//addDevicesIcon + List groupDevices = [ + GroupDevicesModel( + dec: 'Syncroom', icon: Assets.minusIcon, name: '6 Scene Switch') + ]; + + List devices = [ + GroupDevicesModel( + dec: 'Syncroom', icon: Assets.addDevicesIcon, name: '6 Scene Switch') + ]; + + // @override + // Stream mapEventToState(FourSceneEvent event) async* { + // if (event is AddDeviceToGroup) { + // devices.remove(event.device); + // groupDevices.add(event.device); + // yield UpdateStateList(groupDevices: groupDevices, devices: devices); + // } else if (event is RemoveDeviceFromGroup) { + // groupDevices.remove(event.device); + // devices.add(event.device); + // yield UpdateStateList(groupDevices: groupDevices, devices: devices); + // } + // } + + // Handler for AddDeviceToGroup + void _addDeviceToGroup(AddDeviceToGroup event, Emitter emit) { + devices.remove(event.device); + groupDevices.add(event.device); + for (var device in groupDevices) { + device.icon = event.icon; + } + emit(UpdateStateList(groupDevices: groupDevices, devices: devices)); + } + + // Handler for RemoveDeviceFromGroup + void _removeDeviceFromGroup( + RemoveDeviceFromGroup event, Emitter emit) { + groupDevices.remove(event.device); + devices.add(event.device); + for (var device in groupDevices) { + device.icon = event.icon; + } + emit(UpdateStateList(groupDevices: groupDevices, devices: devices)); + } +} diff --git a/lib/features/devices/bloc/four_scene_bloc/four_scene_event.dart b/lib/features/devices/bloc/four_scene_bloc/four_scene_event.dart new file mode 100644 index 0000000..39a13be --- /dev/null +++ b/lib/features/devices/bloc/four_scene_bloc/four_scene_event.dart @@ -0,0 +1,174 @@ +import 'package:equatable/equatable.dart'; +import 'package:syncrow_app/features/app_layout/model/space_model.dart'; +import 'package:syncrow_app/features/devices/model/group_devices_model.dart'; + +abstract class FourSceneEvent extends Equatable { + const FourSceneEvent(); + + @override + List get props => []; +} + +class FourSceneLoading extends FourSceneEvent {} + +class FourSceneSwitch extends FourSceneEvent { + final String switchD; + final String deviceId; + final String productId; + const FourSceneSwitch( + {required this.switchD, this.deviceId = '', this.productId = ''}); + + @override + List get props => [switchD, deviceId, productId]; +} + +class FourSceneUpdated extends FourSceneEvent {} +class FourSceneInitialInfo extends FourSceneEvent {} + +class FourSceneInitial extends FourSceneEvent { + const FourSceneInitial(); +} + +class ReportLogsInitial extends FourSceneEvent { + const ReportLogsInitial(); +} + +class FourSceneChangeStatus extends FourSceneEvent {} + +class GetCounterEvent extends FourSceneEvent { + final String deviceCode; + const GetCounterEvent({required this.deviceCode}); + @override + List get props => [deviceCode]; +} + +class ToggleEnableAlarmEvent extends FourSceneEvent { + final bool isLowBatteryEnabled; + + const ToggleEnableAlarmEvent(this.isLowBatteryEnabled); + + @override + List get props => [isLowBatteryEnabled]; +} + +class ToggleNotificationEvent extends FourSceneEvent { + final bool isClosingEnabled; + + const ToggleNotificationEvent(this.isClosingEnabled); + + @override + List get props => [isClosingEnabled]; +} + +class ToggleFourSceneAlarmEvent extends FourSceneEvent { + final bool isFourSceneAlarmEnabled; + + const ToggleFourSceneAlarmEvent(this.isFourSceneAlarmEnabled); + + @override + List get props => [isFourSceneAlarmEnabled]; +} + +class SetCounterValue extends FourSceneEvent { + final Duration duration; + final String deviceCode; + const SetCounterValue({required this.duration, required this.deviceCode}); + @override + List get props => [duration, deviceCode]; +} + +class StartTimer extends FourSceneEvent { + final int duration; + + const StartTimer(this.duration); + + @override + List get props => [duration]; +} + +class TickTimer extends FourSceneEvent { + final int remainingTime; + + const TickTimer(this.remainingTime); + + @override + List get props => [remainingTime]; +} + +class StopTimer extends FourSceneEvent {} + +class OnClose extends FourSceneEvent {} + +class ChangeNameEvent extends FourSceneEvent { + final bool? value; + const ChangeNameEvent({this.value}); +} + +class SearchFaqEvent extends FourSceneEvent { + final String query; + + const SearchFaqEvent(this.query); +} + +class FourSceneInitialQuestion extends FourSceneEvent { + const FourSceneInitialQuestion(); +} + +class ChangeSwitchStatusEvent extends FourSceneEvent {} + +class FetchRoomsEvent extends FourSceneEvent { + final SpaceModel unit; + + const FetchRoomsEvent({required this.unit}); + + @override + List get props => [unit]; +} + +class LoadScenes extends FourSceneEvent { + final String unitId; + final bool showInDevice; + final SpaceModel unit; + + const LoadScenes( + {required this.unitId, required this.unit, this.showInDevice = false}); + + @override + List get props => [unitId, showInDevice]; +} + +class SelectSceneEvent extends FourSceneEvent { + final String unitId; + const SelectSceneEvent({ + required this.unitId, + }); +} + +class SearchScenesEvent extends FourSceneEvent { + final String query; + const SearchScenesEvent({ + required this.query, + }); +} + +class SaveSelectionEvent extends FourSceneEvent {} + +class SelectOptionEvent extends FourSceneEvent { + dynamic selectedOption; + SelectOptionEvent({ + this.selectedOption, + }); +} + +class AddDeviceToGroup extends FourSceneEvent { + final GroupDevicesModel device; + final String icon; + AddDeviceToGroup(this.device, this.icon); +} + +class RemoveDeviceFromGroup extends FourSceneEvent { + final GroupDevicesModel device; + final String icon; + + RemoveDeviceFromGroup(this.device, this.icon); +} diff --git a/lib/features/devices/bloc/four_scene_bloc/four_scene_state.dart b/lib/features/devices/bloc/four_scene_bloc/four_scene_state.dart new file mode 100644 index 0000000..b407837 --- /dev/null +++ b/lib/features/devices/bloc/four_scene_bloc/four_scene_state.dart @@ -0,0 +1,123 @@ +import 'package:equatable/equatable.dart'; +import 'package:syncrow_app/features/devices/model/device_model.dart'; +import 'package:syncrow_app/features/devices/model/four_scene_model.dart'; +import 'package:syncrow_app/features/devices/model/four_scene_question_model.dart'; +import 'package:syncrow_app/features/devices/model/group_devices_model.dart'; +import 'package:syncrow_app/features/devices/model/scene_switch_model.dart'; +import 'package:syncrow_app/features/devices/model/subspace_model.dart'; +import 'package:syncrow_app/features/scene/model/scenes_model.dart'; + +class FourSceneState extends Equatable { + const FourSceneState(); + + @override + List get props => []; +} + +class FourSceneInitialState extends FourSceneState {} + +class FourSceneLoadingState extends FourSceneState {} + +class FourSceState extends FourSceneState {} + +class UpdateStateList extends FourSceneState { + final List groupDevices; + final List devices; + const UpdateStateList({required this.groupDevices, required this.devices}); +} + +class FourSceneFailedState extends FourSceneState { + final String errorMessage; + + const FourSceneFailedState({required this.errorMessage}); + + @override + List get props => [errorMessage]; +} + +class UpdateState extends FourSceneState { + final FourSceneModel sensor; + const UpdateState({required this.sensor}); + + @override + List get props => [sensor]; +} + +class LoadingNewSate extends FourSceneState { + final FourSceneModel sosSensor; + const LoadingNewSate({required this.sosSensor}); + + @override + List get props => [sosSensor]; +} + +class NameEditingState extends FourSceneState { + final bool editName; + + NameEditingState({required this.editName}); +} + +class FaqLoadedState extends FourSceneState { + final List filteredFaqQuestions; + + FaqLoadedState({this.filteredFaqQuestions = const []}); +} + +class FaqSearchState extends FourSceneState { + final List filteredFaqQuestions; + + const FaqSearchState({this.filteredFaqQuestions = const []}); +} + +class FetchRoomsState extends FourSceneState { + final List roomsList; + final List devicesList; + + const FetchRoomsState({required this.devicesList, required this.roomsList}); + + @override + List get props => [devicesList]; +} + +class ChangeSwitchState extends FourSceneState { + final bool isEnable; + + const ChangeSwitchState({required this.isEnable}); +} + +class SceneLoaded extends FourSceneState { + final List scenes; + final String? loadingSceneId; + final Map loadingStates; + + const SceneLoaded(this.scenes, + {this.loadingSceneId, this.loadingStates = const {}}); +} + +class SelectedSceneState extends FourSceneState {} + +class SearchResultsState extends FourSceneState {} + +class SaveSelectionSuccessState extends FourSceneState {} + +class OptionSelectedState extends FourSceneState { + final String selectedOption; + final bool hasSelectionChanged; + + OptionSelectedState({ + required this.selectedOption, + required this.hasSelectionChanged, + }); + + @override + List get props => [selectedOption, hasSelectionChanged]; +} + + +class LoadingDeviceInfo extends FourSceneState { + final SceneSwitch sosSensor; + const LoadingDeviceInfo({required this.sosSensor}); + + @override + List get props => [sosSensor]; +} \ No newline at end of file diff --git a/lib/features/devices/model/four_scene_model.dart b/lib/features/devices/model/four_scene_model.dart new file mode 100644 index 0000000..82f2b73 --- /dev/null +++ b/lib/features/devices/model/four_scene_model.dart @@ -0,0 +1,52 @@ +import 'package:syncrow_app/features/devices/model/status_model.dart'; + +class FourSceneModel { + dynamic scene_1; + dynamic scene_2; + dynamic scene_3; + dynamic scene_4; + dynamic scene_id_group_id; + dynamic switch_backlight; + + FourSceneModel({ + required this.scene_1, + required this.scene_2, + required this.scene_3, + required this.scene_4, + required this.scene_id_group_id, + required this.switch_backlight, + }); + + factory FourSceneModel.fromJson(List jsonList) { + late dynamic _scene_1; + late dynamic _scene_2; + late dynamic _scene_3; + late dynamic _scene_4; + late dynamic _scene_id_group_id; + late dynamic _switch_backlight; + + for (int i = 0; i < jsonList.length; i++) { + if (jsonList[i].code == 'scene_1') { + _scene_1 = jsonList[i].value ?? ''; + } else if (jsonList[i].code == 'scene_2') { + _scene_2 = jsonList[i].value ?? ''; + } else if (jsonList[i].code == 'scene_3') { + _scene_3 = jsonList[i].value ?? ''; + } else if (jsonList[i].code == 'scene_4') { + _scene_4 = jsonList[i].value ?? ''; + } else if (jsonList[i].code == 'scene_id_group_id') { + _scene_id_group_id = jsonList[i].value ?? 0; + } else if (jsonList[i].code == 'switch_backlight') { + _switch_backlight = jsonList[i].value ?? false; + } + } + return FourSceneModel( + scene_1: _scene_1, + scene_2: _scene_2, + scene_3: _scene_3, + scene_4: _scene_4, + scene_id_group_id: _scene_id_group_id, + switch_backlight: _switch_backlight, + ); + } +} diff --git a/lib/features/devices/model/four_scene_question_model.dart b/lib/features/devices/model/four_scene_question_model.dart new file mode 100644 index 0000000..ed4eacc --- /dev/null +++ b/lib/features/devices/model/four_scene_question_model.dart @@ -0,0 +1,11 @@ +class FourSceneQuestionModel { + final int id; + final String question; + final String answer; + + FourSceneQuestionModel({ + required this.id, + required this.question, + required this.answer, + }); +} diff --git a/lib/features/devices/model/group_devices_model.dart b/lib/features/devices/model/group_devices_model.dart new file mode 100644 index 0000000..b0a36d3 --- /dev/null +++ b/lib/features/devices/model/group_devices_model.dart @@ -0,0 +1,6 @@ +class GroupDevicesModel { + String? icon; + final String? name; + final String? dec; + GroupDevicesModel({this.icon, this.name, this.dec}); +} diff --git a/lib/features/devices/model/scene_switch_model.dart b/lib/features/devices/model/scene_switch_model.dart new file mode 100644 index 0000000..f21c1ad --- /dev/null +++ b/lib/features/devices/model/scene_switch_model.dart @@ -0,0 +1,149 @@ +import 'dart:convert'; + +class SceneSwitch { + final int activeTime; + final String category; + final String categoryName; + final int createTime; + final String gatewayId; + final String icon; + final String ip; + final String lat; + final String localKey; + final String lon; + final String model; + final String name; + final String nodeId; + final bool online; + final String ownerId; + final String productName; + final bool sub; + final String timeZone; + final int updateTime; + final String uuid; + final String productUuid; + final String productType; + final String permissionType; + final String macAddress; + final Subspace subspace; + + SceneSwitch({ + required this.activeTime, + required this.category, + required this.categoryName, + required this.createTime, + required this.gatewayId, + required this.icon, + required this.ip, + required this.lat, + required this.localKey, + required this.lon, + required this.model, + required this.name, + required this.nodeId, + required this.online, + required this.ownerId, + required this.productName, + required this.sub, + required this.timeZone, + required this.updateTime, + required this.uuid, + required this.productUuid, + required this.productType, + required this.permissionType, + required this.macAddress, + required this.subspace, + }); + + factory SceneSwitch.fromJson(Map json) { + return SceneSwitch( + activeTime: json['activeTime'], + category: json['category'], + categoryName: json['categoryName'], + createTime: json['createTime'], + gatewayId: json['gatewayId'], + icon: json['icon'], + ip: json['ip'] ?? "", + lat: json['lat'], + localKey: json['localKey'], + lon: json['lon'], + model: json['model'], + name: json['name'], + nodeId: json['nodeId'], + online: json['online'], + ownerId: json['ownerId'], + productName: json['productName'], + sub: json['sub'], + timeZone: json['timeZone'], + updateTime: json['updateTime'], + uuid: json['uuid'], + productUuid: json['productUuid'], + productType: json['productType'], + permissionType: json['permissionType'], + macAddress: json['macAddress'], + subspace: Subspace.fromJson(json['subspace']), + ); + } + + Map toJson() { + return { + 'activeTime': activeTime, + 'category': category, + 'categoryName': categoryName, + 'createTime': createTime, + 'gatewayId': gatewayId, + 'icon': icon, + 'ip': ip, + 'lat': lat, + 'localKey': localKey, + 'lon': lon, + 'model': model, + 'name': name, + 'nodeId': nodeId, + 'online': online, + 'ownerId': ownerId, + 'productName': productName, + 'sub': sub, + 'timeZone': timeZone, + 'updateTime': updateTime, + 'uuid': uuid, + 'productUuid': productUuid, + 'productType': productType, + 'permissionType': permissionType, + 'macAddress': macAddress, + 'subspace': subspace.toJson(), + }; + } +} + +class Subspace { + final String uuid; + final String createdAt; + final String updatedAt; + final String subspaceName; + + Subspace({ + required this.uuid, + required this.createdAt, + required this.updatedAt, + required this.subspaceName, + }); + + factory Subspace.fromJson(Map json) { + return Subspace( + uuid: json['uuid'], + createdAt: json['createdAt'], + updatedAt: json['updatedAt'], + subspaceName: json['subspaceName'], + ); + } + + Map toJson() { + return { + 'uuid': uuid, + 'createdAt': createdAt, + 'updatedAt': updatedAt, + 'subspaceName': subspaceName, + }; + } +} diff --git a/lib/features/devices/model/sex_scene_question_model.dart b/lib/features/devices/model/sex_scene_question_model.dart new file mode 100644 index 0000000..6822d93 --- /dev/null +++ b/lib/features/devices/model/sex_scene_question_model.dart @@ -0,0 +1,11 @@ +class SixSceneQuestionModel { + final int id; + final String question; + final String answer; + + SixSceneQuestionModel({ + required this.id, + required this.question, + required this.answer, + }); +} diff --git a/lib/features/devices/model/six_scene_model.dart b/lib/features/devices/model/six_scene_model.dart new file mode 100644 index 0000000..0bbb82a --- /dev/null +++ b/lib/features/devices/model/six_scene_model.dart @@ -0,0 +1,28 @@ +import 'package:syncrow_app/features/devices/model/status_model.dart'; + +class SixSceneModel { + String waterContactState; + int batteryPercentage; + + SixSceneModel({ + required this.waterContactState, + required this.batteryPercentage, + }); + + factory SixSceneModel.fromJson(List jsonList) { + late String _waterContactState; + late int _batteryPercentage; + + for (int i = 0; i < jsonList.length; i++) { + if (jsonList[i].code == 'sossensor_state') { + _waterContactState = jsonList[i].value ?? false; + } else if (jsonList[i].code == 'battery_percentage') { + _batteryPercentage = jsonList[i].value ?? 0; + } + } + return SixSceneModel( + waterContactState: _waterContactState, + batteryPercentage: _batteryPercentage, + ); + } +} diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/faq_six_scene_page.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/faq_six_scene_page.dart new file mode 100644 index 0000000..e22f0aa --- /dev/null +++ b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/faq_six_scene_page.dart @@ -0,0 +1,151 @@ +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/6_scene_switch_bloc/6_scene_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart'; +import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart'; +import 'package:syncrow_app/features/devices/model/device_model.dart'; +import 'package:syncrow_app/features/devices/model/sex_scene_question_model.dart'; +import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/6_scene_setting/question_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_medium.dart'; +import 'package:syncrow_app/generated/assets.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +class FaqSixScenePage extends StatelessWidget { + final DeviceModel? device; + + const FaqSixScenePage({super.key, this.device}); + + @override + Widget build(BuildContext context) { + TextEditingController _searchController = TextEditingController(); + return DefaultScaffold( + title: 'FAQ', + child: BlocProvider( + create: (context) => SixSceneBloc(sixSceneId: device?.uuid ?? '') + ..add(const SixSceneInitialQuestion()), + child: BlocBuilder( + builder: (context, state) { + final sensor = BlocProvider.of(context); + + List displayedQuestions = []; + if (state is FaqSearchState) { + displayedQuestions = state.filteredFaqQuestions; + } else if (state is FaqLoadedState) { + displayedQuestions = state.filteredFaqQuestions; + } + return state is SixSceneLoadingState + ? const Center( + child: DefaultContainer( + width: 50, + height: 50, + child: CircularProgressIndicator()), + ) + : RefreshIndicator( + onRefresh: () async { + // sensor.add(const SosInitial()); + }, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + DefaultContainer( + padding: const EdgeInsets.all(5), + child: TextFormField( + controller: _searchController, + onChanged: (value) { + sensor.add(SearchFaqEvent(value)); + }, + decoration: InputDecoration( + hintText: 'Enter your questions', + hintStyle: const TextStyle( + color: ColorsManager.textGray, + fontSize: 16, + fontWeight: FontWeight.w400), + suffixIcon: Container( + padding: const EdgeInsets.all(5.0), + margin: const EdgeInsets.all(10.0), + child: SvgPicture.asset( + Assets.searchIcon, + fit: BoxFit.contain, + ), + ), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(8.0), + ), + ), + ), + ), + SizedBox( + height: MediaQuery.of(context).size.height * 0.04, + ), + BodyMedium( + text: _searchController.text.isEmpty + ? 'Device Related FAQs' + : '${displayedQuestions.length} Help Topics', + fontWeight: FontWeight.w700, + fontSize: 12, + fontColor: ColorsManager.grayColor, + ), + Expanded( + child: DefaultContainer( + child: ListView.builder( + shrinkWrap: true, + itemCount: displayedQuestions.length, + itemBuilder: (context, index) { + final faq = displayedQuestions[index]; + return InkWell( + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => QuestionPage( + questionModel: faq, + )), + ); + }, + child: SizedBox( + child: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Row( + children: [ + Expanded( + child: BodyMedium( + fontSize: 14, + fontWeight: FontWeight.w400, + text: faq.question, + ), + ), + const Icon( + Icons.keyboard_arrow_right, + color: ColorsManager.textGray, + ), + ], + ), + ), + const Divider( + color: ColorsManager.dividerColor, + ), + ], + ), + ), + ); + }, + )), + ), + ], + ), + ); + }, + ), + ), + ); + } +} diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/location_setting.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/location_setting.dart new file mode 100644 index 0000000..2913f41 --- /dev/null +++ b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/location_setting.dart @@ -0,0 +1,197 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_app/features/app_layout/model/space_model.dart'; +import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart'; +import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart'; +import 'package:syncrow_app/features/devices/model/six_scene_model.dart'; + +import 'package:syncrow_app/features/devices/model/subspace_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/features/shared_widgets/text_widgets/body_medium.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +class LocationSixScenePage extends StatefulWidget { + final SpaceModel? space; + LocationSixScenePage({super.key, this.space}); + + @override + _LocationSixScenePageState createState() => _LocationSixScenePageState(); +} + +class _LocationSixScenePageState extends State { + String _selectedOption = 'Conference Room'; + bool _hasSelectionChanged = false; + + @override + Widget build(BuildContext context) { + return DefaultScaffold( + title: 'Device Location', + actions: [ + InkWell( + onTap: _hasSelectionChanged + ? () { + print('Save button clicked'); + } + : null, + child: BodyMedium( + text: 'Save', + fontWeight: FontWeight.w700, + fontSize: 16, + fontColor: _hasSelectionChanged + ? ColorsManager.slidingBlueColor + : ColorsManager.primaryTextColor, + ), + ), + const SizedBox(width: 20), + ], + child: BlocProvider( + create: (context) => SixSceneBloc(sixSceneId: '') + ..add(FetchRoomsEvent(unit: widget.space!)), + child: BlocBuilder( + builder: (context, state) { + final sensor = BlocProvider.of(context); + SixSceneModel model = SixSceneModel( + batteryPercentage: 0, waterContactState: 'normal'); + List? rooms = []; + if (state is LoadingNewSate) { + model = state.sosSensor; + } else if (state is FetchRoomsState) { + rooms = state.roomsList; + } + return state is SixSceneLoadingState + ? const Center( + child: DefaultContainer( + width: 50, + height: 50, + child: CircularProgressIndicator(), + ), + ) + : RefreshIndicator( + onRefresh: () async { + sensor.add(const SixSceneInitial()); + }, + child: ListView( + padding: const EdgeInsets.symmetric(vertical: 20), + children: [ + const BodyMedium( + text: 'Smart Device Location', + fontWeight: FontWeight.w700, + fontSize: 12, + fontColor: ColorsManager.grayColor, + ), + const SizedBox(height: 5), + DefaultContainer( + padding: const EdgeInsets.all(20), + child: ListView.builder( + physics: const NeverScrollableScrollPhysics(), + shrinkWrap: true, + itemCount: rooms!.length, + itemBuilder: (context, index) { + final room = rooms![index]; + return Column( + children: [ + _buildCheckboxOption( + label: room.name!, + onTap: (v) { + setState(() { + _selectedOption = v; + _hasSelectionChanged = true; + }); + }, + ), + if (index < rooms.length - 1) ...[ + const SizedBox(height: 10), + const Divider( + color: ColorsManager.dividerColor, + ), + const SizedBox(height: 10), + ], + ], + ); + }, + ), + ), + ], + ), + ); + }, + ), + ), + ); + } + + Widget _buildCheckboxOption( + {required String label, required 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; + _hasSelectionChanged = true; + }); + 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/6_scene_switch/6_scene_setting/question_page.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/question_page.dart new file mode 100644 index 0000000..2cbfa9b --- /dev/null +++ b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/question_page.dart @@ -0,0 +1,144 @@ +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/6_scene_switch_bloc/6_scene_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart'; +import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart'; +import 'package:syncrow_app/features/devices/model/sex_scene_question_model.dart'; +import 'package:syncrow_app/features/devices/model/six_scene_model.dart'; +import 'package:syncrow_app/features/shared_widgets/default_button.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/generated/assets.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +class QuestionPage extends StatelessWidget { + final SixSceneQuestionModel? questionModel; + + const QuestionPage({super.key, this.questionModel}); + + @override + Widget build(BuildContext context) { + return DefaultScaffold( + title: 'FAQ', + child: BlocProvider( + create: (context) => + SixSceneBloc(sixSceneId: '')..add(const SixSceneInitial()), + child: BlocBuilder( + builder: (context, state) { + final sensor = BlocProvider.of(context); + SixSceneModel model = SixSceneModel( + batteryPercentage: 0, waterContactState: 'normal'); + if (state is LoadingNewSate) { + model = state.sosSensor; + } else if (state is UpdateState) { + model = state.sensor; + } + return state is SixSceneLoadingState + ? const Center( + child: DefaultContainer( + width: 50, + height: 50, + child: CircularProgressIndicator()), + ) + : RefreshIndicator( + onRefresh: () async { + sensor.add(const SixSceneInitial()); + }, + child: Column( + children: [ + DefaultContainer( + padding: EdgeInsets.all(15), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + BodyLarge( + text: questionModel!.question, + fontSize: 22, + fontWeight: FontWeight.w400, + fontColor: ColorsManager.blackColor, + ), + SizedBox( + height: 15, + ), + BodyMedium( + text: questionModel!.answer, + fontSize: 14, + fontWeight: FontWeight.w400, + fontColor: ColorsManager.secondaryTextColor, + ), + ], + ), + ), + SizedBox( + height: MediaQuery.of(context).size.height * 0.15, + ), + Center( + child: SizedBox( + width: 180, + child: DefaultButton( + backgroundColor: ColorsManager.grayButtonColors, + borderRadius: 50, + onPressed: () {}, + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SvgPicture.asset( + Assets.thumbUp, + fit: BoxFit.fill, + ), + SizedBox( + width: 10, + ), + BodyMedium( + text: 'Helpful', + fontSize: 12, + fontWeight: FontWeight.w400, + fontColor: ColorsManager.blackColor, + ), + ], + )), + ), + ), + SizedBox( + height: 15, + ), + Center( + child: SizedBox( + width: 180, + child: DefaultButton( + backgroundColor: ColorsManager.grayButtonColors, + borderRadius: 50, + onPressed: () {}, + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SvgPicture.asset( + Assets.thumbDown, + fit: BoxFit.fill, + ), + SizedBox( + width: 10, + ), + BodyMedium( + text: 'Not Helpful', + fontSize: 12, + fontWeight: FontWeight.w400, + fontColor: ColorsManager.blackColor, + ), + ], + )), + ), + ), + ], + )); + }, + ), + ), + ); + } +} diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/share_six_scene_page.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/share_six_scene_page.dart new file mode 100644 index 0000000..ca89955 --- /dev/null +++ b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/share_six_scene_page.dart @@ -0,0 +1,101 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart'; +import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart'; + +import 'package:syncrow_app/features/devices/model/device_model.dart'; +import 'package:syncrow_app/features/devices/model/six_scene_model.dart'; +import 'package:syncrow_app/features/shared_widgets/default_button.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 ShareSixScenePage extends StatelessWidget { + final DeviceModel? device; + + const ShareSixScenePage({super.key, this.device}); + + @override + Widget build(BuildContext context) { + return DefaultScaffold( + title: 'Share Device', + child: BlocProvider( + create: (context) => SixSceneBloc(sixSceneId: device?.uuid ?? '') + ..add(const SixSceneInitial()), + child: BlocBuilder( + builder: (context, state) { + final sensor = BlocProvider.of(context); + SixSceneModel model = SixSceneModel( + batteryPercentage: 0, waterContactState: 'normal'); + if (state is LoadingNewSate) { + model = state.sosSensor; + } else if (state is UpdateState) { + model = state.sensor; + } + return state is LoadingNewSate + ? const Center( + child: DefaultContainer( + width: 50, + height: 50, + child: CircularProgressIndicator()), + ) + : RefreshIndicator( + onRefresh: () async { + sensor.add(const SixSceneInitial()); + }, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const BodyLarge( + text: 'Sharing Method Not Supported', + fontSize: 15, + fontWeight: FontWeight.w400, + fontColor: ColorsManager.blackColor, + ), + const BodyMedium( + text: + 'Currently, you cannot use the specified method to share Bluetooth mesh devices Zigbee devices, infrared devices, Bluetooth Beacon Devices, and certain Bluetooth LE devices with other users.', + fontSize: 14, + fontWeight: FontWeight.w400, + fontColor: ColorsManager.secondaryTextColor, + ), + const SizedBox( + height: 10, + ), + const BodyLarge( + text: 'Recommended Sharing Method', + fontSize: 15, + fontWeight: FontWeight.w400, + fontColor: ColorsManager.blackColor, + ), + const BodyMedium( + text: + 'If the recipient is a home member or a reliable user, tap Me > Home Management > Add Member and add the recipient to your home. Then, devices in the home can be shared with the recipient in bulk.', + fontSize: 14, + fontWeight: FontWeight.w400, + fontColor: ColorsManager.secondaryTextColor, + ), + SizedBox( + height: MediaQuery.of(context).size.height * 0.15, + ), + Center( + child: SizedBox( + width: 250, + child: DefaultButton( + backgroundColor: ColorsManager.blueColor1, + borderRadius: 50, + onPressed: () {}, + child: Text('Add Home Member')), + ), + ) + ], + )); + }, + ), + ), + ); + } +} diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_create_group.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_create_group.dart new file mode 100644 index 0000000..8183902 --- /dev/null +++ b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_create_group.dart @@ -0,0 +1,208 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart'; +import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart'; +import 'package:syncrow_app/features/devices/model/device_model.dart'; +import 'package:syncrow_app/features/devices/model/six_scene_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/features/shared_widgets/text_widgets/body_large.dart'; +import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart'; +import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart'; +import 'package:syncrow_app/generated/assets.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +class SixSceneCreateGroup extends StatelessWidget { + final DeviceModel? device; + + const SixSceneCreateGroup({super.key, this.device}); + + @override + Widget build(BuildContext context) { + return DefaultScaffold( + title: 'Create Group', + child: BlocProvider( + create: (context) => SixSceneBloc(sixSceneId: device?.uuid ?? '') + ..add(const SixSceneInitial()), + child: BlocBuilder( + builder: (context, state) { + final sensor = BlocProvider.of(context); + SixSceneModel model = SixSceneModel( + batteryPercentage: 0, waterContactState: 'normal'); + if (state is LoadingNewSate) { + model = state.sosSensor; + } else if (state is UpdateState) { + model = state.sensor; + } + return state is LoadingNewSate + ? const Center( + child: DefaultContainer( + width: 50, + height: 50, + child: CircularProgressIndicator()), + ) + : Padding( + padding: EdgeInsets.all(8.0), + child: Column( + children: [ + const Padding( + padding: EdgeInsets.only(left: 25, right: 25), + child: BodySmall( + text: + 'Devices in the same group can be controlled together', + fontColor: ColorsManager.primaryTextColor, + textAlign: TextAlign.center, + ), + ), + Flexible( + child: ListView.builder( + itemCount: sensor.groupDevices.length, + itemBuilder: (context, index) { + return InkWell( + onTap: () { + BlocProvider.of(context).add( + RemoveDeviceFromGroup( + sensor.groupDevices[index], + Assets.addDevicesIcon)); + }, + child: DefaultContainer( + child: Padding( + padding: const EdgeInsets.all(5.0), + child: Row( + crossAxisAlignment: + CrossAxisAlignment.start, + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + SvgPicture.asset( + sensor.groupDevices[index].icon!, + fit: BoxFit.contain, + ), + const SizedBox( + width: 15, + ), + BodyMedium( + text: sensor + .groupDevices[index].name!, + fontColor: + ColorsManager.primaryTextColor, + textAlign: TextAlign.center, + fontSize: 15, + ), + ], + ), + BodyMedium( + text: sensor.groupDevices[index].dec!, + fontColor: ColorsManager.grayColor, + textAlign: TextAlign.center, + fontSize: 15, + ), + ], + ), + )), + ); + }, + ), + ), + Flexible( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const BodyLarge( + text: 'Devices to be added', + fontColor: ColorsManager.grayColor, + textAlign: TextAlign.center, + fontSize: 12, + fontWeight: FontWeight.w700, + ), + const SizedBox( + height: 5, + ), + sensor.devices.isNotEmpty + ? Expanded( + child: ListView.builder( + itemCount: sensor.devices.length, + itemBuilder: (context, index) { + final device = sensor.devices[index]; + return GestureDetector( + onTap: () { + BlocProvider.of( + context) + .add(AddDeviceToGroup(device, + Assets.minusIcon)); + }, + child: DefaultContainer( + child: Padding( + padding: + const EdgeInsets.all(5.0), + child: Row( + crossAxisAlignment: + CrossAxisAlignment.start, + mainAxisAlignment: + MainAxisAlignment + .spaceBetween, + children: [ + Row( + children: [ + SvgPicture.asset( + device.icon!, + fit: BoxFit.contain, + ), + const SizedBox( + width: 15, + ), + BodyMedium( + text: device.name!, + fontColor: ColorsManager + .primaryTextColor, + textAlign: + TextAlign.center, + fontSize: 15, + ), + ], + ), + BodyMedium( + text: device.dec!, + fontColor: ColorsManager + .grayColor, + textAlign: + TextAlign.center, + fontSize: 15, + ), + ], + ), + ), + ), + ); + }, + ), + ) + : const Column( + children: [ + BodySmall( + text: + 'Currently no devices available to create group', + fontColor: ColorsManager.grayColor, + textAlign: TextAlign.center, + fontSize: 12, + fontWeight: FontWeight.w400, + ), + ], + ), + ], + ), + ), + Spacer() + ], + ), + ); + }, + ), + ), + ); + } +} diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_delete_dialog.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_delete_dialog.dart new file mode 100644 index 0000000..67c62e2 --- /dev/null +++ b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_delete_dialog.dart @@ -0,0 +1,227 @@ +import 'package:flutter/material.dart'; +import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +class DisconnectDeviceDialog extends StatelessWidget { + final Function()? cancelTab; + final Function()? confirmTab; + + const DisconnectDeviceDialog({ + super.key, + required this.cancelTab, + required this.confirmTab, + }); + + @override + Widget build(BuildContext context) { + return AlertDialog( + contentPadding: EdgeInsets.zero, + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const SizedBox( + height: 10, + ), + const BodyLarge( + text: 'Disconnect Device', + fontWeight: FontWeight.w700, + fontColor: ColorsManager.red, + fontSize: 16, + ), + const Padding( + padding: EdgeInsets.only(left: 15, right: 15), + child: Divider( + color: ColorsManager.textGray, + ), + ), + const Padding( + padding: EdgeInsets.only(left: 15, right: 20, top: 15, bottom: 20), + child: Column( + children: [ + Center( + child: Text( + 'This will disconnect your device from this Application')), + ], + ), + ), + 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: 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: confirmTab, + child: const Padding( + padding: EdgeInsets.all(15), + child: Center( + child: Text( + 'Disconnect', + style: TextStyle( + color: ColorsManager.red, + fontSize: 14, + fontWeight: FontWeight.w400), + ), + ), + )), + )) + ], + ) + ], + ), + ); + } +} + +class DisconnectWipeData extends StatelessWidget { + final Function()? cancelTab; + final Function()? confirmTab; + + const DisconnectWipeData({ + super.key, + required this.cancelTab, + required this.confirmTab, + }); + + @override + Widget build(BuildContext context) { + return AlertDialog( + contentPadding: EdgeInsets.zero, + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const SizedBox( + height: 10, + ), + const BodyLarge( + text: 'Disconnect and Wipe Data', + fontWeight: FontWeight.w700, + fontColor: ColorsManager.red, + fontSize: 16, + ), + const Padding( + padding: EdgeInsets.only(left: 15, right: 15), + child: Divider( + color: ColorsManager.textGray, + ), + ), + const Padding( + padding: EdgeInsets.only(left: 15, right: 20, top: 15, bottom: 20), + child: Column( + children: [ + Center( + child: Text( + 'This will disconnect your device from this Application and wipe all the data')), + ], + ), + ), + 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: 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: confirmTab, + child: const Padding( + padding: EdgeInsets.all(15), + child: Center( + child: Text( + 'Disconnect', + style: TextStyle( + color: ColorsManager.red, + fontSize: 14, + fontWeight: FontWeight.w400), + ), + ), + )), + )) + ], + ) + ], + ), + ); + } +} diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_info_page.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_info_page.dart new file mode 100644 index 0000000..0caed76 --- /dev/null +++ b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_info_page.dart @@ -0,0 +1,132 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart'; +import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart'; + +import 'package:syncrow_app/features/devices/model/device_model.dart'; +import 'package:syncrow_app/features/devices/model/six_scene_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/features/shared_widgets/text_widgets/body_large.dart'; +import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart'; +import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +class SixSceneInfoPage extends StatelessWidget { + final DeviceModel? device; + + const SixSceneInfoPage({super.key, this.device}); + + @override + Widget build(BuildContext context) { + return DefaultScaffold( + title: 'Device Information', + child: BlocProvider( + create: (context) => SixSceneBloc(sixSceneId: device?.uuid ?? '') + ..add(const SixSceneInitial()), + child: BlocBuilder( + builder: (context, state) { + final sensor = BlocProvider.of(context); + SixSceneModel model = SixSceneModel( + batteryPercentage: 0, waterContactState: 'normal'); + if (state is LoadingNewSate) { + model = state.sosSensor; + } else if (state is UpdateState) { + model = state.sensor; + } + return state is SixSceneLoadingState + ? const Center( + child: DefaultContainer( + width: 50, + height: 50, + child: CircularProgressIndicator()), + ) + : RefreshIndicator( + onRefresh: () async { + sensor.add(const SixSceneInitial()); + }, + child: DefaultContainer( + child: Padding( + padding: const EdgeInsets.only(left: 10, right: 10), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + const BodyLarge( + text: 'Virtual ID', + fontSize: 15, + fontWeight: FontWeight.w400, + fontColor: ColorsManager.blackColor, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + const BodySmall( + text: 'bf3575d0e0c8b6e0a6hybl', + fontColor: ColorsManager.primaryTextColor, + ), + InkWell( + onTap: () {}, + child: const Row( + children: [ + Icon( + Icons.copy, + color: ColorsManager.blueColor, + ), + BodyMedium( + text: 'Copy', + fontColor: ColorsManager.blueColor, + ), + ], + ), + ) + ], + ), + const Divider( + color: ColorsManager.dividerColor, + ), + const Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + BodyLarge( + text: 'MAC', + fontSize: 15, + fontWeight: FontWeight.w400, + fontColor: ColorsManager.blackColor, + ), + BodySmall( + text: 'bf3575d0e0c8b6e0a6hybl', + fontColor: ColorsManager.primaryTextColor, + ), + ], + ), + const Divider( + color: ColorsManager.dividerColor, + ), + const Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + BodyLarge( + text: 'Time Zone', + fontSize: 15, + fontWeight: FontWeight.w400, + fontColor: ColorsManager.blackColor, + ), + BodySmall( + text: 'Asia/Dubai', + fontColor: ColorsManager.primaryTextColor, + ), + ], + ), + ]), + ))); + }, + ), + ), + ); + } +} diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_profile_page.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_profile_page.dart new file mode 100644 index 0000000..09f4fc0 --- /dev/null +++ b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_profile_page.dart @@ -0,0 +1,171 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart'; +import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart'; +import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart'; + +import 'package:syncrow_app/features/devices/model/device_model.dart'; +import 'package:syncrow_app/features/devices/model/six_scene_model.dart'; +import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/6_scene_setting/location_setting.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_medium.dart'; +import 'package:syncrow_app/generated/assets.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +class SixSceneProfilePage extends StatelessWidget { + final DeviceModel? device; + + const SixSceneProfilePage({super.key, this.device}); + + @override + Widget build(BuildContext context) { + var spaces = HomeCubit.getInstance().spaces; + + return DefaultScaffold( + title: 'Device Settings', + child: BlocProvider( + create: (context) => SixSceneBloc(sixSceneId: device?.uuid ?? '') + ..add(const SixSceneInitial()), + child: BlocBuilder( + builder: (context, state) { + final sensor = BlocProvider.of(context); + SixSceneModel model = SixSceneModel( + batteryPercentage: 0, waterContactState: 'normal'); + if (state is LoadingNewSate) { + model = state.sosSensor; + } else if (state is UpdateState) { + model = state.sensor; + } + return state is SixSceneLoadingState + ? const Center( + child: DefaultContainer( + width: 50, + height: 50, + child: CircularProgressIndicator()), + ) + : RefreshIndicator( + onRefresh: () async { + sensor.add(const SixSceneInitial()); + }, + child: ListView( + children: [ + CircleAvatar( + radius: 60, + backgroundColor: Colors.white, + child: CircleAvatar( + radius: 55, + backgroundColor: Colors.grey, + child: ClipOval( + child: SvgPicture.asset( + Assets.sosProfileIcon, + fit: BoxFit.fill, + ), + ), + ), + ), + const SizedBox( + height: 10, + ), + SizedBox( + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + IntrinsicWidth( + child: ConstrainedBox( + constraints: + const BoxConstraints(maxWidth: 200), + child: TextFormField( + maxLength: 30, + style: const TextStyle( + color: Colors.black, + ), + textAlign: TextAlign.center, + focusNode: sensor.focusNode, + controller: sensor.nameController, + enabled: sensor.editName, + onEditingComplete: () { + // sensor.add(SaveNameEvent(context: context)); + }, + decoration: const InputDecoration( + hintText: "Your Name", + border: InputBorder.none, + fillColor: Colors.white10, + counterText: '', + ), + ), + ), + ), + const SizedBox(width: 5), + InkWell( + onTap: () { + sensor + .add(const ChangeNameEvent(value: true)); + }, + child: const Padding( + padding: EdgeInsets.symmetric(horizontal: 10), + child: Icon( + Icons.edit_outlined, + size: 20, + color: ColorsManager.textPrimaryColor, + ), + ), + ), + ], + ), + ), + const SizedBox(height: 20), + const BodyMedium( + text: 'Smart Device Information', + fontWeight: FontWeight.w700, + fontSize: 12, + fontColor: ColorsManager.grayColor, + ), + DefaultContainer( + padding: const EdgeInsets.all(20), + child: InkWell( + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => LocationSixScenePage( + space: spaces!.first, + )), + ); + }, + child: const Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + SizedBox( + child: Text('Location'), + ), + Row( + children: [ + SizedBox( + child: BodyMedium( + text: 'Syncroom', + fontColor: ColorsManager.textGray, + ), + ), + Icon( + Icons.arrow_forward_ios, + size: 15, + color: ColorsManager.textGray, + ), + ], + ) + ], + ), + ), + ) + ], + ), + ); + }, + ), + ), + ); + } +} diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_settings.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_settings.dart new file mode 100644 index 0000000..b02274d --- /dev/null +++ b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_settings.dart @@ -0,0 +1,520 @@ +import 'package:flutter/cupertino.dart'; +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/6_scene_switch_bloc/6_scene_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart'; +import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart'; +import 'package:syncrow_app/features/devices/model/device_model.dart'; +import 'package:syncrow_app/features/devices/model/six_scene_model.dart'; +import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/6_scene_setting/faq_six_scene_page.dart'; +import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/6_scene_setting/share_six_scene_page.dart'; +import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_create_group.dart'; +import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_delete_dialog.dart'; +import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_info_page.dart'; +import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_profile_page.dart'; +import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_update_dialog.dart'; +import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_update_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_medium.dart'; +import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart'; +import 'package:syncrow_app/generated/assets.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +class SixSceneSettings extends StatelessWidget { + final DeviceModel? device; + + const SixSceneSettings({super.key, this.device}); + + @override + Widget build(BuildContext context) { + return DefaultScaffold( + title: 'Device Settings', + child: BlocProvider( + create: (context) => SixSceneBloc(sixSceneId: device?.uuid ?? '') + ..add(const SixSceneInitial()), + child: BlocBuilder( + builder: (context, state) { + final sensor = BlocProvider.of(context); + SixSceneModel model = SixSceneModel( + batteryPercentage: 0, waterContactState: 'normal'); + if (state is LoadingNewSate) { + model = state.sosSensor; + } else if (state is UpdateState) { + model = state.sensor; + } + return state is SixSceneLoadingState + ? const Center( + child: DefaultContainer( + width: 50, + height: 50, + child: CircularProgressIndicator()), + ) + : RefreshIndicator( + onRefresh: () async { + sensor.add(const SixSceneInitial()); + }, + child: ListView( + children: [ + Padding( + padding: const EdgeInsets.symmetric( + vertical: 10, + ), + child: InkWell( + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => + const SixSceneProfilePage(), + ), + ); + }, + child: Stack( + children: [ + const Column( + crossAxisAlignment: + CrossAxisAlignment.stretch, + children: [ + SizedBox(height: 20), + DefaultContainer( + borderRadius: + BorderRadius.all(Radius.circular(30)), + child: Padding( + padding: EdgeInsets.all(10.0), + child: Padding( + padding: EdgeInsets.only(left: 90), + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + BodyMedium( + text: '6 Scene Switch', + fontWeight: FontWeight.bold, + ), + SizedBox( + height: 5, + ), + BodySmall( + text: "Room: Syncrow"), + ], + ), + Icon(Icons.edit_sharp) + ], + ), + ), + ), + ), + ], + ), + Positioned( + top: 0, + left: 20, + child: CircleAvatar( + radius: 43, + backgroundColor: Colors.white, + child: CircleAvatar( + radius: 40, + backgroundColor: Colors.white, + child: CircleAvatar( + radius: 40, + backgroundColor: + ColorsManager.backgroundColor, + child: SvgPicture.asset( + Assets.sixSceneIcon, + fit: BoxFit.fill, + ), + ), + )), + ), + ], + ), + ), + ), + const SizedBox(height: 20), + const BodyMedium( + text: 'Device Management', + fontWeight: FontWeight.w700, + fontSize: 12, + fontColor: ColorsManager.grayColor, + ), + DefaultContainer( + child: Column( + children: [ + SettingWidget( + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => + const SixSceneInfoPage()), + ); + }, + text: 'Device Information', + icon: Assets.infoIcon, + ), + const Divider( + color: ColorsManager.dividerColor, + ), + SettingWidget( + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => + ShareSixScenePage(device: device!)), + ); + }, + text: 'Tap-to Run and Automation', + icon: Assets.tapRunIcon, + ), + ], + ), + ), + const SizedBox(height: 20), + const BodyMedium( + text: 'Device Offline Notification', + fontWeight: FontWeight.w700, + fontSize: 12, + fontColor: ColorsManager.grayColor, + ), + DefaultContainer( + child: Column( + children: [ + SettingWidget( + onChanged: (p0) {}, + isNotification: true, + onTap: () {}, + text: 'Offline Notification', + icon: Assets.notificationIcon, + ), + ], + ), + ), + const SizedBox(height: 20), + const BodyMedium( + text: 'Others', + fontWeight: FontWeight.w700, + fontSize: 12, + fontColor: ColorsManager.grayColor, + ), + const SizedBox(height: 5), + DefaultContainer( + child: Column( + children: [ + SettingWidget( + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => + ShareSixScenePage(device: device!)), + ); + }, + text: 'Share Device', + icon: Assets.shareIcon, + ), + const Divider( + color: ColorsManager.dividerColor, + ), + SettingWidget( + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => + SixSceneCreateGroup( + device: device!)), + ); + }, + text: 'Create Group', + icon: Assets.createGroupIcon, + ), + const Divider( + color: ColorsManager.dividerColor, + ), + SettingWidget( + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => + FaqSixScenePage(device: device!)), + ); + }, + text: 'Device FAQ', + icon: Assets.faqIcon, + ), + const Divider( + color: ColorsManager.dividerColor, + ), + SettingWidget( + onTapUpdate: () { + showDialog( + context: context, + builder: (context) { + return UpdateInfoDialog( + cancelTab: () { + Navigator.of(context).pop(); + }, + confirmTab: () { + // context + // .read< + // CreateSceneBloc>() + // .add(DeleteSceneEvent( + // sceneId: sceneId, + // unitUuid: HomeCubit + // .getInstance() + // .selectedSpace! + // .id!, + // )); + Navigator.of(context).pop(); + }, + ); + }, + ); + }, + isUpdate: true, + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => + const SixSceneUpdatePage()), + ); + }, + text: 'Device Update', + icon: Assets.updateIcon, + ), + ], + ), + ), + const SizedBox(height: 20), + InkWell( + onTap: () { + showModalBottomSheet( + context: context, + builder: (BuildContext context) { + return Container( + height: 200, + padding: const EdgeInsets.all(16.0), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const BodyMedium( + text: 'Remove Device', + fontWeight: FontWeight.w700, + fontSize: 16, + fontColor: ColorsManager.red, + ), + const SizedBox(height: 10), + const SizedBox( + width: 250, + child: Divider( + color: ColorsManager.dividerColor, + ), + ), + const SizedBox(height: 10), + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + InkWell( + onTap: () { + showDialog( + context: context, + builder: (context) { + return DisconnectDeviceDialog( + cancelTab: () { + Navigator.of(context) + .pop(); + }, + confirmTab: () { + // context + // .read< + // CreateSceneBloc>() + // .add(DeleteSceneEvent( + // sceneId: sceneId, + // unitUuid: HomeCubit + // .getInstance() + // .selectedSpace! + // .id!, + // )); + Navigator.of(context) + .pop(); + }, + ); + }, + ); + }, + child: const BodyMedium( + text: 'Disconnect Device', + fontWeight: FontWeight.w400, + fontSize: 15, + fontColor: ColorsManager + .textPrimaryColor, + ), + ), + const Icon( + Icons.keyboard_arrow_right, + color: ColorsManager.textGray, + ) + ], + ), + const SizedBox(height: 20), + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + InkWell( + onTap: () { + showDialog( + context: context, + builder: (context) { + return DisconnectWipeData( + cancelTab: () { + Navigator.of(context) + .pop(); + }, + confirmTab: () { + // context + // .read< + // CreateSceneBloc>() + // .add(DeleteSceneEvent( + // sceneId: sceneId, + // unitUuid: HomeCubit + // .getInstance() + // .selectedSpace! + // .id!, + // )); + Navigator.of(context) + .pop(); + }, + ); + }, + ); + }, + child: const BodyMedium( + text: + 'Disconnect Device and Wipe Data', + fontWeight: FontWeight.w400, + fontSize: 15, + fontColor: ColorsManager + .textPrimaryColor, + ), + ), + const Icon( + Icons.keyboard_arrow_right, + color: ColorsManager.textGray, + ) + ], + ), + ], + ), + ); + }, + ); + }, + child: const Center( + child: BodyMedium( + text: 'Remove Device', + fontWeight: FontWeight.w400, + fontSize: 15, + fontColor: ColorsManager.red, + ), + ), + ), + ], + ), + ); + }, + ), + ), + ); + } +} + +class SettingWidget extends StatelessWidget { + final String? text; + final bool? isUpdate; + final bool? isNotification; + final String? icon; + final Function()? onTap; + final Function()? onTapUpdate; + final Function(bool)? onChanged; + const SettingWidget( + {super.key, + this.text, + this.icon, + this.onTap, + this.isUpdate, + this.onChanged, + this.isNotification = false, + this.onTapUpdate}); + + @override + Widget build(BuildContext context) { + return InkWell( + onTap: onTap, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Row( + children: [ + Expanded( + flex: 2, + child: Container( + padding: EdgeInsets.all(8), + decoration: const BoxDecoration( + color: ColorsManager.primaryColor, + borderRadius: BorderRadius.all(Radius.circular(20))), + child: SvgPicture.asset( + icon!, + fit: BoxFit.none, + height: 30, + ), + ), + ), + const SizedBox( + width: 8, + ), + Expanded( + flex: isUpdate == true ? 5 : 10, + child: BodyMedium( + text: text!, + fontSize: 15, + fontWeight: FontWeight.w400, + )), + ], + ), + ), + isUpdate == true + ? InkWell( + onTap: onTapUpdate, + child: BodyMedium( + text: '1 Update Available', + fontSize: 13, + fontWeight: FontWeight.w400, + fontColor: ColorsManager.blueColor, + ), + ) + : SizedBox(), + isNotification == false + ? const Icon( + Icons.arrow_forward_ios, + color: ColorsManager.graysColor, + size: 20, + ) + : Transform.scale( + scale: .8, + child: CupertinoSwitch( + value: true, + onChanged: onChanged, + applyTheme: true, + ), + ), + ], + ), + ); + } +} diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_update_dialog.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_update_dialog.dart new file mode 100644 index 0000000..0529161 --- /dev/null +++ b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_update_dialog.dart @@ -0,0 +1,118 @@ +import 'package:flutter/material.dart'; +import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +class UpdateInfoDialog extends StatelessWidget { + final Function()? cancelTab; + final Function()? confirmTab; + + const UpdateInfoDialog({ + super.key, + required this.cancelTab, + required this.confirmTab, + }); + + @override + Widget build(BuildContext context) { + return AlertDialog( + contentPadding: EdgeInsets.zero, + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const SizedBox( + height: 10, + ), + BodyLarge( + text: 'Update Available', + fontWeight: FontWeight.w700, + fontColor: ColorsManager.switchButton.withOpacity(0.6), + fontSize: 16, + ), + const Padding( + padding: EdgeInsets.only(left: 15, right: 15), + child: Divider( + color: ColorsManager.textGray, + ), + ), + const Padding( + padding: EdgeInsets.only(left: 15, right: 20, top: 15, bottom: 20), + child: Column( + children: [ + Center( + child: Text( + 'An update is available for your device. Version 2.1.0 includes new features and important fixes to enhance performance and security.', + textAlign: TextAlign.center, + )), + ], + ), + ), + 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: cancelTab, + child: const Padding( + padding: const EdgeInsets.only(top: 15, bottom: 15), + child: Center( + child: Text( + 'Remind me later', + 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: confirmTab, + child: Padding( + padding: const EdgeInsets.only(top: 15, bottom: 15), + child: Center( + child: Text( + 'Update Now', + style: TextStyle( + color: + ColorsManager.switchButton.withOpacity(0.6), + fontSize: 14, + fontWeight: FontWeight.w400), + ), + ), + )), + )) + ], + ) + ], + ), + ); + } +} diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_update_note.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_update_note.dart new file mode 100644 index 0000000..3023d3e --- /dev/null +++ b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_update_note.dart @@ -0,0 +1,118 @@ +import 'package:flutter/material.dart'; +import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +class upDateNote extends StatelessWidget { + final Function()? cancelTab; + final Function()? confirmTab; + + const upDateNote({ + super.key, + required this.cancelTab, + required this.confirmTab, + }); + + @override + Widget build(BuildContext context) { + return AlertDialog( + contentPadding: EdgeInsets.zero, + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const SizedBox( + height: 10, + ), + BodyLarge( + text: 'Update Note', + fontWeight: FontWeight.w700, + fontColor: ColorsManager.switchButton.withOpacity(0.6), + fontSize: 16, + ), + const Padding( + padding: EdgeInsets.only(left: 15, right: 15), + child: Divider( + color: ColorsManager.textGray, + ), + ), + const Padding( + padding: EdgeInsets.only(left: 15, right: 20, top: 15, bottom: 20), + child: Column( + children: [ + Center( + child: Text( + 'This update may take a long time. Make sure that the device is fully charged. The device will be unavailable during the update.', + textAlign: TextAlign.center, + )), + ], + ), + ), + 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: cancelTab, + child: const Padding( + padding: const EdgeInsets.only(top: 15, bottom: 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: confirmTab, + child: Padding( + padding: const EdgeInsets.only(top: 15, bottom: 15), + child: Center( + child: Text( + 'Start Update', + style: TextStyle( + color: + ColorsManager.switchButton.withOpacity(0.6), + fontSize: 14, + fontWeight: FontWeight.w400), + ), + ), + )), + )) + ], + ) + ], + ), + ); + } +} diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_update_page.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_update_page.dart new file mode 100644 index 0000000..b8c0019 --- /dev/null +++ b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_update_page.dart @@ -0,0 +1,345 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:percent_indicator/linear_percent_indicator.dart'; +import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart'; +import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart'; +import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_update_note.dart'; +import 'package:syncrow_app/features/shared_widgets/default_button.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_medium.dart'; +import 'package:syncrow_app/generated/assets.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +class SixSceneUpdatePage extends StatelessWidget { + const SixSceneUpdatePage({super.key}); + + @override + Widget build(BuildContext context) { + return DefaultScaffold( + title: 'Device Update', + child: BlocProvider( + create: (context) => + SixSceneBloc(sixSceneId: '')..add(const SixSceneInitial()), + child: BlocBuilder( + builder: (context, state) { + return state is SixSceneLoadingState + ? const Center( + child: DefaultContainer( + width: 50, + height: 50, + child: CircularProgressIndicator()), + ) + : RefreshIndicator( + onRefresh: () async {}, + child: Column( + children: [ + // SizedBox( + // height: MediaQuery.of(context).size.height * 0.15, + // ), + DefaultContainer( + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + height: 50, + child: ListTile( + contentPadding: EdgeInsets.zero, + leading: SizedBox( + width: 200, + child: Row( + children: [ + Container( + padding: const EdgeInsets.all(10), + decoration: const BoxDecoration( + color: ColorsManager + .primaryColor, + borderRadius: + BorderRadius.all( + Radius.circular(50))), + child: SvgPicture.asset( + Assets.checkUpdateIcon, + fit: BoxFit.fill, + height: 25, + ), + ), + const SizedBox( + width: 10, + ), + InkWell( + onTap: () {}, + child: const BodyMedium( + text: 'Automatic Update', + fontWeight: FontWeight.normal, + ), + ), + ], + ), + ), + trailing: Container( + width: 100, + child: Row( + mainAxisAlignment: + MainAxisAlignment.end, + children: [ + const BodyMedium( + text: 'Off', + fontColor: ColorsManager.textGray, + ), + Transform.scale( + scale: .8, + child: CupertinoSwitch( + value: true, + onChanged: (value) {}, + applyTheme: true, + ), + ), + ], + ), + )), + ), + ], + ), + ), + const SizedBox( + height: 10, + ), + UpdateSosContainerWithProgressBar( + sosDescription: + 'Connectivity Issue Resolved Fixed a bug that caused the SOS button to disconnect from the app intermittently.', + sosVersion: 'SOS v2.0.5', + ), + // const UpdatedContainer( + // sosVersion: 'SOS v1.0.13', + // sosDescription: 'SOS is up to date', + // ), + + // const NewUpdateContainer( + // sosVersion: 'SOS v2.0.5', + // sosDescription: + // 'Connectivity Issue Resolved Fixed a bug that caused the SOS button to disconnect from the app intermittently.', + // ), + const SizedBox( + height: 15, + ), + ], + )); + }, + ), + )); + } +} + +class UpdatedContainer extends StatelessWidget { + final String? sosVersion; + final String? sosDescription; + const UpdatedContainer({ + this.sosVersion, + this.sosDescription, + super.key, + }); + + @override + Widget build(BuildContext context) { + return DefaultContainer( + height: MediaQuery.of(context).size.height * 0.35, + child: Padding( + padding: const EdgeInsets.all(25), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SvgPicture.asset( + Assets.emptyUpdateIcon, + fit: BoxFit.fill, + ), + BodyMedium( + text: sosVersion!, + fontColor: ColorsManager.primaryTextColor, + ), + BodyMedium( + text: sosDescription!, + fontColor: ColorsManager.blackColor, + ), + ], + ), + ], + ), + ), + ); + } +} + +class NewUpdateContainer extends StatelessWidget { + final String? sosVersion; + final String? sosDescription; + const NewUpdateContainer({ + this.sosVersion, + this.sosDescription, + super.key, + }); + + @override + Widget build(BuildContext context) { + return DefaultContainer( + height: MediaQuery.of(context).size.height * 0.50, + child: Padding( + padding: const EdgeInsets.all(25), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SvgPicture.asset( + Assets.emptyUpdateIcon, + fit: BoxFit.fill, + ), + const BodyMedium( + text: 'New Update Available Now!', + fontColor: ColorsManager.blueColor, + ), + BodyMedium( + text: sosVersion!, + fontColor: ColorsManager.primaryTextColor, + ), + Container( + width: MediaQuery.of(context).size.width * 0.7, + child: BodyMedium( + text: sosDescription!, + fontColor: ColorsManager.textPrimaryColor, + textAlign: TextAlign.center, + ), + ), + SizedBox( + width: MediaQuery.of(context).size.width * 0.6, + child: DefaultButton( + borderRadius: 25, + backgroundColor: ColorsManager.blueColor1, + height: 150, + onPressed: () { + showDialog( + context: context, + builder: (context) { + return upDateNote( + cancelTab: () { + Navigator.of(context).pop(); + }, + confirmTab: () { + Navigator.of(context).pop(); + }, + ); + }, + ); + }, + child: const BodyMedium( + text: 'Update Now', + fontColor: Colors.white, + fontSize: 16, + fontWeight: FontWeight.w700, + textAlign: TextAlign.center, + ), + ), + ) + ], + ), + ], + ), + ), + ); + } +} + +class UpdateSosContainerWithProgressBar extends StatelessWidget { + final String? sosVersion; + final String? sosDescription; + const UpdateSosContainerWithProgressBar({ + this.sosVersion, + this.sosDescription, + super.key, + }); + + @override + Widget build(BuildContext context) { + return Column( + children: [ + DefaultContainer( + height: MediaQuery.of(context).size.height * 0.50, + child: Padding( + padding: const EdgeInsets.all(25), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SvgPicture.asset( + Assets.emptyUpdateIcon, + fit: BoxFit.fill, + ), + BodyMedium( + text: 'New Update Available Now!', + fontColor: ColorsManager.blueColor, + ), + BodyMedium( + text: sosVersion!, + fontColor: ColorsManager.primaryTextColor, + ), + SizedBox( + width: MediaQuery.of(context).size.width * 0.7, + child: BodyMedium( + text: sosDescription!, + fontColor: ColorsManager.textPrimaryColor, + textAlign: TextAlign.center, + ), + ), + LinearPercentIndicator( + barRadius: Radius.circular(10), + width: 170.0, + animation: true, + animationDuration: 1000, + lineHeight: 5.0, + percent: 0.2, + linearStrokeCap: LinearStrokeCap.butt, + progressColor: ColorsManager.blueColor1, + ), + SizedBox( + width: MediaQuery.of(context).size.width * 0.7, + child: const BodyMedium( + text: 'Downloading Update please be patient', + fontColor: ColorsManager.textPrimaryColor, + textAlign: TextAlign.center, + ), + ), + ], + ), + ], + ), + ), + ), + SizedBox( + width: MediaQuery.of(context).size.width * 0.7, + child: const BodyMedium( + text: + 'Please keep the power of the device connected during the upgrade process.', + fontColor: ColorsManager.textPrimaryColor, + textAlign: TextAlign.center, + ), + ), + ], + ); + } +} diff --git a/lib/features/devices/view/widgets/6_scene_switch/select_scene_page.dart b/lib/features/devices/view/widgets/6_scene_switch/select_scene_page.dart new file mode 100644 index 0000000..34ec82a --- /dev/null +++ b/lib/features/devices/view/widgets/6_scene_switch/select_scene_page.dart @@ -0,0 +1,286 @@ +import 'dart:typed_data'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart'; +import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart'; +import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart'; +import 'package:syncrow_app/features/devices/view/widgets/restart_status_dialog.dart'; +import 'package:syncrow_app/features/scene/model/scene_settings_route_arguments.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_medium.dart'; +import 'package:syncrow_app/generated/assets.dart'; +import 'package:syncrow_app/navigation/navigation_service.dart'; +import 'package:syncrow_app/navigation/routing_constants.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +class SelectSceneSixPage extends StatelessWidget { + SelectSceneSixPage({super.key}); + + final TextEditingController _searchController = TextEditingController(); + final int? selectedSwitchIndex = 0; + final spaces = HomeCubit.getInstance().spaces; + + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (context) => SixSceneBloc(sixSceneId: '') + ..add(LoadScenes( + unit: spaces!.first, + unitId: spaces!.first.id, + showInDevice: false, + )), + child: BlocBuilder( + builder: (context, state) { + final sensorBloc = BlocProvider.of(context); + + return DefaultScaffold( + title: 'Select Scene', + actions: [_buildSaveButton(context, state, sensorBloc)], + child: state is SixSceneLoadingState + ? _buildLoadingIndicator() + : _buildSceneContent(context, sensorBloc), + ); + }, + ), + ); + } + + // Save button builder + Widget _buildSaveButton( + BuildContext context, SixSceneState state, SixSceneBloc sensorBloc) { + final bool canSave = + state is OptionSelectedState && state.hasSelectionChanged; + + return GestureDetector( + onTap: canSave + ? () { + print('object'); + context.read().add(SaveSelectionEvent()); + } + : null, + child: BodyMedium( + text: 'Save', + fontWeight: FontWeight.w700, + fontSize: 16, + fontColor: canSave + ? ColorsManager.slidingBlueColor + : ColorsManager.primaryTextColor, + ), + ); + } + + // Loading indicator + Widget _buildLoadingIndicator() { + return const Center( + child: DefaultContainer( + width: 50, + height: 50, + child: CircularProgressIndicator(), + ), + ); + } + + // Main scene content with search bar and grid + Widget _buildSceneContent(BuildContext context, SixSceneBloc sensorBloc) { + return Column( + children: [ + _buildSearchBar(sensorBloc), + const SizedBox(height: 20), + Expanded( + child: _buildSceneGrid(sensorBloc), + ), + ], + ); + } + + // Search bar widget + Widget _buildSearchBar(SixSceneBloc sensorBloc) { + return TextFormField( + controller: _searchController, + onChanged: (value) { + sensorBloc.add(SearchScenesEvent(query: value)); + }, + decoration: InputDecoration( + hintText: 'Search', + hintStyle: const TextStyle( + color: ColorsManager.textGray, + fontSize: 16, + fontWeight: FontWeight.w400), + suffixIcon: Container( + padding: const EdgeInsets.all(5.0), + margin: const EdgeInsets.all(10.0), + child: SvgPicture.asset( + Assets.searchIcon, + fit: BoxFit.contain, + ), + ), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(8.0), + ), + ), + ); + } + + // Scene grid builder + Widget _buildSceneGrid(SixSceneBloc sensorBloc) { + final scenes = sensorBloc.filteredScenes; + + return GridView.builder( + itemCount: scenes.length + 1, + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + mainAxisSpacing: 16, + crossAxisSpacing: 16, + mainAxisExtent: 120, + ), + itemBuilder: (context, index) { + if (index == scenes.length) { + return InkWell( + onTap: () => Navigator.pushNamed( + NavigationService.navigatorKey.currentContext!, + Routes.sceneTasksRoute, + arguments: SceneSettingsRouteArguments( + sceneType: '', + sceneId: '', + sceneName: '', + ), + ), + child: CreateSceneItem(), + ); + } else { + final scene = scenes[index]; + return SceneItem( + id: scene.id, + value: sensorBloc.selectedSceneId == scene.id, + disablePlayButton: false, + onChanged: (isSelected) { + sensorBloc.selectedSceneId = isSelected ? scene.id : 'null'; + sensorBloc.add(SelectOptionEvent(selectedOption: scene.id)); + }, + icon: scene.iconInBytes, + title: scene.name, + ); + } + }, + ); + } +} + +class SceneItem extends StatefulWidget { + final String id; // Unique ID for each scene + final Uint8List icon; + final String title; + final bool disablePlayButton; + final bool value; + final Function(bool) onChanged; + + const SceneItem({ + required this.id, + required this.icon, + required this.title, + this.disablePlayButton = false, + required this.value, + required this.onChanged, + }); + + @override + State createState() => _SceneItemState(); +} + +class _SceneItemState extends State { + @override + Widget build(BuildContext context) { + return Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(20), + boxShadow: const [ + BoxShadow( + color: Colors.black12, + blurRadius: 2, + spreadRadius: 1, + offset: Offset(0, 3), + ), + ], + ), + padding: const EdgeInsets.all(16), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + if (!widget.disablePlayButton) + Image.memory( + widget.icon, + height: 32, + width: 32, + fit: BoxFit.fill, + errorBuilder: (context, error, stackTrace) => Image.asset( + Assets.assetsIconsLogo, + height: 32, + width: 32, + fit: BoxFit.fill), + ), + BodyMedium( + text: widget.title, + style: const TextStyle( + fontSize: 17, + fontWeight: FontWeight.w700, + color: ColorsManager.secondaryTextColor), + textAlign: TextAlign.center, + ), + ], + ), + CircularCheckbox( + value: widget.value, + onChanged: (isSelected) => widget.onChanged(isSelected!), + ), + ], + ), + ); + } +} + +// Widget for the static "Create Scene" button +class CreateSceneItem extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(20), + boxShadow: const [ + BoxShadow( + color: Colors.black12, + blurRadius: 5, + spreadRadius: 2, + offset: Offset(0, 3), + ), + ], + ), + padding: const EdgeInsets.all(16), + child: const Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Icon(Icons.add_circle, + color: ColorsManager.grayButtonColors, size: 36), + BodyMedium( + text: 'Create Scene', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w400, + color: ColorsManager.secondaryTextColor), + textAlign: TextAlign.center, + ), + ], + ), + ); + } +} diff --git a/lib/features/devices/view/widgets/6_scene_switch/select_switch_dialog.dart b/lib/features/devices/view/widgets/6_scene_switch/select_switch_dialog.dart new file mode 100644 index 0000000..453722c --- /dev/null +++ b/lib/features/devices/view/widgets/6_scene_switch/select_switch_dialog.dart @@ -0,0 +1,146 @@ +import 'package:flutter/material.dart'; +import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/switches_card.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'; + +class SelectSwitchDialog extends StatefulWidget { + final Function()? cancelTab; + final Function()? confirmTab; + + const SelectSwitchDialog({ + super.key, + required this.cancelTab, + required this.confirmTab, + }); + + @override + State createState() => _SelectSwitchDialogState(); +} + +class _SelectSwitchDialogState extends State { + int? selectedSwitchIndex = 0; // State variable to track selected switch + + @override + Widget build(BuildContext context) { + return AlertDialog( + backgroundColor: ColorsManager.onPrimaryColor, + contentPadding: EdgeInsets.zero, + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const SizedBox(height: 10), + const BodyLarge( + text: 'Select Switch', + fontWeight: FontWeight.w700, + fontColor: ColorsManager.primaryColor, + fontSize: 16, + ), + const Padding( + padding: EdgeInsets.only(left: 15, right: 15), + child: Divider(color: ColorsManager.textGray), + ), + const SizedBox(height: 20), + Row( + children: [ + SwitchsCard( + switch1Down: selectedSwitchIndex == -1 + ? Assets.removeSceneIcon + : Assets.addSwitchIcon, + switch1Up: selectedSwitchIndex == 1 + ? Assets.removeSceneIcon + : Assets.addSwitchIcon, + switch2Down: selectedSwitchIndex == -2 + ? Assets.removeSceneIcon + : Assets.addSwitchIcon, + switch2Up: selectedSwitchIndex == 2 + ? Assets.removeSceneIcon + : Assets.addSwitchIcon, + + onSwitch1UpTap: () { + setState(() => selectedSwitchIndex = 1); + }, + onSwitch1DownTap: () { + setState(() => selectedSwitchIndex = -1); + }, + onSwitch2UpTap: () { + setState(() => selectedSwitchIndex = 2); + }, + onSwitch2DownTap: () { + setState(() => selectedSwitchIndex = -2); + }, + + + ), + ], + ), + const SizedBox(height: 20), + const Center( + child: Text( + 'Please select one of the switches available to continue', + textAlign: TextAlign.center, + ), + ), + 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.textPrimaryColor, + 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: selectedSwitchIndex == 0 ? () {} : widget.confirmTab, + child: Padding( + padding: EdgeInsets.all(15), + child: Center( + child: Text( + 'Next', + style: TextStyle( + color: selectedSwitchIndex == 0 + ? ColorsManager.textPrimaryColor + .withOpacity(0.6) + : ColorsManager.primaryColor, + fontSize: 14, + fontWeight: FontWeight.w400), + ), + ), + ), + ), + ), + ), + ], + ) + ], + ), + ); + } +} diff --git a/lib/features/devices/view/widgets/6_scene_switch/six_scene_screen.dart b/lib/features/devices/view/widgets/6_scene_switch/six_scene_screen.dart new file mode 100644 index 0000000..f502a55 --- /dev/null +++ b/lib/features/devices/view/widgets/6_scene_switch/six_scene_screen.dart @@ -0,0 +1,200 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart'; +import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart'; +import 'package:syncrow_app/features/devices/model/device_model.dart'; +import 'package:syncrow_app/features/devices/model/six_scene_model.dart'; +import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_settings.dart'; +import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/select_scene_page.dart'; +import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/select_switch_dialog.dart'; +import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/switches_card.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 SixSceneScreen extends StatelessWidget { + final DeviceModel? device; + + const SixSceneScreen({super.key, this.device}); + + @override + Widget build(BuildContext context) { + return DefaultScaffold( + title: '6 Scene Switch', + actions: [ + InkWell( + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => SixSceneSettings(device: device!)), + ); + }, + child: SvgPicture.asset(Assets.assetsIconsSettings)), + const SizedBox( + width: 10, + ) + ], + child: BlocProvider( + create: (context) => SixSceneBloc(sixSceneId: device?.uuid ?? '') + ..add(const SixSceneInitial()), + child: BlocBuilder( + builder: (context, state) { + final sensor = BlocProvider.of(context); + SixSceneModel model = SixSceneModel( + batteryPercentage: 0, waterContactState: 'normal'); + if (state is LoadingNewSate) { + model = state.sosSensor; + } else if (state is UpdateState) { + model = state.sensor; + } + return state is SixSceneLoadingState + ? const Center( + child: DefaultContainer( + width: 50, + height: 50, + child: CircularProgressIndicator()), + ) + : RefreshIndicator( + onRefresh: () async { + sensor.add(const SixSceneInitial()); + }, + child: ListView( + children: [ + SizedBox( + height: MediaQuery.sizeOf(context).height * 0.8, + child: Column( + children: [ + SwitchsCard( + switch1Down: sensor.switchStatus == true + ? Assets.switchOn + : Assets.switchOff, + switch1Up: sensor.switchStatus == true + ? Assets.switchOn + : Assets.switchOff, + switch2Down: sensor.switchStatus == true + ? Assets.switchOn + : Assets.switchOff, + switch2Up: sensor.switchStatus == true + ? Assets.switchOn + : Assets.switchOff, + + onSwitch1UpTap: () { + debugPrint("Switch 1 Up tapped"); + }, + onSwitch1DownTap: () { + debugPrint("Switch 1 Down tapped"); + }, + onSwitch2UpTap: () { + debugPrint("Switch 2 Up tapped"); + }, + onSwitch2DownTap: () { + debugPrint("Switch 2 Down tapped"); + }, + + ), + Flexible( + child: Row( + children: [ + Expanded( + child: DefaultContainer( + onTap: () { + sensor.add(ChangeSwitchStatusEvent()); + }, + child: Column( + crossAxisAlignment: + CrossAxisAlignment.center, + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + ConstrainedBox( + constraints: const BoxConstraints( + maxHeight: 46, maxWidth: 50), + child: SvgPicture.asset( + Assets.backlightIcon), + ), + const SizedBox( + height: 15, + ), + const Flexible( + child: FittedBox( + child: BodySmall( + text: 'Backlight', + textAlign: TextAlign.center, + ), + ), + ), + ], + ), + ), + ), + const SizedBox( + width: 10, + ), + Expanded( + child: DefaultContainer( + onTap: () { + showDialog( + context: context, + builder: (context) { + return SelectSwitchDialog( + cancelTab: () { + Navigator.of(context).pop(); + }, + confirmTab: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => + SelectSceneSixPage()), + ); + }, + ); + }, + ); + }, + child: Column( + crossAxisAlignment: + CrossAxisAlignment.center, + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + ConstrainedBox( + constraints: const BoxConstraints( + maxHeight: 46, maxWidth: 50), + child: SvgPicture.asset( + Assets.addSceneIcon), + ), + const SizedBox( + height: 15, + ), + const Flexible( + child: FittedBox( + child: BodySmall( + text: 'Add Scene', + textAlign: TextAlign.center, + ), + ), + ), + ], + ), + ), + ), + ], + ), + ) + ], + ), + ), + ], + ), + ); + }, + ), + ), + ); + } +} diff --git a/lib/features/devices/view/widgets/6_scene_switch/switches_card.dart b/lib/features/devices/view/widgets/6_scene_switch/switches_card.dart new file mode 100644 index 0000000..de4a0a3 --- /dev/null +++ b/lib/features/devices/view/widgets/6_scene_switch/switches_card.dart @@ -0,0 +1,135 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +class SwitchsCard extends StatelessWidget { + final String switch1Up; + final String switch1Down; + final String switch2Up; + final String switch2Down; + + final VoidCallback onSwitch1UpTap; + final VoidCallback onSwitch1DownTap; + final VoidCallback onSwitch2UpTap; + final VoidCallback onSwitch2DownTap; + + SwitchsCard({ + required this.switch1Down, + required this.switch1Up, + required this.switch2Down, + required this.switch2Up, + required this.onSwitch1UpTap, + required this.onSwitch1DownTap, + required this.onSwitch2UpTap, + required this.onSwitch2DownTap, + }); + + @override + Widget build(BuildContext context) { + return Expanded( + flex: 4, + child: InkWell( + overlayColor: MaterialStateProperty.all(Colors.transparent), + onTap: () {}, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Expanded( + child: Container( + margin: const EdgeInsets.symmetric(horizontal: 10), + decoration: const BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all(Radius.circular(10)), + ), + child: Container( + margin: const EdgeInsets.symmetric(horizontal: 10), + decoration: BoxDecoration( + color: ColorsManager.onPrimaryColor, + boxShadow: [ + BoxShadow( + color: Colors.white.withOpacity(0.1), + blurRadius: 24, + offset: const Offset(-2, -2), + blurStyle: BlurStyle.outer, + ), + BoxShadow( + color: Colors.black.withOpacity(0.11), + blurRadius: 5, + offset: const Offset(2, 0), + blurStyle: BlurStyle.outer, + ), + BoxShadow( + color: Colors.white.withOpacity(0.13), + blurRadius: 10, + offset: const Offset(5, 1), + blurStyle: BlurStyle.inner, + ), + ], + ), + child: SizedBox( + height: 300, + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + // Switch 1 + _buildSwitchColumn(switch1Up, switch1Down, + onSwitch1UpTap, onSwitch1DownTap), + _buildDivider(), + // Switch 2 + _buildSwitchColumn(switch2Up, switch2Down, + onSwitch2UpTap, onSwitch2DownTap), + ], + ), + ), + ), + ), + ), + ], + ), + ), + ); + } + + Widget _buildSwitchColumn( + String switchUp, + String switchDown, + VoidCallback onUpTap, + VoidCallback onDownTap, + ) { + return Expanded( + child: Padding( + padding: const EdgeInsets.only(top: 30, bottom: 30), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + InkWell( + onTap: onUpTap, + child: Container( + height: 20, + width: 20, + child: SvgPicture.asset(switchUp), + ), + ), + InkWell( + onTap: onDownTap, + child: Container( + height: 20, + width: 20, + child: SvgPicture.asset(switchDown), + ), + ), + ], + ), + ), + ); + } + + Widget _buildDivider() { + return Container( + width: 3, + color: ColorsManager.dividerColor, + ); + } +} diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_screen.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_screen.dart new file mode 100644 index 0000000..34e79ef --- /dev/null +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_screen.dart @@ -0,0 +1,204 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_event.dart'; +import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_state.dart'; +import 'package:syncrow_app/features/devices/model/device_model.dart'; +import 'package:syncrow_app/features/devices/model/four_scene_model.dart'; +import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart'; +import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_select_scene_page.dart'; +import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_select_switch_dialog.dart'; +import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_switches_card.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 FourSceneScreen extends StatelessWidget { + final DeviceModel? device; + + const FourSceneScreen({super.key, this.device}); + + @override + Widget build(BuildContext context) { + return DefaultScaffold( + title: '4 Scene Switch', + actions: [ + InkWell( + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => FourSceneSettings(device: device!)), + ); + }, + child: SvgPicture.asset(Assets.assetsIconsSettings)), + const SizedBox( + width: 10, + ) + ], + child: BlocProvider( + create: (context) => FourSceneBloc(fourSceneId: device?.uuid ?? '') + ..add(const FourSceneInitial()) + ..add(FourSceneInitialInfo()), + child: BlocBuilder( + builder: (context, state) { + final sensor = BlocProvider.of(context); + FourSceneModel model = FourSceneModel( + scene_1: '', + scene_2: '', + scene_3: '', + scene_4: '', + scene_id_group_id: '', + switch_backlight: ''); + if (state is LoadingNewSate) { + model = state.sosSensor; + } else if (state is UpdateState) { + model = state.sensor; + } + return state is FourSceneLoadingState + ? const Center( + child: DefaultContainer( + width: 50, + height: 50, + child: CircularProgressIndicator()), + ) + : RefreshIndicator( + onRefresh: () async { + sensor.add(const FourSceneInitial()); + }, + child: ListView( + children: [ + SizedBox( + height: MediaQuery.sizeOf(context).height * 0.8, + child: Column( + children: [ + FourSwitchsCard( + switch1Down: sensor.switchStatus == true + ? Assets.switchOn + : Assets.switchOff, + switch1Up: sensor.switchStatus == true + ? Assets.switchOn + : Assets.switchOff, + switch2Down: sensor.switchStatus == true + ? Assets.switchOn + : Assets.switchOff, + switch2Up: sensor.switchStatus == true + ? Assets.switchOn + : Assets.switchOff, + onSwitch1UpTap: () { + debugPrint("Switch 1 Up tapped"); + }, + onSwitch1DownTap: () { + debugPrint("Switch 1 Down tapped"); + }, + onSwitch2UpTap: () { + debugPrint("Switch 2 Up tapped"); + }, + onSwitch2DownTap: () { + debugPrint("Switch 2 Down tapped"); + }, + ), + Flexible( + child: Row( + children: [ + Expanded( + child: DefaultContainer( + onTap: () { + sensor.add(ChangeSwitchStatusEvent()); + }, + child: Column( + crossAxisAlignment: + CrossAxisAlignment.center, + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + ConstrainedBox( + constraints: const BoxConstraints( + maxHeight: 46, maxWidth: 50), + child: SvgPicture.asset( + Assets.backlightIcon), + ), + const SizedBox( + height: 15, + ), + const Flexible( + child: FittedBox( + child: BodySmall( + text: 'Backlight', + textAlign: TextAlign.center, + ), + ), + ), + ], + ), + ), + ), + const SizedBox( + width: 10, + ), + Expanded( + child: DefaultContainer( + onTap: () { + showDialog( + context: context, + builder: (context) { + return FourSelectSwitchDialog( + cancelTab: () { + Navigator.of(context).pop(); + }, + confirmTab: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => + FourSelectSceneFourPage()), + ); + }, + ); + }, + ); + }, + child: Column( + crossAxisAlignment: + CrossAxisAlignment.center, + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + ConstrainedBox( + constraints: const BoxConstraints( + maxHeight: 46, maxWidth: 50), + child: SvgPicture.asset( + Assets.addSceneIcon), + ), + const SizedBox( + height: 15, + ), + const Flexible( + child: FittedBox( + child: BodySmall( + text: 'Add Scene', + textAlign: TextAlign.center, + ), + ), + ), + ], + ), + ), + ), + ], + ), + ) + ], + ), + ), + ], + ), + ); + }, + ), + ), + ); + } +} diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/faq_four_scene_page.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/faq_four_scene_page.dart new file mode 100644 index 0000000..0787e38 --- /dev/null +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/faq_four_scene_page.dart @@ -0,0 +1,151 @@ +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/four_scene_bloc/four_scene_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_event.dart'; +import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_state.dart'; +import 'package:syncrow_app/features/devices/model/device_model.dart'; +import 'package:syncrow_app/features/devices/model/four_scene_question_model.dart'; +import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_scene_setting/question_page_four_scene.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_medium.dart'; +import 'package:syncrow_app/generated/assets.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +class FaqFourScenePage extends StatelessWidget { + final DeviceModel? device; + + const FaqFourScenePage({super.key, this.device}); + + @override + Widget build(BuildContext context) { + TextEditingController _searchController = TextEditingController(); + return DefaultScaffold( + title: 'FAQ', + child: BlocProvider( + create: (context) => FourSceneBloc(fourSceneId: device?.uuid ?? '') + ..add(const FourSceneInitialQuestion()), + child: BlocBuilder( + builder: (context, state) { + final sensor = BlocProvider.of(context); + + List displayedQuestions = []; + if (state is FaqSearchState) { + displayedQuestions = state.filteredFaqQuestions; + } else if (state is FaqLoadedState) { + displayedQuestions = state.filteredFaqQuestions; + } + return state is FourSceneLoadingState + ? const Center( + child: DefaultContainer( + width: 50, + height: 50, + child: CircularProgressIndicator()), + ) + : RefreshIndicator( + onRefresh: () async { + // sensor.add(const SosInitial()); + }, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + DefaultContainer( + padding: const EdgeInsets.all(5), + child: TextFormField( + controller: _searchController, + onChanged: (value) { + sensor.add(SearchFaqEvent(value)); + }, + decoration: InputDecoration( + hintText: 'Enter your questions', + hintStyle: const TextStyle( + color: ColorsManager.textGray, + fontSize: 16, + fontWeight: FontWeight.w400), + suffixIcon: Container( + padding: const EdgeInsets.all(5.0), + margin: const EdgeInsets.all(10.0), + child: SvgPicture.asset( + Assets.searchIcon, + fit: BoxFit.contain, + ), + ), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(8.0), + ), + ), + ), + ), + SizedBox( + height: MediaQuery.of(context).size.height * 0.04, + ), + BodyMedium( + text: _searchController.text.isEmpty + ? 'Device Related FAQs' + : '${displayedQuestions.length} Help Topics', + fontWeight: FontWeight.w700, + fontSize: 12, + fontColor: ColorsManager.grayColor, + ), + Expanded( + child: DefaultContainer( + child: ListView.builder( + shrinkWrap: true, + itemCount: displayedQuestions.length, + itemBuilder: (context, index) { + final faq = displayedQuestions[index]; + return InkWell( + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => QuestionPageFourScene( + questionModel: faq, + )), + ); + }, + child: SizedBox( + child: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Row( + children: [ + Expanded( + child: BodyMedium( + fontSize: 14, + fontWeight: FontWeight.w400, + text: faq.question, + ), + ), + const Icon( + Icons.keyboard_arrow_right, + color: ColorsManager.textGray, + ), + ], + ), + ), + const Divider( + color: ColorsManager.dividerColor, + ), + ], + ), + ), + ); + }, + )), + ), + ], + ), + ); + }, + ), + ), + ); + } +} diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_create_group.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_create_group.dart new file mode 100644 index 0000000..fed78f3 --- /dev/null +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_create_group.dart @@ -0,0 +1,213 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_event.dart'; +import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_state.dart'; +import 'package:syncrow_app/features/devices/model/device_model.dart'; +import 'package:syncrow_app/features/devices/model/four_scene_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/features/shared_widgets/text_widgets/body_large.dart'; +import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart'; +import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart'; +import 'package:syncrow_app/generated/assets.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +class FourSceneCreateGroup extends StatelessWidget { + final DeviceModel? device; + + const FourSceneCreateGroup({super.key, this.device}); + + @override + Widget build(BuildContext context) { + return DefaultScaffold( + title: 'Create Group', + child: BlocProvider( + create: (context) => FourSceneBloc(fourSceneId: device?.uuid ?? '') + ..add(const FourSceneInitial()), + child: BlocBuilder( + builder: (context, state) { + final sensor = BlocProvider.of(context); + FourSceneModel model = FourSceneModel( + scene_1: '', + scene_2: '', + scene_3: '', + scene_4: '', + scene_id_group_id: '', + switch_backlight: ''); + if (state is LoadingNewSate) { + model = state.sosSensor; + } else if (state is UpdateState) { + model = state.sensor; + } + return state is LoadingNewSate + ? const Center( + child: DefaultContainer( + width: 50, + height: 50, + child: CircularProgressIndicator()), + ) + : Padding( + padding: EdgeInsets.all(8.0), + child: Column( + children: [ + const Padding( + padding: EdgeInsets.only(left: 25, right: 25), + child: BodySmall( + text: + 'Devices in the same group can be controlled together', + fontColor: ColorsManager.primaryTextColor, + textAlign: TextAlign.center, + ), + ), + Flexible( + child: ListView.builder( + itemCount: sensor.groupDevices.length, + itemBuilder: (context, index) { + return InkWell( + onTap: () { + BlocProvider.of(context).add( + RemoveDeviceFromGroup( + sensor.groupDevices[index], + Assets.addDevicesIcon)); + }, + child: DefaultContainer( + child: Padding( + padding: const EdgeInsets.all(5.0), + child: Row( + crossAxisAlignment: + CrossAxisAlignment.start, + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + SvgPicture.asset( + sensor.groupDevices[index].icon!, + fit: BoxFit.contain, + ), + const SizedBox( + width: 15, + ), + BodyMedium( + text: sensor + .groupDevices[index].name!, + fontColor: + ColorsManager.primaryTextColor, + textAlign: TextAlign.center, + fontSize: 15, + ), + ], + ), + BodyMedium( + text: sensor.groupDevices[index].dec!, + fontColor: ColorsManager.grayColor, + textAlign: TextAlign.center, + fontSize: 15, + ), + ], + ), + )), + ); + }, + ), + ), + Flexible( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const BodyLarge( + text: 'Devices to be added', + fontColor: ColorsManager.grayColor, + textAlign: TextAlign.center, + fontSize: 12, + fontWeight: FontWeight.w700, + ), + const SizedBox( + height: 5, + ), + sensor.devices.isNotEmpty + ? Expanded( + child: ListView.builder( + itemCount: sensor.devices.length, + itemBuilder: (context, index) { + final device = sensor.devices[index]; + return GestureDetector( + onTap: () { + BlocProvider.of( + context) + .add(AddDeviceToGroup(device, + Assets.minusIcon)); + }, + child: DefaultContainer( + child: Padding( + padding: + const EdgeInsets.all(5.0), + child: Row( + crossAxisAlignment: + CrossAxisAlignment.start, + mainAxisAlignment: + MainAxisAlignment + .spaceBetween, + children: [ + Row( + children: [ + SvgPicture.asset( + device.icon!, + fit: BoxFit.contain, + ), + const SizedBox( + width: 15, + ), + BodyMedium( + text: device.name!, + fontColor: ColorsManager + .primaryTextColor, + textAlign: + TextAlign.center, + fontSize: 15, + ), + ], + ), + BodyMedium( + text: device.dec!, + fontColor: ColorsManager + .grayColor, + textAlign: + TextAlign.center, + fontSize: 15, + ), + ], + ), + ), + ), + ); + }, + ), + ) + : const Column( + children: [ + BodySmall( + text: + 'Currently no devices available to create group', + fontColor: ColorsManager.grayColor, + textAlign: TextAlign.center, + fontSize: 12, + fontWeight: FontWeight.w400, + ), + ], + ), + ], + ), + ), + Spacer() + ], + ), + ); + }, + ), + ), + ); + } +} diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_delete_dialog.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_delete_dialog.dart new file mode 100644 index 0000000..67c62e2 --- /dev/null +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_delete_dialog.dart @@ -0,0 +1,227 @@ +import 'package:flutter/material.dart'; +import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +class DisconnectDeviceDialog extends StatelessWidget { + final Function()? cancelTab; + final Function()? confirmTab; + + const DisconnectDeviceDialog({ + super.key, + required this.cancelTab, + required this.confirmTab, + }); + + @override + Widget build(BuildContext context) { + return AlertDialog( + contentPadding: EdgeInsets.zero, + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const SizedBox( + height: 10, + ), + const BodyLarge( + text: 'Disconnect Device', + fontWeight: FontWeight.w700, + fontColor: ColorsManager.red, + fontSize: 16, + ), + const Padding( + padding: EdgeInsets.only(left: 15, right: 15), + child: Divider( + color: ColorsManager.textGray, + ), + ), + const Padding( + padding: EdgeInsets.only(left: 15, right: 20, top: 15, bottom: 20), + child: Column( + children: [ + Center( + child: Text( + 'This will disconnect your device from this Application')), + ], + ), + ), + 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: 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: confirmTab, + child: const Padding( + padding: EdgeInsets.all(15), + child: Center( + child: Text( + 'Disconnect', + style: TextStyle( + color: ColorsManager.red, + fontSize: 14, + fontWeight: FontWeight.w400), + ), + ), + )), + )) + ], + ) + ], + ), + ); + } +} + +class DisconnectWipeData extends StatelessWidget { + final Function()? cancelTab; + final Function()? confirmTab; + + const DisconnectWipeData({ + super.key, + required this.cancelTab, + required this.confirmTab, + }); + + @override + Widget build(BuildContext context) { + return AlertDialog( + contentPadding: EdgeInsets.zero, + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const SizedBox( + height: 10, + ), + const BodyLarge( + text: 'Disconnect and Wipe Data', + fontWeight: FontWeight.w700, + fontColor: ColorsManager.red, + fontSize: 16, + ), + const Padding( + padding: EdgeInsets.only(left: 15, right: 15), + child: Divider( + color: ColorsManager.textGray, + ), + ), + const Padding( + padding: EdgeInsets.only(left: 15, right: 20, top: 15, bottom: 20), + child: Column( + children: [ + Center( + child: Text( + 'This will disconnect your device from this Application and wipe all the data')), + ], + ), + ), + 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: 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: confirmTab, + child: const Padding( + padding: EdgeInsets.all(15), + child: Center( + child: Text( + 'Disconnect', + style: TextStyle( + color: ColorsManager.red, + fontSize: 14, + fontWeight: FontWeight.w400), + ), + ), + )), + )) + ], + ) + ], + ), + ); + } +} diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_info_page.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_info_page.dart new file mode 100644 index 0000000..0caed76 --- /dev/null +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_info_page.dart @@ -0,0 +1,132 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart'; +import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart'; + +import 'package:syncrow_app/features/devices/model/device_model.dart'; +import 'package:syncrow_app/features/devices/model/six_scene_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/features/shared_widgets/text_widgets/body_large.dart'; +import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart'; +import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +class SixSceneInfoPage extends StatelessWidget { + final DeviceModel? device; + + const SixSceneInfoPage({super.key, this.device}); + + @override + Widget build(BuildContext context) { + return DefaultScaffold( + title: 'Device Information', + child: BlocProvider( + create: (context) => SixSceneBloc(sixSceneId: device?.uuid ?? '') + ..add(const SixSceneInitial()), + child: BlocBuilder( + builder: (context, state) { + final sensor = BlocProvider.of(context); + SixSceneModel model = SixSceneModel( + batteryPercentage: 0, waterContactState: 'normal'); + if (state is LoadingNewSate) { + model = state.sosSensor; + } else if (state is UpdateState) { + model = state.sensor; + } + return state is SixSceneLoadingState + ? const Center( + child: DefaultContainer( + width: 50, + height: 50, + child: CircularProgressIndicator()), + ) + : RefreshIndicator( + onRefresh: () async { + sensor.add(const SixSceneInitial()); + }, + child: DefaultContainer( + child: Padding( + padding: const EdgeInsets.only(left: 10, right: 10), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + const BodyLarge( + text: 'Virtual ID', + fontSize: 15, + fontWeight: FontWeight.w400, + fontColor: ColorsManager.blackColor, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + const BodySmall( + text: 'bf3575d0e0c8b6e0a6hybl', + fontColor: ColorsManager.primaryTextColor, + ), + InkWell( + onTap: () {}, + child: const Row( + children: [ + Icon( + Icons.copy, + color: ColorsManager.blueColor, + ), + BodyMedium( + text: 'Copy', + fontColor: ColorsManager.blueColor, + ), + ], + ), + ) + ], + ), + const Divider( + color: ColorsManager.dividerColor, + ), + const Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + BodyLarge( + text: 'MAC', + fontSize: 15, + fontWeight: FontWeight.w400, + fontColor: ColorsManager.blackColor, + ), + BodySmall( + text: 'bf3575d0e0c8b6e0a6hybl', + fontColor: ColorsManager.primaryTextColor, + ), + ], + ), + const Divider( + color: ColorsManager.dividerColor, + ), + const Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + BodyLarge( + text: 'Time Zone', + fontSize: 15, + fontWeight: FontWeight.w400, + fontColor: ColorsManager.blackColor, + ), + BodySmall( + text: 'Asia/Dubai', + fontColor: ColorsManager.primaryTextColor, + ), + ], + ), + ]), + ))); + }, + ), + ), + ); + } +} diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_profile_page.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_profile_page.dart new file mode 100644 index 0000000..d363321 --- /dev/null +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_profile_page.dart @@ -0,0 +1,175 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart'; +import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_event.dart'; +import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_state.dart'; +import 'package:syncrow_app/features/devices/model/device_model.dart'; +import 'package:syncrow_app/features/devices/model/four_scene_model.dart'; +import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_scene_setting/location_setting_four_scene.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_medium.dart'; +import 'package:syncrow_app/generated/assets.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +class FourSceneProfilePage extends StatelessWidget { + final DeviceModel? device; + + const FourSceneProfilePage({super.key, this.device}); + + @override + Widget build(BuildContext context) { + var spaces = HomeCubit.getInstance().spaces; + + return DefaultScaffold( + title: 'Device Settings', + child: BlocProvider( + create: (context) => FourSceneBloc(fourSceneId: device?.uuid ?? '') + ..add(const FourSceneInitial()), + child: BlocBuilder( + builder: (context, state) { + final sensor = BlocProvider.of(context); + FourSceneModel model = FourSceneModel( + scene_1: '', + scene_2: '', + scene_3: '', + scene_4: '', + scene_id_group_id: '', + switch_backlight: ''); + if (state is LoadingNewSate) { + model = state.sosSensor; + } else if (state is UpdateState) { + model = state.sensor; + } + return state is FourSceneLoadingState + ? const Center( + child: DefaultContainer( + width: 50, + height: 50, + child: CircularProgressIndicator()), + ) + : RefreshIndicator( + onRefresh: () async { + sensor.add(const FourSceneInitial()); + }, + child: ListView( + children: [ + CircleAvatar( + radius: 60, + backgroundColor: Colors.white, + child: CircleAvatar( + radius: 55, + backgroundColor: Colors.grey, + child: ClipOval( + child: SvgPicture.asset( + Assets.sosProfileIcon, + fit: BoxFit.fill, + ), + ), + ), + ), + const SizedBox( + height: 10, + ), + SizedBox( + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + IntrinsicWidth( + child: ConstrainedBox( + constraints: + const BoxConstraints(maxWidth: 200), + child: TextFormField( + maxLength: 30, + style: const TextStyle( + color: Colors.black, + ), + textAlign: TextAlign.center, + focusNode: sensor.focusNode, + controller: sensor.nameController, + enabled: sensor.editName, + onEditingComplete: () { + // sensor.add(SaveNameEvent(context: context)); + }, + decoration: const InputDecoration( + hintText: "Your Name", + border: InputBorder.none, + fillColor: Colors.white10, + counterText: '', + ), + ), + ), + ), + const SizedBox(width: 5), + InkWell( + onTap: () { + sensor + .add(const ChangeNameEvent(value: true)); + }, + child: const Padding( + padding: EdgeInsets.symmetric(horizontal: 10), + child: Icon( + Icons.edit_outlined, + size: 20, + color: ColorsManager.textPrimaryColor, + ), + ), + ), + ], + ), + ), + const SizedBox(height: 20), + const BodyMedium( + text: 'Smart Device Information', + fontWeight: FontWeight.w700, + fontSize: 12, + fontColor: ColorsManager.grayColor, + ), + DefaultContainer( + padding: const EdgeInsets.all(20), + child: InkWell( + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => LocationFourScenePage( + space: spaces!.first, + )), + ); + }, + child: const Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + SizedBox( + child: Text('Location'), + ), + Row( + children: [ + SizedBox( + child: BodyMedium( + text: 'Syncroom', + fontColor: ColorsManager.textGray, + ), + ), + Icon( + Icons.arrow_forward_ios, + size: 15, + color: ColorsManager.textGray, + ), + ], + ) + ], + ), + ), + ) + ], + ), + ); + }, + ), + ), + ); + } +} diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart new file mode 100644 index 0000000..1b1451f --- /dev/null +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart @@ -0,0 +1,526 @@ +import 'package:flutter/cupertino.dart'; +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/four_scene_bloc/four_scene_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_event.dart'; +import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_state.dart'; +import 'package:syncrow_app/features/devices/model/device_model.dart'; +import 'package:syncrow_app/features/devices/model/four_scene_model.dart'; +import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_scene_setting/faq_four_scene_page.dart'; +import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_create_group.dart'; +import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_delete_dialog.dart'; +import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_profile_page.dart'; +import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_update_dialog.dart'; +import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_update_page.dart'; +import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_scene_setting/share_four_scene_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_medium.dart'; +import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart'; +import 'package:syncrow_app/generated/assets.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +class FourSceneSettings extends StatelessWidget { + final DeviceModel? device; + + const FourSceneSettings({super.key, this.device}); + + @override + Widget build(BuildContext context) { + return DefaultScaffold( + title: 'Device Settings', + child: BlocProvider( + create: (context) => FourSceneBloc(fourSceneId: device?.uuid ?? '') + ..add(const FourSceneInitial()), + child: BlocBuilder( + builder: (context, state) { + final sensor = BlocProvider.of(context); + FourSceneModel model = FourSceneModel( + scene_1: '', + scene_2: '', + scene_3: '', + scene_4: '', + scene_id_group_id: '', + switch_backlight: ''); + if (state is LoadingNewSate) { + model = state.sosSensor; + } else if (state is UpdateState) { + model = state.sensor; + } + return state is FourSceneLoadingState + ? const Center( + child: DefaultContainer( + width: 50, + height: 50, + child: CircularProgressIndicator()), + ) + : RefreshIndicator( + onRefresh: () async { + sensor.add(const FourSceneInitial()); + }, + child: ListView( + children: [ + Padding( + padding: const EdgeInsets.symmetric( + vertical: 10, + ), + child: InkWell( + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => + const FourSceneProfilePage(), + ), + ); + }, + child: Stack( + children: [ + const Column( + crossAxisAlignment: + CrossAxisAlignment.stretch, + children: [ + SizedBox(height: 20), + DefaultContainer( + borderRadius: + BorderRadius.all(Radius.circular(30)), + child: Padding( + padding: EdgeInsets.all(10.0), + child: Padding( + padding: EdgeInsets.only(left: 90), + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + BodyMedium( + text: '4 Scene Switch', + fontWeight: FontWeight.bold, + ), + SizedBox( + height: 5, + ), + BodySmall( + text: "Room: Syncrow"), + ], + ), + Icon(Icons.edit_sharp) + ], + ), + ), + ), + ), + ], + ), + Positioned( + top: 0, + left: 20, + child: CircleAvatar( + radius: 43, + backgroundColor: Colors.white, + child: CircleAvatar( + radius: 40, + backgroundColor: Colors.white, + child: CircleAvatar( + radius: 40, + backgroundColor: + ColorsManager.backgroundColor, + child: SvgPicture.asset( + Assets.sixSceneIcon, + fit: BoxFit.fill, + ), + ), + )), + ), + ], + ), + ), + ), + const SizedBox(height: 20), + const BodyMedium( + text: 'Device Management', + fontWeight: FontWeight.w700, + fontSize: 12, + fontColor: ColorsManager.grayColor, + ), + DefaultContainer( + child: Column( + children: [ + SettingWidget( + onTap: () { + // Navigator.of(context).push( + // MaterialPageRoute( + // builder: (context) => + // const FourSceneInfoPage()), + // ); + }, + text: 'Device Information', + icon: Assets.infoIcon, + ), + const Divider( + color: ColorsManager.dividerColor, + ), + SettingWidget( + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => + ShareFourScenePage( + device: device!)), + ); + }, + text: 'Tap-to Run and Automation', + icon: Assets.tapRunIcon, + ), + ], + ), + ), + const SizedBox(height: 20), + const BodyMedium( + text: 'Device Offline Notification', + fontWeight: FontWeight.w700, + fontSize: 12, + fontColor: ColorsManager.grayColor, + ), + DefaultContainer( + child: Column( + children: [ + SettingWidget( + onChanged: (p0) {}, + isNotification: true, + onTap: () {}, + text: 'Offline Notification', + icon: Assets.notificationIcon, + ), + ], + ), + ), + const SizedBox(height: 20), + const BodyMedium( + text: 'Others', + fontWeight: FontWeight.w700, + fontSize: 12, + fontColor: ColorsManager.grayColor, + ), + const SizedBox(height: 5), + DefaultContainer( + child: Column( + children: [ + SettingWidget( + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => + ShareFourScenePage( + device: device!)), + ); + }, + text: 'Share Device', + icon: Assets.shareIcon, + ), + const Divider( + color: ColorsManager.dividerColor, + ), + SettingWidget( + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => + FourSceneCreateGroup( + device: device!)), + ); + }, + text: 'Create Group', + icon: Assets.createGroupIcon, + ), + const Divider( + color: ColorsManager.dividerColor, + ), + SettingWidget( + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => + FaqFourScenePage(device: device!)), + ); + }, + text: 'Device FAQ', + icon: Assets.faqIcon, + ), + const Divider( + color: ColorsManager.dividerColor, + ), + SettingWidget( + onTapUpdate: () { + showDialog( + context: context, + builder: (context) { + return UpdateInfoDialog( + cancelTab: () { + Navigator.of(context).pop(); + }, + confirmTab: () { + // context + // .read< + // CreateSceneBloc>() + // .add(DeleteSceneEvent( + // sceneId: sceneId, + // unitUuid: HomeCubit + // .getInstance() + // .selectedSpace! + // .id!, + // )); + Navigator.of(context).pop(); + }, + ); + }, + ); + }, + isUpdate: true, + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => + const FourSceneUpdatePage()), + ); + }, + text: 'Device Update', + icon: Assets.updateIcon, + ), + ], + ), + ), + const SizedBox(height: 20), + InkWell( + onTap: () { + showModalBottomSheet( + context: context, + builder: (BuildContext context) { + return Container( + height: 200, + padding: const EdgeInsets.all(16.0), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const BodyMedium( + text: 'Remove Device', + fontWeight: FontWeight.w700, + fontSize: 16, + fontColor: ColorsManager.red, + ), + const SizedBox(height: 10), + const SizedBox( + width: 250, + child: Divider( + color: ColorsManager.dividerColor, + ), + ), + const SizedBox(height: 10), + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + InkWell( + onTap: () { + showDialog( + context: context, + builder: (context) { + return DisconnectDeviceDialog( + cancelTab: () { + Navigator.of(context) + .pop(); + }, + confirmTab: () { + // context + // .read< + // CreateSceneBloc>() + // .add(DeleteSceneEvent( + // sceneId: sceneId, + // unitUuid: HomeCubit + // .getInstance() + // .selectedSpace! + // .id!, + // )); + Navigator.of(context) + .pop(); + }, + ); + }, + ); + }, + child: const BodyMedium( + text: 'Disconnect Device', + fontWeight: FontWeight.w400, + fontSize: 15, + fontColor: ColorsManager + .textPrimaryColor, + ), + ), + const Icon( + Icons.keyboard_arrow_right, + color: ColorsManager.textGray, + ) + ], + ), + const SizedBox(height: 20), + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + InkWell( + onTap: () { + showDialog( + context: context, + builder: (context) { + return DisconnectWipeData( + cancelTab: () { + Navigator.of(context) + .pop(); + }, + confirmTab: () { + // context + // .read< + // CreateSceneBloc>() + // .add(DeleteSceneEvent( + // sceneId: sceneId, + // unitUuid: HomeCubit + // .getInstance() + // .selectedSpace! + // .id!, + // )); + Navigator.of(context) + .pop(); + }, + ); + }, + ); + }, + child: const BodyMedium( + text: + 'Disconnect Device and Wipe Data', + fontWeight: FontWeight.w400, + fontSize: 15, + fontColor: ColorsManager + .textPrimaryColor, + ), + ), + const Icon( + Icons.keyboard_arrow_right, + color: ColorsManager.textGray, + ) + ], + ), + ], + ), + ); + }, + ); + }, + child: const Center( + child: BodyMedium( + text: 'Remove Device', + fontWeight: FontWeight.w400, + fontSize: 15, + fontColor: ColorsManager.red, + ), + ), + ), + ], + ), + ); + }, + ), + ), + ); + } +} + +class SettingWidget extends StatelessWidget { + final String? text; + final bool? isUpdate; + final bool? isNotification; + final String? icon; + final Function()? onTap; + final Function()? onTapUpdate; + final Function(bool)? onChanged; + const SettingWidget( + {super.key, + this.text, + this.icon, + this.onTap, + this.isUpdate, + this.onChanged, + this.isNotification = false, + this.onTapUpdate}); + + @override + Widget build(BuildContext context) { + return InkWell( + onTap: onTap, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Row( + children: [ + Expanded( + flex: 2, + child: Container( + padding: EdgeInsets.all(8), + decoration: const BoxDecoration( + color: ColorsManager.primaryColor, + borderRadius: BorderRadius.all(Radius.circular(20))), + child: SvgPicture.asset( + icon!, + fit: BoxFit.none, + height: 30, + ), + ), + ), + const SizedBox( + width: 8, + ), + Expanded( + flex: isUpdate == true ? 5 : 10, + child: BodyMedium( + text: text!, + fontSize: 15, + fontWeight: FontWeight.w400, + )), + ], + ), + ), + isUpdate == true + ? InkWell( + onTap: onTapUpdate, + child: BodyMedium( + text: '1 Update Available', + fontSize: 13, + fontWeight: FontWeight.w400, + fontColor: ColorsManager.blueColor, + ), + ) + : SizedBox(), + isNotification == false + ? const Icon( + Icons.arrow_forward_ios, + color: ColorsManager.graysColor, + size: 20, + ) + : Transform.scale( + scale: .8, + child: CupertinoSwitch( + value: true, + onChanged: onChanged, + applyTheme: true, + ), + ), + ], + ), + ); + } +} diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_update_dialog.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_update_dialog.dart new file mode 100644 index 0000000..0529161 --- /dev/null +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_update_dialog.dart @@ -0,0 +1,118 @@ +import 'package:flutter/material.dart'; +import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +class UpdateInfoDialog extends StatelessWidget { + final Function()? cancelTab; + final Function()? confirmTab; + + const UpdateInfoDialog({ + super.key, + required this.cancelTab, + required this.confirmTab, + }); + + @override + Widget build(BuildContext context) { + return AlertDialog( + contentPadding: EdgeInsets.zero, + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const SizedBox( + height: 10, + ), + BodyLarge( + text: 'Update Available', + fontWeight: FontWeight.w700, + fontColor: ColorsManager.switchButton.withOpacity(0.6), + fontSize: 16, + ), + const Padding( + padding: EdgeInsets.only(left: 15, right: 15), + child: Divider( + color: ColorsManager.textGray, + ), + ), + const Padding( + padding: EdgeInsets.only(left: 15, right: 20, top: 15, bottom: 20), + child: Column( + children: [ + Center( + child: Text( + 'An update is available for your device. Version 2.1.0 includes new features and important fixes to enhance performance and security.', + textAlign: TextAlign.center, + )), + ], + ), + ), + 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: cancelTab, + child: const Padding( + padding: const EdgeInsets.only(top: 15, bottom: 15), + child: Center( + child: Text( + 'Remind me later', + 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: confirmTab, + child: Padding( + padding: const EdgeInsets.only(top: 15, bottom: 15), + child: Center( + child: Text( + 'Update Now', + style: TextStyle( + color: + ColorsManager.switchButton.withOpacity(0.6), + fontSize: 14, + fontWeight: FontWeight.w400), + ), + ), + )), + )) + ], + ) + ], + ), + ); + } +} diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_update_note.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_update_note.dart new file mode 100644 index 0000000..3023d3e --- /dev/null +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_update_note.dart @@ -0,0 +1,118 @@ +import 'package:flutter/material.dart'; +import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +class upDateNote extends StatelessWidget { + final Function()? cancelTab; + final Function()? confirmTab; + + const upDateNote({ + super.key, + required this.cancelTab, + required this.confirmTab, + }); + + @override + Widget build(BuildContext context) { + return AlertDialog( + contentPadding: EdgeInsets.zero, + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const SizedBox( + height: 10, + ), + BodyLarge( + text: 'Update Note', + fontWeight: FontWeight.w700, + fontColor: ColorsManager.switchButton.withOpacity(0.6), + fontSize: 16, + ), + const Padding( + padding: EdgeInsets.only(left: 15, right: 15), + child: Divider( + color: ColorsManager.textGray, + ), + ), + const Padding( + padding: EdgeInsets.only(left: 15, right: 20, top: 15, bottom: 20), + child: Column( + children: [ + Center( + child: Text( + 'This update may take a long time. Make sure that the device is fully charged. The device will be unavailable during the update.', + textAlign: TextAlign.center, + )), + ], + ), + ), + 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: cancelTab, + child: const Padding( + padding: const EdgeInsets.only(top: 15, bottom: 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: confirmTab, + child: Padding( + padding: const EdgeInsets.only(top: 15, bottom: 15), + child: Center( + child: Text( + 'Start Update', + style: TextStyle( + color: + ColorsManager.switchButton.withOpacity(0.6), + fontSize: 14, + fontWeight: FontWeight.w400), + ), + ), + )), + )) + ], + ) + ], + ), + ); + } +} diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_update_page.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_update_page.dart new file mode 100644 index 0000000..8fcee56 --- /dev/null +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_update_page.dart @@ -0,0 +1,345 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:percent_indicator/linear_percent_indicator.dart'; +import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_event.dart'; +import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_state.dart'; +import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_update_note.dart'; +import 'package:syncrow_app/features/shared_widgets/default_button.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_medium.dart'; +import 'package:syncrow_app/generated/assets.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +class FourSceneUpdatePage extends StatelessWidget { + const FourSceneUpdatePage({super.key}); + + @override + Widget build(BuildContext context) { + return DefaultScaffold( + title: 'Device Update', + child: BlocProvider( + create: (context) => + FourSceneBloc(fourSceneId: '')..add(const FourSceneInitial()), + child: BlocBuilder( + builder: (context, state) { + return state is FourSceneLoadingState + ? const Center( + child: DefaultContainer( + width: 50, + height: 50, + child: CircularProgressIndicator()), + ) + : RefreshIndicator( + onRefresh: () async {}, + child: Column( + children: [ + // SizedBox( + // height: MediaQuery.of(context).size.height * 0.15, + // ), + DefaultContainer( + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + height: 50, + child: ListTile( + contentPadding: EdgeInsets.zero, + leading: SizedBox( + width: 200, + child: Row( + children: [ + Container( + padding: const EdgeInsets.all(10), + decoration: const BoxDecoration( + color: ColorsManager + .primaryColor, + borderRadius: + BorderRadius.all( + Radius.circular(50))), + child: SvgPicture.asset( + Assets.checkUpdateIcon, + fit: BoxFit.fill, + height: 25, + ), + ), + const SizedBox( + width: 10, + ), + InkWell( + onTap: () {}, + child: const BodyMedium( + text: 'Automatic Update', + fontWeight: FontWeight.normal, + ), + ), + ], + ), + ), + trailing: Container( + width: 100, + child: Row( + mainAxisAlignment: + MainAxisAlignment.end, + children: [ + const BodyMedium( + text: 'Off', + fontColor: ColorsManager.textGray, + ), + Transform.scale( + scale: .8, + child: CupertinoSwitch( + value: true, + onChanged: (value) {}, + applyTheme: true, + ), + ), + ], + ), + )), + ), + ], + ), + ), + const SizedBox( + height: 10, + ), + UpdateSosContainerWithProgressBar( + sosDescription: + 'Connectivity Issue Resolved Fixed a bug that caused the SOS button to disconnect from the app intermittently.', + sosVersion: 'SOS v2.0.5', + ), + // const UpdatedContainer( + // sosVersion: 'SOS v1.0.13', + // sosDescription: 'SOS is up to date', + // ), + + // const NewUpdateContainer( + // sosVersion: 'SOS v2.0.5', + // sosDescription: + // 'Connectivity Issue Resolved Fixed a bug that caused the SOS button to disconnect from the app intermittently.', + // ), + const SizedBox( + height: 15, + ), + ], + )); + }, + ), + )); + } +} + +class UpdatedContainer extends StatelessWidget { + final String? sosVersion; + final String? sosDescription; + const UpdatedContainer({ + this.sosVersion, + this.sosDescription, + super.key, + }); + + @override + Widget build(BuildContext context) { + return DefaultContainer( + height: MediaQuery.of(context).size.height * 0.35, + child: Padding( + padding: const EdgeInsets.all(25), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SvgPicture.asset( + Assets.emptyUpdateIcon, + fit: BoxFit.fill, + ), + BodyMedium( + text: sosVersion!, + fontColor: ColorsManager.primaryTextColor, + ), + BodyMedium( + text: sosDescription!, + fontColor: ColorsManager.blackColor, + ), + ], + ), + ], + ), + ), + ); + } +} + +class NewUpdateContainer extends StatelessWidget { + final String? sosVersion; + final String? sosDescription; + const NewUpdateContainer({ + this.sosVersion, + this.sosDescription, + super.key, + }); + + @override + Widget build(BuildContext context) { + return DefaultContainer( + height: MediaQuery.of(context).size.height * 0.50, + child: Padding( + padding: const EdgeInsets.all(25), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SvgPicture.asset( + Assets.emptyUpdateIcon, + fit: BoxFit.fill, + ), + const BodyMedium( + text: 'New Update Available Now!', + fontColor: ColorsManager.blueColor, + ), + BodyMedium( + text: sosVersion!, + fontColor: ColorsManager.primaryTextColor, + ), + Container( + width: MediaQuery.of(context).size.width * 0.7, + child: BodyMedium( + text: sosDescription!, + fontColor: ColorsManager.textPrimaryColor, + textAlign: TextAlign.center, + ), + ), + SizedBox( + width: MediaQuery.of(context).size.width * 0.6, + child: DefaultButton( + borderRadius: 25, + backgroundColor: ColorsManager.blueColor1, + height: 150, + onPressed: () { + showDialog( + context: context, + builder: (context) { + return upDateNote( + cancelTab: () { + Navigator.of(context).pop(); + }, + confirmTab: () { + Navigator.of(context).pop(); + }, + ); + }, + ); + }, + child: const BodyMedium( + text: 'Update Now', + fontColor: Colors.white, + fontSize: 16, + fontWeight: FontWeight.w700, + textAlign: TextAlign.center, + ), + ), + ) + ], + ), + ], + ), + ), + ); + } +} + +class UpdateSosContainerWithProgressBar extends StatelessWidget { + final String? sosVersion; + final String? sosDescription; + const UpdateSosContainerWithProgressBar({ + this.sosVersion, + this.sosDescription, + super.key, + }); + + @override + Widget build(BuildContext context) { + return Column( + children: [ + DefaultContainer( + height: MediaQuery.of(context).size.height * 0.50, + child: Padding( + padding: const EdgeInsets.all(25), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SvgPicture.asset( + Assets.emptyUpdateIcon, + fit: BoxFit.fill, + ), + BodyMedium( + text: 'New Update Available Now!', + fontColor: ColorsManager.blueColor, + ), + BodyMedium( + text: sosVersion!, + fontColor: ColorsManager.primaryTextColor, + ), + SizedBox( + width: MediaQuery.of(context).size.width * 0.7, + child: BodyMedium( + text: sosDescription!, + fontColor: ColorsManager.textPrimaryColor, + textAlign: TextAlign.center, + ), + ), + LinearPercentIndicator( + barRadius: Radius.circular(10), + width: 170.0, + animation: true, + animationDuration: 1000, + lineHeight: 5.0, + percent: 0.2, + linearStrokeCap: LinearStrokeCap.butt, + progressColor: ColorsManager.blueColor1, + ), + SizedBox( + width: MediaQuery.of(context).size.width * 0.7, + child: const BodyMedium( + text: 'Downloading Update please be patient', + fontColor: ColorsManager.textPrimaryColor, + textAlign: TextAlign.center, + ), + ), + ], + ), + ], + ), + ), + ), + SizedBox( + width: MediaQuery.of(context).size.width * 0.7, + child: const BodyMedium( + text: + 'Please keep the power of the device connected during the upgrade process.', + fontColor: ColorsManager.textPrimaryColor, + textAlign: TextAlign.center, + ), + ), + ], + ); + } +} diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/location_setting_four_scene.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/location_setting_four_scene.dart new file mode 100644 index 0000000..aa6a80b --- /dev/null +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/location_setting_four_scene.dart @@ -0,0 +1,202 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_app/features/app_layout/model/space_model.dart'; +import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_state.dart'; +import 'package:syncrow_app/features/devices/model/four_scene_model.dart'; +import 'package:syncrow_app/features/devices/model/subspace_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/features/shared_widgets/text_widgets/body_medium.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +import '../../../../bloc/four_scene_bloc/four_scene_event.dart'; + +class LocationFourScenePage extends StatefulWidget { + final SpaceModel? space; + LocationFourScenePage({super.key, this.space}); + + @override + _LocationFourScenePageState createState() => _LocationFourScenePageState(); +} + +class _LocationFourScenePageState extends State { + String _selectedOption = 'Conference Room'; + bool _hasSelectionChanged = false; + + @override + Widget build(BuildContext context) { + return DefaultScaffold( + title: 'Device Location', + actions: [ + InkWell( + onTap: _hasSelectionChanged + ? () { + print('Save button clicked'); + } + : null, + child: BodyMedium( + text: 'Save', + fontWeight: FontWeight.w700, + fontSize: 16, + fontColor: _hasSelectionChanged + ? ColorsManager.slidingBlueColor + : ColorsManager.primaryTextColor, + ), + ), + const SizedBox(width: 20), + ], + child: BlocProvider( + create: (context) => FourSceneBloc(fourSceneId: '') + ..add(FetchRoomsEvent(unit: widget.space!)), + child: BlocBuilder( + builder: (context, state) { + final sensor = BlocProvider.of(context); + FourSceneModel model = FourSceneModel( + scene_1: '', + scene_2: '', + scene_3: '', + scene_4: '', + scene_id_group_id: '', + switch_backlight: ''); + List? rooms = []; + if (state is LoadingNewSate) { + model = state.sosSensor; + } else if (state is FetchRoomsState) { + rooms = state.roomsList; + } + return state is FourSceneLoadingState + ? const Center( + child: DefaultContainer( + width: 50, + height: 50, + child: CircularProgressIndicator(), + ), + ) + : RefreshIndicator( + onRefresh: () async { + sensor.add(const FourSceneInitial()); + }, + child: ListView( + padding: const EdgeInsets.symmetric(vertical: 20), + children: [ + const BodyMedium( + text: 'Smart Device Location', + fontWeight: FontWeight.w700, + fontSize: 12, + fontColor: ColorsManager.grayColor, + ), + const SizedBox(height: 5), + DefaultContainer( + padding: const EdgeInsets.all(20), + child: ListView.builder( + physics: const NeverScrollableScrollPhysics(), + shrinkWrap: true, + itemCount: rooms!.length, + itemBuilder: (context, index) { + final room = rooms![index]; + return Column( + children: [ + _buildCheckboxOption( + label: room.name!, + onTap: (v) { + setState(() { + _selectedOption = v; + _hasSelectionChanged = true; + }); + }, + ), + if (index < rooms.length - 1) ...[ + const SizedBox(height: 10), + const Divider( + color: ColorsManager.dividerColor, + ), + const SizedBox(height: 10), + ], + ], + ); + }, + ), + ), + ], + ), + ); + }, + ), + ), + ); + } + + Widget _buildCheckboxOption( + {required String label, required 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; + _hasSelectionChanged = true; + }); + 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/four_scene_switch/four_scene_setting/question_page_four_scene.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/question_page_four_scene.dart new file mode 100644 index 0000000..778df50 --- /dev/null +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/question_page_four_scene.dart @@ -0,0 +1,149 @@ +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/four_scene_bloc/four_scene_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_event.dart'; +import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_state.dart'; +import 'package:syncrow_app/features/devices/model/four_scene_model.dart'; +import 'package:syncrow_app/features/devices/model/four_scene_question_model.dart'; +import 'package:syncrow_app/features/shared_widgets/default_button.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/generated/assets.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +class QuestionPageFourScene extends StatelessWidget { + final FourSceneQuestionModel? questionModel; + + const QuestionPageFourScene({super.key, this.questionModel}); + + @override + Widget build(BuildContext context) { + return DefaultScaffold( + title: 'FAQ', + child: BlocProvider( + create: (context) => + FourSceneBloc(fourSceneId: '')..add(const FourSceneInitial()), + child: BlocBuilder( + builder: (context, state) { + final sensor = BlocProvider.of(context); + FourSceneModel model = FourSceneModel( + scene_1: '', + scene_2: '', + scene_3: '', + scene_4: '', + scene_id_group_id: '', + switch_backlight: ''); + if (state is LoadingNewSate) { + model = state.sosSensor; + } else if (state is UpdateState) { + model = state.sensor; + } + return state is FourSceneLoadingState + ? const Center( + child: DefaultContainer( + width: 50, + height: 50, + child: CircularProgressIndicator()), + ) + : RefreshIndicator( + onRefresh: () async { + sensor.add(const FourSceneInitial()); + }, + child: Column( + children: [ + DefaultContainer( + padding: EdgeInsets.all(15), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + BodyLarge( + text: questionModel!.question, + fontSize: 22, + fontWeight: FontWeight.w400, + fontColor: ColorsManager.blackColor, + ), + SizedBox( + height: 15, + ), + BodyMedium( + text: questionModel!.answer, + fontSize: 14, + fontWeight: FontWeight.w400, + fontColor: ColorsManager.secondaryTextColor, + ), + ], + ), + ), + SizedBox( + height: MediaQuery.of(context).size.height * 0.15, + ), + Center( + child: SizedBox( + width: 180, + child: DefaultButton( + backgroundColor: ColorsManager.grayButtonColors, + borderRadius: 50, + onPressed: () {}, + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SvgPicture.asset( + Assets.thumbUp, + fit: BoxFit.fill, + ), + SizedBox( + width: 10, + ), + BodyMedium( + text: 'Helpful', + fontSize: 12, + fontWeight: FontWeight.w400, + fontColor: ColorsManager.blackColor, + ), + ], + )), + ), + ), + SizedBox( + height: 15, + ), + Center( + child: SizedBox( + width: 180, + child: DefaultButton( + backgroundColor: ColorsManager.grayButtonColors, + borderRadius: 50, + onPressed: () {}, + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SvgPicture.asset( + Assets.thumbDown, + fit: BoxFit.fill, + ), + SizedBox( + width: 10, + ), + BodyMedium( + text: 'Not Helpful', + fontSize: 12, + fontWeight: FontWeight.w400, + fontColor: ColorsManager.blackColor, + ), + ], + )), + ), + ), + ], + )); + }, + ), + ), + ); + } +} diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/share_four_scene_page.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/share_four_scene_page.dart new file mode 100644 index 0000000..f253ad9 --- /dev/null +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/share_four_scene_page.dart @@ -0,0 +1,103 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_event.dart'; +import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_state.dart'; +import 'package:syncrow_app/features/devices/model/device_model.dart'; +import 'package:syncrow_app/features/devices/model/four_scene_model.dart'; +import 'package:syncrow_app/features/shared_widgets/default_button.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 ShareFourScenePage extends StatelessWidget { + final DeviceModel? device; + const ShareFourScenePage({super.key, this.device}); + @override + Widget build(BuildContext context) { + return DefaultScaffold( + title: 'Share Device', + child: BlocProvider( + create: (context) => FourSceneBloc(fourSceneId: device?.uuid ?? '') + ..add(const FourSceneInitial()), + child: BlocBuilder( + builder: (context, state) { + final sensor = BlocProvider.of(context); + FourSceneModel model = FourSceneModel( + scene_1: '', + scene_2: '', + scene_3: '', + scene_4: '', + scene_id_group_id: '', + switch_backlight: ''); + if (state is LoadingNewSate) { + model = state.sosSensor; + } else if (state is UpdateState) { + model = state.sensor; + } + return state is LoadingNewSate + ? const Center( + child: DefaultContainer( + width: 50, + height: 50, + child: CircularProgressIndicator()), + ) + : RefreshIndicator( + onRefresh: () async { + sensor.add(const FourSceneInitial()); + }, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const BodyLarge( + text: 'Sharing Method Not Supported', + fontSize: 15, + fontWeight: FontWeight.w400, + fontColor: ColorsManager.blackColor, + ), + const BodyMedium( + text: + 'Currently, you cannot use the specified method to share Bluetooth mesh devices Zigbee devices, infrared devices, Bluetooth Beacon Devices, and certain Bluetooth LE devices with other users.', + fontSize: 14, + fontWeight: FontWeight.w400, + fontColor: ColorsManager.secondaryTextColor, + ), + const SizedBox( + height: 10, + ), + const BodyLarge( + text: 'Recommended Sharing Method', + fontSize: 15, + fontWeight: FontWeight.w400, + fontColor: ColorsManager.blackColor, + ), + const BodyMedium( + text: + 'If the recipient is a home member or a reliable user, tap Me > Home Management > Add Member and add the recipient to your home. Then, devices in the home can be shared with the recipient in bulk.', + fontSize: 14, + fontWeight: FontWeight.w400, + fontColor: ColorsManager.secondaryTextColor, + ), + SizedBox( + height: MediaQuery.of(context).size.height * 0.15, + ), + Center( + child: SizedBox( + width: 250, + child: DefaultButton( + backgroundColor: ColorsManager.blueColor1, + borderRadius: 50, + onPressed: () {}, + child: Text('Add Home Member')), + ), + ) + ], + )); + }, + ), + ), + ); + } +} diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_select_scene_page.dart b/lib/features/devices/view/widgets/four_scene_switch/four_select_scene_page.dart new file mode 100644 index 0000000..7553b7d --- /dev/null +++ b/lib/features/devices/view/widgets/four_scene_switch/four_select_scene_page.dart @@ -0,0 +1,286 @@ +import 'dart:typed_data'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart'; +import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_event.dart'; +import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_state.dart'; +import 'package:syncrow_app/features/devices/view/widgets/restart_status_dialog.dart'; +import 'package:syncrow_app/features/scene/model/scene_settings_route_arguments.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_medium.dart'; +import 'package:syncrow_app/generated/assets.dart'; +import 'package:syncrow_app/navigation/navigation_service.dart'; +import 'package:syncrow_app/navigation/routing_constants.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +class FourSelectSceneFourPage extends StatelessWidget { + FourSelectSceneFourPage({super.key}); + + final TextEditingController _searchController = TextEditingController(); + final int? selectedSwitchIndex = 0; + final spaces = HomeCubit.getInstance().spaces; + + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (context) => FourSceneBloc(fourSceneId: '') + ..add(LoadScenes( + unit: spaces!.first, + unitId: spaces!.first.id, + showInDevice: false, + )), + child: BlocBuilder( + builder: (context, state) { + final sensorBloc = BlocProvider.of(context); + + return DefaultScaffold( + title: 'Select Scene', + actions: [_buildSaveButton(context, state, sensorBloc)], + child: state is FourSceneLoadingState + ? _buildLoadingIndicator() + : _buildSceneContent(context, sensorBloc), + ); + }, + ), + ); + } + + // Save button builder + Widget _buildSaveButton( + BuildContext context, FourSceneState state, FourSceneBloc sensorBloc) { + final bool canSave = + state is OptionSelectedState && state.hasSelectionChanged; + + return GestureDetector( + onTap: canSave + ? () { + print('object'); + context.read().add(SaveSelectionEvent()); + } + : null, + child: BodyMedium( + text: 'Save', + fontWeight: FontWeight.w700, + fontSize: 16, + fontColor: canSave + ? ColorsManager.slidingBlueColor + : ColorsManager.primaryTextColor, + ), + ); + } + + // Loading indicator + Widget _buildLoadingIndicator() { + return const Center( + child: DefaultContainer( + width: 50, + height: 50, + child: CircularProgressIndicator(), + ), + ); + } + + // Main scene content with search bar and grid + Widget _buildSceneContent(BuildContext context, FourSceneBloc sensorBloc) { + return Column( + children: [ + _buildSearchBar(sensorBloc), + const SizedBox(height: 20), + Expanded( + child: _buildSceneGrid(sensorBloc), + ), + ], + ); + } + + // Search bar widget + Widget _buildSearchBar(FourSceneBloc sensorBloc) { + return TextFormField( + controller: _searchController, + onChanged: (value) { + sensorBloc.add(SearchScenesEvent(query: value)); + }, + decoration: InputDecoration( + hintText: 'Search', + hintStyle: const TextStyle( + color: ColorsManager.textGray, + fontSize: 16, + fontWeight: FontWeight.w400), + suffixIcon: Container( + padding: const EdgeInsets.all(5.0), + margin: const EdgeInsets.all(10.0), + child: SvgPicture.asset( + Assets.searchIcon, + fit: BoxFit.contain, + ), + ), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(8.0), + ), + ), + ); + } + + // Scene grid builder + Widget _buildSceneGrid(FourSceneBloc sensorBloc) { + final scenes = sensorBloc.filteredScenes; + + return GridView.builder( + itemCount: scenes.length + 1, + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + mainAxisSpacing: 16, + crossAxisSpacing: 16, + mainAxisExtent: 120, + ), + itemBuilder: (context, index) { + if (index == scenes.length) { + return InkWell( + onTap: () => Navigator.pushNamed( + NavigationService.navigatorKey.currentContext!, + Routes.sceneTasksRoute, + arguments: SceneSettingsRouteArguments( + sceneType: '', + sceneId: '', + sceneName: '', + ), + ), + child: CreateSceneItem(), + ); + } else { + final scene = scenes[index]; + return SceneItem( + id: scene.id, + value: sensorBloc.selectedSceneId == scene.id, + disablePlayButton: false, + onChanged: (isSelected) { + sensorBloc.selectedSceneId = isSelected ? scene.id : 'null'; + sensorBloc.add(SelectOptionEvent(selectedOption: scene.id)); + }, + icon: scene.iconInBytes, + title: scene.name, + ); + } + }, + ); + } +} + +class SceneItem extends StatefulWidget { + final String id; // Unique ID for each scene + final Uint8List icon; + final String title; + final bool disablePlayButton; + final bool value; + final Function(bool) onChanged; + + const SceneItem({ + required this.id, + required this.icon, + required this.title, + this.disablePlayButton = false, + required this.value, + required this.onChanged, + }); + + @override + State createState() => _SceneItemState(); +} + +class _SceneItemState extends State { + @override + Widget build(BuildContext context) { + return Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(20), + boxShadow: const [ + BoxShadow( + color: Colors.black12, + blurRadius: 2, + spreadRadius: 1, + offset: Offset(0, 3), + ), + ], + ), + padding: const EdgeInsets.all(16), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + if (!widget.disablePlayButton) + Image.memory( + widget.icon, + height: 32, + width: 32, + fit: BoxFit.fill, + errorBuilder: (context, error, stackTrace) => Image.asset( + Assets.assetsIconsLogo, + height: 32, + width: 32, + fit: BoxFit.fill), + ), + BodyMedium( + text: widget.title, + style: const TextStyle( + fontSize: 17, + fontWeight: FontWeight.w700, + color: ColorsManager.secondaryTextColor), + textAlign: TextAlign.center, + ), + ], + ), + CircularCheckbox( + value: widget.value, + onChanged: (isSelected) => widget.onChanged(isSelected!), + ), + ], + ), + ); + } +} + +// Widget for the static "Create Scene" button +class CreateSceneItem extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(20), + boxShadow: const [ + BoxShadow( + color: Colors.black12, + blurRadius: 5, + spreadRadius: 2, + offset: Offset(0, 3), + ), + ], + ), + padding: const EdgeInsets.all(16), + child: const Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Icon(Icons.add_circle, + color: ColorsManager.grayButtonColors, size: 36), + BodyMedium( + text: 'Create Scene', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w400, + color: ColorsManager.secondaryTextColor), + textAlign: TextAlign.center, + ), + ], + ), + ); + } +} diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_select_switch_dialog.dart b/lib/features/devices/view/widgets/four_scene_switch/four_select_switch_dialog.dart new file mode 100644 index 0000000..99af6f9 --- /dev/null +++ b/lib/features/devices/view/widgets/four_scene_switch/four_select_switch_dialog.dart @@ -0,0 +1,145 @@ +import 'package:flutter/material.dart'; +import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/switches_card.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'; + +class FourSelectSwitchDialog extends StatefulWidget { + final Function()? cancelTab; + final Function()? confirmTab; + + const FourSelectSwitchDialog({ + super.key, + required this.cancelTab, + required this.confirmTab, + }); + + @override + State createState() => _FourSelectSwitchDialogState(); +} + +class _FourSelectSwitchDialogState extends State { + int? selectedSwitchIndex = 0; // State variable to track selected switch + + @override + Widget build(BuildContext context) { + return AlertDialog( + backgroundColor: ColorsManager.onPrimaryColor, + contentPadding: EdgeInsets.zero, + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const SizedBox(height: 10), + const BodyLarge( + text: 'Select Switch', + fontWeight: FontWeight.w700, + fontColor: ColorsManager.primaryColor, + fontSize: 16, + ), + const Padding( + padding: EdgeInsets.only(left: 15, right: 15), + child: Divider(color: ColorsManager.textGray), + ), + const SizedBox(height: 20), + Row( + children: [ + SwitchsCard( + switch1Down: selectedSwitchIndex == -1 + ? Assets.removeSceneIcon + : Assets.addSwitchIcon, + switch1Up: selectedSwitchIndex == 1 + ? Assets.removeSceneIcon + : Assets.addSwitchIcon, + switch2Down: selectedSwitchIndex == -2 + ? Assets.removeSceneIcon + : Assets.addSwitchIcon, + switch2Up: selectedSwitchIndex == 2 + ? Assets.removeSceneIcon + : Assets.addSwitchIcon, + + onSwitch1UpTap: () { + setState(() => selectedSwitchIndex = 1); + }, + onSwitch1DownTap: () { + setState(() => selectedSwitchIndex = -1); + }, + onSwitch2UpTap: () { + setState(() => selectedSwitchIndex = 2); + }, + onSwitch2DownTap: () { + setState(() => selectedSwitchIndex = -2); + }, + + ), + ], + ), + const SizedBox(height: 20), + const Center( + child: Text( + 'Please select one of the switches available to continue', + textAlign: TextAlign.center, + ), + ), + 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.textPrimaryColor, + 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: selectedSwitchIndex == 0 ? () {} : widget.confirmTab, + child: Padding( + padding: EdgeInsets.all(15), + child: Center( + child: Text( + 'Next', + style: TextStyle( + color: selectedSwitchIndex == 0 + ? ColorsManager.textPrimaryColor + .withOpacity(0.6) + : ColorsManager.primaryColor, + fontSize: 14, + fontWeight: FontWeight.w400), + ), + ), + ), + ), + ), + ), + ], + ) + ], + ), + ); + } +} diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_switches_card.dart b/lib/features/devices/view/widgets/four_scene_switch/four_switches_card.dart new file mode 100644 index 0000000..d1192bb --- /dev/null +++ b/lib/features/devices/view/widgets/four_scene_switch/four_switches_card.dart @@ -0,0 +1,131 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +class FourSwitchsCard extends StatelessWidget { + final String switch1Up; + final String switch1Down; + final String switch2Up; + final String switch2Down; + + final VoidCallback onSwitch1UpTap; + final VoidCallback onSwitch1DownTap; + final VoidCallback onSwitch2UpTap; + final VoidCallback onSwitch2DownTap; + + FourSwitchsCard({ + required this.switch1Down, + required this.switch1Up, + required this.switch2Down, + required this.switch2Up, + required this.onSwitch1UpTap, + required this.onSwitch1DownTap, + required this.onSwitch2UpTap, + required this.onSwitch2DownTap, + }); + + @override + Widget build(BuildContext context) { + return Expanded( + flex: 4, + child: InkWell( + overlayColor: MaterialStateProperty.all(Colors.transparent), + onTap: () {}, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Expanded( + child: Container( + margin: const EdgeInsets.symmetric(horizontal: 10), + decoration: const BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all(Radius.circular(10)), + ), + child: Container( + margin: const EdgeInsets.symmetric(horizontal: 10), + decoration: BoxDecoration( + color: ColorsManager.onPrimaryColor, + boxShadow: [ + BoxShadow( + color: Colors.white.withOpacity(0.1), + blurRadius: 24, + offset: const Offset(-2, -2), + blurStyle: BlurStyle.outer, + ), + BoxShadow( + color: Colors.black.withOpacity(0.11), + blurRadius: 5, + offset: const Offset(2, 0), + blurStyle: BlurStyle.outer, + ), + BoxShadow( + color: Colors.white.withOpacity(0.13), + blurRadius: 10, + offset: const Offset(5, 1), + blurStyle: BlurStyle.inner, + ), + ], + ), + child: SizedBox( + height: 300, + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + _buildSwitchColumn(switch1Up, switch1Down, onSwitch1UpTap, onSwitch1DownTap), + _buildDivider(), + _buildSwitchColumn(switch2Up, switch2Down, onSwitch2UpTap, onSwitch2DownTap), + ], + ), + ), + ), + ), + ), + ], + ), + ), + ); + } + + Widget _buildSwitchColumn( + String switchUp, + String switchDown, + VoidCallback onUpTap, + VoidCallback onDownTap, + ) { + return Expanded( + child: Padding( + padding: const EdgeInsets.only(top: 30, bottom: 30), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + InkWell( + onTap: onUpTap, + child: Container( + height: 20, + width: 20, + child: SvgPicture.asset(switchUp), + ), + ), + InkWell( + onTap: onDownTap, + child: Container( + height: 20, + width: 20, + child: SvgPicture.asset(switchDown), + ), + ), + ], + ), + ), + ); + } + + Widget _buildDivider() { + return Container( + width: 3, + color: ColorsManager.dividerColor, + ); + } +} diff --git a/lib/features/devices/view/widgets/room_page_switch.dart b/lib/features/devices/view/widgets/room_page_switch.dart index 4a0acab..f21a3b0 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/four_scene_switch/four_scene_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'; @@ -87,7 +88,6 @@ class RoomPageSwitch extends StatelessWidget { /// /// The [device] parameter represents the device model. void showDeviceInterface(DeviceModel device, BuildContext context) { - switch (device.productType) { case DeviceType.AC: Navigator.push( @@ -213,6 +213,13 @@ void showDeviceInterface(DeviceModel device, BuildContext context) { pageBuilder: (context, animation1, animation2) => WaterLeakScreen(device: device))); + case DeviceType.FourScene: + Navigator.push( + context, + PageRouteBuilder( + pageBuilder: (context, animation1, animation2) => + FourSceneScreen(device: device))); + break; default: } diff --git a/lib/generated/assets.dart b/lib/generated/assets.dart index 1a2ecf7..b111362 100644 --- a/lib/generated/assets.dart +++ b/lib/generated/assets.dart @@ -3,7 +3,8 @@ 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 @@ -19,82 +20,98 @@ 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 @@ -104,37 +121,44 @@ 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 @@ -144,37 +168,44 @@ 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 @@ -218,7 +249,8 @@ class Assets { static const String assetsIconsCurtainsIconVerticalBlade = "assets/icons/curtainsIcon/left_vertical_blade.svg"; - static const String rightVerticalBlade = "assets/icons/curtainsIcon/right_vertical_blade.svg"; + static const String rightVerticalBlade = + "assets/icons/curtainsIcon/right_vertical_blade.svg"; /// Assets for assetsIconsDashboard /// assets/icons/dashboard.svg @@ -228,7 +260,8 @@ 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 @@ -244,7 +277,8 @@ 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 @@ -252,15 +286,18 @@ 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 @@ -281,7 +318,8 @@ 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 @@ -369,11 +407,13 @@ 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 @@ -382,7 +422,8 @@ 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 @@ -390,7 +431,8 @@ 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 @@ -559,11 +601,13 @@ 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 @@ -596,7 +640,8 @@ 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 @@ -628,7 +673,8 @@ 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 @@ -724,7 +770,8 @@ 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 @@ -732,7 +779,8 @@ 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 @@ -762,7 +810,8 @@ class Assets { /// 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 = @@ -770,59 +819,73 @@ 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 @@ -831,15 +894,18 @@ 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 @@ -848,11 +914,13 @@ 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 @@ -861,15 +929,18 @@ 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 @@ -878,7 +949,8 @@ 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 @@ -952,7 +1024,8 @@ 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 @@ -974,27 +1047,33 @@ 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 garagePreferencesIcon = + "assets/icons/garage_preferences_icon.svg"; static const String garageSchedule = "assets/icons/garage_schedule.svg"; static const String garageIcon = "assets/icons/garageIcon.svg"; static const String normalWaterLeak = "assets/icons/normal_water_leak.svg"; - static const String detectedWaterLeak = "assets/icons/detected_water_leak.svg"; + static const String detectedWaterLeak = + "assets/icons/detected_water_leak.svg"; static const String waterLeakIcon = "assets/icons/waterleak_icon.svg"; static const String leakDetectedIcon = "assets/icons/leak_detected.svg"; @@ -1012,5 +1091,32 @@ class Assets { static const String powerClampIcon = "assets/icons/power_clamp.svg"; static const String automationIcon = "assets/icons/automation_ic.svg"; + static const String redSos = "assets/icons/red_sos.svg"; + static const String greenSos = "assets/icons/green_sos.svg"; + static const String emptyLog = "assets/icons/empty_log.svg"; + static const String sosProfileIcon = "assets/icons/sos_profile_icon.svg"; + static const String sosEditProfile = "assets/icons/edit_sos_icon.svg"; + static const String thumbUp = "assets/icons/thumb_up.svg"; + static const String thumbDown = "assets/icons/thumb_down.svg"; + static const String shareIcon = "assets/icons/share_icon.svg"; + static const String infoIcon = "assets/icons/info.svg"; + static const String notificationIcon = "assets/icons/notification_icon.svg"; + static const String faqIcon = "assets/icons/faq_icon.svg"; + static const String updateIcon = "assets/icons/update_icon.svg"; + static const String emptyUpdateIcon = "assets/icons/empty_update_icon.svg"; + static const String checkUpdateIcon = "assets/icons/check_update_icon.svg"; + + static const String switchOn = "assets/icons/switch_on.svg"; + static const String switchOff = "assets/icons/switch_off.svg"; + static const String backlightIcon = "assets/icons/backlight_icon.svg"; + static const String addSwitchIcon = "assets/icons/add_switch_icon.svg"; + static const String addSceneIcon = "assets/icons/add_scene_icon.svg"; + static const String removeSceneIcon = "assets/icons/remove_scene_icon.svg"; + static const String tapRunIcon = "assets/icons/tap_run_icon.svg"; + static const String createGroupIcon = "assets/icons/create_group_icon.svg"; + static const String sixSceneIcon = "assets/icons/six_scene_icon.svg"; + static const String minusIcon = "assets/icons/minus_icon.svg"; + static const String addDevicesIcon = "assets/icons/add_devices_icon.svg"; + //powerClampIcon } diff --git a/lib/services/api/devices_api.dart b/lib/services/api/devices_api.dart index fe6cc56..9b6f93a 100644 --- a/lib/services/api/devices_api.dart +++ b/lib/services/api/devices_api.dart @@ -65,7 +65,7 @@ class DevicesAPI { showServerMessage: false, expectedResponseModel: (json) => DevicesCategoryModel.fromJsonList(json), ); - + return response; } @@ -75,6 +75,7 @@ class DevicesAPI { .replaceAll('{deviceUuid}', deviceId), showServerMessage: false, expectedResponseModel: (json) { + print('json==#$json'); return json; }, ); @@ -121,6 +122,16 @@ class DevicesAPI { return response; } + static Future getDeviceInfo(String deviceId) async { + final response = await _httpService.get( + path: ApiEndpoints.deviceByUuid.replaceAll('{deviceUuid}', deviceId), + showServerMessage: false, + expectedResponseModel: (json) { + return json; + }); + return response; + } + static Future> getDeviceByGroupName( String unitId, String groupName) async { final response = await _httpService.get( diff --git a/lib/utils/resource_manager/color_manager.dart b/lib/utils/resource_manager/color_manager.dart index c078eab..ac3a4bb 100644 --- a/lib/utils/resource_manager/color_manager.dart +++ b/lib/utils/resource_manager/color_manager.dart @@ -31,5 +31,8 @@ abstract class ColorsManager { static const Color switchButton = Color(0xff023DFE); static const Color grayBox = Color(0xffF5F5F5); static const Color chart = Color(0xff023DFE); + static const Color blueColor = Color(0xff5481F3); + static const Color blueColor1 = Color(0xff0A7AFF); + static const Color grayButtonColors = Color(0xffCCCCCC); } //background: #F5F5F5;023DFE diff --git a/lib/utils/resource_manager/constants.dart b/lib/utils/resource_manager/constants.dart index b1129b2..dc913ce 100644 --- a/lib/utils/resource_manager/constants.dart +++ b/lib/utils/resource_manager/constants.dart @@ -56,6 +56,7 @@ enum DeviceType { GarageDoor, WaterLeak, PC, + FourScene, Other, } @@ -88,11 +89,14 @@ Map devicesTypesMap = { "GD": DeviceType.GarageDoor, "WL": DeviceType.WaterLeak, "PC": DeviceType.PC, + "4S": DeviceType.FourScene, }; Map> devicesFunctionsMap = { DeviceType.AC: [ FunctionModel( - code: 'switch', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})), + code: 'switch', + type: functionTypesMap['Boolean'], + values: ValueModel.fromJson({})), FunctionModel( code: 'mode', type: functionTypesMap['Enum'], @@ -115,7 +119,9 @@ Map> devicesFunctionsMap = { // "range": ["low", "middle", "high", "auto"] })), FunctionModel( - code: 'child_lock', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})), + code: 'child_lock', + type: functionTypesMap['Boolean'], + values: ValueModel.fromJson({})), ], DeviceType.Gateway: [ FunctionModel( @@ -129,7 +135,9 @@ Map> devicesFunctionsMap = { "range": ["normal", "alarm"] })), FunctionModel( - code: 'factory_reset', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})), + code: 'factory_reset', + type: functionTypesMap['Boolean'], + values: ValueModel.fromJson({})), FunctionModel( code: 'alarm_active', type: functionTypesMap['String'], @@ -139,7 +147,8 @@ Map> devicesFunctionsMap = { FunctionModel( code: 'sensitivity', type: functionTypesMap['Integer'], - values: ValueModel.fromJson({"unit": "", "min": 1, "max": 10, "scale": 0, "step": 1})), + values: ValueModel.fromJson( + {"unit": "", "min": 1, "max": 10, "scale": 0, "step": 1})), ], DeviceType.DoorLock: [ FunctionModel( @@ -147,7 +156,9 @@ Map> devicesFunctionsMap = { type: functionTypesMap['Raw'], values: ValueModel.fromJson({})), FunctionModel( - code: 'remote_no_dp_key', type: functionTypesMap['Raw'], values: ValueModel.fromJson({})), + code: 'remote_no_dp_key', + type: functionTypesMap['Raw'], + values: ValueModel.fromJson({})), FunctionModel( code: 'normal_open_switch', type: functionTypesMap['Boolean'], @@ -157,64 +168,87 @@ Map> devicesFunctionsMap = { FunctionModel( code: 'far_detection', type: functionTypesMap['Integer'], - values: ValueModel.fromJson({"unit": "cm", "min": 75, "max": 600, "scale": 0, "step": 75})), + values: ValueModel.fromJson( + {"unit": "cm", "min": 75, "max": 600, "scale": 0, "step": 75})), FunctionModel( code: 'presence_time', type: functionTypesMap['Integer'], - values: - ValueModel.fromJson({"unit": "Min", "min": 0, "max": 65535, "scale": 0, "step": 1})), + values: ValueModel.fromJson( + {"unit": "Min", "min": 0, "max": 65535, "scale": 0, "step": 1})), FunctionModel( code: 'motion_sensitivity_value', type: functionTypesMap['Integer'], - values: ValueModel.fromJson({"unit": "", "min": 1, "max": 5, "scale": 0, "step": 1})), + values: ValueModel.fromJson( + {"unit": "", "min": 1, "max": 5, "scale": 0, "step": 1})), FunctionModel( code: 'motionless_sensitivity', type: functionTypesMap['Integer'], - values: ValueModel.fromJson({"unit": "", "min": 1, "max": 5, "scale": 0, "step": 1})), + values: ValueModel.fromJson( + {"unit": "", "min": 1, "max": 5, "scale": 0, "step": 1})), FunctionModel( - code: 'indicator', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})), + code: 'indicator', + type: functionTypesMap['Boolean'], + values: ValueModel.fromJson({})), ], DeviceType.OneGang: [ FunctionModel( - code: 'switch_1', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})), + code: 'switch_1', + type: functionTypesMap['Boolean'], + values: ValueModel.fromJson({})), FunctionModel( code: 'countdown_1', type: functionTypesMap['Integer'], - values: ValueModel.fromJson({"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})), + values: ValueModel.fromJson( + {"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})), ], DeviceType.TwoGang: [ FunctionModel( - code: 'switch_1', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})), + code: 'switch_1', + type: functionTypesMap['Boolean'], + values: ValueModel.fromJson({})), FunctionModel( - code: 'switch_2', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})), + code: 'switch_2', + type: functionTypesMap['Boolean'], + values: ValueModel.fromJson({})), FunctionModel( code: 'countdown_1', type: functionTypesMap['Integer'], - values: ValueModel.fromJson({"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})), + values: ValueModel.fromJson( + {"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})), FunctionModel( code: 'countdown_2', type: functionTypesMap['Integer'], - values: ValueModel.fromJson({"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})), + values: ValueModel.fromJson( + {"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})), ], DeviceType.ThreeGang: [ FunctionModel( - code: 'switch_1', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})), + code: 'switch_1', + type: functionTypesMap['Boolean'], + values: ValueModel.fromJson({})), FunctionModel( - code: 'switch_2', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})), + code: 'switch_2', + type: functionTypesMap['Boolean'], + values: ValueModel.fromJson({})), FunctionModel( - code: 'switch_3', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})), + code: 'switch_3', + type: functionTypesMap['Boolean'], + values: ValueModel.fromJson({})), FunctionModel( code: 'countdown_1', type: functionTypesMap['Integer'], - values: ValueModel.fromJson({"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})), + values: ValueModel.fromJson( + {"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})), FunctionModel( code: 'countdown_2', type: functionTypesMap['Integer'], - values: ValueModel.fromJson({"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})), + values: ValueModel.fromJson( + {"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})), FunctionModel( code: 'countdown_3', type: functionTypesMap['Integer'], - values: ValueModel.fromJson({"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})), + values: ValueModel.fromJson( + {"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})), ], DeviceType.Curtain: [ FunctionModel( @@ -226,15 +260,19 @@ Map> devicesFunctionsMap = { FunctionModel( code: 'percent_control', type: functionTypesMap['Integer'], - values: ValueModel.fromJson({"unit": "%", "min": 0, "max": 100, "scale": 0, "step": 1})), + values: ValueModel.fromJson( + {"unit": "%", "min": 0, "max": 100, "scale": 0, "step": 1})), ], DeviceType.WH: [ FunctionModel( - code: 'switch_1', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})), + code: 'switch_1', + type: functionTypesMap['Boolean'], + values: ValueModel.fromJson({})), FunctionModel( code: 'countdown_1', type: functionTypesMap['Integer'], - values: ValueModel.fromJson({"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})), + values: ValueModel.fromJson( + {"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})), FunctionModel( code: 'relay_status', type: functionTypesMap['Enum'], @@ -258,7 +296,9 @@ Map> devicesFunctionsMap = { ], DeviceType.DS: [ FunctionModel( - code: 'doorcontact_state', type: functionTypesMap['Raw'], values: ValueModel.fromJson({})), + code: 'doorcontact_state', + type: functionTypesMap['Raw'], + values: ValueModel.fromJson({})), FunctionModel( code: 'battery_percentage', type: functionTypesMap['Integer'], @@ -266,11 +306,14 @@ Map> devicesFunctionsMap = { ], DeviceType.OneTouch: [ FunctionModel( - code: 'switch_1', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})), + code: 'switch_1', + type: functionTypesMap['Boolean'], + values: ValueModel.fromJson({})), FunctionModel( code: 'countdown_1', type: functionTypesMap['Integer'], - values: ValueModel.fromJson({"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})), + values: ValueModel.fromJson( + {"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})), FunctionModel( code: 'relay_status', type: functionTypesMap['Enum'], @@ -292,17 +335,23 @@ Map> devicesFunctionsMap = { ], DeviceType.TowTouch: [ FunctionModel( - code: 'switch_1', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})), + code: 'switch_1', + type: functionTypesMap['Boolean'], + values: ValueModel.fromJson({})), FunctionModel( - code: 'switch_2', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})), + code: 'switch_2', + type: functionTypesMap['Boolean'], + values: ValueModel.fromJson({})), FunctionModel( code: 'countdown_1', type: functionTypesMap['Integer'], - values: ValueModel.fromJson({"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})), + values: ValueModel.fromJson( + {"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})), FunctionModel( code: 'countdown_2', type: functionTypesMap['Integer'], - values: ValueModel.fromJson({"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})), + values: ValueModel.fromJson( + {"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})), FunctionModel( code: 'relay_status', type: functionTypesMap['Enum'], @@ -330,23 +379,32 @@ Map> devicesFunctionsMap = { ], DeviceType.ThreeTouch: [ FunctionModel( - code: 'switch_1', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})), + code: 'switch_1', + type: functionTypesMap['Boolean'], + values: ValueModel.fromJson({})), FunctionModel( - code: 'switch_2', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})), + code: 'switch_2', + type: functionTypesMap['Boolean'], + values: ValueModel.fromJson({})), FunctionModel( - code: 'switch_3', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})), + code: 'switch_3', + type: functionTypesMap['Boolean'], + values: ValueModel.fromJson({})), FunctionModel( code: 'countdown_1', type: functionTypesMap['Integer'], - values: ValueModel.fromJson({"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})), + values: ValueModel.fromJson( + {"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})), FunctionModel( code: 'countdown_2', type: functionTypesMap['Integer'], - values: ValueModel.fromJson({"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})), + values: ValueModel.fromJson( + {"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})), FunctionModel( code: 'countdown_3', type: functionTypesMap['Integer'], - values: ValueModel.fromJson({"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})), + values: ValueModel.fromJson( + {"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})), FunctionModel( code: 'relay_status', type: functionTypesMap['Enum'], @@ -380,19 +438,24 @@ Map> devicesFunctionsMap = { ], DeviceType.GarageDoor: [ FunctionModel( - code: 'switch_1', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})), + 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})), + 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})), + 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})), + values: ValueModel.fromJson( + {"unit": "s", "min": 0, "max": 86400, "scale": 0, "step": 1})), FunctionModel( code: 'door_control_1', type: functionTypesMap['Enum'], @@ -413,19 +476,24 @@ Map> devicesFunctionsMap = { DeviceType.WaterLeak: [], DeviceType.PC: [ FunctionModel( - code: 'switch_1', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})), + 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})), + 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})), + 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})), + values: ValueModel.fromJson( + {"unit": "s", "min": 0, "max": 86400, "scale": 0, "step": 1})), FunctionModel( code: 'door_control_1', type: functionTypesMap['Enum'], @@ -443,6 +511,40 @@ Map> devicesFunctionsMap = { "range": ["unclosed_time", "close_time_alarm", "none"] })), ], + DeviceType.FourScene: [ + FunctionModel( + code: 'scene_1', + type: functionTypesMap['Boolean'], + values: ValueModel.fromJson({ + "range": ["scene"] + })), + FunctionModel( + code: 'scene_2', + type: functionTypesMap['Integer'], + values: ValueModel.fromJson({ + "range": ["scene"] + })), + FunctionModel( + code: 'scene_3', + type: functionTypesMap['Integer'], + values: ValueModel.fromJson({ + "range": ["scene"] + })), + FunctionModel( + code: 'scene_4', + type: functionTypesMap['Integer'], + values: ValueModel.fromJson({ + "range": ["scene"] + })), + FunctionModel( + code: 'scene_id_group_id', + type: functionTypesMap['Raw'], + values: ValueModel.fromJson({})), + FunctionModel( + code: 'switch_backlight', + type: functionTypesMap['Enum'], + values: ValueModel.fromJson({})), + ] }; enum TempModes { hot, cold, wind } @@ -588,7 +690,11 @@ List> menuSections = [ 'Icon': Assets.assetsIconsMenuIconsMessagesCenterIconsMessages, 'page': null }, - {'title': 'FAQs', 'Icon': Assets.assetsIconsMenuIconsMessagesCenterIconsFAQs, 'page': null}, + { + 'title': 'FAQs', + 'Icon': Assets.assetsIconsMenuIconsMessagesCenterIconsFAQs, + 'page': null + }, { 'title': 'Help & Feedback', 'Icon': Assets.assetsIconsMenuIconsMessagesCenterIconsHelpAndFeedback, @@ -618,7 +724,11 @@ List> menuSections = [ 'title': 'Legal Information', 'color': const Color(0xFF001B72), 'buttons': [ - {'title': 'About', 'Icon': Assets.assetsIconsMenuIconsLeagalInfoIconsAbout, 'page': null}, + { + 'title': 'About', + 'Icon': Assets.assetsIconsMenuIconsLeagalInfoIconsAbout, + 'page': null + }, { 'title': 'Privacy Policy', 'Icon': Assets.assetsIconsMenuIconsLeagalInfoIconsPrivacyPolicy, diff --git a/pubspec.lock b/pubspec.lock index 4b11f46..057d001 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -704,6 +704,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.2.1" + percent_indicator: + dependency: "direct main" + description: + name: percent_indicator + sha256: c37099ad833a883c9d71782321cb65c3a848c21b6939b6185f0ff6640d05814c + url: "https://pub.dev" + source: hosted + version: "4.2.3" permission_handler: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index e2f30e0..22267ad 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -46,6 +46,7 @@ dependencies: device_info_plus: ^10.1.0 fl_chart: ^0.69.0 firebase_database: ^10.5.7 + percent_indicator: ^4.2.3 dev_dependencies: From f1bb4544291f4b06805011da889c0147404fe89c Mon Sep 17 00:00:00 2001 From: mohammad Date: Mon, 18 Nov 2024 16:19:01 +0300 Subject: [PATCH 02/29] four_scene --- .../bloc/four_scene_bloc/four_scene_bloc.dart | 76 +++--- .../four_scene_bloc/four_scene_event.dart | 19 +- .../four_scene_bloc/four_scene_state.dart | 6 +- .../four_scene_info_page.dart | 68 +++-- .../four_scene_profile_page.dart | 22 +- .../four_scene_settings.dart | 46 ++-- .../location_setting_four_scene.dart | 244 +++++++++--------- .../four_select_scene_page.dart | 2 +- lib/services/api/devices_api.dart | 1 + 9 files changed, 276 insertions(+), 208 deletions(-) diff --git a/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart b/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart index c74b990..97c335c 100644 --- a/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart +++ b/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart @@ -1,5 +1,4 @@ import 'dart:async'; -import 'dart:convert'; import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -12,9 +11,11 @@ import 'package:syncrow_app/features/devices/model/four_scene_question_model.dar import 'package:syncrow_app/features/devices/model/group_devices_model.dart'; import 'package:syncrow_app/features/devices/model/scene_switch_model.dart'; import 'package:syncrow_app/features/devices/model/status_model.dart'; +import 'package:syncrow_app/features/devices/model/subspace_model.dart'; import 'package:syncrow_app/features/scene/model/scenes_model.dart'; import 'package:syncrow_app/generated/assets.dart'; import 'package:syncrow_app/services/api/devices_api.dart'; +import 'package:syncrow_app/services/api/home_management_api.dart'; import 'package:syncrow_app/services/api/scene_api.dart'; import 'package:syncrow_app/services/api/spaces_api.dart'; @@ -34,19 +35,22 @@ class FourSceneBloc extends Bloc { on(_onLoadScenes); on(_selectScene); on(searchScene); - on(_onSaveSelection); + on(_assignDevice); on(_onOptionSelected); - on(_addDeviceToGroup); // Register handler here + on(_addDeviceToGroup); on(_removeDeviceFromGroup); + on(_onFourSceneInitial); } final TextEditingController nameController = - TextEditingController(text: '${'firstName'}'); + TextEditingController(text: deviceName); bool isSaving = false; bool editName = false; final FocusNode focusNode = FocusNode(); bool closingReminder = false; bool waterAlarm = false; + static String deviceName = ''; + static String selectedRoomId = ''; FourSceneModel deviceStatus = FourSceneModel( scene_1: '', @@ -56,11 +60,11 @@ class FourSceneBloc extends Bloc { scene_id_group_id: '', switch_backlight: false); - SceneSwitch sceneInfo = SceneSwitch( - activeTime: 1728118263, + SceneSwitch deviceInfo = SceneSwitch( + activeTime: 0, category: "", categoryName: "", - createTime: 1728118263, + createTime: 0, gatewayId: "", icon: "", ip: "", @@ -70,10 +74,10 @@ class FourSceneBloc extends Bloc { model: "", name: "", nodeId: "", - online: true, + online: false, ownerId: "", productName: "", - sub: true, + sub: false, timeZone: "", updateTime: 0, uuid: "", @@ -102,7 +106,6 @@ class FourSceneBloc extends Bloc { statusModelList, ); emit(UpdateState(sensor: deviceStatus)); - Future.delayed(const Duration(milliseconds: 500)); // _listenToChanges(); } catch (e) { @@ -115,13 +118,9 @@ class FourSceneBloc extends Bloc { FourSceneInitialInfo event, Emitter emit) async { emit(FourSceneLoadingState()); var response = await DevicesAPI.getDeviceInfo(fourSceneId); - if (response.statusCode == 200) { - Map jsonData = jsonDecode(response.body); - sceneInfo = SceneSwitch.fromJson(jsonData); - emit(LoadingDeviceInfo(sosSensor: sceneInfo)); - } else { - throw Exception('Failed to load device data: ${response.reasonPhrase}'); - } + deviceInfo = SceneSwitch.fromJson(response); + deviceName = deviceInfo.name; + emit(LoadingDeviceInfo(deviceInfo: deviceInfo)); } void _onSearchFaq(SearchFaqEvent event, Emitter emit) { @@ -131,8 +130,6 @@ class FourSceneBloc extends Bloc { .toLowerCase() .contains(event.query.toLowerCase()); }).toList(); - - print(_faqQuestions); emit(FaqSearchState(filteredFaqQuestions: _faqQuestions)); } @@ -155,7 +152,6 @@ class FourSceneBloc extends Bloc { try { closingReminder = event.isClosingEnabled; emit(UpdateState(sensor: deviceStatus)); - // API call to update the state, if necessary // await DevicesAPI.controlDevice( // DeviceControlModel( @@ -235,13 +231,15 @@ class FourSceneBloc extends Bloc { } List allDevices = []; + List roomsList = []; void _fetchRoomsAndDevices( FetchRoomsEvent event, Emitter emit) async { try { emit(FourSceneLoadingState()); - final roomsList = await SpacesAPI.getSubSpaceBySpaceId( + roomsList = await SpacesAPI.getSubSpaceBySpaceId( event.unit.community.uuid, event.unit.id); + print(roomsList); emit(FetchRoomsState(devicesList: allDevices, roomsList: roomsList)); } catch (e) { emit(const FourSceneFailedState(errorMessage: 'Something went wrong')); @@ -257,8 +255,6 @@ class FourSceneBloc extends Bloc { emit(ChangeSwitchState(isEnable: switchStatus)); } - // List allScenes = []; - Future _onLoadScenes( LoadScenes event, Emitter emit) async { emit(FourSceneLoadingState()); @@ -314,16 +310,6 @@ class FourSceneBloc extends Bloc { hasSelectionChanged: _hasSelectionChanged)); } - void _onSaveSelection( - SaveSelectionEvent event, Emitter emit) { - if (_hasSelectionChanged) { - print('Save button clicked with selected option: $_selectedOption'); - _hasSelectionChanged = false; - emit(SaveSelectionSuccessState()); - } - } - -//addDevicesIcon List groupDevices = [ GroupDevicesModel( dec: 'Syncroom', icon: Assets.minusIcon, name: '6 Scene Switch') @@ -367,4 +353,28 @@ class FourSceneBloc extends Bloc { } emit(UpdateStateList(groupDevices: groupDevices, devices: devices)); } + + void _assignDevice( + AssignRoomEvent event, Emitter emit) async { + try { + emit(FourSceneLoadingState()); + if (_hasSelectionChanged) { + await HomeManagementAPI.assignDeviceToRoom(event.unit.community.uuid, + event.unit.id, event.roomId, fourSceneId); + final devicesList = await DevicesAPI.getDevicesByRoomId( + communityUuid: event.unit.community.uuid, + spaceUuid: event.unit.id, + roomId: event.roomId); + List allDevicesIds = []; + allDevices.forEach((element) { + allDevicesIds.add(element.uuid!); + }); + emit(SaveSelectionSuccessState()); + } + } catch (e) { + emit(const FourSceneFailedState(errorMessage: 'Something went wrong')); + return; + } + } + } diff --git a/lib/features/devices/bloc/four_scene_bloc/four_scene_event.dart b/lib/features/devices/bloc/four_scene_bloc/four_scene_event.dart index 39a13be..ae89a6a 100644 --- a/lib/features/devices/bloc/four_scene_bloc/four_scene_event.dart +++ b/lib/features/devices/bloc/four_scene_bloc/four_scene_event.dart @@ -151,7 +151,7 @@ class SearchScenesEvent extends FourSceneEvent { }); } -class SaveSelectionEvent extends FourSceneEvent {} +class SaveLocationSelectionEvent extends FourSceneEvent {} class SelectOptionEvent extends FourSceneEvent { dynamic selectedOption; @@ -172,3 +172,20 @@ class RemoveDeviceFromGroup extends FourSceneEvent { RemoveDeviceFromGroup(this.device, this.icon); } + + +class AssignRoomEvent extends FourSceneEvent { + final String roomId; + final SpaceModel unit; + + const AssignRoomEvent({ + required this.roomId, + required this.unit, + }); + + @override + List get props => [ + roomId, + unit, + ]; +} diff --git a/lib/features/devices/bloc/four_scene_bloc/four_scene_state.dart b/lib/features/devices/bloc/four_scene_bloc/four_scene_state.dart index b407837..9645459 100644 --- a/lib/features/devices/bloc/four_scene_bloc/four_scene_state.dart +++ b/lib/features/devices/bloc/four_scene_bloc/four_scene_state.dart @@ -115,9 +115,9 @@ class OptionSelectedState extends FourSceneState { class LoadingDeviceInfo extends FourSceneState { - final SceneSwitch sosSensor; - const LoadingDeviceInfo({required this.sosSensor}); + final SceneSwitch deviceInfo; + const LoadingDeviceInfo({required this.deviceInfo}); @override - List get props => [sosSensor]; + List get props => [deviceInfo]; } \ No newline at end of file diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_info_page.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_info_page.dart index 0caed76..1798750 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_info_page.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_info_page.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart'; -import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart'; -import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart'; - +import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_event.dart'; +import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_state.dart'; import 'package:syncrow_app/features/devices/model/device_model.dart'; -import 'package:syncrow_app/features/devices/model/six_scene_model.dart'; +import 'package:syncrow_app/features/devices/model/four_scene_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/features/shared_widgets/text_widgets/body_large.dart'; @@ -13,29 +13,35 @@ import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dar import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart'; import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; -class SixSceneInfoPage extends StatelessWidget { +class FourSceneInfoPage extends StatelessWidget { final DeviceModel? device; - const SixSceneInfoPage({super.key, this.device}); + const FourSceneInfoPage({super.key, this.device}); @override Widget build(BuildContext context) { return DefaultScaffold( title: 'Device Information', child: BlocProvider( - create: (context) => SixSceneBloc(sixSceneId: device?.uuid ?? '') - ..add(const SixSceneInitial()), - child: BlocBuilder( + create: (context) => FourSceneBloc(fourSceneId: device?.uuid ?? '') + ..add(const FourSceneInitial()) + ..add(FourSceneInitialInfo()), + child: BlocBuilder( builder: (context, state) { - final sensor = BlocProvider.of(context); - SixSceneModel model = SixSceneModel( - batteryPercentage: 0, waterContactState: 'normal'); + final _bloc = BlocProvider.of(context); + FourSceneModel model = FourSceneModel( + scene_1: '', + scene_2: '', + scene_3: '', + scene_4: '', + scene_id_group_id: '', + switch_backlight: ''); if (state is LoadingNewSate) { model = state.sosSensor; } else if (state is UpdateState) { model = state.sensor; } - return state is SixSceneLoadingState + return state is FourSceneLoadingState ? const Center( child: DefaultContainer( width: 50, @@ -44,11 +50,11 @@ class SixSceneInfoPage extends StatelessWidget { ) : RefreshIndicator( onRefresh: () async { - sensor.add(const SixSceneInitial()); + _bloc.add(const FourSceneInitial()); }, child: DefaultContainer( child: Padding( - padding: const EdgeInsets.only(left: 10, right: 10), + padding: const EdgeInsets.only(left: 5, right: 5), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, @@ -63,12 +69,24 @@ class SixSceneInfoPage extends StatelessWidget { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - const BodySmall( - text: 'bf3575d0e0c8b6e0a6hybl', + BodySmall( + text: _bloc.deviceInfo.productUuid, fontColor: ColorsManager.primaryTextColor, ), InkWell( - onTap: () {}, + onTap: () { + Clipboard.setData( + ClipboardData( + text: _bloc.deviceInfo.productUuid, + ), + ); + + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text("Copied to Clipboard"), + ), + ); + }, child: const Row( children: [ Icon( @@ -87,18 +105,18 @@ class SixSceneInfoPage extends StatelessWidget { const Divider( color: ColorsManager.dividerColor, ), - const Column( + Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - BodyLarge( + const BodyLarge( text: 'MAC', fontSize: 15, fontWeight: FontWeight.w400, fontColor: ColorsManager.blackColor, ), BodySmall( - text: 'bf3575d0e0c8b6e0a6hybl', + text: _bloc.deviceInfo.macAddress, fontColor: ColorsManager.primaryTextColor, ), ], @@ -106,18 +124,18 @@ class SixSceneInfoPage extends StatelessWidget { const Divider( color: ColorsManager.dividerColor, ), - const Column( + Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - BodyLarge( + const BodyLarge( text: 'Time Zone', fontSize: 15, fontWeight: FontWeight.w400, fontColor: ColorsManager.blackColor, ), BodySmall( - text: 'Asia/Dubai', + text: _bloc.deviceInfo.timeZone, fontColor: ColorsManager.primaryTextColor, ), ], diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_profile_page.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_profile_page.dart index d363321..aa05cfe 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_profile_page.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_profile_page.dart @@ -27,10 +27,11 @@ class FourSceneProfilePage extends StatelessWidget { title: 'Device Settings', child: BlocProvider( create: (context) => FourSceneBloc(fourSceneId: device?.uuid ?? '') - ..add(const FourSceneInitial()), + ..add(const FourSceneInitial()) + ..add(FourSceneInitialInfo()), child: BlocBuilder( builder: (context, state) { - final sensor = BlocProvider.of(context); + final _bloc = BlocProvider.of(context); FourSceneModel model = FourSceneModel( scene_1: '', scene_2: '', @@ -52,7 +53,7 @@ class FourSceneProfilePage extends StatelessWidget { ) : RefreshIndicator( onRefresh: () async { - sensor.add(const FourSceneInitial()); + _bloc.add(const FourSceneInitial()); }, child: ListView( children: [ @@ -88,9 +89,9 @@ class FourSceneProfilePage extends StatelessWidget { color: Colors.black, ), textAlign: TextAlign.center, - focusNode: sensor.focusNode, - controller: sensor.nameController, - enabled: sensor.editName, + focusNode: _bloc.focusNode, + controller: _bloc.nameController, + enabled: _bloc.editName, onEditingComplete: () { // sensor.add(SaveNameEvent(context: context)); }, @@ -106,8 +107,7 @@ class FourSceneProfilePage extends StatelessWidget { const SizedBox(width: 5), InkWell( onTap: () { - sensor - .add(const ChangeNameEvent(value: true)); + _bloc.add(const ChangeNameEvent(value: true)); }, child: const Padding( padding: EdgeInsets.symmetric(horizontal: 10), @@ -136,10 +136,11 @@ class FourSceneProfilePage extends StatelessWidget { MaterialPageRoute( builder: (context) => LocationFourScenePage( space: spaces!.first, + deviceId: device?.uuid ?? '', )), ); }, - child: const Row( + child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ SizedBox( @@ -149,7 +150,8 @@ class FourSceneProfilePage extends StatelessWidget { children: [ SizedBox( child: BodyMedium( - text: 'Syncroom', + text: _bloc + .deviceInfo.subspace.subspaceName, fontColor: ColorsManager.textGray, ), ), diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart index 1b1451f..007a42f 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart @@ -10,6 +10,7 @@ import 'package:syncrow_app/features/devices/model/four_scene_model.dart'; import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_scene_setting/faq_four_scene_page.dart'; import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_create_group.dart'; import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_delete_dialog.dart'; +import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_info_page.dart'; import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_profile_page.dart'; import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_update_dialog.dart'; import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_update_page.dart'; @@ -33,10 +34,11 @@ class FourSceneSettings extends StatelessWidget { title: 'Device Settings', child: BlocProvider( create: (context) => FourSceneBloc(fourSceneId: device?.uuid ?? '') - ..add(const FourSceneInitial()), + ..add(const FourSceneInitial()) + ..add(FourSceneInitialInfo()), child: BlocBuilder( builder: (context, state) { - final sensor = BlocProvider.of(context); + final _bloc = BlocProvider.of(context); FourSceneModel model = FourSceneModel( scene_1: '', scene_2: '', @@ -58,7 +60,7 @@ class FourSceneSettings extends StatelessWidget { ) : RefreshIndicator( onRefresh: () async { - sensor.add(const FourSceneInitial()); + _bloc.add(const FourSceneInitial()); }, child: ListView( children: [ @@ -70,25 +72,27 @@ class FourSceneSettings extends StatelessWidget { onTap: () { Navigator.of(context).push( MaterialPageRoute( - builder: (context) => - const FourSceneProfilePage(), + builder: (context) => FourSceneProfilePage( + device: device, + ), ), ); }, child: Stack( children: [ - const Column( + Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - SizedBox(height: 20), + const SizedBox(height: 20), DefaultContainer( - borderRadius: - BorderRadius.all(Radius.circular(30)), + borderRadius: const BorderRadius.all( + Radius.circular(30)), child: Padding( - padding: EdgeInsets.all(10.0), + padding: const EdgeInsets.all(10.0), child: Padding( - padding: EdgeInsets.only(left: 90), + padding: + const EdgeInsets.only(left: 90), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -98,17 +102,20 @@ class FourSceneSettings extends StatelessWidget { CrossAxisAlignment.start, children: [ BodyMedium( - text: '4 Scene Switch', + text: _bloc.deviceInfo.name, fontWeight: FontWeight.bold, ), - SizedBox( + const SizedBox( height: 5, ), BodySmall( - text: "Room: Syncrow"), + text: _bloc + .deviceInfo + .subspace + .subspaceName), ], ), - Icon(Icons.edit_sharp) + const Icon(Icons.edit_sharp) ], ), ), @@ -152,11 +159,10 @@ class FourSceneSettings extends StatelessWidget { children: [ SettingWidget( onTap: () { - // Navigator.of(context).push( - // MaterialPageRoute( - // builder: (context) => - // const FourSceneInfoPage()), - // ); + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => FourSceneInfoPage( device: device!,)), + ); }, text: 'Device Information', icon: Assets.infoIcon, diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/location_setting_four_scene.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/location_setting_four_scene.dart index aa6a80b..71de7e3 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/location_setting_four_scene.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/location_setting_four_scene.dart @@ -3,56 +3,37 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_app/features/app_layout/model/space_model.dart'; import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_event.dart'; import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_state.dart'; import 'package:syncrow_app/features/devices/model/four_scene_model.dart'; -import 'package:syncrow_app/features/devices/model/subspace_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/features/shared_widgets/text_widgets/body_medium.dart'; import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; -import '../../../../bloc/four_scene_bloc/four_scene_event.dart'; - -class LocationFourScenePage extends StatefulWidget { +class LocationFourScenePage extends StatelessWidget { final SpaceModel? space; - LocationFourScenePage({super.key, this.space}); + final String? deviceId; - @override - _LocationFourScenePageState createState() => _LocationFourScenePageState(); -} - -class _LocationFourScenePageState extends State { - String _selectedOption = 'Conference Room'; - bool _hasSelectionChanged = false; + const LocationFourScenePage({ + super.key, + this.space, + this.deviceId, + }); @override Widget build(BuildContext context) { - return DefaultScaffold( - title: 'Device Location', - actions: [ - InkWell( - onTap: _hasSelectionChanged - ? () { - print('Save button clicked'); - } - : null, - child: BodyMedium( - text: 'Save', - fontWeight: FontWeight.w700, - fontSize: 16, - fontColor: _hasSelectionChanged - ? ColorsManager.slidingBlueColor - : ColorsManager.primaryTextColor, - ), - ), - const SizedBox(width: 20), - ], - child: BlocProvider( - create: (context) => FourSceneBloc(fourSceneId: '') - ..add(FetchRoomsEvent(unit: widget.space!)), + String roomIdSelected = ''; + + return Scaffold( + body: BlocProvider( + create: (context) => FourSceneBloc(fourSceneId: deviceId ?? '') + ..add(const FourSceneInitial()) + ..add(FourSceneInitialInfo()) + ..add(FetchRoomsEvent(unit: space!)), child: BlocBuilder( builder: (context, state) { - final sensor = BlocProvider.of(context); + final _bloc = BlocProvider.of(context); FourSceneModel model = FourSceneModel( scene_1: '', scene_2: '', @@ -60,12 +41,6 @@ class _LocationFourScenePageState extends State { scene_4: '', scene_id_group_id: '', switch_backlight: ''); - List? rooms = []; - if (state is LoadingNewSate) { - model = state.sosSensor; - } else if (state is FetchRoomsState) { - rooms = state.roomsList; - } return state is FourSceneLoadingState ? const Center( child: DefaultContainer( @@ -74,52 +49,92 @@ class _LocationFourScenePageState extends State { child: CircularProgressIndicator(), ), ) - : RefreshIndicator( - onRefresh: () async { - sensor.add(const FourSceneInitial()); - }, - child: ListView( - padding: const EdgeInsets.symmetric(vertical: 20), - children: [ - const BodyMedium( - text: 'Smart Device Location', - fontWeight: FontWeight.w700, - fontSize: 12, - fontColor: ColorsManager.grayColor, - ), - const SizedBox(height: 5), - DefaultContainer( - padding: const EdgeInsets.all(20), - child: ListView.builder( - physics: const NeverScrollableScrollPhysics(), - shrinkWrap: true, - itemCount: rooms!.length, - itemBuilder: (context, index) { - final room = rooms![index]; - return Column( - children: [ - _buildCheckboxOption( - label: room.name!, - onTap: (v) { - setState(() { - _selectedOption = v; - _hasSelectionChanged = true; - }); - }, - ), - if (index < rooms.length - 1) ...[ - const SizedBox(height: 10), - const Divider( - color: ColorsManager.dividerColor, - ), - const SizedBox(height: 10), - ], - ], - ); - }, + : DefaultScaffold( + actions: [ + BlocBuilder( + builder: (context, state) { + final bool canSave = state is OptionSelectedState && + state.hasSelectionChanged; + return InkWell( + onTap: canSave + ? () { + context.read().add( + AssignRoomEvent( + roomId: roomIdSelected, + unit: space!)); + } + : null, + child: BodyMedium( + text: 'Save', + fontWeight: FontWeight.w700, + fontSize: 16, + fontColor: canSave + ? ColorsManager.slidingBlueColor + : ColorsManager.primaryTextColor, + ), + ); + }, + ), + const SizedBox(width: 20), + ], + child: RefreshIndicator( + onRefresh: () async { + // sensor.add(const SosInitial()); + }, + child: ListView( + shrinkWrap: true, + padding: const EdgeInsets.symmetric(vertical: 20), + children: [ + const BodyMedium( + text: 'Smart Device Location', + fontWeight: FontWeight.w700, + fontSize: 12, + fontColor: ColorsManager.grayColor, ), - ), - ], + const SizedBox(height: 5), + DefaultContainer( + padding: const EdgeInsets.all(20), + child: ListView.builder( + physics: const NeverScrollableScrollPhysics(), + shrinkWrap: true, + itemCount: _bloc.roomsList.length, + itemBuilder: (context, index) { + final fromRoom = _bloc.roomsList[index]; + final isSelected = (state + is OptionSelectedState && + state.selectedOption == fromRoom.id) || + (state is! OptionSelectedState && + fromRoom.id == + _bloc.deviceInfo.subspace.uuid); + + return Column( + children: [ + _buildCheckboxOption( + label: fromRoom.name!, + isSelected: isSelected, + onTap: (label) { + context.read().add( + SelectOptionEvent( + selectedOption: fromRoom.id!, + ), + ); + roomIdSelected = fromRoom.id!; + }, + ), + if (index < _bloc.roomsList.length - 1) ...[ + const SizedBox(height: 10), + const Divider( + color: ColorsManager.dividerColor, + ), + const SizedBox(height: 10), + ], + ], + ); + }, + ), + ), + ], + ), ), ); }, @@ -127,34 +142,6 @@ class _LocationFourScenePageState extends State { ), ); } - - Widget _buildCheckboxOption( - {required String label, required 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; - _hasSelectionChanged = true; - }); - onTap(label); - } - }, - ), - ], - ), - ); - } } class CircularCheckbox extends StatefulWidget { @@ -200,3 +187,30 @@ class _CircularCheckboxState extends State { ); } } + +Widget _buildCheckboxOption({ + required String label, + required bool isSelected, + required 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: isSelected, + onChanged: (bool? value) { + if (value == true) { + onTap(label); + } + }, + ), + ], + ), + ); +} diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_select_scene_page.dart b/lib/features/devices/view/widgets/four_scene_switch/four_select_scene_page.dart index 7553b7d..4d463b0 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_select_scene_page.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_select_scene_page.dart @@ -58,7 +58,7 @@ class FourSelectSceneFourPage extends StatelessWidget { onTap: canSave ? () { print('object'); - context.read().add(SaveSelectionEvent()); + // context.read().add(SaveSelectionEvent()); } : null, child: BodyMedium( diff --git a/lib/services/api/devices_api.dart b/lib/services/api/devices_api.dart index 9b6f93a..3298c96 100644 --- a/lib/services/api/devices_api.dart +++ b/lib/services/api/devices_api.dart @@ -127,6 +127,7 @@ class DevicesAPI { path: ApiEndpoints.deviceByUuid.replaceAll('{deviceUuid}', deviceId), showServerMessage: false, expectedResponseModel: (json) { + print('object-=-=-$json'); return json; }); return response; From 1be6d71e89f72720fce98211fb82eb9df168f531 Mon Sep 17 00:00:00 2001 From: mohammad Date: Tue, 19 Nov 2024 11:31:17 +0300 Subject: [PATCH 03/29] four_scene --- .../bloc/four_scene_bloc/four_scene_bloc.dart | 91 ++++++++++++++++++- .../four_scene_bloc/four_scene_event.dart | 16 +++- .../four_scene_bloc/four_scene_state.dart | 1 + .../four_scene_profile_page.dart | 18 +++- .../four_scene_settings.dart | 11 ++- .../location_setting_four_scene.dart | 8 ++ lib/services/api/devices_api.dart | 16 ++++ 7 files changed, 151 insertions(+), 10 deletions(-) diff --git a/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart b/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart index 97c335c..d141214 100644 --- a/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart +++ b/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart @@ -18,6 +18,7 @@ import 'package:syncrow_app/services/api/devices_api.dart'; import 'package:syncrow_app/services/api/home_management_api.dart'; import 'package:syncrow_app/services/api/scene_api.dart'; import 'package:syncrow_app/services/api/spaces_api.dart'; +import 'package:syncrow_app/utils/helpers/snack_bar.dart'; class FourSceneBloc extends Bloc { final String fourSceneId; @@ -27,6 +28,7 @@ class FourSceneBloc extends Bloc { on(_fetchStatus); on(fetchDeviceData); on(fetchLogsForLastMonth); + on(saveName); on(_toggleNotification); on(_changeName); on(_onSearchFaq); @@ -40,6 +42,7 @@ class FourSceneBloc extends Bloc { on(_addDeviceToGroup); on(_removeDeviceFromGroup); on(_onFourSceneInitial); + on(_fetchDeviceScene); } final TextEditingController nameController = @@ -93,6 +96,47 @@ class FourSceneBloc extends Bloc { ), ); + // void changeDeviceName( + // SaveNameEvent event, Emitter emit) async { + // emit(FourSceneLoadingState()); + // try { + // var response = await DevicesAPI.putDeviceName( + // deviceId: fourSceneId, deviceName: event.deviceName!); + // List statusModelList = []; + // for (var status in response['status']) { + // statusModelList.add(StatusModel.fromJson(status)); + // } + // deviceStatus = FourSceneModel.fromJson( + // statusModelList, + // ); + // emit(UpdateState(sensor: deviceStatus)); + // Future.delayed(const Duration(milliseconds: 500)); + // // _listenToChanges(); + // } catch (e) { + // emit(FourSceneFailedState(errorMessage: e.toString())); + // return; + // } + // } + + Future saveName( + SaveNameEvent event, Emitter emit) async { + if (_validateInputs()) return; + try { + add(const ChangeNameEvent(value: false)); + isSaving = true; + emit(FourSceneLoadingState()); + var response = await DevicesAPI.putDeviceName( + deviceId: fourSceneId, deviceName: nameController.text); + add(FourSceneInitialInfo()); + CustomSnackBar.displaySnackBar('Save Successfully'); + emit(SaveState()); + } catch (e) { + emit(FourSceneFailedState(errorMessage: e.toString())); + } finally { + isSaving = false; + } + } + void _fetchStatus( FourSceneInitial event, Emitter emit) async { emit(FourSceneLoadingState()); @@ -114,6 +158,27 @@ class FourSceneBloc extends Bloc { } } + void _fetchDeviceScene( + FetchDeviceScene event, Emitter emit) async { + emit(FourSceneLoadingState()); + try { + var response = await DevicesAPI.getDeviceStatus(fourSceneId); + List statusModelList = []; + for (var status in response['status']) { + statusModelList.add(StatusModel.fromJson(status)); + } + deviceStatus = FourSceneModel.fromJson( + statusModelList, + ); + emit(UpdateState(sensor: deviceStatus)); + Future.delayed(const Duration(milliseconds: 500)); + // _listenToChanges(); + } catch (e) { + emit(FourSceneFailedState(errorMessage: e.toString())); + return; + } + } + Future fetchDeviceData( FourSceneInitialInfo event, Emitter emit) async { emit(FourSceneLoadingState()); @@ -369,6 +434,8 @@ class FourSceneBloc extends Bloc { allDevices.forEach((element) { allDevicesIds.add(element.uuid!); }); + CustomSnackBar.displaySnackBar('Save Successfully'); + emit(SaveSelectionSuccessState()); } } catch (e) { @@ -376,5 +443,27 @@ class FourSceneBloc extends Bloc { return; } } - + + bool _validateInputs() { + final nameError = fullNameValidator(nameController.text); + if (nameError != null) { + CustomSnackBar.displaySnackBar(nameError); + return true; + } + return false; + } + + String? fullNameValidator(String? value) { + if (value == null) return 'name is required'; + final withoutExtraSpaces = value.replaceAll(RegExp(r"\s+"), ' ').trim(); + if (withoutExtraSpaces.length < 2 || withoutExtraSpaces.length > 30) { + return 'Full name must be between 2 and 30 characters long'; + } + // Test if it contains anything but alphanumeric spaces and single quote + if (RegExp(r"/[^ a-zA-Z0-9-\']/").hasMatch(withoutExtraSpaces)) { + return 'Only alphanumeric characters, space, dash and single quote are allowed'; + } + + return null; + } } diff --git a/lib/features/devices/bloc/four_scene_bloc/four_scene_event.dart b/lib/features/devices/bloc/four_scene_bloc/four_scene_event.dart index ae89a6a..da82021 100644 --- a/lib/features/devices/bloc/four_scene_bloc/four_scene_event.dart +++ b/lib/features/devices/bloc/four_scene_bloc/four_scene_event.dart @@ -1,4 +1,5 @@ import 'package:equatable/equatable.dart'; +import 'package:flutter/material.dart'; import 'package:syncrow_app/features/app_layout/model/space_model.dart'; import 'package:syncrow_app/features/devices/model/group_devices_model.dart'; @@ -23,12 +24,19 @@ class FourSceneSwitch extends FourSceneEvent { } class FourSceneUpdated extends FourSceneEvent {} + class FourSceneInitialInfo extends FourSceneEvent {} class FourSceneInitial extends FourSceneEvent { const FourSceneInitial(); } +class SaveNameEvent extends FourSceneEvent { + final String? deviceName; + + const SaveNameEvent({this.deviceName}); +} + class ReportLogsInitial extends FourSceneEvent { const ReportLogsInitial(); } @@ -173,19 +181,25 @@ class RemoveDeviceFromGroup extends FourSceneEvent { RemoveDeviceFromGroup(this.device, this.icon); } - class AssignRoomEvent extends FourSceneEvent { final String roomId; final SpaceModel unit; + final BuildContext context; const AssignRoomEvent({ required this.roomId, required this.unit, + required this.context, }); @override List get props => [ roomId, unit, + context, ]; } + +class FetchDeviceScene extends FourSceneEvent { + const FetchDeviceScene(); +} diff --git a/lib/features/devices/bloc/four_scene_bloc/four_scene_state.dart b/lib/features/devices/bloc/four_scene_bloc/four_scene_state.dart index 9645459..951ea3f 100644 --- a/lib/features/devices/bloc/four_scene_bloc/four_scene_state.dart +++ b/lib/features/devices/bloc/four_scene_bloc/four_scene_state.dart @@ -97,6 +97,7 @@ class SceneLoaded extends FourSceneState { class SelectedSceneState extends FourSceneState {} class SearchResultsState extends FourSceneState {} +class SaveState extends FourSceneState {} class SaveSelectionSuccessState extends FourSceneState {} diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_profile_page.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_profile_page.dart index aa05cfe..da0fa3d 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_profile_page.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_profile_page.dart @@ -25,6 +25,11 @@ class FourSceneProfilePage extends StatelessWidget { return DefaultScaffold( title: 'Device Settings', + leading: IconButton( + onPressed: () { + Navigator.of(context).pop(true); + }, + icon: const Icon(Icons.arrow_back_ios)), child: BlocProvider( create: (context) => FourSceneBloc(fourSceneId: device?.uuid ?? '') ..add(const FourSceneInitial()) @@ -93,7 +98,7 @@ class FourSceneProfilePage extends StatelessWidget { controller: _bloc.nameController, enabled: _bloc.editName, onEditingComplete: () { - // sensor.add(SaveNameEvent(context: context)); + _bloc.add(const SaveNameEvent()); }, decoration: const InputDecoration( hintText: "Your Name", @@ -131,19 +136,22 @@ class FourSceneProfilePage extends StatelessWidget { DefaultContainer( padding: const EdgeInsets.all(20), child: InkWell( - onTap: () { - Navigator.of(context).push( + onTap: () async { + bool val = await Navigator.of(context).push( MaterialPageRoute( builder: (context) => LocationFourScenePage( space: spaces!.first, deviceId: device?.uuid ?? '', )), ); + if (val == true) { + _bloc.add(FourSceneInitialInfo()); + } }, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - SizedBox( + const SizedBox( child: Text('Location'), ), Row( @@ -155,7 +163,7 @@ class FourSceneProfilePage extends StatelessWidget { fontColor: ColorsManager.textGray, ), ), - Icon( + const Icon( Icons.arrow_forward_ios, size: 15, color: ColorsManager.textGray, diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart index 007a42f..ee0a5af 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart @@ -69,14 +69,17 @@ class FourSceneSettings extends StatelessWidget { vertical: 10, ), child: InkWell( - onTap: () { - Navigator.of(context).push( + onTap: () async { + bool val = await Navigator.of(context).push( MaterialPageRoute( builder: (context) => FourSceneProfilePage( device: device, ), ), ); + if (val == true) { + _bloc.add(FourSceneInitialInfo()); + } }, child: Stack( children: [ @@ -161,7 +164,9 @@ class FourSceneSettings extends StatelessWidget { onTap: () { Navigator.of(context).push( MaterialPageRoute( - builder: (context) => FourSceneInfoPage( device: device!,)), + builder: (context) => FourSceneInfoPage( + device: device!, + )), ); }, text: 'Device Information', diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/location_setting_four_scene.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/location_setting_four_scene.dart index 71de7e3..43b8dfd 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/location_setting_four_scene.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/location_setting_four_scene.dart @@ -41,6 +41,12 @@ class LocationFourScenePage extends StatelessWidget { scene_4: '', scene_id_group_id: '', switch_backlight: ''); + if (state is SaveSelectionSuccessState) { + new Future.delayed(const Duration(microseconds: 500), () { + _bloc.add(FourSceneInitialInfo()); + Navigator.of(context).pop(true); + }); + } return state is FourSceneLoadingState ? const Center( child: DefaultContainer( @@ -60,6 +66,7 @@ class LocationFourScenePage extends StatelessWidget { ? () { context.read().add( AssignRoomEvent( + context: context, roomId: roomIdSelected, unit: space!)); } @@ -77,6 +84,7 @@ class LocationFourScenePage extends StatelessWidget { ), const SizedBox(width: 20), ], + child: RefreshIndicator( onRefresh: () async { // sensor.add(const SosInitial()); diff --git a/lib/services/api/devices_api.dart b/lib/services/api/devices_api.dart index 3298c96..ac18192 100644 --- a/lib/services/api/devices_api.dart +++ b/lib/services/api/devices_api.dart @@ -31,6 +31,22 @@ class DevicesAPI { } } + static Future> putDeviceName( + {required String deviceId, required String deviceName}) async { + try { + final response = await _httpService.put( + path: ApiEndpoints.deviceByUuid.replaceAll('{deviceUuid}', deviceId), + body: {"deviceName": deviceName}, + expectedResponseModel: (json) { + return json; + }, + ); + return response; + } catch (e) { + rethrow; + } + } + static Future> controlDevice( DeviceControlModel controlModel, String deviceId) async { try { From 777bd549ca720c0753bade8fb7f514b62b770d01 Mon Sep 17 00:00:00 2001 From: mohammad Date: Tue, 19 Nov 2024 15:45:28 +0300 Subject: [PATCH 04/29] 4scene --- .../bloc/four_scene_bloc/four_scene_bloc.dart | 135 +++++++++++------- .../four_scene_bloc/four_scene_event.dart | 15 +- .../four_scene_bloc/four_scene_state.dart | 12 +- .../devices/model/four_scene_model.dart | 8 +- .../model/four_scene_switch_model.dart | 85 +++++++++++ .../four_scene_switch/four_scene_screen.dart | 65 +++++---- .../four_scene_create_group.dart | 6 +- .../four_scene_info_page.dart | 6 +- .../four_scene_profile_page.dart | 8 +- .../four_scene_settings.dart | 6 +- .../location_setting_four_scene.dart | 2 +- .../question_page_four_scene.dart | 6 +- .../share_four_scene_page.dart | 6 +- .../four_select_switch_dialog.dart | 1 + .../four_scene_switch/four_switches_card.dart | 102 ++++++++----- lib/services/api/api_links_endpoints.dart | 1 + lib/services/api/devices_api.dart | 11 +- 17 files changed, 334 insertions(+), 141 deletions(-) create mode 100644 lib/features/devices/model/four_scene_switch_model.dart diff --git a/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart b/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart index d141214..6105b64 100644 --- a/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart +++ b/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart @@ -4,10 +4,12 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_event.dart'; import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_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/four_scene_model.dart'; import 'package:syncrow_app/features/devices/model/four_scene_question_model.dart'; +import 'package:syncrow_app/features/devices/model/four_scene_switch_model.dart'; import 'package:syncrow_app/features/devices/model/group_devices_model.dart'; import 'package:syncrow_app/features/devices/model/scene_switch_model.dart'; import 'package:syncrow_app/features/devices/model/status_model.dart'; @@ -43,6 +45,8 @@ class FourSceneBloc extends Bloc { on(_removeDeviceFromGroup); on(_onFourSceneInitial); on(_fetchDeviceScene); + on(_controlDevice); + on(_fetchFourSceneSwitches); } final TextEditingController nameController = @@ -55,7 +59,7 @@ class FourSceneBloc extends Bloc { static String deviceName = ''; static String selectedRoomId = ''; - FourSceneModel deviceStatus = FourSceneModel( + FourSceneModelState deviceStatus = FourSceneModelState( scene_1: '', scene_2: '', scene_3: '', @@ -96,28 +100,6 @@ class FourSceneBloc extends Bloc { ), ); - // void changeDeviceName( - // SaveNameEvent event, Emitter emit) async { - // emit(FourSceneLoadingState()); - // try { - // var response = await DevicesAPI.putDeviceName( - // deviceId: fourSceneId, deviceName: event.deviceName!); - // List statusModelList = []; - // for (var status in response['status']) { - // statusModelList.add(StatusModel.fromJson(status)); - // } - // deviceStatus = FourSceneModel.fromJson( - // statusModelList, - // ); - // emit(UpdateState(sensor: deviceStatus)); - // Future.delayed(const Duration(milliseconds: 500)); - // // _listenToChanges(); - // } catch (e) { - // emit(FourSceneFailedState(errorMessage: e.toString())); - // return; - // } - // } - Future saveName( SaveNameEvent event, Emitter emit) async { if (_validateInputs()) return; @@ -137,6 +119,34 @@ class FourSceneBloc extends Bloc { } } + List fourScene = []; + + void _fetchFourSceneSwitches( + FourSceneSwitchInitial event, Emitter emit) async { + emit(FourSceneLoadingState()); + try { + List response = await DevicesAPI.getFourSceneInfo(fourSceneId); + fourScene = + response.map((item) => FourSceneSwitchModel.fromJson(item)).toList(); + print('Fetched response: $fourScene'); + _rankFourSceneSwitches(); + + emit(UpdateState(device: deviceStatus)); + } catch (e) { + print('Error in _fetchFourSceneSwitches: $e'); + emit(FourSceneFailedState(errorMessage: e.toString())); + } + } + + void _rankFourSceneSwitches() { + const switchOrder = ['scene_1', 'scene_2', 'scene_3', 'scene_4']; + fourScene.sort((a, b) { + return switchOrder + .indexOf(a.switchName) + .compareTo(switchOrder.indexOf(b.switchName)); + }); + } + void _fetchStatus( FourSceneInitial event, Emitter emit) async { emit(FourSceneLoadingState()); @@ -146,10 +156,10 @@ class FourSceneBloc extends Bloc { for (var status in response['status']) { statusModelList.add(StatusModel.fromJson(status)); } - deviceStatus = FourSceneModel.fromJson( + deviceStatus = FourSceneModelState.fromJson( statusModelList, ); - emit(UpdateState(sensor: deviceStatus)); + emit(UpdateState(device: deviceStatus)); Future.delayed(const Duration(milliseconds: 500)); // _listenToChanges(); } catch (e) { @@ -167,10 +177,10 @@ class FourSceneBloc extends Bloc { for (var status in response['status']) { statusModelList.add(StatusModel.fromJson(status)); } - deviceStatus = FourSceneModel.fromJson( + deviceStatus = FourSceneModelState.fromJson( statusModelList, ); - emit(UpdateState(sensor: deviceStatus)); + emit(UpdateState(device: deviceStatus)); Future.delayed(const Duration(milliseconds: 500)); // _listenToChanges(); } catch (e) { @@ -179,6 +189,27 @@ class FourSceneBloc extends Bloc { } } + void _controlDevice( + ControlDeviceScene event, Emitter emit) async { + emit(FourSceneLoadingState()); + try { + deviceStatus.switch_backlight = !event.backLight!; + emit(UpdateState(device: deviceStatus)); + final response = await DevicesAPI.controlDevice( + DeviceControlModel( + deviceId: fourSceneId, + code: 'switch_backlight', + value: !event.backLight!), + fourSceneId); + + if (!response['success']) { + // add(InitialEvent(groupScreen: oneTouchGroup)); + } + } catch (_) { + // add(InitialEvent(groupScreen: oneTouchGroup)); + } + } + Future fetchDeviceData( FourSceneInitialInfo event, Emitter emit) async { emit(FourSceneLoadingState()); @@ -213,10 +244,10 @@ class FourSceneBloc extends Bloc { void _toggleNotification( ToggleNotificationEvent event, Emitter emit) async { - emit(LoadingNewSate(sosSensor: deviceStatus)); + emit(LoadingNewSate(device: deviceStatus)); try { closingReminder = event.isClosingEnabled; - emit(UpdateState(sensor: deviceStatus)); + emit(UpdateState(device: deviceStatus)); // API call to update the state, if necessary // await DevicesAPI.controlDevice( // DeviceControlModel( @@ -249,7 +280,7 @@ class FourSceneBloc extends Bloc { code: 'sossensor_state', ); recordGroups = response; - emit(UpdateState(sensor: deviceStatus)); + emit(UpdateState(device: deviceStatus)); } on DioException catch (e) { final errorData = e.response!.data; String errorMessage = errorData['message']; @@ -304,7 +335,6 @@ class FourSceneBloc extends Bloc { emit(FourSceneLoadingState()); roomsList = await SpacesAPI.getSubSpaceBySpaceId( event.unit.community.uuid, event.unit.id); - print(roomsList); emit(FetchRoomsState(devicesList: allDevices, roomsList: roomsList)); } catch (e) { emit(const FourSceneFailedState(errorMessage: 'Something went wrong')); @@ -313,11 +343,26 @@ class FourSceneBloc extends Bloc { } bool switchStatus = true; - void changeSwitchStatus( - ChangeSwitchStatusEvent event, Emitter emit) { - emit(FourSceneLoadingState()); - switchStatus = !switchStatus; - emit(ChangeSwitchState(isEnable: switchStatus)); + Future changeSwitchStatus( + ChangeSwitchStatusEvent event, Emitter emit) async { + try { + emit(FourSceneLoadingState()); + switchStatus = deviceStatus.switch_backlight; + switchStatus = !switchStatus; + final response = await DevicesAPI.controlDevice( + DeviceControlModel( + deviceId: fourSceneId, + code: 'switch_backlight', + value: switchStatus), + fourSceneId); + deviceStatus.switch_backlight = switchStatus; + if (!response['success']) { + add(const FourSceneInitial()); + } + emit(ChangeSwitchState(isEnable: switchStatus)); + } catch (_) { + add(const FourSceneInitial()); + } } Future _onLoadScenes( @@ -385,19 +430,6 @@ class FourSceneBloc extends Bloc { dec: 'Syncroom', icon: Assets.addDevicesIcon, name: '6 Scene Switch') ]; - // @override - // Stream mapEventToState(FourSceneEvent event) async* { - // if (event is AddDeviceToGroup) { - // devices.remove(event.device); - // groupDevices.add(event.device); - // yield UpdateStateList(groupDevices: groupDevices, devices: devices); - // } else if (event is RemoveDeviceFromGroup) { - // groupDevices.remove(event.device); - // devices.add(event.device); - // yield UpdateStateList(groupDevices: groupDevices, devices: devices); - // } - // } - // Handler for AddDeviceToGroup void _addDeviceToGroup(AddDeviceToGroup event, Emitter emit) { devices.remove(event.device); @@ -466,4 +498,9 @@ class FourSceneBloc extends Bloc { return null; } + + String scene1 = 'scene_1'; + String scene2 = 'scene_2'; + String scene3 = 'scene_3'; + String scene4 = 'scene_4'; } diff --git a/lib/features/devices/bloc/four_scene_bloc/four_scene_event.dart b/lib/features/devices/bloc/four_scene_bloc/four_scene_event.dart index da82021..f2c69b0 100644 --- a/lib/features/devices/bloc/four_scene_bloc/four_scene_event.dart +++ b/lib/features/devices/bloc/four_scene_bloc/four_scene_event.dart @@ -25,7 +25,9 @@ class FourSceneSwitch extends FourSceneEvent { class FourSceneUpdated extends FourSceneEvent {} -class FourSceneInitialInfo extends FourSceneEvent {} +class FourSceneInitialInfo extends FourSceneEvent { + const FourSceneInitialInfo(); +} class FourSceneInitial extends FourSceneEvent { const FourSceneInitial(); @@ -200,6 +202,13 @@ class AssignRoomEvent extends FourSceneEvent { ]; } -class FetchDeviceScene extends FourSceneEvent { - const FetchDeviceScene(); +class FetchDeviceScene extends FourSceneEvent {} + +class ControlDeviceScene extends FourSceneEvent { + final bool? backLight; + const ControlDeviceScene({this.backLight}); +} + +class FourSceneSwitchInitial extends FourSceneEvent { + const FourSceneSwitchInitial(); } diff --git a/lib/features/devices/bloc/four_scene_bloc/four_scene_state.dart b/lib/features/devices/bloc/four_scene_bloc/four_scene_state.dart index 951ea3f..a0dba6b 100644 --- a/lib/features/devices/bloc/four_scene_bloc/four_scene_state.dart +++ b/lib/features/devices/bloc/four_scene_bloc/four_scene_state.dart @@ -36,19 +36,19 @@ class FourSceneFailedState extends FourSceneState { } class UpdateState extends FourSceneState { - final FourSceneModel sensor; - const UpdateState({required this.sensor}); + final FourSceneModelState device; + const UpdateState({required this.device}); @override - List get props => [sensor]; + List get props => [device]; } class LoadingNewSate extends FourSceneState { - final FourSceneModel sosSensor; - const LoadingNewSate({required this.sosSensor}); + final FourSceneModelState device; + const LoadingNewSate({required this.device}); @override - List get props => [sosSensor]; + List get props => [device]; } class NameEditingState extends FourSceneState { diff --git a/lib/features/devices/model/four_scene_model.dart b/lib/features/devices/model/four_scene_model.dart index 82f2b73..8bf1ce0 100644 --- a/lib/features/devices/model/four_scene_model.dart +++ b/lib/features/devices/model/four_scene_model.dart @@ -1,6 +1,6 @@ import 'package:syncrow_app/features/devices/model/status_model.dart'; -class FourSceneModel { +class FourSceneModelState { dynamic scene_1; dynamic scene_2; dynamic scene_3; @@ -8,7 +8,7 @@ class FourSceneModel { dynamic scene_id_group_id; dynamic switch_backlight; - FourSceneModel({ + FourSceneModelState({ required this.scene_1, required this.scene_2, required this.scene_3, @@ -17,7 +17,7 @@ class FourSceneModel { required this.switch_backlight, }); - factory FourSceneModel.fromJson(List jsonList) { + factory FourSceneModelState.fromJson(List jsonList) { late dynamic _scene_1; late dynamic _scene_2; late dynamic _scene_3; @@ -40,7 +40,7 @@ class FourSceneModel { _switch_backlight = jsonList[i].value ?? false; } } - return FourSceneModel( + return FourSceneModelState( scene_1: _scene_1, scene_2: _scene_2, scene_3: _scene_3, diff --git a/lib/features/devices/model/four_scene_switch_model.dart b/lib/features/devices/model/four_scene_switch_model.dart new file mode 100644 index 0000000..d837262 --- /dev/null +++ b/lib/features/devices/model/four_scene_switch_model.dart @@ -0,0 +1,85 @@ +class FourSceneSwitchModel { + final String switchName; + final DateTime createdAt; + final DateTime updatedAt; + final String deviceUuid; + final Scene scene; + + FourSceneSwitchModel({ + required this.switchName, + required this.createdAt, + required this.updatedAt, + required this.deviceUuid, + required this.scene, + }); + + factory FourSceneSwitchModel.fromJson(Map json) { + return FourSceneSwitchModel( + switchName: json['switchName'], + createdAt: DateTime.parse(json['createdAt']), + updatedAt: DateTime.parse(json['updatedAt']), + deviceUuid: json['deviceUuid'], + scene: Scene.fromJson(json['scene']), + ); + } +} + +class Scene { + final String uuid; + final String sceneTuyaId; + final String name; + final String status; + final String icon; + final String iconUuid; + final bool showInHome; + final String type; + final List actions; + + Scene({ + required this.uuid, + required this.sceneTuyaId, + required this.name, + required this.status, + required this.icon, + required this.iconUuid, + required this.showInHome, + required this.type, + required this.actions, + }); + + factory Scene.fromJson(Map json) { + return Scene( + uuid: json['uuid'], + sceneTuyaId: json['sceneTuyaId'], + name: json['name'], + status: json['status'], + icon: json['icon'], + iconUuid: json['iconUuid'], + showInHome: json['showInHome'], + type: json['type'], + actions: (json['actions'] as List) + .map((action) => Action.fromJson(action)) + .toList(), + ); + } +} + +class Action { + final String actionExecutor; + final String entityId; + final Map executorProperty; + + Action({ + required this.actionExecutor, + required this.entityId, + required this.executorProperty, + }); + + factory Action.fromJson(Map json) { + return Action( + actionExecutor: json['actionExecutor'], + entityId: json['entityId'], + executorProperty: json['executorProperty'], + ); + } +} diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_screen.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_screen.dart index 34e79ef..b566fbf 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_screen.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_screen.dart @@ -42,11 +42,12 @@ class FourSceneScreen extends StatelessWidget { child: BlocProvider( create: (context) => FourSceneBloc(fourSceneId: device?.uuid ?? '') ..add(const FourSceneInitial()) - ..add(FourSceneInitialInfo()), + ..add(const FourSceneInitialInfo()) + ..add(const FourSceneSwitchInitial()), child: BlocBuilder( builder: (context, state) { - final sensor = BlocProvider.of(context); - FourSceneModel model = FourSceneModel( + final _bloc = BlocProvider.of(context); + FourSceneModelState model = FourSceneModelState( scene_1: '', scene_2: '', scene_3: '', @@ -54,9 +55,9 @@ class FourSceneScreen extends StatelessWidget { scene_id_group_id: '', switch_backlight: ''); if (state is LoadingNewSate) { - model = state.sosSensor; + model = state.device; } else if (state is UpdateState) { - model = state.sensor; + model = state.device; } return state is FourSceneLoadingState ? const Center( @@ -67,7 +68,7 @@ class FourSceneScreen extends StatelessWidget { ) : RefreshIndicator( onRefresh: () async { - sensor.add(const FourSceneInitial()); + _bloc.add(const FourSceneInitial()); }, child: ListView( children: [ @@ -76,29 +77,45 @@ class FourSceneScreen extends StatelessWidget { child: Column( children: [ FourSwitchsCard( - switch1Down: sensor.switchStatus == true - ? Assets.switchOn - : Assets.switchOff, - switch1Up: sensor.switchStatus == true - ? Assets.switchOn - : Assets.switchOff, - switch2Down: sensor.switchStatus == true - ? Assets.switchOn - : Assets.switchOff, - switch2Up: sensor.switchStatus == true - ? Assets.switchOn - : Assets.switchOff, + title1: _bloc.fourScene.isNotEmpty + ? _bloc.fourScene[0].switchName + : 'title1', + title2: _bloc.fourScene.length > 1 + ? _bloc.fourScene[1].switchName + : 'title2', + title3: _bloc.fourScene.length > 2 + ? _bloc.fourScene[2].switchName + : 'title3', + title4: _bloc.fourScene.length > 3 + ? _bloc.fourScene[3].switchName + : 'title4', + switch1: + _bloc.deviceStatus.switch_backlight == true + ? Assets.switchOn + : Assets.switchOff, + switch2: + _bloc.deviceStatus.switch_backlight == true + ? Assets.switchOn + : Assets.switchOff, + switch3: + _bloc.deviceStatus.switch_backlight == true + ? Assets.switchOn + : Assets.switchOff, + switch4: + _bloc.deviceStatus.switch_backlight == true + ? Assets.switchOn + : Assets.switchOff, onSwitch1UpTap: () { debugPrint("Switch 1 Up tapped"); }, - onSwitch1DownTap: () { - debugPrint("Switch 1 Down tapped"); - }, onSwitch2UpTap: () { debugPrint("Switch 2 Up tapped"); }, - onSwitch2DownTap: () { - debugPrint("Switch 2 Down tapped"); + onSwitch3DownTap: () { + debugPrint("onSwitch3DownTap"); + }, + onSwitch4DownTap: () { + debugPrint("onSwitch4DownTap"); }, ), Flexible( @@ -107,7 +124,7 @@ class FourSceneScreen extends StatelessWidget { Expanded( child: DefaultContainer( onTap: () { - sensor.add(ChangeSwitchStatusEvent()); + _bloc.add(ChangeSwitchStatusEvent()); }, child: Column( crossAxisAlignment: diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_create_group.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_create_group.dart index fed78f3..5c3cb20 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_create_group.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_create_group.dart @@ -29,7 +29,7 @@ class FourSceneCreateGroup extends StatelessWidget { child: BlocBuilder( builder: (context, state) { final sensor = BlocProvider.of(context); - FourSceneModel model = FourSceneModel( + FourSceneModelState model = FourSceneModelState( scene_1: '', scene_2: '', scene_3: '', @@ -37,9 +37,9 @@ class FourSceneCreateGroup extends StatelessWidget { scene_id_group_id: '', switch_backlight: ''); if (state is LoadingNewSate) { - model = state.sosSensor; + model = state.device; } else if (state is UpdateState) { - model = state.sensor; + model = state.device; } return state is LoadingNewSate ? const Center( diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_info_page.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_info_page.dart index 1798750..d040eea 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_info_page.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_info_page.dart @@ -29,7 +29,7 @@ class FourSceneInfoPage extends StatelessWidget { child: BlocBuilder( builder: (context, state) { final _bloc = BlocProvider.of(context); - FourSceneModel model = FourSceneModel( + FourSceneModelState model = FourSceneModelState( scene_1: '', scene_2: '', scene_3: '', @@ -37,9 +37,9 @@ class FourSceneInfoPage extends StatelessWidget { scene_id_group_id: '', switch_backlight: ''); if (state is LoadingNewSate) { - model = state.sosSensor; + model = state.device; } else if (state is UpdateState) { - model = state.sensor; + model = state.device; } return state is FourSceneLoadingState ? const Center( diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_profile_page.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_profile_page.dart index da0fa3d..d62ceda 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_profile_page.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_profile_page.dart @@ -33,11 +33,11 @@ class FourSceneProfilePage extends StatelessWidget { child: BlocProvider( create: (context) => FourSceneBloc(fourSceneId: device?.uuid ?? '') ..add(const FourSceneInitial()) - ..add(FourSceneInitialInfo()), + ..add(const FourSceneInitialInfo()), child: BlocBuilder( builder: (context, state) { final _bloc = BlocProvider.of(context); - FourSceneModel model = FourSceneModel( + FourSceneModelState model = FourSceneModelState( scene_1: '', scene_2: '', scene_3: '', @@ -45,9 +45,9 @@ class FourSceneProfilePage extends StatelessWidget { scene_id_group_id: '', switch_backlight: ''); if (state is LoadingNewSate) { - model = state.sosSensor; + model = state.device; } else if (state is UpdateState) { - model = state.sensor; + model = state.device; } return state is FourSceneLoadingState ? const Center( diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart index ee0a5af..390280c 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart @@ -39,7 +39,7 @@ class FourSceneSettings extends StatelessWidget { child: BlocBuilder( builder: (context, state) { final _bloc = BlocProvider.of(context); - FourSceneModel model = FourSceneModel( + FourSceneModelState model = FourSceneModelState( scene_1: '', scene_2: '', scene_3: '', @@ -47,9 +47,9 @@ class FourSceneSettings extends StatelessWidget { scene_id_group_id: '', switch_backlight: ''); if (state is LoadingNewSate) { - model = state.sosSensor; + model = state.device; } else if (state is UpdateState) { - model = state.sensor; + model = state.device; } return state is FourSceneLoadingState ? const Center( diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/location_setting_four_scene.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/location_setting_four_scene.dart index 43b8dfd..0828fbc 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/location_setting_four_scene.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/location_setting_four_scene.dart @@ -34,7 +34,7 @@ class LocationFourScenePage extends StatelessWidget { child: BlocBuilder( builder: (context, state) { final _bloc = BlocProvider.of(context); - FourSceneModel model = FourSceneModel( + FourSceneModelState model = FourSceneModelState( scene_1: '', scene_2: '', scene_3: '', diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/question_page_four_scene.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/question_page_four_scene.dart index 778df50..3d1b495 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/question_page_four_scene.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/question_page_four_scene.dart @@ -29,7 +29,7 @@ class QuestionPageFourScene extends StatelessWidget { child: BlocBuilder( builder: (context, state) { final sensor = BlocProvider.of(context); - FourSceneModel model = FourSceneModel( + FourSceneModelState model = FourSceneModelState( scene_1: '', scene_2: '', scene_3: '', @@ -37,9 +37,9 @@ class QuestionPageFourScene extends StatelessWidget { scene_id_group_id: '', switch_backlight: ''); if (state is LoadingNewSate) { - model = state.sosSensor; + model = state.device; } else if (state is UpdateState) { - model = state.sensor; + model = state.device; } return state is FourSceneLoadingState ? const Center( diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/share_four_scene_page.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/share_four_scene_page.dart index f253ad9..890ef9d 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/share_four_scene_page.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/share_four_scene_page.dart @@ -25,7 +25,7 @@ class ShareFourScenePage extends StatelessWidget { child: BlocBuilder( builder: (context, state) { final sensor = BlocProvider.of(context); - FourSceneModel model = FourSceneModel( + FourSceneModelState model = FourSceneModelState( scene_1: '', scene_2: '', scene_3: '', @@ -33,9 +33,9 @@ class ShareFourScenePage extends StatelessWidget { scene_id_group_id: '', switch_backlight: ''); if (state is LoadingNewSate) { - model = state.sosSensor; + model = state.device; } else if (state is UpdateState) { - model = state.sensor; + model = state.device; } return state is LoadingNewSate ? const Center( diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_select_switch_dialog.dart b/lib/features/devices/view/widgets/four_scene_switch/four_select_switch_dialog.dart index 99af6f9..c89fdce 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_select_switch_dialog.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_select_switch_dialog.dart @@ -68,6 +68,7 @@ class _FourSelectSwitchDialogState extends State { }, onSwitch2DownTap: () { setState(() => selectedSwitchIndex = -2); + }, ), diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_switches_card.dart b/lib/features/devices/view/widgets/four_scene_switch/four_switches_card.dart index d1192bb..1217067 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_switches_card.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_switches_card.dart @@ -3,25 +3,35 @@ import 'package:flutter_svg/svg.dart'; import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; class FourSwitchsCard extends StatelessWidget { - final String switch1Up; - final String switch1Down; - final String switch2Up; - final String switch2Down; + final String switch1; + final String title1; + final String switch3; + final String title3; + + final String switch2; + final String title2; + + final String switch4; + final String title4; final VoidCallback onSwitch1UpTap; - final VoidCallback onSwitch1DownTap; + final VoidCallback onSwitch4DownTap; final VoidCallback onSwitch2UpTap; - final VoidCallback onSwitch2DownTap; + final VoidCallback onSwitch3DownTap; FourSwitchsCard({ - required this.switch1Down, - required this.switch1Up, - required this.switch2Down, - required this.switch2Up, + required this.title1, + required this.title2, + required this.title3, + required this.title4, + required this.switch3, + required this.switch1, + required this.switch4, + required this.switch2, required this.onSwitch1UpTap, - required this.onSwitch1DownTap, + required this.onSwitch3DownTap, required this.onSwitch2UpTap, - required this.onSwitch2DownTap, + required this.onSwitch4DownTap, }); @override @@ -73,9 +83,21 @@ class FourSwitchsCard extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ - _buildSwitchColumn(switch1Up, switch1Down, onSwitch1UpTap, onSwitch1DownTap), + _buildSwitchColumn( + switchUp: switch1, + switchDown: switch3, + onUpTap: onSwitch1UpTap, + onDownTap: onSwitch3DownTap, + titleDown: title3, + titleUp: title1), _buildDivider(), - _buildSwitchColumn(switch2Up, switch2Down, onSwitch2UpTap, onSwitch2DownTap), + _buildSwitchColumn( + titleDown: title4, + titleUp: title2, + switchUp: switch2, + switchDown: switch4, + onUpTap: onSwitch2UpTap, + onDownTap: onSwitch4DownTap), ], ), ), @@ -88,33 +110,45 @@ class FourSwitchsCard extends StatelessWidget { ); } - Widget _buildSwitchColumn( - String switchUp, - String switchDown, - VoidCallback onUpTap, - VoidCallback onDownTap, - ) { + Widget _buildSwitchColumn({ + String switchUp = '', + String switchDown = '', + String titleUp = '', + String titleDown = '', + VoidCallback? onUpTap, + VoidCallback? onDownTap, + }) { return Expanded( child: Padding( padding: const EdgeInsets.only(top: 30, bottom: 30), child: Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - InkWell( - onTap: onUpTap, - child: Container( - height: 20, - width: 20, - child: SvgPicture.asset(switchUp), - ), + Column( + children: [ + InkWell( + onTap: onUpTap, + child: Container( + height: 20, + width: 20, + child: SvgPicture.asset(switchUp), + ), + ), + Text(titleUp) + ], ), - InkWell( - onTap: onDownTap, - child: Container( - height: 20, - width: 20, - child: SvgPicture.asset(switchDown), - ), + Column( + children: [ + InkWell( + onTap: onDownTap, + child: Container( + height: 20, + width: 20, + child: SvgPicture.asset(switchDown), + ), + ), + Text(titleDown) + ], ), ], ), diff --git a/lib/services/api/api_links_endpoints.dart b/lib/services/api/api_links_endpoints.dart index 5d9528a..048a364 100644 --- a/lib/services/api/api_links_endpoints.dart +++ b/lib/services/api/api_links_endpoints.dart @@ -213,4 +213,5 @@ abstract class ApiEndpoints { '/device/report-logs/{deviceUuid}?code={code}&startTime={startTime}&endTime={endTime}'; static const String controlBatch = '/device/control/batch'; static const String statusBatch = '/device/status/batch'; + static const String getFourScene = '/device/four-scene/{deviceUuid}'; } diff --git a/lib/services/api/devices_api.dart b/lib/services/api/devices_api.dart index ac18192..b439e87 100644 --- a/lib/services/api/devices_api.dart +++ b/lib/services/api/devices_api.dart @@ -138,12 +138,21 @@ class DevicesAPI { return response; } + static Future getFourSceneInfo(String deviceId) async { + final response = await _httpService.get( + path: ApiEndpoints.getFourScene.replaceAll('{deviceUuid}', deviceId), + showServerMessage: false, + expectedResponseModel: (json) { + return json; + }); + return response; + } + static Future getDeviceInfo(String deviceId) async { final response = await _httpService.get( path: ApiEndpoints.deviceByUuid.replaceAll('{deviceUuid}', deviceId), showServerMessage: false, expectedResponseModel: (json) { - print('object-=-=-$json'); return json; }); return response; From 4b0270a70dabe6dc901b4a4f260bbd74cea93753 Mon Sep 17 00:00:00 2001 From: mohammad Date: Tue, 19 Nov 2024 15:56:53 +0300 Subject: [PATCH 05/29] four_scene --- .../bloc/four_scene_bloc/four_scene_bloc.dart | 4 +--- .../four_scene_switch/four_scene_screen.dart | 16 ++++++++-------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart b/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart index 6105b64..b2857d6 100644 --- a/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart +++ b/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart @@ -109,7 +109,7 @@ class FourSceneBloc extends Bloc { emit(FourSceneLoadingState()); var response = await DevicesAPI.putDeviceName( deviceId: fourSceneId, deviceName: nameController.text); - add(FourSceneInitialInfo()); + add(const FourSceneInitialInfo()); CustomSnackBar.displaySnackBar('Save Successfully'); emit(SaveState()); } catch (e) { @@ -128,12 +128,10 @@ class FourSceneBloc extends Bloc { List response = await DevicesAPI.getFourSceneInfo(fourSceneId); fourScene = response.map((item) => FourSceneSwitchModel.fromJson(item)).toList(); - print('Fetched response: $fourScene'); _rankFourSceneSwitches(); emit(UpdateState(device: deviceStatus)); } catch (e) { - print('Error in _fetchFourSceneSwitches: $e'); emit(FourSceneFailedState(errorMessage: e.toString())); } } diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_screen.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_screen.dart index b566fbf..5b01828 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_screen.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_screen.dart @@ -78,17 +78,17 @@ class FourSceneScreen extends StatelessWidget { children: [ FourSwitchsCard( title1: _bloc.fourScene.isNotEmpty - ? _bloc.fourScene[0].switchName - : 'title1', + ? _bloc.fourScene[0].scene.name + : '', title2: _bloc.fourScene.length > 1 - ? _bloc.fourScene[1].switchName - : 'title2', + ? _bloc.fourScene[0].scene.name + : '', title3: _bloc.fourScene.length > 2 - ? _bloc.fourScene[2].switchName - : 'title3', + ? _bloc.fourScene[0].scene.name + : '', title4: _bloc.fourScene.length > 3 - ? _bloc.fourScene[3].switchName - : 'title4', + ? _bloc.fourScene[0].scene.name + : '', switch1: _bloc.deviceStatus.switch_backlight == true ? Assets.switchOn From b4f990e7a9412c4d63b89ad89d7f811a6f1c1a9d Mon Sep 17 00:00:00 2001 From: mohammad Date: Wed, 20 Nov 2024 16:58:49 +0300 Subject: [PATCH 06/29] 4scene --- ios/Runner.xcodeproj/project.pbxproj | 218 +++++++++--------- .../bloc/four_scene_bloc/four_scene_bloc.dart | 128 +++++----- .../four_scene_bloc/four_scene_event.dart | 17 ++ .../four_scene_bloc/four_scene_state.dart | 6 +- .../6_scene_switch/select_switch_dialog.dart | 27 ++- .../6_scene_switch/six_scene_screen.dart | 5 +- .../widgets/6_scene_switch/switches_card.dart | 84 +++++-- .../four_scene_switch/four_scene_screen.dart | 29 +-- .../four_select_scene_page.dart | 19 +- .../four_select_switch_dialog.dart | 51 ++-- lib/services/api/api_links_endpoints.dart | 5 +- lib/services/api/devices_api.dart | 38 ++- 12 files changed, 371 insertions(+), 256 deletions(-) diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 0e5c500..40f2b75 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -10,12 +10,12 @@ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; - 611C662010675536F855E5CA /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 490AAF90B8FBFCC5BA996845 /* Pods_RunnerTests.framework */; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; + 964EC64D4BABF3375BEBF6DE /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FB51EC18BE9E4FD7A688D262 /* Pods_RunnerTests.framework */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; - D31283674D2826D7EF8E56BC /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25B37F5982CD6994FABA2CC1 /* Pods_Runner.framework */; }; + CE9CA504D8FF2965F977B16B /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 274C82CD6955A1499B0B1ECC /* Pods_Runner.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -42,24 +42,20 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ - 01BAAF935356ECBDD35AF0DB /* Pods-RunnerTests.debug-prod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug-prod.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug-prod.xcconfig"; sourceTree = ""; }; - 12AD49A621BEBB053FD06115 /* Pods-Runner.release-prod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release-prod.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release-prod.xcconfig"; sourceTree = ""; }; + 064BE0B8B723A6E30728B215 /* Pods-RunnerTests.release-prod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release-prod.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release-prod.xcconfig"; sourceTree = ""; }; + 0D60D6C4BBD804473BD9E4A0 /* Pods-RunnerTests.profile-prod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile-prod.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile-prod.xcconfig"; sourceTree = ""; }; 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; - 1F99043C7AC9BDABD8A4D41A /* Pods-Runner.profile-dev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile-dev.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile-dev.xcconfig"; sourceTree = ""; }; - 210827A693936E5201C5E75C /* Pods-RunnerTests.profile-dev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile-dev.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile-dev.xcconfig"; sourceTree = ""; }; - 238CAAD9FFF9A0C9ED3CFAB2 /* Pods-RunnerTests.profile-prod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile-prod.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile-prod.xcconfig"; sourceTree = ""; }; - 25B37F5982CD6994FABA2CC1 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 2688A8D4C03F1C4585B3EFE2 /* Pods-Runner.release-dev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release-dev.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release-dev.xcconfig"; sourceTree = ""; }; + 274C82CD6955A1499B0B1ECC /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; - 444D77D28A8CDF32047CD0AF /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; - 490AAF90B8FBFCC5BA996845 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 5DE3E6D1EADE3D3859FC1B69 /* Pods-Runner.debug-dev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug-dev.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug-dev.xcconfig"; sourceTree = ""; }; + 4F6A2F89436864C7EE769652 /* Pods-RunnerTests.profile-dev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile-dev.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile-dev.xcconfig"; sourceTree = ""; }; + 54B9D4926B53AAFC49A54F19 /* Pods-Runner.release-prod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release-prod.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release-prod.xcconfig"; sourceTree = ""; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; - 949637473C534E1F68B19CC0 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -67,16 +63,14 @@ 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 9B82456986D7FA25420A224F /* Pods-Runner.debug-prod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug-prod.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug-prod.xcconfig"; sourceTree = ""; }; - A3D4DF5D9888DAC25E2380AA /* Pods-RunnerTests.release-dev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release-dev.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release-dev.xcconfig"; sourceTree = ""; }; - AAC9129FD50E64509AD1B9AF /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; }; - BFD4DDED98208034B60B5311 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; - C41134CD2FDFC1A2BDF49283 /* Pods-Runner.release-dev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release-dev.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release-dev.xcconfig"; sourceTree = ""; }; - C5DBBF9417E4F8A9A08DFF02 /* Pods-RunnerTests.release-prod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release-prod.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release-prod.xcconfig"; sourceTree = ""; }; - D0F6245A5BF345FCC425515C /* Pods-Runner.profile-prod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile-prod.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile-prod.xcconfig"; sourceTree = ""; }; - DFB6BB492A265F2BF6FDC8C0 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; - EE971EFEA60AEDFDB361D9A3 /* Pods-RunnerTests.debug-dev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug-dev.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug-dev.xcconfig"; sourceTree = ""; }; - F323D632CA976B68DDB0E669 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; + 9D1B204BC7CD29434FE9D537 /* Pods-Runner.profile-dev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile-dev.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile-dev.xcconfig"; sourceTree = ""; }; + C33EAABFBF3F560A8EFB0BC0 /* Pods-RunnerTests.release-dev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release-dev.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release-dev.xcconfig"; sourceTree = ""; }; + E0A467016A4C6B17ECA05534 /* Pods-Runner.profile-prod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile-prod.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile-prod.xcconfig"; sourceTree = ""; }; + E2512B7B8C737577EB9DB570 /* Pods-RunnerTests.debug-dev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug-dev.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug-dev.xcconfig"; sourceTree = ""; }; + F5E8A17F8AB7D50983179FD3 /* Pods-Runner.debug-dev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug-dev.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug-dev.xcconfig"; sourceTree = ""; }; + FA2359C69B2F150BE9833D5A /* Pods-RunnerTests.debug-prod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug-prod.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug-prod.xcconfig"; sourceTree = ""; }; + FB51EC18BE9E4FD7A688D262 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + FC3EFA91747319965EF91609 /* Pods-Runner.debug-prod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug-prod.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug-prod.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -84,7 +78,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - D31283674D2826D7EF8E56BC /* Pods_Runner.framework in Frameworks */, + CE9CA504D8FF2965F977B16B /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -92,7 +86,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 611C662010675536F855E5CA /* Pods_RunnerTests.framework in Frameworks */, + 964EC64D4BABF3375BEBF6DE /* Pods_RunnerTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -102,24 +96,18 @@ 2F70EB4341A83C900EB253DC /* Pods */ = { isa = PBXGroup; children = ( - BFD4DDED98208034B60B5311 /* Pods-Runner.debug.xcconfig */, - 949637473C534E1F68B19CC0 /* Pods-Runner.release.xcconfig */, - 444D77D28A8CDF32047CD0AF /* Pods-Runner.profile.xcconfig */, - DFB6BB492A265F2BF6FDC8C0 /* Pods-RunnerTests.debug.xcconfig */, - F323D632CA976B68DDB0E669 /* Pods-RunnerTests.release.xcconfig */, - AAC9129FD50E64509AD1B9AF /* Pods-RunnerTests.profile.xcconfig */, - 9B82456986D7FA25420A224F /* Pods-Runner.debug-prod.xcconfig */, - 5DE3E6D1EADE3D3859FC1B69 /* Pods-Runner.debug-dev.xcconfig */, - 12AD49A621BEBB053FD06115 /* Pods-Runner.release-prod.xcconfig */, - C41134CD2FDFC1A2BDF49283 /* Pods-Runner.release-dev.xcconfig */, - D0F6245A5BF345FCC425515C /* Pods-Runner.profile-prod.xcconfig */, - 1F99043C7AC9BDABD8A4D41A /* Pods-Runner.profile-dev.xcconfig */, - 01BAAF935356ECBDD35AF0DB /* Pods-RunnerTests.debug-prod.xcconfig */, - EE971EFEA60AEDFDB361D9A3 /* Pods-RunnerTests.debug-dev.xcconfig */, - C5DBBF9417E4F8A9A08DFF02 /* Pods-RunnerTests.release-prod.xcconfig */, - A3D4DF5D9888DAC25E2380AA /* Pods-RunnerTests.release-dev.xcconfig */, - 238CAAD9FFF9A0C9ED3CFAB2 /* Pods-RunnerTests.profile-prod.xcconfig */, - 210827A693936E5201C5E75C /* Pods-RunnerTests.profile-dev.xcconfig */, + FC3EFA91747319965EF91609 /* Pods-Runner.debug-prod.xcconfig */, + F5E8A17F8AB7D50983179FD3 /* Pods-Runner.debug-dev.xcconfig */, + 54B9D4926B53AAFC49A54F19 /* Pods-Runner.release-prod.xcconfig */, + 2688A8D4C03F1C4585B3EFE2 /* Pods-Runner.release-dev.xcconfig */, + E0A467016A4C6B17ECA05534 /* Pods-Runner.profile-prod.xcconfig */, + 9D1B204BC7CD29434FE9D537 /* Pods-Runner.profile-dev.xcconfig */, + FA2359C69B2F150BE9833D5A /* Pods-RunnerTests.debug-prod.xcconfig */, + E2512B7B8C737577EB9DB570 /* Pods-RunnerTests.debug-dev.xcconfig */, + 064BE0B8B723A6E30728B215 /* Pods-RunnerTests.release-prod.xcconfig */, + C33EAABFBF3F560A8EFB0BC0 /* Pods-RunnerTests.release-dev.xcconfig */, + 0D60D6C4BBD804473BD9E4A0 /* Pods-RunnerTests.profile-prod.xcconfig */, + 4F6A2F89436864C7EE769652 /* Pods-RunnerTests.profile-dev.xcconfig */, ); path = Pods; sourceTree = ""; @@ -132,11 +120,11 @@ path = RunnerTests; sourceTree = ""; }; - 876D3217A8BBDAF41961161F /* Frameworks */ = { + 61B46FA3FB0932D29E3C6E47 /* Frameworks */ = { isa = PBXGroup; children = ( - 25B37F5982CD6994FABA2CC1 /* Pods_Runner.framework */, - 490AAF90B8FBFCC5BA996845 /* Pods_RunnerTests.framework */, + 274C82CD6955A1499B0B1ECC /* Pods_Runner.framework */, + FB51EC18BE9E4FD7A688D262 /* Pods_RunnerTests.framework */, ); name = Frameworks; sourceTree = ""; @@ -160,7 +148,7 @@ 97C146EF1CF9000F007C117D /* Products */, 331C8082294A63A400263BE5 /* RunnerTests */, 2F70EB4341A83C900EB253DC /* Pods */, - 876D3217A8BBDAF41961161F /* Frameworks */, + 61B46FA3FB0932D29E3C6E47 /* Frameworks */, ); sourceTree = ""; }; @@ -195,7 +183,7 @@ isa = PBXNativeTarget; buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; buildPhases = ( - 3B971DE531245D7FD2921C30 /* [CP] Check Pods Manifest.lock */, + 73698F4EABFF3F9B7ADF4220 /* [CP] Check Pods Manifest.lock */, 331C807D294A63A400263BE5 /* Sources */, 331C807F294A63A400263BE5 /* Resources */, C2B33A7265AF659D80692473 /* Frameworks */, @@ -214,7 +202,7 @@ isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( - 3DC878D0674AA34AEC9695FB /* [CP] Check Pods Manifest.lock */, + BF71A0E0099ADA10FE9B580A /* [CP] Check Pods Manifest.lock */, 9740EEB61CF901F6004384FC /* Run Script */, B07E4A152C9B8EA4001F6910 /* copy GoogleService.plist file to the correct location */, 97C146EA1CF9000F007C117D /* Sources */, @@ -222,9 +210,9 @@ 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - 315A05630CF83C532DBBCBF2 /* [CP] Embed Pods Frameworks */, - 3724F7A126D8469D5B04D144 /* [CP] Copy Pods Resources */, 4768286A3BADB12BBB8C6996 /* FlutterFire: "flutterfire upload-crashlytics-symbols" */, + 6CF71F42A45B39E9945C8410 /* [CP] Embed Pods Frameworks */, + 14DF593CA13D27D3781140F6 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -296,24 +284,7 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 315A05630CF83C532DBBCBF2 /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", - ); - name = "[CP] Embed Pods Frameworks"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; - 3724F7A126D8469D5B04D144 /* [CP] Copy Pods Resources */ = { + 14DF593CA13D27D3781140F6 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -346,7 +317,42 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; - 3B971DE531245D7FD2921C30 /* [CP] Check Pods Manifest.lock */ = { + 4768286A3BADB12BBB8C6996 /* FlutterFire: "flutterfire upload-crashlytics-symbols" */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "FlutterFire: \"flutterfire upload-crashlytics-symbols\""; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\n#!/bin/bash\nPATH=${PATH}:$FLUTTER_ROOT/bin:$HOME/.pub-cache/bin\nflutterfire upload-crashlytics-symbols --upload-symbols-script-path=$PODS_ROOT/FirebaseCrashlytics/upload-symbols --platform=ios --apple-project-path=${SRCROOT} --env-platform-name=${PLATFORM_NAME} --env-configuration=${CONFIGURATION} --env-project-dir=${PROJECT_DIR} --env-built-products-dir=${BUILT_PRODUCTS_DIR} --env-dwarf-dsym-folder-path=${DWARF_DSYM_FOLDER_PATH} --env-dwarf-dsym-file-name=${DWARF_DSYM_FILE_NAME} --env-infoplist-path=${INFOPLIST_PATH} --default-config=default\n"; + }; + 6CF71F42A45B39E9945C8410 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 73698F4EABFF3F9B7ADF4220 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -368,46 +374,6 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - 3DC878D0674AA34AEC9695FB /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - 4768286A3BADB12BBB8C6996 /* FlutterFire: "flutterfire upload-crashlytics-symbols" */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - ); - name = "FlutterFire: \"flutterfire upload-crashlytics-symbols\""; - outputFileListPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\n#!/bin/bash\nPATH=${PATH}:$FLUTTER_ROOT/bin:$HOME/.pub-cache/bin\nflutterfire upload-crashlytics-symbols --upload-symbols-script-path=$PODS_ROOT/FirebaseCrashlytics/upload-symbols --platform=ios --apple-project-path=${SRCROOT} --env-platform-name=${PLATFORM_NAME} --env-configuration=${CONFIGURATION} --env-project-dir=${PROJECT_DIR} --env-built-products-dir=${BUILT_PRODUCTS_DIR} --env-dwarf-dsym-folder-path=${DWARF_DSYM_FOLDER_PATH} --env-dwarf-dsym-file-name=${DWARF_DSYM_FILE_NAME} --env-infoplist-path=${INFOPLIST_PATH} --default-config=default\n"; - }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -441,6 +407,28 @@ shellPath = /bin/sh; shellScript = "# Get a reference to the destination location for the GoogleService-Info.plist\n# This is the default location where Firebase init code expects to find GoogleServices-Info.plist file.\nPLIST_DESTINATION=${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app\n# We have named our Build Configurations as Debug-dev, Debug-prod etc.\n# Here, dev and prod are the scheme names. This kind of naming is required by Flutter for flavors to work.\n# We are using the $CONFIGURATION variable available in the XCode build environment to get the build configuration.\nif [ \"${CONFIGURATION}\" == \"Debug-prod\" ] || [ \"${CONFIGURATION}\" == \"Release-prod\" ] || [ \"${CONFIGURATION}\" == \"Profile-prod\" ] || [ \"${CONFIGURATION}\" == \"Release\" ]; then\ncp \"${PROJECT_DIR}/config/prod/GoogleService-Info.plist\" \"${PLIST_DESTINATION}/GoogleService-Info.plist\"\necho \"Production plist copied\"\nelif [ \"${CONFIGURATION}\" == \"Debug-dev\" ] || [ \"${CONFIGURATION}\" == \"Release-dev\" ] || [ \"${CONFIGURATION}\" == \"Profile-dev\" ] || [ \"${CONFIGURATION}\" == \"Debug\" ]; then\ncp \"${PROJECT_DIR}/config/dev/GoogleService-Info.plist\" \"${PLIST_DESTINATION}/GoogleService-Info.plist\"\necho \"Development plist copied\"\nfi\n"; }; + BF71A0E0099ADA10FE9B580A /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -575,7 +563,7 @@ }; 331C8088294A63A400263BE5 /* Debug-prod */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 01BAAF935356ECBDD35AF0DB /* Pods-RunnerTests.debug-prod.xcconfig */; + baseConfigurationReference = FA2359C69B2F150BE9833D5A /* Pods-RunnerTests.debug-prod.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; @@ -593,7 +581,7 @@ }; 331C8089294A63A400263BE5 /* Release-prod */ = { isa = XCBuildConfiguration; - baseConfigurationReference = C5DBBF9417E4F8A9A08DFF02 /* Pods-RunnerTests.release-prod.xcconfig */; + baseConfigurationReference = 064BE0B8B723A6E30728B215 /* Pods-RunnerTests.release-prod.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; @@ -609,7 +597,7 @@ }; 331C808A294A63A400263BE5 /* Profile-prod */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 238CAAD9FFF9A0C9ED3CFAB2 /* Pods-RunnerTests.profile-prod.xcconfig */; + baseConfigurationReference = 0D60D6C4BBD804473BD9E4A0 /* Pods-RunnerTests.profile-prod.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; @@ -885,7 +873,7 @@ }; B07E4A0E2C9B8C45001F6910 /* Debug-dev */ = { isa = XCBuildConfiguration; - baseConfigurationReference = EE971EFEA60AEDFDB361D9A3 /* Pods-RunnerTests.debug-dev.xcconfig */; + baseConfigurationReference = E2512B7B8C737577EB9DB570 /* Pods-RunnerTests.debug-dev.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; @@ -987,7 +975,7 @@ }; B07E4A112C9B8C52001F6910 /* Release-dev */ = { isa = XCBuildConfiguration; - baseConfigurationReference = A3D4DF5D9888DAC25E2380AA /* Pods-RunnerTests.release-dev.xcconfig */; + baseConfigurationReference = C33EAABFBF3F560A8EFB0BC0 /* Pods-RunnerTests.release-dev.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; @@ -1085,7 +1073,7 @@ }; B07E4A142C9B8C5C001F6910 /* Profile-dev */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 210827A693936E5201C5E75C /* Pods-RunnerTests.profile-dev.xcconfig */; + baseConfigurationReference = 4F6A2F89436864C7EE769652 /* Pods-RunnerTests.profile-dev.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; diff --git a/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart b/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart index b2857d6..a1ff854 100644 --- a/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart +++ b/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart @@ -1,5 +1,4 @@ import 'dart:async'; -import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_event.dart'; @@ -27,9 +26,8 @@ class FourSceneBloc extends Bloc { FourSceneBloc({ required this.fourSceneId, }) : super(const FourSceneState()) { - on(_fetchStatus); - on(fetchDeviceData); - on(fetchLogsForLastMonth); + on(_fetchDeviceStatus); + on(fetchDeviceInfo); on(saveName); on(_toggleNotification); on(_changeName); @@ -47,6 +45,8 @@ class FourSceneBloc extends Bloc { on(_fetchDeviceScene); on(_controlDevice); on(_fetchFourSceneSwitches); + on(assignScene); + on(getSceneByName); } final TextEditingController nameController = @@ -99,7 +99,7 @@ class FourSceneBloc extends Bloc { subspaceName: "", ), ); - + String sceneId = ''; Future saveName( SaveNameEvent event, Emitter emit) async { if (_validateInputs()) return; @@ -125,27 +125,36 @@ class FourSceneBloc extends Bloc { FourSceneSwitchInitial event, Emitter emit) async { emit(FourSceneLoadingState()); try { - List response = await DevicesAPI.getFourSceneInfo(fourSceneId); - fourScene = - response.map((item) => FourSceneSwitchModel.fromJson(item)).toList(); - _rankFourSceneSwitches(); + var response = await DevicesAPI.getFourSceneInfo(fourSceneId); + Map sceneTitles = { + "scene_1": '', + "scene_2": '', + "scene_3": '', + "scene_4": '' + }; + for (var item in response) { + if (item["switchName"] != null) { + sceneTitles[item["switchName"]] = item["scene"]["name"] ?? ''; + } + } + print('object======4${response}'); + FourSceneModelState deviceStatus = FourSceneModelState( + scene_1: sceneTitles["scene_1"] ?? '', + scene_2: sceneTitles["scene_2"] ?? '', + scene_3: sceneTitles["scene_3"] ?? '', + scene_4: sceneTitles["scene_4"] ?? '', + scene_id_group_id: '', + switch_backlight: '', + ); emit(UpdateState(device: deviceStatus)); } catch (e) { emit(FourSceneFailedState(errorMessage: e.toString())); + return; } } - void _rankFourSceneSwitches() { - const switchOrder = ['scene_1', 'scene_2', 'scene_3', 'scene_4']; - fourScene.sort((a, b) { - return switchOrder - .indexOf(a.switchName) - .compareTo(switchOrder.indexOf(b.switchName)); - }); - } - - void _fetchStatus( + void _fetchDeviceStatus( FourSceneInitial event, Emitter emit) async { emit(FourSceneLoadingState()); try { @@ -157,15 +166,41 @@ class FourSceneBloc extends Bloc { deviceStatus = FourSceneModelState.fromJson( statusModelList, ); - emit(UpdateState(device: deviceStatus)); - Future.delayed(const Duration(milliseconds: 500)); - // _listenToChanges(); + add(const FourSceneSwitchInitial()); } catch (e) { emit(FourSceneFailedState(errorMessage: e.toString())); return; } } + void assignScene( + AssignDeviceScene event, Emitter emit) async { + emit(FourSceneLoadingState()); + try { + final response = await DevicesAPI.postFourSceneInfo( + deviceId: fourSceneId, + sceneUuid: event.sceneUuid, + spaceUuid: event.unit!.id, + switchName: event.switchName); + emit(SaveSelectionSuccessState()); + } catch (e) { + emit(FourSceneFailedState(errorMessage: e.toString())); + } + } + + void getSceneByName( + GetSceneBySwitchName event, Emitter emit) async { + emit(FourSceneLoadingState()); + try { + final response = await DevicesAPI.getSceneBySwitchName( + deviceId: fourSceneId, switchName: event.switchName); + sceneId = response['scene']['uuid']; + emit(SaveSelectionSuccessState()); + } catch (e) { + emit(FourSceneFailedState(errorMessage: e.toString())); + } + } + void _fetchDeviceScene( FetchDeviceScene event, Emitter emit) async { emit(FourSceneLoadingState()); @@ -180,7 +215,6 @@ class FourSceneBloc extends Bloc { ); emit(UpdateState(device: deviceStatus)); Future.delayed(const Duration(milliseconds: 500)); - // _listenToChanges(); } catch (e) { emit(FourSceneFailedState(errorMessage: e.toString())); return; @@ -208,13 +242,17 @@ class FourSceneBloc extends Bloc { } } - Future fetchDeviceData( + Future fetchDeviceInfo( FourSceneInitialInfo event, Emitter emit) async { - emit(FourSceneLoadingState()); - var response = await DevicesAPI.getDeviceInfo(fourSceneId); - deviceInfo = SceneSwitch.fromJson(response); - deviceName = deviceInfo.name; - emit(LoadingDeviceInfo(deviceInfo: deviceInfo)); + try { + emit(FourSceneLoadingState()); + var response = await DevicesAPI.getDeviceInfo(fourSceneId); + deviceInfo = SceneSwitch.fromJson(response); + deviceName = deviceInfo.name; + emit(LoadingDeviceInfo(deviceInfo: deviceInfo)); + } catch (e) { + emit(FourSceneFailedState(errorMessage: e.toString())); + } } void _onSearchFaq(SearchFaqEvent event, Emitter emit) { @@ -263,29 +301,6 @@ class FourSceneBloc extends Bloc { 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(FourSceneLoadingState()); - var response = await DevicesAPI.getReportLogs( - startTime: startTime.toString(), - endTime: endTime.toString(), - deviceUuid: fourSceneId, - code: 'sossensor_state', - ); - recordGroups = response; - emit(UpdateState(device: deviceStatus)); - } on DioException catch (e) { - final errorData = e.response!.data; - String errorMessage = errorData['message']; - emit(FourSceneFailedState(errorMessage: e.toString())); - } - } - final List faqQuestions = [ FourSceneQuestionModel( id: 1, @@ -487,18 +502,11 @@ class FourSceneBloc extends Bloc { if (value == null) return 'name is required'; final withoutExtraSpaces = value.replaceAll(RegExp(r"\s+"), ' ').trim(); if (withoutExtraSpaces.length < 2 || withoutExtraSpaces.length > 30) { - return 'Full name must be between 2 and 30 characters long'; + return 'name must be between 2 and 30 characters long'; } - // Test if it contains anything but alphanumeric spaces and single quote if (RegExp(r"/[^ a-zA-Z0-9-\']/").hasMatch(withoutExtraSpaces)) { return 'Only alphanumeric characters, space, dash and single quote are allowed'; } - return null; } - - String scene1 = 'scene_1'; - String scene2 = 'scene_2'; - String scene3 = 'scene_3'; - String scene4 = 'scene_4'; } diff --git a/lib/features/devices/bloc/four_scene_bloc/four_scene_event.dart b/lib/features/devices/bloc/four_scene_bloc/four_scene_event.dart index f2c69b0..0571e27 100644 --- a/lib/features/devices/bloc/four_scene_bloc/four_scene_event.dart +++ b/lib/features/devices/bloc/four_scene_bloc/four_scene_event.dart @@ -212,3 +212,20 @@ class ControlDeviceScene extends FourSceneEvent { class FourSceneSwitchInitial extends FourSceneEvent { const FourSceneSwitchInitial(); } +class SaveSelectionSceneEvent extends FourSceneEvent { + const SaveSelectionSceneEvent(); +} + +class AssignDeviceScene extends FourSceneEvent { + final String? sceneUuid; + final String? switchName; + final SpaceModel? unit; + const AssignDeviceScene({this.sceneUuid, this.unit,this.switchName}); +} + + +class GetSceneBySwitchName extends FourSceneEvent { + final String? switchName; + + const GetSceneBySwitchName({this.switchName}); +} \ No newline at end of file diff --git a/lib/features/devices/bloc/four_scene_bloc/four_scene_state.dart b/lib/features/devices/bloc/four_scene_bloc/four_scene_state.dart index a0dba6b..0242034 100644 --- a/lib/features/devices/bloc/four_scene_bloc/four_scene_state.dart +++ b/lib/features/devices/bloc/four_scene_bloc/four_scene_state.dart @@ -54,7 +54,7 @@ class LoadingNewSate extends FourSceneState { class NameEditingState extends FourSceneState { final bool editName; - NameEditingState({required this.editName}); + const NameEditingState({required this.editName}); } class FaqLoadedState extends FourSceneState { @@ -97,6 +97,7 @@ class SceneLoaded extends FourSceneState { class SelectedSceneState extends FourSceneState {} class SearchResultsState extends FourSceneState {} + class SaveState extends FourSceneState {} class SaveSelectionSuccessState extends FourSceneState {} @@ -114,11 +115,10 @@ class OptionSelectedState extends FourSceneState { List get props => [selectedOption, hasSelectionChanged]; } - class LoadingDeviceInfo extends FourSceneState { final SceneSwitch deviceInfo; const LoadingDeviceInfo({required this.deviceInfo}); @override List get props => [deviceInfo]; -} \ No newline at end of file +} diff --git a/lib/features/devices/view/widgets/6_scene_switch/select_switch_dialog.dart b/lib/features/devices/view/widgets/6_scene_switch/select_switch_dialog.dart index 453722c..1195d85 100644 --- a/lib/features/devices/view/widgets/6_scene_switch/select_switch_dialog.dart +++ b/lib/features/devices/view/widgets/6_scene_switch/select_switch_dialog.dart @@ -7,19 +7,25 @@ import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; class SelectSwitchDialog extends StatefulWidget { final Function()? cancelTab; final Function()? confirmTab; - - const SelectSwitchDialog({ - super.key, - required this.cancelTab, - required this.confirmTab, - }); + String? switch1Title; + String? switch2Title; + String? switch3Title; + String? switch4Title; + SelectSwitchDialog( + {super.key, + required this.cancelTab, + required this.confirmTab, + this.switch1Title, + this.switch2Title, + this.switch3Title, + this.switch4Title}); @override State createState() => _SelectSwitchDialogState(); } class _SelectSwitchDialogState extends State { - int? selectedSwitchIndex = 0; // State variable to track selected switch + int? selectedSwitchIndex = 0; @override Widget build(BuildContext context) { @@ -44,6 +50,10 @@ class _SelectSwitchDialogState extends State { Row( children: [ SwitchsCard( + switch1Title: widget.switch1Title, + switch2Title: widget.switch2Title, + switch3Title: widget.switch3Title, + switch4Title: widget.switch4Title, switch1Down: selectedSwitchIndex == -1 ? Assets.removeSceneIcon : Assets.addSwitchIcon, @@ -56,7 +66,6 @@ class _SelectSwitchDialogState extends State { switch2Up: selectedSwitchIndex == 2 ? Assets.removeSceneIcon : Assets.addSwitchIcon, - onSwitch1UpTap: () { setState(() => selectedSwitchIndex = 1); }, @@ -69,8 +78,6 @@ class _SelectSwitchDialogState extends State { onSwitch2DownTap: () { setState(() => selectedSwitchIndex = -2); }, - - ), ], ), diff --git a/lib/features/devices/view/widgets/6_scene_switch/six_scene_screen.dart b/lib/features/devices/view/widgets/6_scene_switch/six_scene_screen.dart index f502a55..50a3034 100644 --- a/lib/features/devices/view/widgets/6_scene_switch/six_scene_screen.dart +++ b/lib/features/devices/view/widgets/6_scene_switch/six_scene_screen.dart @@ -70,6 +70,10 @@ class SixSceneScreen extends StatelessWidget { child: Column( children: [ SwitchsCard( + // switch1Title: , + // switch2Title: , + // switch3Title: , + // switch4Title: , switch1Down: sensor.switchStatus == true ? Assets.switchOn : Assets.switchOff, @@ -95,7 +99,6 @@ class SixSceneScreen extends StatelessWidget { onSwitch2DownTap: () { debugPrint("Switch 2 Down tapped"); }, - ), Flexible( child: Row( diff --git a/lib/features/devices/view/widgets/6_scene_switch/switches_card.dart b/lib/features/devices/view/widgets/6_scene_switch/switches_card.dart index de4a0a3..9c39772 100644 --- a/lib/features/devices/view/widgets/6_scene_switch/switches_card.dart +++ b/lib/features/devices/view/widgets/6_scene_switch/switches_card.dart @@ -1,8 +1,14 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; +import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart'; import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; class SwitchsCard extends StatelessWidget { + final String? switch1Title; + final String? switch2Title; + final String? switch3Title; + final String? switch4Title; + final String switch1Up; final String switch1Down; final String switch2Up; @@ -22,6 +28,10 @@ class SwitchsCard extends StatelessWidget { required this.onSwitch1DownTap, required this.onSwitch2UpTap, required this.onSwitch2DownTap, + this.switch1Title, + this.switch2Title, + this.switch3Title, + this.switch4Title, }); @override @@ -74,12 +84,22 @@ class SwitchsCard extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ // Switch 1 - _buildSwitchColumn(switch1Up, switch1Down, - onSwitch1UpTap, onSwitch1DownTap), + _buildSwitchColumn( + switchUp: switch1Up, + switchDown: switch1Down, + onUpTap: onSwitch1UpTap, + onDownTap: onSwitch1DownTap, + titleDown: switch3Title!, + titleUp: switch1Title!), _buildDivider(), // Switch 2 - _buildSwitchColumn(switch2Up, switch2Down, - onSwitch2UpTap, onSwitch2DownTap), + _buildSwitchColumn( + switchUp: switch2Up, + switchDown: switch2Down, + onDownTap: onSwitch2UpTap, + onUpTap: onSwitch2DownTap, + titleDown: switch4Title!, + titleUp: switch2Title!), ], ), ), @@ -92,33 +112,49 @@ class SwitchsCard extends StatelessWidget { ); } - Widget _buildSwitchColumn( - String switchUp, - String switchDown, - VoidCallback onUpTap, - VoidCallback onDownTap, - ) { + Widget _buildSwitchColumn({ + String switchUp = '', + String titleUp = '', + String titleDown = '', + String switchDown = '', + VoidCallback? onUpTap, + VoidCallback? onDownTap, + }) { return Expanded( child: Padding( padding: const EdgeInsets.only(top: 30, bottom: 30), child: Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - InkWell( - onTap: onUpTap, - child: Container( - height: 20, - width: 20, - child: SvgPicture.asset(switchUp), - ), + Column( + children: [ + InkWell( + onTap: onUpTap, + child: Container( + height: 20, + width: 20, + child: SvgPicture.asset(switchUp), + ), + ), + BodySmall( + text: titleUp, + ) + ], ), - InkWell( - onTap: onDownTap, - child: Container( - height: 20, - width: 20, - child: SvgPicture.asset(switchDown), - ), + Column( + children: [ + InkWell( + onTap: onDownTap, + child: Container( + height: 20, + width: 20, + child: SvgPicture.asset(switchDown), + ), + ), + BodySmall( + text: titleDown, + ) + ], ), ], ), diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_screen.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_screen.dart index 5b01828..3c96bc0 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_screen.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_screen.dart @@ -77,18 +77,10 @@ class FourSceneScreen extends StatelessWidget { child: Column( children: [ FourSwitchsCard( - title1: _bloc.fourScene.isNotEmpty - ? _bloc.fourScene[0].scene.name - : '', - title2: _bloc.fourScene.length > 1 - ? _bloc.fourScene[0].scene.name - : '', - title3: _bloc.fourScene.length > 2 - ? _bloc.fourScene[0].scene.name - : '', - title4: _bloc.fourScene.length > 3 - ? _bloc.fourScene[0].scene.name - : '', + title1: model.scene_1, + title2: model.scene_2, + title3: model.scene_3, + title4: model.scene_4, switch1: _bloc.deviceStatus.switch_backlight == true ? Assets.switchOn @@ -163,14 +155,20 @@ class FourSceneScreen extends StatelessWidget { context: context, builder: (context) { return FourSelectSwitchDialog( + switch1Title: model.scene_1, + switch2Title: model.scene_2, + switch3Title: model.scene_3, + switch4Title: model.scene_4, cancelTab: () { Navigator.of(context).pop(); }, - confirmTab: () { + confirmTab: (switchSelected) { Navigator.of(context).push( MaterialPageRoute( builder: (context) => - FourSelectSceneFourPage()), + FourSelectSceneFourPage( + switchSelected: switchSelected, + deviceId:device!.uuid)), ); }, ); @@ -219,3 +217,6 @@ class FourSceneScreen extends StatelessWidget { ); } } + + +//MohaM&&&uba1 \ No newline at end of file diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_select_scene_page.dart b/lib/features/devices/view/widgets/four_scene_switch/four_select_scene_page.dart index 4d463b0..8eee620 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_select_scene_page.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_select_scene_page.dart @@ -17,7 +17,9 @@ import 'package:syncrow_app/navigation/routing_constants.dart'; import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; class FourSelectSceneFourPage extends StatelessWidget { - FourSelectSceneFourPage({super.key}); + final String? switchSelected; + final String? deviceId; + FourSelectSceneFourPage({super.key, this.switchSelected, this.deviceId}); final TextEditingController _searchController = TextEditingController(); final int? selectedSwitchIndex = 0; @@ -26,12 +28,13 @@ class FourSelectSceneFourPage extends StatelessWidget { @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => FourSceneBloc(fourSceneId: '') + create: (context) => FourSceneBloc(fourSceneId: deviceId!) ..add(LoadScenes( unit: spaces!.first, unitId: spaces!.first.id, showInDevice: false, - )), + )) + ..add(GetSceneBySwitchName(switchName: switchSelected)), child: BlocBuilder( builder: (context, state) { final sensorBloc = BlocProvider.of(context); @@ -57,8 +60,10 @@ class FourSelectSceneFourPage extends StatelessWidget { return GestureDetector( onTap: canSave ? () { - print('object'); - // context.read().add(SaveSelectionEvent()); + context.read().add(AssignDeviceScene( + sceneUuid: sensorBloc.selectedSceneId, + switchName: switchSelected, + unit: spaces!.first)); } : null, child: BodyMedium( @@ -127,7 +132,6 @@ class FourSelectSceneFourPage extends StatelessWidget { // Scene grid builder Widget _buildSceneGrid(FourSceneBloc sensorBloc) { final scenes = sensorBloc.filteredScenes; - return GridView.builder( itemCount: scenes.length + 1, gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( @@ -137,6 +141,7 @@ class FourSelectSceneFourPage extends StatelessWidget { mainAxisExtent: 120, ), itemBuilder: (context, index) { + // sensorBloc.sceneId; if (index == scenes.length) { return InkWell( onTap: () => Navigator.pushNamed( @@ -154,7 +159,7 @@ class FourSelectSceneFourPage extends StatelessWidget { final scene = scenes[index]; return SceneItem( id: scene.id, - value: sensorBloc.selectedSceneId == scene.id, + value: (sensorBloc.selectedSceneId == scene.id), disablePlayButton: false, onChanged: (isSelected) { sensorBloc.selectedSceneId = isSelected ? scene.id : 'null'; diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_select_switch_dialog.dart b/lib/features/devices/view/widgets/four_scene_switch/four_select_switch_dialog.dart index c89fdce..28e2255 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_select_switch_dialog.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_select_switch_dialog.dart @@ -6,20 +6,28 @@ import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; class FourSelectSwitchDialog extends StatefulWidget { final Function()? cancelTab; - final Function()? confirmTab; + final Function(String)? confirmTab; - const FourSelectSwitchDialog({ - super.key, - required this.cancelTab, - required this.confirmTab, - }); + final String switch1Title; + final String switch2Title; + final String switch3Title; + final String switch4Title; + + const FourSelectSwitchDialog( + {super.key, + required this.cancelTab, + required this.confirmTab, + required this.switch1Title, + required this.switch2Title, + required this.switch3Title, + required this.switch4Title}); @override State createState() => _FourSelectSwitchDialogState(); } class _FourSelectSwitchDialogState extends State { - int? selectedSwitchIndex = 0; // State variable to track selected switch + String selectedSwitchName = ''; // State variable to track selected switch @override Widget build(BuildContext context) { @@ -44,33 +52,34 @@ class _FourSelectSwitchDialogState extends State { Row( children: [ SwitchsCard( - switch1Down: selectedSwitchIndex == -1 + switch1Title: widget.switch1Title, + switch2Title: widget.switch2Title, + switch3Title: widget.switch3Title, + switch4Title: widget.switch4Title, + switch1Down: selectedSwitchName == 'scene_3' ? Assets.removeSceneIcon : Assets.addSwitchIcon, - switch1Up: selectedSwitchIndex == 1 + switch1Up: selectedSwitchName == 'scene_1' ? Assets.removeSceneIcon : Assets.addSwitchIcon, - switch2Down: selectedSwitchIndex == -2 + switch2Down: selectedSwitchName == 'scene_4' ? Assets.removeSceneIcon : Assets.addSwitchIcon, - switch2Up: selectedSwitchIndex == 2 + switch2Up: selectedSwitchName == 'scene_2' ? Assets.removeSceneIcon : Assets.addSwitchIcon, - onSwitch1UpTap: () { - setState(() => selectedSwitchIndex = 1); + setState(() => selectedSwitchName = 'scene_1'); }, onSwitch1DownTap: () { - setState(() => selectedSwitchIndex = -1); + setState(() => selectedSwitchName = 'scene_3'); }, onSwitch2UpTap: () { - setState(() => selectedSwitchIndex = 2); + setState(() => selectedSwitchName = 'scene_4'); }, onSwitch2DownTap: () { - setState(() => selectedSwitchIndex = -2); - + setState(() => selectedSwitchName = 'scene_2'); }, - ), ], ), @@ -118,14 +127,16 @@ class _FourSelectSwitchDialogState extends State { top: BorderSide(color: ColorsManager.textGray, width: 1.0), )), child: InkWell( - onTap: selectedSwitchIndex == 0 ? () {} : widget.confirmTab, + onTap: selectedSwitchName == '' + ? () {} + : () => widget.confirmTab!(selectedSwitchName), child: Padding( padding: EdgeInsets.all(15), child: Center( child: Text( 'Next', style: TextStyle( - color: selectedSwitchIndex == 0 + color: selectedSwitchName == '' ? ColorsManager.textPrimaryColor .withOpacity(0.6) : ColorsManager.primaryColor, diff --git a/lib/services/api/api_links_endpoints.dart b/lib/services/api/api_links_endpoints.dart index 048a364..1c954e6 100644 --- a/lib/services/api/api_links_endpoints.dart +++ b/lib/services/api/api_links_endpoints.dart @@ -213,5 +213,8 @@ abstract class ApiEndpoints { '/device/report-logs/{deviceUuid}?code={code}&startTime={startTime}&endTime={endTime}'; static const String controlBatch = '/device/control/batch'; static const String statusBatch = '/device/status/batch'; - static const String getFourScene = '/device/four-scene/{deviceUuid}'; + static const String fourScene = '/device/{deviceUuid}/scenes'; + + static const String fourSceneByName = + '/device/{deviceUuid}/scenes?switchName={switchName}'; } diff --git a/lib/services/api/devices_api.dart b/lib/services/api/devices_api.dart index b439e87..f7d5409 100644 --- a/lib/services/api/devices_api.dart +++ b/lib/services/api/devices_api.dart @@ -140,7 +140,7 @@ class DevicesAPI { static Future getFourSceneInfo(String deviceId) async { final response = await _httpService.get( - path: ApiEndpoints.getFourScene.replaceAll('{deviceUuid}', deviceId), + path: ApiEndpoints.fourScene.replaceAll('{deviceUuid}', deviceId), showServerMessage: false, expectedResponseModel: (json) { return json; @@ -148,6 +148,42 @@ class DevicesAPI { return response; } + static Future getSceneBySwitchName( + {String? deviceId, String? switchName}) async { + final response = await _httpService.get( + path: ApiEndpoints.fourSceneByName + .replaceAll('{deviceUuid}', deviceId!) + .replaceAll('{switchName}', switchName!), + showServerMessage: false, + expectedResponseModel: (json) { + return json; + }); + return response; + } + + static Future postFourSceneInfo({ + String? switchName, + String? sceneUuid, + String? deviceId, + String? spaceUuid, + }) async { + final response = await _httpService.post( + path: ApiEndpoints.fourScene.replaceAll('{deviceUuid}', deviceId!), + body: jsonEncode( + { + "switchName": switchName, + "sceneUuid": sceneUuid, + "spaceUuid": spaceUuid + }, + ), + showServerMessage: false, + expectedResponseModel: (json) { + print('postFourSceneInfo=$json'); + return json; + }); + return response; + } + static Future getDeviceInfo(String deviceId) async { final response = await _httpService.get( path: ApiEndpoints.deviceByUuid.replaceAll('{deviceUuid}', deviceId), From 6c2c866969a799235657ce6e1a2808a216faabb6 Mon Sep 17 00:00:00 2001 From: mohammad Date: Thu, 21 Nov 2024 15:34:20 +0300 Subject: [PATCH 07/29] four_scene&6scene --- .../6_scene_switch_bloc/6_scene_bloc.dart | 260 +++++++++++++----- .../6_scene_switch_bloc/6_scene_event.dart | 30 ++ .../6_scene_switch_bloc/6_scene_state.dart | 15 + .../bloc/four_scene_bloc/four_scene_bloc.dart | 80 +++--- .../four_scene_bloc/four_scene_event.dart | 18 +- .../four_scene_bloc/four_scene_state.dart | 6 + .../devices/model/six_scene_model.dart | 60 +++- .../6_scene_setting/location_setting.dart | 9 +- .../6_scene_setting/question_page.dart | 9 +- .../6_scene_setting/share_six_scene_page.dart | 9 +- .../six_scene_create_group.dart | 11 +- .../6_scene_setting/six_scene_info_page.dart | 11 +- .../six_scene_profile_page.dart | 11 +- .../6_scene_setting/six_scene_settings.dart | 14 +- .../6_scene_switch/select_scene_page.dart | 62 +++-- .../6_scene_switch/select_switch_dialog.dart | 50 +++- .../6_scene_switch/six_scene_screen.dart | 95 +++++-- .../6_scene_switch/six_switches_card.dart | 193 +++++++++++++ .../four_scene_switch/four_scene_screen.dart | 21 +- .../four_scene_profile_page.dart | 19 +- .../four_scene_settings.dart | 22 +- .../four_select_scene_page.dart | 47 ++-- .../four_select_switch_dialog.dart | 4 +- .../four_switches_card_dialog.dart} | 4 +- .../view/widgets/room_page_switch.dart | 8 + lib/generated/assets.dart | 1 + lib/utils/resource_manager/constants.dart | 48 ++++ 27 files changed, 867 insertions(+), 250 deletions(-) create mode 100644 lib/features/devices/view/widgets/6_scene_switch/six_switches_card.dart rename lib/features/devices/view/widgets/{6_scene_switch/switches_card.dart => four_scene_switch/four_switches_card_dialog.dart} (98%) diff --git a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart index dfb11d4..51353c8 100644 --- a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart +++ b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart @@ -4,9 +4,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart'; import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_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/group_devices_model.dart'; +import 'package:syncrow_app/features/devices/model/scene_switch_model.dart'; import 'package:syncrow_app/features/devices/model/sex_scene_question_model.dart'; import 'package:syncrow_app/features/devices/model/six_scene_model.dart'; import 'package:syncrow_app/features/devices/model/status_model.dart'; @@ -15,40 +17,100 @@ import 'package:syncrow_app/generated/assets.dart'; import 'package:syncrow_app/services/api/devices_api.dart'; import 'package:syncrow_app/services/api/scene_api.dart'; import 'package:syncrow_app/services/api/spaces_api.dart'; +import 'package:syncrow_app/utils/helpers/snack_bar.dart'; class SixSceneBloc extends Bloc { final String sixSceneId; SixSceneBloc({ required this.sixSceneId, }) : super(const SixSceneState()) { - on(_fetchStatus); - on(fetchLogsForLastMonth); + on(_fetchDeviceStatus); on(_toggleNotification); on(_changeName); on(_onSearchFaq); on(_fetchRoomsAndDevices); on(changeSwitchStatus); on(_onLoadScenes); - on(_selectScene); on(searchScene); on(_onSaveSelection); on(_onOptionSelected); on(_addDeviceToGroup); // Register handler here on(_removeDeviceFromGroup); + on(_fetchFourSceneSwitches); + on(assignScene); + on(getSceneByName); + on(_selectScene); + on(fetchDeviceInfo); + on(_controlDevice); } final TextEditingController nameController = - TextEditingController(text: '${'firstName'}'); + TextEditingController(text: deviceName); bool isSaving = false; bool editName = false; final FocusNode focusNode = FocusNode(); bool closingReminder = false; bool waterAlarm = false; + static String deviceName = ''; - SixSceneModel deviceStatus = - SixSceneModel(waterContactState: 'normal', batteryPercentage: 0); + SixSceneModel deviceStatus = SixSceneModel( + scene_1: '', + scene_2: '', + scene_3: '', + scene_4: '', + scene_5: '', + scene_6: '', + scene_id_group_id: '', + switch_backlight: false); - void _fetchStatus(SixSceneInitial event, Emitter emit) async { + SceneSwitch deviceInfo = SceneSwitch( + activeTime: 0, + category: "", + categoryName: "", + createTime: 0, + gatewayId: "", + icon: "", + ip: "", + lat: "", + localKey: "", + lon: "", + model: "", + name: "", + nodeId: "", + online: false, + ownerId: "", + productName: "", + sub: false, + timeZone: "", + updateTime: 0, + uuid: "", + productUuid: "", + productType: "", + permissionType: "", + macAddress: "", + subspace: Subspace( + uuid: "", + createdAt: "", + updatedAt: "", + subspaceName: "", + ), + ); + + Future fetchDeviceInfo( + SixSceneInitialInfo event, Emitter emit) async { + try { + emit(SixSceneLoadingState()); + var response = await DevicesAPI.getDeviceInfo(sixSceneId); + deviceInfo = SceneSwitch.fromJson(response); + deviceName = deviceInfo.name; + emit(LoadingDeviceInfo(deviceInfo: deviceInfo)); + } catch (e) { + emit(SixSceneFailedState(errorMessage: e.toString())); + } + } + + void _fetchDeviceStatus( + SixSceneInitial event, Emitter emit) async { emit(SixSceneLoadingState()); try { var response = await DevicesAPI.getDeviceStatus(sixSceneId); @@ -59,16 +121,90 @@ class SixSceneBloc extends Bloc { deviceStatus = SixSceneModel.fromJson( statusModelList, ); + add(const SexSceneSwitchInitial()); emit(UpdateState(sensor: deviceStatus)); - - Future.delayed(const Duration(milliseconds: 500)); - // _listenToChanges(); } catch (e) { emit(SixSceneFailedState(errorMessage: e.toString())); return; } } + String selectedFormApiSceneId = ''; + + void getSceneByName( + GetSceneBySwitchName event, Emitter emit) async { + emit(SixSceneLoadingState()); + try { + final response = await DevicesAPI.getSceneBySwitchName( + deviceId: sixSceneId, switchName: event.switchName); + selectedFormApiSceneId = response['scene']['uuid']; + emit(UpdateState(sensor: deviceStatus)); + } catch (e) { + emit(SixSceneFailedState(errorMessage: e.toString())); + } + } + + String selectedSceneId = ''; + + _selectScene(SelectSceneEvent event, Emitter emit) { + emit(SixSceneLoadingState()); + selectedSceneId = event.unitId; + emit(SceneSelectionUpdatedState(selectedSceneId: selectedSceneId)); + } + + List fourScene = []; + + void _fetchFourSceneSwitches( + SexSceneSwitchInitial event, Emitter emit) async { + emit(SixSceneLoadingState()); + try { + var response = await DevicesAPI.getFourSceneInfo(sixSceneId); + Map sceneTitles = { + "scene_1": '', + "scene_2": '', + "scene_3": '', + "scene_4": '', + "scene_5": '', + "scene_6": '', + }; + for (var item in response) { + if (item["switchName"] != null) { + sceneTitles[item["switchName"]] = item["scene"]["name"] ?? ''; + } + } + SixSceneModel deviceStatus = SixSceneModel( + scene_1: sceneTitles["scene_1"] ?? '', + scene_2: sceneTitles["scene_2"] ?? '', + scene_3: sceneTitles["scene_3"] ?? '', + scene_4: sceneTitles["scene_4"] ?? '', + scene_5: sceneTitles["scene_5"] ?? '', + scene_6: sceneTitles["scene_6"] ?? '', + scene_id_group_id: '', + switch_backlight: '', + ); + emit(UpdateState(sensor: deviceStatus)); + } catch (e) { + emit(SixSceneFailedState(errorMessage: e.toString())); + return; + } + } + + void assignScene(AssignDeviceScene event, Emitter emit) async { + emit(SixSceneLoadingState()); + try { + final response = await DevicesAPI.postFourSceneInfo( + deviceId: sixSceneId, + sceneUuid: event.sceneUuid, + spaceUuid: event.unit!.id, + switchName: event.switchName); + + emit(SaveSelectionSuccessState()); + CustomSnackBar.displaySnackBar('Save Successfully'); + } catch (e) { + emit(SixSceneFailedState(errorMessage: e.toString())); + } + } + void _onSearchFaq(SearchFaqEvent event, Emitter emit) { emit(SixSceneLoadingState()); // Filter FAQ questions based on search query @@ -77,8 +213,6 @@ class SixSceneBloc extends Bloc { .toLowerCase() .contains(event.query.toLowerCase()); }).toList(); - - print(_faqQuestions); emit(FaqSearchState(filteredFaqQuestions: _faqQuestions)); } @@ -101,16 +235,6 @@ class SixSceneBloc extends Bloc { try { closingReminder = event.isClosingEnabled; emit(UpdateState(sensor: deviceStatus)); - - // API call to update the state, if necessary - // await DevicesAPI.controlDevice( - // DeviceControlModel( - // deviceId: sosId, - // code: 'closing_reminder', - // value: closingReminder, - // ), - // sosId, - // ); } catch (e) { emit(SixSceneFailedState(errorMessage: e.toString())); } @@ -119,29 +243,6 @@ class SixSceneBloc extends Bloc { 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(SixSceneLoadingState()); - var response = await DevicesAPI.getReportLogs( - startTime: startTime.toString(), - endTime: endTime.toString(), - deviceUuid: sixSceneId, - code: 'sossensor_state', - ); - recordGroups = response; - emit(UpdateState(sensor: deviceStatus)); - } on DioException catch (e) { - final errorData = e.response!.data; - String errorMessage = errorData['message']; - emit(SixSceneFailedState(errorMessage: e.toString())); - } - } - final List faqQuestions = [ SixSceneQuestionModel( id: 1, @@ -196,15 +297,28 @@ class SixSceneBloc extends Bloc { } bool switchStatus = true; - void changeSwitchStatus( - ChangeSwitchStatusEvent event, Emitter emit) { - emit(SixSceneLoadingState()); - switchStatus = !switchStatus; - emit(ChangeSwitchState(isEnable: switchStatus)); + Future changeSwitchStatus( + ChangeSwitchStatusEvent event, Emitter emit) async { + try { + emit(SixSceneLoadingState()); + switchStatus = deviceStatus.switch_backlight; + switchStatus = !switchStatus; + final response = await DevicesAPI.controlDevice( + DeviceControlModel( + deviceId: sixSceneId, + code: 'switch_backlight', + value: switchStatus), + sixSceneId); + deviceStatus.switch_backlight = switchStatus; + if (!response['success']) { + add(const SixSceneInitial()); + } + emit(ChangeSwitchState(isEnable: switchStatus)); + } catch (_) { + add(const SixSceneInitial()); + } } - // List allScenes = []; - Future _onLoadScenes( LoadScenes event, Emitter emit) async { emit(SixSceneLoadingState()); @@ -226,12 +340,6 @@ class SixSceneBloc extends Bloc { } bool selecedScene = false; - String selectedSceneId = ''; - _selectScene(SelectSceneEvent event, Emitter emit) { - emit(SixSceneLoadingState()); - selecedScene = !selecedScene; - emit(SelectedSceneState()); - } List allScenes = []; List filteredScenes = []; @@ -278,19 +386,6 @@ class SixSceneBloc extends Bloc { dec: 'Syncroom', icon: Assets.addDevicesIcon, name: '6 Scene Switch') ]; - // @override - // Stream mapEventToState(SixSceneEvent event) async* { - // if (event is AddDeviceToGroup) { - // devices.remove(event.device); - // groupDevices.add(event.device); - // yield UpdateStateList(groupDevices: groupDevices, devices: devices); - // } else if (event is RemoveDeviceFromGroup) { - // groupDevices.remove(event.device); - // devices.add(event.device); - // yield UpdateStateList(groupDevices: groupDevices, devices: devices); - // } - // } - // Handler for AddDeviceToGroup void _addDeviceToGroup(AddDeviceToGroup event, Emitter emit) { devices.remove(event.device); @@ -306,9 +401,30 @@ class SixSceneBloc extends Bloc { RemoveDeviceFromGroup event, Emitter emit) { groupDevices.remove(event.device); devices.add(event.device); - for (var device in groupDevices) { + for (var device in groupDevices) { device.icon = event.icon; } emit(UpdateStateList(groupDevices: groupDevices, devices: devices)); } + + void _controlDevice( + ControlDeviceScene event, Emitter emit) async { + emit(SixSceneLoadingState()); + try { + deviceStatus.switch_backlight = !event.backLight!; + emit(UpdateState(sensor: deviceStatus)); + final response = await DevicesAPI.controlDevice( + DeviceControlModel( + deviceId: sixSceneId, + code: 'switch_backlight', + value: !event.backLight!), + sixSceneId); + + if (!response['success']) { + // add(InitialEvent(groupScreen: oneTouchGroup)); + } + } catch (_) { + // add(InitialEvent(groupScreen: oneTouchGroup)); + } + } } diff --git a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart index 52b5ed3..5f4e4c2 100644 --- a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart +++ b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart @@ -24,10 +24,24 @@ class SixSceneSwitch extends SixSceneEvent { class SixSceneUpdated extends SixSceneEvent {} +class GetSceneBySwitchName extends SixSceneEvent { + final String? switchName; + + const GetSceneBySwitchName({this.switchName}); +} + class SixSceneInitial extends SixSceneEvent { const SixSceneInitial(); } +class SixSceneInitialInfo extends SixSceneEvent { + const SixSceneInitialInfo(); +} + +class SexSceneSwitchInitial extends SixSceneEvent { + const SexSceneSwitchInitial(); +} + class ReportLogsInitial extends SixSceneEvent { const ReportLogsInitial(); } @@ -171,3 +185,19 @@ class RemoveDeviceFromGroup extends SixSceneEvent { RemoveDeviceFromGroup(this.device, this.icon); } + +class AssignDeviceScene extends SixSceneEvent { + final String? sceneUuid; + final String? switchName; + final SpaceModel? unit; + const AssignDeviceScene({ + this.sceneUuid, + this.unit, + this.switchName, + }); +} + +class ControlDeviceScene extends SixSceneEvent { + final bool? backLight; + const ControlDeviceScene({this.backLight}); +} diff --git a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart index de478df..8c2edfa 100644 --- a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart +++ b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart @@ -1,6 +1,7 @@ import 'package:equatable/equatable.dart'; import 'package:syncrow_app/features/devices/model/device_model.dart'; import 'package:syncrow_app/features/devices/model/group_devices_model.dart'; +import 'package:syncrow_app/features/devices/model/scene_switch_model.dart'; import 'package:syncrow_app/features/devices/model/sex_scene_question_model.dart'; import 'package:syncrow_app/features/devices/model/six_scene_model.dart'; import 'package:syncrow_app/features/devices/model/subspace_model.dart'; @@ -111,3 +112,17 @@ class OptionSelectedState extends SixSceneState { @override List get props => [selectedOption, hasSelectionChanged]; } + +class SceneSelectionUpdatedState extends SixSceneState { + final String selectedSceneId; + + SceneSelectionUpdatedState({required this.selectedSceneId}); +} + +class LoadingDeviceInfo extends SixSceneState { + final SceneSwitch deviceInfo; + const LoadingDeviceInfo({required this.deviceInfo}); + + @override + List get props => [deviceInfo]; +} diff --git a/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart b/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart index a1ff854..c432bc3 100644 --- a/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart +++ b/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart @@ -35,7 +35,6 @@ class FourSceneBloc extends Bloc { on(_fetchRoomsAndDevices); on(changeSwitchStatus); on(_onLoadScenes); - on(_selectScene); on(searchScene); on(_assignDevice); on(_onOptionSelected); @@ -47,6 +46,7 @@ class FourSceneBloc extends Bloc { on(_fetchFourSceneSwitches); on(assignScene); on(getSceneByName); + on(_selectScene); } final TextEditingController nameController = @@ -99,7 +99,17 @@ class FourSceneBloc extends Bloc { subspaceName: "", ), ); - String sceneId = ''; + String selectedFormApiSceneId = ''; + + String selectedSceneId = ''; + + _selectScene(SelectSceneEvent event, Emitter emit) { + emit(FourSceneLoadingState()); + + selectedSceneId = event.selectedSceneId; + emit(SceneSelectionUpdatedState(selectedSceneId: selectedSceneId)); + } + Future saveName( SaveNameEvent event, Emitter emit) async { if (_validateInputs()) return; @@ -119,6 +129,34 @@ class FourSceneBloc extends Bloc { } } + void getSceneByName( + GetSceneBySwitchName event, Emitter emit) async { + emit(FourSceneLoadingState()); + try { + final response = await DevicesAPI.getSceneBySwitchName( + deviceId: fourSceneId, switchName: event.switchName); + selectedFormApiSceneId = response['scene']['uuid']; + emit(UpdateState(device: deviceStatus)); + } catch (e) { + emit(FourSceneFailedState(errorMessage: e.toString())); + } + } + + bool selecedScene = false; + + String _selectedOption = ''; + bool _hasSelectionChanged = false; + + void _onOptionSelected( + SelectOptionEvent event, Emitter emit) { + emit(FourSceneLoadingState()); + _selectedOption = event.selectedOption; + _hasSelectionChanged = true; + emit(OptionSelectedState( + selectedOption: _selectedOption, + hasSelectionChanged: _hasSelectionChanged)); + } + List fourScene = []; void _fetchFourSceneSwitches( @@ -130,15 +168,13 @@ class FourSceneBloc extends Bloc { "scene_1": '', "scene_2": '', "scene_3": '', - "scene_4": '' + "scene_4": '', }; for (var item in response) { if (item["switchName"] != null) { sceneTitles[item["switchName"]] = item["scene"]["name"] ?? ''; } } - print('object======4${response}'); - FourSceneModelState deviceStatus = FourSceneModelState( scene_1: sceneTitles["scene_1"] ?? '', scene_2: sceneTitles["scene_2"] ?? '', @@ -182,20 +218,9 @@ class FourSceneBloc extends Bloc { sceneUuid: event.sceneUuid, spaceUuid: event.unit!.id, switchName: event.switchName); - emit(SaveSelectionSuccessState()); - } catch (e) { - emit(FourSceneFailedState(errorMessage: e.toString())); - } - } - void getSceneByName( - GetSceneBySwitchName event, Emitter emit) async { - emit(FourSceneLoadingState()); - try { - final response = await DevicesAPI.getSceneBySwitchName( - deviceId: fourSceneId, switchName: event.switchName); - sceneId = response['scene']['uuid']; emit(SaveSelectionSuccessState()); + CustomSnackBar.displaySnackBar('Save Successfully'); } catch (e) { emit(FourSceneFailedState(errorMessage: e.toString())); } @@ -398,14 +423,6 @@ class FourSceneBloc extends Bloc { } } - bool selecedScene = false; - String selectedSceneId = ''; - _selectScene(SelectSceneEvent event, Emitter emit) { - emit(FourSceneLoadingState()); - selecedScene = !selecedScene; - emit(SelectedSceneState()); - } - List allScenes = []; List filteredScenes = []; @@ -420,19 +437,6 @@ class FourSceneBloc extends Bloc { emit(SearchResultsState()); } - String _selectedOption = ''; - bool _hasSelectionChanged = false; - - void _onOptionSelected( - SelectOptionEvent event, Emitter emit) { - emit(FourSceneLoadingState()); - _selectedOption = event.selectedOption; - _hasSelectionChanged = true; - emit(OptionSelectedState( - selectedOption: _selectedOption, - hasSelectionChanged: _hasSelectionChanged)); - } - List groupDevices = [ GroupDevicesModel( dec: 'Syncroom', icon: Assets.minusIcon, name: '6 Scene Switch') diff --git a/lib/features/devices/bloc/four_scene_bloc/four_scene_event.dart b/lib/features/devices/bloc/four_scene_bloc/four_scene_event.dart index 0571e27..6e4d9d1 100644 --- a/lib/features/devices/bloc/four_scene_bloc/four_scene_event.dart +++ b/lib/features/devices/bloc/four_scene_bloc/four_scene_event.dart @@ -148,9 +148,11 @@ class LoadScenes extends FourSceneEvent { } class SelectSceneEvent extends FourSceneEvent { - final String unitId; + final String selectedSceneId; + // final String unitId; const SelectSceneEvent({ - required this.unitId, + // required this.unitId, + required this.selectedSceneId, }); } @@ -212,6 +214,7 @@ class ControlDeviceScene extends FourSceneEvent { class FourSceneSwitchInitial extends FourSceneEvent { const FourSceneSwitchInitial(); } + class SaveSelectionSceneEvent extends FourSceneEvent { const SaveSelectionSceneEvent(); } @@ -220,12 +223,15 @@ class AssignDeviceScene extends FourSceneEvent { final String? sceneUuid; final String? switchName; final SpaceModel? unit; - const AssignDeviceScene({this.sceneUuid, this.unit,this.switchName}); + const AssignDeviceScene({ + this.sceneUuid, + this.unit, + this.switchName, + }); } - class GetSceneBySwitchName extends FourSceneEvent { - final String? switchName; + final String? switchName; const GetSceneBySwitchName({this.switchName}); -} \ No newline at end of file +} diff --git a/lib/features/devices/bloc/four_scene_bloc/four_scene_state.dart b/lib/features/devices/bloc/four_scene_bloc/four_scene_state.dart index 0242034..66c888d 100644 --- a/lib/features/devices/bloc/four_scene_bloc/four_scene_state.dart +++ b/lib/features/devices/bloc/four_scene_bloc/four_scene_state.dart @@ -122,3 +122,9 @@ class LoadingDeviceInfo extends FourSceneState { @override List get props => [deviceInfo]; } + +class SceneSelectionUpdatedState extends FourSceneState { + final String selectedSceneId; + + SceneSelectionUpdatedState({required this.selectedSceneId}); +} diff --git a/lib/features/devices/model/six_scene_model.dart b/lib/features/devices/model/six_scene_model.dart index 0bbb82a..c3c01b5 100644 --- a/lib/features/devices/model/six_scene_model.dart +++ b/lib/features/devices/model/six_scene_model.dart @@ -1,28 +1,64 @@ import 'package:syncrow_app/features/devices/model/status_model.dart'; class SixSceneModel { - String waterContactState; - int batteryPercentage; + dynamic scene_1; + dynamic scene_2; + dynamic scene_3; + dynamic scene_4; + dynamic scene_5; + dynamic scene_6; + dynamic scene_id_group_id; + dynamic switch_backlight; SixSceneModel({ - required this.waterContactState, - required this.batteryPercentage, + required this.scene_1, + required this.scene_2, + required this.scene_3, + required this.scene_4, + required this.scene_5, + required this.scene_6, + required this.scene_id_group_id, + required this.switch_backlight, }); factory SixSceneModel.fromJson(List jsonList) { - late String _waterContactState; - late int _batteryPercentage; + late dynamic _scene_1; + late dynamic _scene_2; + late dynamic _scene_3; + late dynamic _scene_4; + late dynamic _scene_5; + late dynamic _scene_6; + late dynamic _scene_id_group_id; + late dynamic _switch_backlight; for (int i = 0; i < jsonList.length; i++) { - if (jsonList[i].code == 'sossensor_state') { - _waterContactState = jsonList[i].value ?? false; - } else if (jsonList[i].code == 'battery_percentage') { - _batteryPercentage = jsonList[i].value ?? 0; + if (jsonList[i].code == 'scene_1') { + _scene_1 = jsonList[i].value ?? ''; + } else if (jsonList[i].code == 'scene_2') { + _scene_2 = jsonList[i].value ?? ''; + } else if (jsonList[i].code == 'scene_3') { + _scene_3 = jsonList[i].value ?? ''; + } else if (jsonList[i].code == 'scene_4') { + _scene_4 = jsonList[i].value ?? ''; + } else if (jsonList[i].code == 'scene_5') { + _scene_5 = jsonList[i].value ?? ''; + } else if (jsonList[i].code == 'scene_6') { + _scene_6 = jsonList[i].value ?? ''; + } else if (jsonList[i].code == 'scene_id_group_id') { + _scene_id_group_id = jsonList[i].value ?? 0; + } else if (jsonList[i].code == 'switch_backlight') { + _switch_backlight = jsonList[i].value ?? false; } } return SixSceneModel( - waterContactState: _waterContactState, - batteryPercentage: _batteryPercentage, + scene_1: _scene_1, + scene_2: _scene_2, + scene_3: _scene_3, + scene_4: _scene_4, + scene_5: _scene_5, + scene_6: _scene_6, + scene_id_group_id: _scene_id_group_id, + switch_backlight: _switch_backlight, ); } } diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/location_setting.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/location_setting.dart index 2913f41..dcfc976 100644 --- a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/location_setting.dart +++ b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/location_setting.dart @@ -54,7 +54,14 @@ class _LocationSixScenePageState extends State { builder: (context, state) { final sensor = BlocProvider.of(context); SixSceneModel model = SixSceneModel( - batteryPercentage: 0, waterContactState: 'normal'); + scene_1: '', + scene_2: '', + scene_3: '', + scene_4: '', + scene_5: '', + scene_6: '', + scene_id_group_id: '', + switch_backlight: ''); List? rooms = []; if (state is LoadingNewSate) { model = state.sosSensor; diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/question_page.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/question_page.dart index 2cbfa9b..a580e3b 100644 --- a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/question_page.dart +++ b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/question_page.dart @@ -30,7 +30,14 @@ class QuestionPage extends StatelessWidget { builder: (context, state) { final sensor = BlocProvider.of(context); SixSceneModel model = SixSceneModel( - batteryPercentage: 0, waterContactState: 'normal'); + scene_1: '', + scene_2: '', + scene_3: '', + scene_4: '', + scene_5: '', + scene_6: '', + scene_id_group_id: '', + switch_backlight: ''); if (state is LoadingNewSate) { model = state.sosSensor; } else if (state is UpdateState) { diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/share_six_scene_page.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/share_six_scene_page.dart index ca89955..3dc8f28 100644 --- a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/share_six_scene_page.dart +++ b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/share_six_scene_page.dart @@ -29,7 +29,14 @@ class ShareSixScenePage extends StatelessWidget { builder: (context, state) { final sensor = BlocProvider.of(context); SixSceneModel model = SixSceneModel( - batteryPercentage: 0, waterContactState: 'normal'); + scene_1: '', + scene_2: '', + scene_3: '', + scene_4: '', + scene_5: '', + scene_6: '', + scene_id_group_id: '', + switch_backlight: ''); if (state is LoadingNewSate) { model = state.sosSensor; } else if (state is UpdateState) { diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_create_group.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_create_group.dart index 8183902..6585edb 100644 --- a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_create_group.dart +++ b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_create_group.dart @@ -29,8 +29,15 @@ class SixSceneCreateGroup extends StatelessWidget { child: BlocBuilder( builder: (context, state) { final sensor = BlocProvider.of(context); - SixSceneModel model = SixSceneModel( - batteryPercentage: 0, waterContactState: 'normal'); + SixSceneModel model = SixSceneModel( + scene_1: '', + scene_2: '', + scene_3: '', + scene_4: '', + scene_5: '', + scene_6: '', + scene_id_group_id: '', + switch_backlight: ''); if (state is LoadingNewSate) { model = state.sosSensor; } else if (state is UpdateState) { diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_info_page.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_info_page.dart index 0caed76..310f8e5 100644 --- a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_info_page.dart +++ b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_info_page.dart @@ -28,8 +28,15 @@ class SixSceneInfoPage extends StatelessWidget { child: BlocBuilder( builder: (context, state) { final sensor = BlocProvider.of(context); - SixSceneModel model = SixSceneModel( - batteryPercentage: 0, waterContactState: 'normal'); + SixSceneModel model = SixSceneModel( + scene_1: '', + scene_2: '', + scene_3: '', + scene_4: '', + scene_5: '', + scene_6: '', + scene_id_group_id: '', + switch_backlight: ''); if (state is LoadingNewSate) { model = state.sosSensor; } else if (state is UpdateState) { diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_profile_page.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_profile_page.dart index 09f4fc0..9ca477d 100644 --- a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_profile_page.dart +++ b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_profile_page.dart @@ -32,8 +32,15 @@ class SixSceneProfilePage extends StatelessWidget { child: BlocBuilder( builder: (context, state) { final sensor = BlocProvider.of(context); - SixSceneModel model = SixSceneModel( - batteryPercentage: 0, waterContactState: 'normal'); + SixSceneModel model = SixSceneModel( + scene_1: '', + scene_2: '', + scene_3: '', + scene_4: '', + scene_5: '', + scene_6: '', + scene_id_group_id: '', + switch_backlight: ''); if (state is LoadingNewSate) { model = state.sosSensor; } else if (state is UpdateState) { diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_settings.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_settings.dart index b02274d..cba5cca 100644 --- a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_settings.dart +++ b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_settings.dart @@ -38,8 +38,15 @@ class SixSceneSettings extends StatelessWidget { child: BlocBuilder( builder: (context, state) { final sensor = BlocProvider.of(context); - SixSceneModel model = SixSceneModel( - batteryPercentage: 0, waterContactState: 'normal'); + SixSceneModel model = SixSceneModel( + scene_1: '', + scene_2: '', + scene_3: '', + scene_4: '', + scene_5: '', + scene_6: '', + scene_id_group_id: '', + switch_backlight: ''); if (state is LoadingNewSate) { model = state.sosSensor; } else if (state is UpdateState) { @@ -74,8 +81,7 @@ class SixSceneSettings extends StatelessWidget { child: Stack( children: [ const Column( - crossAxisAlignment: - CrossAxisAlignment.stretch, + crossAxisAlignment: CrossAxisAlignment.stretch, children: [ SizedBox(height: 20), DefaultContainer( diff --git a/lib/features/devices/view/widgets/6_scene_switch/select_scene_page.dart b/lib/features/devices/view/widgets/6_scene_switch/select_scene_page.dart index 34ec82a..c330028 100644 --- a/lib/features/devices/view/widgets/6_scene_switch/select_scene_page.dart +++ b/lib/features/devices/view/widgets/6_scene_switch/select_scene_page.dart @@ -16,8 +16,10 @@ import 'package:syncrow_app/navigation/navigation_service.dart'; import 'package:syncrow_app/navigation/routing_constants.dart'; import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; -class SelectSceneSixPage extends StatelessWidget { - SelectSceneSixPage({super.key}); +class SixSelectSceneFourPage extends StatelessWidget { + final String? switchSelected; + final String? deviceId; + SixSelectSceneFourPage({super.key, this.switchSelected, this.deviceId}); final TextEditingController _searchController = TextEditingController(); final int? selectedSwitchIndex = 0; @@ -26,22 +28,26 @@ class SelectSceneSixPage extends StatelessWidget { @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => SixSceneBloc(sixSceneId: '') + create: (context) => SixSceneBloc(sixSceneId: deviceId!) ..add(LoadScenes( unit: spaces!.first, unitId: spaces!.first.id, showInDevice: false, - )), + )) + ..add(GetSceneBySwitchName(switchName: switchSelected)), child: BlocBuilder( builder: (context, state) { final sensorBloc = BlocProvider.of(context); - + if (state is SaveSelectionSuccessState) { + Navigator.of(context).pop(true); + Navigator.of(context).pop(true); + } return DefaultScaffold( title: 'Select Scene', actions: [_buildSaveButton(context, state, sensorBloc)], child: state is SixSceneLoadingState ? _buildLoadingIndicator() - : _buildSceneContent(context, sensorBloc), + : _buildSceneContent(context, sensorBloc, state), ); }, ), @@ -51,14 +57,15 @@ class SelectSceneSixPage extends StatelessWidget { // Save button builder Widget _buildSaveButton( BuildContext context, SixSceneState state, SixSceneBloc sensorBloc) { - final bool canSave = - state is OptionSelectedState && state.hasSelectionChanged; + final bool canSave = state is SceneSelectionUpdatedState; return GestureDetector( onTap: canSave ? () { - print('object'); - context.read().add(SaveSelectionEvent()); + context.read().add(AssignDeviceScene( + sceneUuid: sensorBloc.selectedSceneId, + switchName: switchSelected, + unit: spaces!.first)); } : null, child: BodyMedium( @@ -84,13 +91,14 @@ class SelectSceneSixPage extends StatelessWidget { } // Main scene content with search bar and grid - Widget _buildSceneContent(BuildContext context, SixSceneBloc sensorBloc) { + Widget _buildSceneContent( + BuildContext context, SixSceneBloc sensorBloc, SixSceneState state) { return Column( children: [ _buildSearchBar(sensorBloc), const SizedBox(height: 20), Expanded( - child: _buildSceneGrid(sensorBloc), + child: _buildSceneGrid(sensorBloc, state), ), ], ); @@ -125,7 +133,7 @@ class SelectSceneSixPage extends StatelessWidget { } // Scene grid builder - Widget _buildSceneGrid(SixSceneBloc sensorBloc) { + Widget _buildSceneGrid(SixSceneBloc sensorBloc, SixSceneState state) { final scenes = sensorBloc.filteredScenes; return GridView.builder( @@ -152,13 +160,18 @@ class SelectSceneSixPage extends StatelessWidget { ); } else { final scene = scenes[index]; + bool isSelected = scene.id == + (state is SceneSelectionUpdatedState + ? state.selectedSceneId + : sensorBloc.selectedFormApiSceneId); return SceneItem( id: scene.id, - value: sensorBloc.selectedSceneId == scene.id, + value: isSelected, disablePlayButton: false, onChanged: (isSelected) { - sensorBloc.selectedSceneId = isSelected ? scene.id : 'null'; sensorBloc.add(SelectOptionEvent(selectedOption: scene.id)); + + sensorBloc.add(SelectSceneEvent(unitId: scene.id)); }, icon: scene.iconInBytes, title: scene.name, @@ -169,8 +182,8 @@ class SelectSceneSixPage extends StatelessWidget { } } -class SceneItem extends StatefulWidget { - final String id; // Unique ID for each scene +class SceneItem extends StatelessWidget { + final String id; final Uint8List icon; final String title; final bool disablePlayButton; @@ -186,11 +199,6 @@ class SceneItem extends StatefulWidget { required this.onChanged, }); - @override - State createState() => _SceneItemState(); -} - -class _SceneItemState extends State { @override Widget build(BuildContext context) { return Container( @@ -215,9 +223,9 @@ class _SceneItemState extends State { crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - if (!widget.disablePlayButton) + if (!disablePlayButton) Image.memory( - widget.icon, + icon, height: 32, width: 32, fit: BoxFit.fill, @@ -228,7 +236,7 @@ class _SceneItemState extends State { fit: BoxFit.fill), ), BodyMedium( - text: widget.title, + text: title, style: const TextStyle( fontSize: 17, fontWeight: FontWeight.w700, @@ -238,8 +246,8 @@ class _SceneItemState extends State { ], ), CircularCheckbox( - value: widget.value, - onChanged: (isSelected) => widget.onChanged(isSelected!), + value: value, + onChanged: (isSelected) => onChanged(isSelected!), ), ], ), diff --git a/lib/features/devices/view/widgets/6_scene_switch/select_switch_dialog.dart b/lib/features/devices/view/widgets/6_scene_switch/select_switch_dialog.dart index 1195d85..be9ac7f 100644 --- a/lib/features/devices/view/widgets/6_scene_switch/select_switch_dialog.dart +++ b/lib/features/devices/view/widgets/6_scene_switch/select_switch_dialog.dart @@ -1,16 +1,18 @@ import 'package:flutter/material.dart'; -import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/switches_card.dart'; +import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/six_switches_card.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'; class SelectSwitchDialog extends StatefulWidget { final Function()? cancelTab; - final Function()? confirmTab; + final Function(String)? confirmTab; String? switch1Title; String? switch2Title; String? switch3Title; String? switch4Title; + String? switch5Title; + String? switch6Title; SelectSwitchDialog( {super.key, required this.cancelTab, @@ -18,14 +20,16 @@ class SelectSwitchDialog extends StatefulWidget { this.switch1Title, this.switch2Title, this.switch3Title, - this.switch4Title}); + this.switch4Title, + this.switch5Title, + this.switch6Title}); @override State createState() => _SelectSwitchDialogState(); } class _SelectSwitchDialogState extends State { - int? selectedSwitchIndex = 0; + String selectedSwitchName = ''; @override Widget build(BuildContext context) { @@ -49,34 +53,48 @@ class _SelectSwitchDialogState extends State { const SizedBox(height: 20), Row( children: [ - SwitchsCard( + SixSwitchsCardDialog( switch1Title: widget.switch1Title, switch2Title: widget.switch2Title, switch3Title: widget.switch3Title, switch4Title: widget.switch4Title, - switch1Down: selectedSwitchIndex == -1 + switch5Title: widget.switch5Title, + switch6Title: widget.switch6Title, + switch1Down: selectedSwitchName == 'scene_4' ? Assets.removeSceneIcon : Assets.addSwitchIcon, - switch1Up: selectedSwitchIndex == 1 + switch1Up: selectedSwitchName == 'scene_1' ? Assets.removeSceneIcon : Assets.addSwitchIcon, - switch2Down: selectedSwitchIndex == -2 + switch2Down: selectedSwitchName == 'scene_5' ? Assets.removeSceneIcon : Assets.addSwitchIcon, - switch2Up: selectedSwitchIndex == 2 + switch2Up: selectedSwitchName == 'scene_2' ? Assets.removeSceneIcon : Assets.addSwitchIcon, + switch3Up: selectedSwitchName == 'scene_3' + ? Assets.removeSceneIcon + : Assets.addSwitchIcon, + switch3Down: selectedSwitchName == 'scene_6' + ? Assets.removeSceneIcon + : Assets.addSwitchIcon, + onSwitch3DownTap: () { + setState(() => selectedSwitchName = 'scene_3'); + }, + onSwitch3UpTap: () { + setState(() => selectedSwitchName = 'scene_6'); + }, onSwitch1UpTap: () { - setState(() => selectedSwitchIndex = 1); + setState(() => selectedSwitchName = 'scene_1'); }, onSwitch1DownTap: () { - setState(() => selectedSwitchIndex = -1); + setState(() => selectedSwitchName = 'scene_4'); }, onSwitch2UpTap: () { - setState(() => selectedSwitchIndex = 2); + setState(() => selectedSwitchName = 'scene_5'); }, onSwitch2DownTap: () { - setState(() => selectedSwitchIndex = -2); + setState(() => selectedSwitchName = 'scene_2'); }, ), ], @@ -125,14 +143,16 @@ class _SelectSwitchDialogState extends State { top: BorderSide(color: ColorsManager.textGray, width: 1.0), )), child: InkWell( - onTap: selectedSwitchIndex == 0 ? () {} : widget.confirmTab, + onTap: selectedSwitchName == '' + ? () {} + : () => widget.confirmTab!(selectedSwitchName), child: Padding( padding: EdgeInsets.all(15), child: Center( child: Text( 'Next', style: TextStyle( - color: selectedSwitchIndex == 0 + color: selectedSwitchName == '' ? ColorsManager.textPrimaryColor .withOpacity(0.6) : ColorsManager.primaryColor, diff --git a/lib/features/devices/view/widgets/6_scene_switch/six_scene_screen.dart b/lib/features/devices/view/widgets/6_scene_switch/six_scene_screen.dart index 50a3034..715bdf9 100644 --- a/lib/features/devices/view/widgets/6_scene_switch/six_scene_screen.dart +++ b/lib/features/devices/view/widgets/6_scene_switch/six_scene_screen.dart @@ -11,7 +11,7 @@ import 'package:syncrow_app/features/devices/model/six_scene_model.dart'; import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_settings.dart'; import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/select_scene_page.dart'; import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/select_switch_dialog.dart'; -import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/switches_card.dart'; +import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/six_switches_card.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'; @@ -41,12 +41,22 @@ class SixSceneScreen extends StatelessWidget { ], child: BlocProvider( create: (context) => SixSceneBloc(sixSceneId: device?.uuid ?? '') - ..add(const SixSceneInitial()), + ..add(const SixSceneInitial()) + ..add(const SixSceneInitialInfo()) + ..add(const SexSceneSwitchInitial()), child: BlocBuilder( builder: (context, state) { - final sensor = BlocProvider.of(context); + final _bloc = BlocProvider.of(context); SixSceneModel model = SixSceneModel( - batteryPercentage: 0, waterContactState: 'normal'); + scene_1: '', + scene_2: '', + scene_3: '', + scene_4: '', + scene_5: '', + scene_6: '', + scene_id_group_id: '', + switch_backlight: ''); + if (state is LoadingNewSate) { model = state.sosSensor; } else if (state is UpdateState) { @@ -61,7 +71,7 @@ class SixSceneScreen extends StatelessWidget { ) : RefreshIndicator( onRefresh: () async { - sensor.add(const SixSceneInitial()); + _bloc.add(const SixSceneInitial()); }, child: ListView( children: [ @@ -69,24 +79,43 @@ class SixSceneScreen extends StatelessWidget { height: MediaQuery.sizeOf(context).height * 0.8, child: Column( children: [ - SwitchsCard( - // switch1Title: , - // switch2Title: , - // switch3Title: , - // switch4Title: , - switch1Down: sensor.switchStatus == true - ? Assets.switchOn - : Assets.switchOff, - switch1Up: sensor.switchStatus == true - ? Assets.switchOn - : Assets.switchOff, - switch2Down: sensor.switchStatus == true - ? Assets.switchOn - : Assets.switchOff, - switch2Up: sensor.switchStatus == true - ? Assets.switchOn - : Assets.switchOff, - + SixSwitchsCardDialog( + switch1Title: model.scene_1, + switch2Title: model.scene_2, + switch3Title: model.scene_3, + switch4Title: model.scene_4, + switch5Title: model.scene_5, + switch6Title: model.scene_6, + switch1Down: + _bloc.deviceStatus.switch_backlight == true + ? Assets.switchOn + : Assets.switchOff, + switch1Up: + _bloc.deviceStatus.switch_backlight == true + ? Assets.switchOn + : Assets.switchOff, + switch2Down: + _bloc.deviceStatus.switch_backlight == true + ? Assets.switchOn + : Assets.switchOff, + switch2Up: + _bloc.deviceStatus.switch_backlight == true + ? Assets.switchOn + : Assets.switchOff, + switch3Up: + _bloc.deviceStatus.switch_backlight == true + ? Assets.switchOn + : Assets.switchOff, + switch3Down: + _bloc.deviceStatus.switch_backlight == true + ? Assets.switchOn + : Assets.switchOff, + onSwitch3DownTap: () { + debugPrint("onSwitch3DownTap"); + }, + onSwitch3UpTap: () { + debugPrint("onSwitch3UpTap"); + }, onSwitch1UpTap: () { debugPrint("Switch 1 Up tapped"); }, @@ -106,7 +135,7 @@ class SixSceneScreen extends StatelessWidget { Expanded( child: DefaultContainer( onTap: () { - sensor.add(ChangeSwitchStatusEvent()); + _bloc.add(ChangeSwitchStatusEvent()); }, child: Column( crossAxisAlignment: @@ -140,19 +169,29 @@ class SixSceneScreen extends StatelessWidget { ), Expanded( child: DefaultContainer( - onTap: () { - showDialog( + onTap: () async { + var value = await showDialog( context: context, builder: (context) { return SelectSwitchDialog( + switch1Title: model.scene_1, + switch2Title: model.scene_2, + switch3Title: model.scene_3, + switch4Title: model.scene_4, + switch5Title: model.scene_5, + switch6Title: model.scene_6, cancelTab: () { Navigator.of(context).pop(); }, - confirmTab: () { + confirmTab: (v) { Navigator.of(context).push( MaterialPageRoute( builder: (context) => - SelectSceneSixPage()), + SixSelectSceneFourPage( + deviceId: + device!.uuid, + switchSelected: v, + )), ); }, ); diff --git a/lib/features/devices/view/widgets/6_scene_switch/six_switches_card.dart b/lib/features/devices/view/widgets/6_scene_switch/six_switches_card.dart new file mode 100644 index 0000000..6ed4cd2 --- /dev/null +++ b/lib/features/devices/view/widgets/6_scene_switch/six_switches_card.dart @@ -0,0 +1,193 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +class SixSwitchsCardDialog extends StatelessWidget { + final String? switch1Title; + final String? switch2Title; + final String? switch3Title; + final String? switch4Title; + final String? switch5Title; + final String? switch6Title; + + final String switch1Up; + final String switch1Down; + final String switch2Up; + final String switch2Down; + + final String switch3Down; + final String switch3Up; + + final VoidCallback onSwitch1UpTap; + final VoidCallback onSwitch1DownTap; + final VoidCallback onSwitch2UpTap; + final VoidCallback onSwitch2DownTap; + + final VoidCallback onSwitch3DownTap; + final VoidCallback onSwitch3UpTap; + + SixSwitchsCardDialog( + {required this.switch1Down, + required this.switch1Up, + required this.switch2Down, + required this.switch2Up, + required this.onSwitch1UpTap, + required this.onSwitch1DownTap, + required this.onSwitch2UpTap, + required this.onSwitch2DownTap, + required this.onSwitch3DownTap, + required this.onSwitch3UpTap, + required this.switch3Down, + this.switch1Title, + this.switch2Title, + this.switch3Title, + this.switch4Title, + this.switch5Title, + this.switch6Title, + required this.switch3Up}); + + @override + Widget build(BuildContext context) { + return Expanded( + flex: 4, + child: InkWell( + overlayColor: MaterialStateProperty.all(Colors.transparent), + onTap: () {}, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Expanded( + child: Container( + margin: const EdgeInsets.symmetric(horizontal: 10), + decoration: const BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all(Radius.circular(10)), + ), + child: Container( + margin: const EdgeInsets.symmetric(horizontal: 10), + decoration: BoxDecoration( + color: ColorsManager.onPrimaryColor, + boxShadow: [ + BoxShadow( + color: Colors.white.withOpacity(0.1), + blurRadius: 24, + offset: const Offset(-2, -2), + blurStyle: BlurStyle.outer, + ), + BoxShadow( + color: Colors.black.withOpacity(0.11), + blurRadius: 5, + offset: const Offset(2, 0), + blurStyle: BlurStyle.outer, + ), + BoxShadow( + color: Colors.white.withOpacity(0.13), + blurRadius: 10, + offset: const Offset(5, 1), + blurStyle: BlurStyle.inner, + ), + ], + ), + child: SizedBox( + height: 300, + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + // Switch 1 + _buildSwitchColumn( + switchUp: switch1Up, + switchDown: switch1Down, + onUpTap: onSwitch1UpTap, + onDownTap: onSwitch1DownTap, + titleDown: switch4Title!, + titleUp: switch1Title!), + _buildDivider(), + // Switch 2 + _buildSwitchColumn( + switchUp: switch2Up, + switchDown: switch2Down, + onDownTap: onSwitch2UpTap, + onUpTap: onSwitch2DownTap, + titleDown: switch5Title!, + titleUp: switch2Title!), + _buildDivider(), + // Switch 3 + _buildSwitchColumn( + switchUp: switch3Up, + switchDown: switch3Down, + onDownTap: onSwitch3UpTap, + onUpTap: onSwitch3DownTap, + titleDown: switch6Title!, + titleUp: switch3Title!), + ], + ), + ), + ), + ), + ), + ], + ), + ), + ); + } + + Widget _buildSwitchColumn({ + String switchUp = '', + String titleUp = '', + String titleDown = '', + String switchDown = '', + VoidCallback? onUpTap, + VoidCallback? onDownTap, + }) { + return Expanded( + child: Padding( + padding: const EdgeInsets.only(top: 30, bottom: 30), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + children: [ + InkWell( + onTap: onUpTap, + child: Container( + height: 20, + width: 20, + child: SvgPicture.asset(switchUp), + ), + ), + BodySmall( + text: titleUp, + ) + ], + ), + Column( + children: [ + InkWell( + onTap: onDownTap, + child: Container( + height: 20, + width: 20, + child: SvgPicture.asset(switchDown), + ), + ), + BodySmall( + text: titleDown, + ) + ], + ), + ], + ), + ), + ); + } + + Widget _buildDivider() { + return Container( + width: 3, + color: ColorsManager.dividerColor, + ); + } +} diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_screen.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_screen.dart index 3c96bc0..9019fd3 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_screen.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_screen.dart @@ -150,8 +150,8 @@ class FourSceneScreen extends StatelessWidget { ), Expanded( child: DefaultContainer( - onTap: () { - showDialog( + onTap: () async { + var value = await showDialog( context: context, builder: (context) { return FourSelectSwitchDialog( @@ -162,18 +162,29 @@ class FourSceneScreen extends StatelessWidget { cancelTab: () { Navigator.of(context).pop(); }, - confirmTab: (switchSelected) { + confirmTab: + (switchSelected) async { Navigator.of(context).push( MaterialPageRoute( builder: (context) => FourSelectSceneFourPage( - switchSelected: switchSelected, - deviceId:device!.uuid)), + switchSelected: + switchSelected, + deviceId: + device! + .uuid)), ); }, ); }, ); + if (value == true) { + _bloc.add(const FourSceneInitial()); + _bloc.add( + const FourSceneInitialInfo()); + _bloc.add( + const FourSceneSwitchInitial()); + } }, child: Column( crossAxisAlignment: diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_profile_page.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_profile_page.dart index d62ceda..0ded218 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_profile_page.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_profile_page.dart @@ -67,11 +67,22 @@ class FourSceneProfilePage extends StatelessWidget { backgroundColor: Colors.white, child: CircleAvatar( radius: 55, - backgroundColor: Colors.grey, + backgroundColor: ColorsManager.graysColor, child: ClipOval( - child: SvgPicture.asset( - Assets.sosProfileIcon, - fit: BoxFit.fill, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox( + height: 10, + ), + Center( + child: SvgPicture.asset( + Assets.fourSceneIcon, + fit: BoxFit.contain, + ), + ), + ], ), ), ), diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart index 390280c..454036e 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart @@ -15,7 +15,6 @@ import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_update_dialog.dart'; import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_update_page.dart'; import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_scene_setting/share_four_scene_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_medium.dart'; @@ -139,9 +138,24 @@ class FourSceneSettings extends StatelessWidget { radius: 40, backgroundColor: ColorsManager.backgroundColor, - child: SvgPicture.asset( - Assets.sixSceneIcon, - fit: BoxFit.fill, + child: Column( + crossAxisAlignment: + CrossAxisAlignment.center, + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + Padding( + padding: const EdgeInsets.only( + top: 8), + child: SizedBox( + height: 70, + child: SvgPicture.asset( + Assets.fourSceneIcon, + fit: BoxFit.contain, + ), + ), + ), + ], ), ), )), diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_select_scene_page.dart b/lib/features/devices/view/widgets/four_scene_switch/four_select_scene_page.dart index 8eee620..c43987d 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_select_scene_page.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_select_scene_page.dart @@ -38,13 +38,16 @@ class FourSelectSceneFourPage extends StatelessWidget { child: BlocBuilder( builder: (context, state) { final sensorBloc = BlocProvider.of(context); - + if (state is SaveSelectionSuccessState) { + Navigator.of(context).pop(true); + Navigator.of(context).pop(true); + } return DefaultScaffold( title: 'Select Scene', actions: [_buildSaveButton(context, state, sensorBloc)], child: state is FourSceneLoadingState ? _buildLoadingIndicator() - : _buildSceneContent(context, sensorBloc), + : _buildSceneContent(context, sensorBloc, state), ); }, ), @@ -54,8 +57,7 @@ class FourSelectSceneFourPage extends StatelessWidget { // Save button builder Widget _buildSaveButton( BuildContext context, FourSceneState state, FourSceneBloc sensorBloc) { - final bool canSave = - state is OptionSelectedState && state.hasSelectionChanged; + final bool canSave = state is SceneSelectionUpdatedState; return GestureDetector( onTap: canSave @@ -89,13 +91,14 @@ class FourSelectSceneFourPage extends StatelessWidget { } // Main scene content with search bar and grid - Widget _buildSceneContent(BuildContext context, FourSceneBloc sensorBloc) { + Widget _buildSceneContent( + BuildContext context, FourSceneBloc sensorBloc, FourSceneState state) { return Column( children: [ _buildSearchBar(sensorBloc), const SizedBox(height: 20), Expanded( - child: _buildSceneGrid(sensorBloc), + child: _buildSceneGrid(sensorBloc, state), ), ], ); @@ -130,8 +133,9 @@ class FourSelectSceneFourPage extends StatelessWidget { } // Scene grid builder - Widget _buildSceneGrid(FourSceneBloc sensorBloc) { + Widget _buildSceneGrid(FourSceneBloc sensorBloc, FourSceneState state) { final scenes = sensorBloc.filteredScenes; + return GridView.builder( itemCount: scenes.length + 1, gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( @@ -141,7 +145,6 @@ class FourSelectSceneFourPage extends StatelessWidget { mainAxisExtent: 120, ), itemBuilder: (context, index) { - // sensorBloc.sceneId; if (index == scenes.length) { return InkWell( onTap: () => Navigator.pushNamed( @@ -157,13 +160,18 @@ class FourSelectSceneFourPage extends StatelessWidget { ); } else { final scene = scenes[index]; + bool isSelected = scene.id == + (state is SceneSelectionUpdatedState + ? state.selectedSceneId + : sensorBloc.selectedFormApiSceneId); return SceneItem( id: scene.id, - value: (sensorBloc.selectedSceneId == scene.id), + value: isSelected, disablePlayButton: false, onChanged: (isSelected) { - sensorBloc.selectedSceneId = isSelected ? scene.id : 'null'; sensorBloc.add(SelectOptionEvent(selectedOption: scene.id)); + + sensorBloc.add(SelectSceneEvent(selectedSceneId: scene.id)); }, icon: scene.iconInBytes, title: scene.name, @@ -174,8 +182,8 @@ class FourSelectSceneFourPage extends StatelessWidget { } } -class SceneItem extends StatefulWidget { - final String id; // Unique ID for each scene +class SceneItem extends StatelessWidget { + final String id; final Uint8List icon; final String title; final bool disablePlayButton; @@ -191,11 +199,6 @@ class SceneItem extends StatefulWidget { required this.onChanged, }); - @override - State createState() => _SceneItemState(); -} - -class _SceneItemState extends State { @override Widget build(BuildContext context) { return Container( @@ -220,9 +223,9 @@ class _SceneItemState extends State { crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - if (!widget.disablePlayButton) + if (!disablePlayButton) Image.memory( - widget.icon, + icon, height: 32, width: 32, fit: BoxFit.fill, @@ -233,7 +236,7 @@ class _SceneItemState extends State { fit: BoxFit.fill), ), BodyMedium( - text: widget.title, + text: title, style: const TextStyle( fontSize: 17, fontWeight: FontWeight.w700, @@ -243,8 +246,8 @@ class _SceneItemState extends State { ], ), CircularCheckbox( - value: widget.value, - onChanged: (isSelected) => widget.onChanged(isSelected!), + value: value, + onChanged: (isSelected) => onChanged(isSelected!), ), ], ), diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_select_switch_dialog.dart b/lib/features/devices/view/widgets/four_scene_switch/four_select_switch_dialog.dart index 28e2255..4467569 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_select_switch_dialog.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_select_switch_dialog.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/switches_card.dart'; +import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_switches_card_dialog.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'; @@ -51,7 +51,7 @@ class _FourSelectSwitchDialogState extends State { const SizedBox(height: 20), Row( children: [ - SwitchsCard( + FourSwitchsCardDialog( switch1Title: widget.switch1Title, switch2Title: widget.switch2Title, switch3Title: widget.switch3Title, diff --git a/lib/features/devices/view/widgets/6_scene_switch/switches_card.dart b/lib/features/devices/view/widgets/four_scene_switch/four_switches_card_dialog.dart similarity index 98% rename from lib/features/devices/view/widgets/6_scene_switch/switches_card.dart rename to lib/features/devices/view/widgets/four_scene_switch/four_switches_card_dialog.dart index 9c39772..2d1edad 100644 --- a/lib/features/devices/view/widgets/6_scene_switch/switches_card.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_switches_card_dialog.dart @@ -3,7 +3,7 @@ import 'package:flutter_svg/svg.dart'; import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart'; import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; -class SwitchsCard extends StatelessWidget { +class FourSwitchsCardDialog extends StatelessWidget { final String? switch1Title; final String? switch2Title; final String? switch3Title; @@ -19,7 +19,7 @@ class SwitchsCard extends StatelessWidget { final VoidCallback onSwitch2UpTap; final VoidCallback onSwitch2DownTap; - SwitchsCard({ + FourSwitchsCardDialog({ required this.switch1Down, required this.switch1Up, required this.switch2Down, diff --git a/lib/features/devices/view/widgets/room_page_switch.dart b/lib/features/devices/view/widgets/room_page_switch.dart index f21a3b0..bb61799 100644 --- a/lib/features/devices/view/widgets/room_page_switch.dart +++ b/lib/features/devices/view/widgets/room_page_switch.dart @@ -7,6 +7,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart'; import 'package:syncrow_app/features/devices/model/device_model.dart'; +import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/six_scene_screen.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'; @@ -213,6 +214,13 @@ void showDeviceInterface(DeviceModel device, BuildContext context) { pageBuilder: (context, animation1, animation2) => WaterLeakScreen(device: device))); + case DeviceType.SixScene: + Navigator.push( + context, + PageRouteBuilder( + pageBuilder: (context, animation1, animation2) => + SixSceneScreen(device: device))); + case DeviceType.FourScene: Navigator.push( context, diff --git a/lib/generated/assets.dart b/lib/generated/assets.dart index b111362..30ae693 100644 --- a/lib/generated/assets.dart +++ b/lib/generated/assets.dart @@ -1117,6 +1117,7 @@ class Assets { static const String sixSceneIcon = "assets/icons/six_scene_icon.svg"; static const String minusIcon = "assets/icons/minus_icon.svg"; static const String addDevicesIcon = "assets/icons/add_devices_icon.svg"; + static const String fourSceneIcon = "assets/icons/four_scene_icon.svg"; //powerClampIcon } diff --git a/lib/utils/resource_manager/constants.dart b/lib/utils/resource_manager/constants.dart index dc913ce..e995a16 100644 --- a/lib/utils/resource_manager/constants.dart +++ b/lib/utils/resource_manager/constants.dart @@ -57,6 +57,7 @@ enum DeviceType { WaterLeak, PC, FourScene, + SixScene, Other, } @@ -90,6 +91,7 @@ Map devicesTypesMap = { "WL": DeviceType.WaterLeak, "PC": DeviceType.PC, "4S": DeviceType.FourScene, + "6S": DeviceType.SixScene, }; Map> devicesFunctionsMap = { DeviceType.AC: [ @@ -544,6 +546,52 @@ Map> devicesFunctionsMap = { code: 'switch_backlight', type: functionTypesMap['Enum'], values: ValueModel.fromJson({})), + ], + DeviceType.SixScene: [ + FunctionModel( + code: 'scene_1', + type: functionTypesMap['Boolean'], + values: ValueModel.fromJson({ + "range": ["scene"] + })), + FunctionModel( + code: 'scene_2', + type: functionTypesMap['Integer'], + values: ValueModel.fromJson({ + "range": ["scene"] + })), + FunctionModel( + code: 'scene_3', + type: functionTypesMap['Integer'], + values: ValueModel.fromJson({ + "range": ["scene"] + })), + FunctionModel( + code: 'scene_4', + type: functionTypesMap['Integer'], + values: ValueModel.fromJson({ + "range": ["scene"] + })), + FunctionModel( + code: 'scene_5', + type: functionTypesMap['Integer'], + values: ValueModel.fromJson({ + "range": ["scene"] + })), + FunctionModel( + code: 'scene_6', + type: functionTypesMap['Integer'], + values: ValueModel.fromJson({ + "range": ["scene"] + })), + FunctionModel( + code: 'scene_id_group_id', + type: functionTypesMap['Raw'], + values: ValueModel.fromJson({})), + FunctionModel( + code: 'switch_backlight', + type: functionTypesMap['Enum'], + values: ValueModel.fromJson({})), ] }; From 60dfb1607abc1b7531fd00f004107c5dfde21331 Mon Sep 17 00:00:00 2001 From: mohammad Date: Thu, 21 Nov 2024 16:25:54 +0300 Subject: [PATCH 08/29] six scene --- .../6_scene_switch_bloc/6_scene_bloc.dart | 111 ++- .../6_scene_switch_bloc/6_scene_event.dart | 24 + .../6_scene_switch_bloc/6_scene_state.dart | 13 +- .../6_scene_setting/location_setting.dart | 256 ++++--- .../6_scene_setting/question_page.dart | 4 +- .../6_scene_setting/share_six_scene_page.dart | 4 +- .../six_scene_create_group.dart | 4 +- .../6_scene_setting/six_scene_info_page.dart | 47 +- .../six_scene_profile_page.dart | 61 +- .../6_scene_setting/six_scene_settings.dart | 723 +++++++++--------- .../6_scene_switch/six_scene_screen.dart | 4 +- .../four_scene_switch/four_scene_screen.dart | 10 +- .../four_scene_info_page.dart | 2 +- lib/services/api/devices_api.dart | 1 + 14 files changed, 699 insertions(+), 565 deletions(-) diff --git a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart index 51353c8..4ba5bf0 100644 --- a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart +++ b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart @@ -1,5 +1,4 @@ import 'dart:async'; -import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart'; @@ -12,9 +11,11 @@ import 'package:syncrow_app/features/devices/model/scene_switch_model.dart'; import 'package:syncrow_app/features/devices/model/sex_scene_question_model.dart'; import 'package:syncrow_app/features/devices/model/six_scene_model.dart'; import 'package:syncrow_app/features/devices/model/status_model.dart'; +import 'package:syncrow_app/features/devices/model/subspace_model.dart'; import 'package:syncrow_app/features/scene/model/scenes_model.dart'; import 'package:syncrow_app/generated/assets.dart'; import 'package:syncrow_app/services/api/devices_api.dart'; +import 'package:syncrow_app/services/api/home_management_api.dart'; import 'package:syncrow_app/services/api/scene_api.dart'; import 'package:syncrow_app/services/api/spaces_api.dart'; import 'package:syncrow_app/utils/helpers/snack_bar.dart'; @@ -28,7 +29,6 @@ class SixSceneBloc extends Bloc { on(_toggleNotification); on(_changeName); on(_onSearchFaq); - on(_fetchRoomsAndDevices); on(changeSwitchStatus); on(_onLoadScenes); on(searchScene); @@ -42,6 +42,9 @@ class SixSceneBloc extends Bloc { on(_selectScene); on(fetchDeviceInfo); on(_controlDevice); + on(saveName); + on(_assignDevice); + on(_fetchRoomsAndDevices); } final TextEditingController nameController = @@ -96,6 +99,64 @@ class SixSceneBloc extends Bloc { ), ); + List roomsList = []; + + void _fetchRoomsAndDevices( + FetchRoomsEvent event, Emitter emit) async { + try { + emit(SixSceneLoadingState()); + roomsList = await SpacesAPI.getSubSpaceBySpaceId( + event.unit.community.uuid, event.unit.id); + emit(FetchRoomsState(devicesList: allDevices, roomsList: roomsList)); + } catch (e) { + emit(SixSceneFailedState(errorMessage: e.toString())); + return; + } + } + + void _assignDevice(AssignRoomEvent event, Emitter emit) async { + try { + emit(SixSceneLoadingState()); + if (_hasSelectionChanged) { + await HomeManagementAPI.assignDeviceToRoom( + event.unit.community.uuid, event.unit.id, event.roomId, sixSceneId); + final devicesList = await DevicesAPI.getDevicesByRoomId( + communityUuid: event.unit.community.uuid, + spaceUuid: event.unit.id, + roomId: event.roomId); + List allDevicesIds = []; + allDevices.forEach((element) { + allDevicesIds.add(element.uuid!); + }); + CustomSnackBar.displaySnackBar('Save Successfully'); + + emit(SaveSelectionSuccessState()); + } + } catch (e) { + emit(SixSceneFailedState(errorMessage: e.toString())); + return; + } + } + + Future saveName( + SaveNameEvent event, Emitter emit) async { + if (_validateInputs()) return; + try { + add(const ChangeNameEvent(value: false)); + isSaving = true; + emit(SixSceneLoadingState()); + var response = await DevicesAPI.putDeviceName( + deviceId: sixSceneId, deviceName: nameController.text); + add(const SixSceneInitialInfo()); + CustomSnackBar.displaySnackBar('Save Successfully'); + emit(SaveState()); + } catch (e) { + emit(SixSceneFailedState(errorMessage: e.toString())); + } finally { + isSaving = false; + } + } + Future fetchDeviceInfo( SixSceneInitialInfo event, Emitter emit) async { try { @@ -122,7 +183,7 @@ class SixSceneBloc extends Bloc { statusModelList, ); add(const SexSceneSwitchInitial()); - emit(UpdateState(sensor: deviceStatus)); + emit(UpdateState(device: deviceStatus)); } catch (e) { emit(SixSceneFailedState(errorMessage: e.toString())); return; @@ -138,7 +199,7 @@ class SixSceneBloc extends Bloc { final response = await DevicesAPI.getSceneBySwitchName( deviceId: sixSceneId, switchName: event.switchName); selectedFormApiSceneId = response['scene']['uuid']; - emit(UpdateState(sensor: deviceStatus)); + emit(UpdateState(device: deviceStatus)); } catch (e) { emit(SixSceneFailedState(errorMessage: e.toString())); } @@ -182,7 +243,7 @@ class SixSceneBloc extends Bloc { scene_id_group_id: '', switch_backlight: '', ); - emit(UpdateState(sensor: deviceStatus)); + emit(UpdateState(device: deviceStatus)); } catch (e) { emit(SixSceneFailedState(errorMessage: e.toString())); return; @@ -231,10 +292,10 @@ class SixSceneBloc extends Bloc { void _toggleNotification( ToggleNotificationEvent event, Emitter emit) async { - emit(LoadingNewSate(sosSensor: deviceStatus)); + emit(LoadingNewSate(device: deviceStatus)); try { closingReminder = event.isClosingEnabled; - emit(UpdateState(sensor: deviceStatus)); + emit(UpdateState(device: deviceStatus)); } catch (e) { emit(SixSceneFailedState(errorMessage: e.toString())); } @@ -283,19 +344,6 @@ class SixSceneBloc extends Bloc { List allDevices = []; - void _fetchRoomsAndDevices( - FetchRoomsEvent event, Emitter emit) async { - try { - emit(SixSceneLoadingState()); - final roomsList = await SpacesAPI.getSubSpaceBySpaceId( - event.unit.community.uuid, event.unit.id); - emit(FetchRoomsState(devicesList: allDevices, roomsList: roomsList)); - } catch (e) { - emit(const SixSceneFailedState(errorMessage: 'Something went wrong')); - return; - } - } - bool switchStatus = true; Future changeSwitchStatus( ChangeSwitchStatusEvent event, Emitter emit) async { @@ -412,7 +460,7 @@ class SixSceneBloc extends Bloc { emit(SixSceneLoadingState()); try { deviceStatus.switch_backlight = !event.backLight!; - emit(UpdateState(sensor: deviceStatus)); + emit(UpdateState(device: deviceStatus)); final response = await DevicesAPI.controlDevice( DeviceControlModel( deviceId: sixSceneId, @@ -427,4 +475,25 @@ class SixSceneBloc extends Bloc { // add(InitialEvent(groupScreen: oneTouchGroup)); } } + + bool _validateInputs() { + final nameError = fullNameValidator(nameController.text); + if (nameError != null) { + CustomSnackBar.displaySnackBar(nameError); + return true; + } + return false; + } + + String? fullNameValidator(String? value) { + if (value == null) return 'name is required'; + final withoutExtraSpaces = value.replaceAll(RegExp(r"\s+"), ' ').trim(); + if (withoutExtraSpaces.length < 2 || withoutExtraSpaces.length > 30) { + return 'name must be between 2 and 30 characters long'; + } + if (RegExp(r"/[^ a-zA-Z0-9-\']/").hasMatch(withoutExtraSpaces)) { + return 'Only alphanumeric characters, space, dash and single quote are allowed'; + } + return null; + } } diff --git a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart index 5f4e4c2..fba85f7 100644 --- a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart +++ b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart @@ -1,4 +1,5 @@ import 'package:equatable/equatable.dart'; +import 'package:flutter/material.dart'; import 'package:syncrow_app/features/app_layout/model/space_model.dart'; import 'package:syncrow_app/features/devices/model/group_devices_model.dart'; @@ -34,6 +35,10 @@ class SixSceneInitial extends SixSceneEvent { const SixSceneInitial(); } +class SaveNameEvent extends SixSceneEvent { + const SaveNameEvent(); +} + class SixSceneInitialInfo extends SixSceneEvent { const SixSceneInitialInfo(); } @@ -201,3 +206,22 @@ class ControlDeviceScene extends SixSceneEvent { final bool? backLight; const ControlDeviceScene({this.backLight}); } + +class AssignRoomEvent extends SixSceneEvent { + final String roomId; + final SpaceModel unit; + final BuildContext context; + + const AssignRoomEvent({ + required this.roomId, + required this.unit, + required this.context, + }); + + @override + List get props => [ + roomId, + unit, + context, + ]; +} diff --git a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart index 8c2edfa..d5480f5 100644 --- a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart +++ b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart @@ -17,6 +17,7 @@ class SixSceneState extends Equatable { class SixSceneInitialState extends SixSceneState {} class SixSceneLoadingState extends SixSceneState {} +class SaveState extends SixSceneState {} class SixSceState extends SixSceneState {} @@ -36,19 +37,19 @@ class SixSceneFailedState extends SixSceneState { } class UpdateState extends SixSceneState { - final SixSceneModel sensor; - const UpdateState({required this.sensor}); + final SixSceneModel device; + const UpdateState({required this.device}); @override - List get props => [sensor]; + List get props => [device]; } class LoadingNewSate extends SixSceneState { - final SixSceneModel sosSensor; - const LoadingNewSate({required this.sosSensor}); + final SixSceneModel device; + const LoadingNewSate({required this.device}); @override - List get props => [sosSensor]; + List get props => [device]; } class NameEditingState extends SixSceneState { diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/location_setting.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/location_setting.dart index dcfc976..2890ea2 100644 --- a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/location_setting.dart +++ b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/location_setting.dart @@ -5,68 +5,47 @@ import 'package:syncrow_app/features/app_layout/model/space_model.dart'; import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart'; import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart'; import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart'; -import 'package:syncrow_app/features/devices/model/six_scene_model.dart'; - -import 'package:syncrow_app/features/devices/model/subspace_model.dart'; +import 'package:syncrow_app/features/devices/model/four_scene_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/features/shared_widgets/text_widgets/body_medium.dart'; import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; -class LocationSixScenePage extends StatefulWidget { +class LocationSixScenePage extends StatelessWidget { final SpaceModel? space; - LocationSixScenePage({super.key, this.space}); + final String? deviceId; - @override - _LocationSixScenePageState createState() => _LocationSixScenePageState(); -} - -class _LocationSixScenePageState extends State { - String _selectedOption = 'Conference Room'; - bool _hasSelectionChanged = false; + const LocationSixScenePage({ + super.key, + this.space, + this.deviceId, + }); @override Widget build(BuildContext context) { - return DefaultScaffold( - title: 'Device Location', - actions: [ - InkWell( - onTap: _hasSelectionChanged - ? () { - print('Save button clicked'); - } - : null, - child: BodyMedium( - text: 'Save', - fontWeight: FontWeight.w700, - fontSize: 16, - fontColor: _hasSelectionChanged - ? ColorsManager.slidingBlueColor - : ColorsManager.primaryTextColor, - ), - ), - const SizedBox(width: 20), - ], - child: BlocProvider( - create: (context) => SixSceneBloc(sixSceneId: '') - ..add(FetchRoomsEvent(unit: widget.space!)), + String roomIdSelected = ''; + + return Scaffold( + body: BlocProvider( + create: (context) => SixSceneBloc(sixSceneId: deviceId ?? '') + ..add(const SixSceneInitial()) + ..add(const SixSceneInitialInfo()) + ..add(FetchRoomsEvent(unit: space!)), child: BlocBuilder( builder: (context, state) { - final sensor = BlocProvider.of(context); - SixSceneModel model = SixSceneModel( + final _bloc = BlocProvider.of(context); + FourSceneModelState model = FourSceneModelState( scene_1: '', scene_2: '', scene_3: '', scene_4: '', - scene_5: '', - scene_6: '', scene_id_group_id: '', switch_backlight: ''); - List? rooms = []; - if (state is LoadingNewSate) { - model = state.sosSensor; - } else if (state is FetchRoomsState) { - rooms = state.roomsList; + if (state is SaveSelectionSuccessState) { + new Future.delayed(const Duration(microseconds: 500), () { + _bloc.add(SixSceneInitialInfo()); + Navigator.of(context).pop(true); + }); } return state is SixSceneLoadingState ? const Center( @@ -76,52 +55,93 @@ class _LocationSixScenePageState extends State { child: CircularProgressIndicator(), ), ) - : RefreshIndicator( - onRefresh: () async { - sensor.add(const SixSceneInitial()); - }, - child: ListView( - padding: const EdgeInsets.symmetric(vertical: 20), - children: [ - const BodyMedium( - text: 'Smart Device Location', - fontWeight: FontWeight.w700, - fontSize: 12, - fontColor: ColorsManager.grayColor, - ), - const SizedBox(height: 5), - DefaultContainer( - padding: const EdgeInsets.all(20), - child: ListView.builder( - physics: const NeverScrollableScrollPhysics(), - shrinkWrap: true, - itemCount: rooms!.length, - itemBuilder: (context, index) { - final room = rooms![index]; - return Column( - children: [ - _buildCheckboxOption( - label: room.name!, - onTap: (v) { - setState(() { - _selectedOption = v; - _hasSelectionChanged = true; - }); - }, - ), - if (index < rooms.length - 1) ...[ - const SizedBox(height: 10), - const Divider( - color: ColorsManager.dividerColor, - ), - const SizedBox(height: 10), - ], - ], - ); - }, + : DefaultScaffold( + actions: [ + BlocBuilder( + builder: (context, state) { + final bool canSave = state is OptionSelectedState && + state.hasSelectionChanged; + return InkWell( + onTap: canSave + ? () { + context.read().add( + AssignRoomEvent( + context: context, + roomId: roomIdSelected, + unit: space!)); + } + : null, + child: BodyMedium( + text: 'Save', + fontWeight: FontWeight.w700, + fontSize: 16, + fontColor: canSave + ? ColorsManager.slidingBlueColor + : ColorsManager.primaryTextColor, + ), + ); + }, + ), + const SizedBox(width: 20), + ], + child: RefreshIndicator( + onRefresh: () async { + // sensor.add(const SosInitial()); + }, + child: ListView( + shrinkWrap: true, + padding: const EdgeInsets.symmetric(vertical: 20), + children: [ + const BodyMedium( + text: 'Smart Device Location', + fontWeight: FontWeight.w700, + fontSize: 12, + fontColor: ColorsManager.grayColor, ), - ), - ], + const SizedBox(height: 5), + DefaultContainer( + padding: const EdgeInsets.all(20), + child: ListView.builder( + physics: const NeverScrollableScrollPhysics(), + shrinkWrap: true, + itemCount: _bloc.roomsList.length, + itemBuilder: (context, index) { + final fromRoom = _bloc.roomsList[index]; + final isSelected = (state + is OptionSelectedState && + state.selectedOption == fromRoom.id) || + (state is! OptionSelectedState && + fromRoom.id == + _bloc.deviceInfo.subspace.uuid); + + return Column( + children: [ + _buildCheckboxOption( + label: fromRoom.name!, + isSelected: isSelected, + onTap: (label) { + context.read().add( + SelectOptionEvent( + selectedOption: fromRoom.id!, + ), + ); + roomIdSelected = fromRoom.id!; + }, + ), + if (index < _bloc.roomsList.length - 1) ...[ + const SizedBox(height: 10), + const Divider( + color: ColorsManager.dividerColor, + ), + const SizedBox(height: 10), + ], + ], + ); + }, + ), + ), + ], + ), ), ); }, @@ -129,34 +149,6 @@ class _LocationSixScenePageState extends State { ), ); } - - Widget _buildCheckboxOption( - {required String label, required 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; - _hasSelectionChanged = true; - }); - onTap(label); - } - }, - ), - ], - ), - ); - } } class CircularCheckbox extends StatefulWidget { @@ -202,3 +194,33 @@ class _CircularCheckboxState extends State { ); } } + +Widget _buildCheckboxOption({ + required String label, + required bool isSelected, + required 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: isSelected, + onChanged: (bool? value) { + if (value == true) { + onTap(label); + } + }, + ), + ], + ), + ); +} + + +//LocationSixScenePage \ No newline at end of file diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/question_page.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/question_page.dart index a580e3b..26fa712 100644 --- a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/question_page.dart +++ b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/question_page.dart @@ -39,9 +39,9 @@ class QuestionPage extends StatelessWidget { scene_id_group_id: '', switch_backlight: ''); if (state is LoadingNewSate) { - model = state.sosSensor; + model = state.device; } else if (state is UpdateState) { - model = state.sensor; + model = state.device; } return state is SixSceneLoadingState ? const Center( diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/share_six_scene_page.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/share_six_scene_page.dart index 3dc8f28..4bc2806 100644 --- a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/share_six_scene_page.dart +++ b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/share_six_scene_page.dart @@ -38,9 +38,9 @@ class ShareSixScenePage extends StatelessWidget { scene_id_group_id: '', switch_backlight: ''); if (state is LoadingNewSate) { - model = state.sosSensor; + model = state.device; } else if (state is UpdateState) { - model = state.sensor; + model = state.device; } return state is LoadingNewSate ? const Center( diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_create_group.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_create_group.dart index 6585edb..70dd76f 100644 --- a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_create_group.dart +++ b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_create_group.dart @@ -39,9 +39,9 @@ class SixSceneCreateGroup extends StatelessWidget { scene_id_group_id: '', switch_backlight: ''); if (state is LoadingNewSate) { - model = state.sosSensor; + model = state.device; } else if (state is UpdateState) { - model = state.sensor; + model = state.device; } return state is LoadingNewSate ? const Center( diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_info_page.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_info_page.dart index 310f8e5..4d133c8 100644 --- a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_info_page.dart +++ b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_info_page.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart'; import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart'; import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart'; - import 'package:syncrow_app/features/devices/model/device_model.dart'; import 'package:syncrow_app/features/devices/model/six_scene_model.dart'; import 'package:syncrow_app/features/shared_widgets/default_container.dart'; @@ -24,11 +24,12 @@ class SixSceneInfoPage extends StatelessWidget { title: 'Device Information', child: BlocProvider( create: (context) => SixSceneBloc(sixSceneId: device?.uuid ?? '') - ..add(const SixSceneInitial()), + ..add(const SixSceneInitial()) + ..add(const SixSceneInitialInfo()), child: BlocBuilder( builder: (context, state) { - final sensor = BlocProvider.of(context); - SixSceneModel model = SixSceneModel( + final _bloc = BlocProvider.of(context); + SixSceneModel model = SixSceneModel( scene_1: '', scene_2: '', scene_3: '', @@ -38,9 +39,9 @@ class SixSceneInfoPage extends StatelessWidget { scene_id_group_id: '', switch_backlight: ''); if (state is LoadingNewSate) { - model = state.sosSensor; + model = state.device; } else if (state is UpdateState) { - model = state.sensor; + model = state.device; } return state is SixSceneLoadingState ? const Center( @@ -51,11 +52,11 @@ class SixSceneInfoPage extends StatelessWidget { ) : RefreshIndicator( onRefresh: () async { - sensor.add(const SixSceneInitial()); + _bloc.add(const SixSceneInitial()); }, child: DefaultContainer( child: Padding( - padding: const EdgeInsets.only(left: 10, right: 10), + padding: const EdgeInsets.only(left: 5, right: 5), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, @@ -70,12 +71,24 @@ class SixSceneInfoPage extends StatelessWidget { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - const BodySmall( - text: 'bf3575d0e0c8b6e0a6hybl', + BodySmall( + text: _bloc.deviceInfo.productUuid, fontColor: ColorsManager.primaryTextColor, ), InkWell( - onTap: () {}, + onTap: () { + Clipboard.setData( + ClipboardData( + text: _bloc.deviceInfo.productUuid, + ), + ); + + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text("Copied to Clipboard"), + ), + ); + }, child: const Row( children: [ Icon( @@ -94,18 +107,18 @@ class SixSceneInfoPage extends StatelessWidget { const Divider( color: ColorsManager.dividerColor, ), - const Column( + Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - BodyLarge( + const BodyLarge( text: 'MAC', fontSize: 15, fontWeight: FontWeight.w400, fontColor: ColorsManager.blackColor, ), BodySmall( - text: 'bf3575d0e0c8b6e0a6hybl', + text: _bloc.deviceInfo.macAddress, fontColor: ColorsManager.primaryTextColor, ), ], @@ -113,18 +126,18 @@ class SixSceneInfoPage extends StatelessWidget { const Divider( color: ColorsManager.dividerColor, ), - const Column( + Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - BodyLarge( + const BodyLarge( text: 'Time Zone', fontSize: 15, fontWeight: FontWeight.w400, fontColor: ColorsManager.blackColor, ), BodySmall( - text: 'Asia/Dubai', + text: _bloc.deviceInfo.timeZone, fontColor: ColorsManager.primaryTextColor, ), ], diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_profile_page.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_profile_page.dart index 9ca477d..e7c8738 100644 --- a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_profile_page.dart +++ b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_profile_page.dart @@ -5,10 +5,9 @@ import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart'; import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart'; import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart'; import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart'; - import 'package:syncrow_app/features/devices/model/device_model.dart'; import 'package:syncrow_app/features/devices/model/six_scene_model.dart'; -import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/6_scene_setting/location_setting.dart'; +import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_scene_setting/location_setting_four_scene.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_medium.dart'; @@ -26,13 +25,19 @@ class SixSceneProfilePage extends StatelessWidget { return DefaultScaffold( title: 'Device Settings', + leading: IconButton( + onPressed: () { + Navigator.of(context).pop(true); + }, + icon: const Icon(Icons.arrow_back_ios)), child: BlocProvider( create: (context) => SixSceneBloc(sixSceneId: device?.uuid ?? '') - ..add(const SixSceneInitial()), + ..add(const SixSceneInitial()) + ..add(const SixSceneInitialInfo()), child: BlocBuilder( builder: (context, state) { - final sensor = BlocProvider.of(context); - SixSceneModel model = SixSceneModel( + final _bloc = BlocProvider.of(context); + SixSceneModel model = SixSceneModel( scene_1: '', scene_2: '', scene_3: '', @@ -42,9 +47,9 @@ class SixSceneProfilePage extends StatelessWidget { scene_id_group_id: '', switch_backlight: ''); if (state is LoadingNewSate) { - model = state.sosSensor; + model = state.device; } else if (state is UpdateState) { - model = state.sensor; + model = state.device; } return state is SixSceneLoadingState ? const Center( @@ -55,7 +60,7 @@ class SixSceneProfilePage extends StatelessWidget { ) : RefreshIndicator( onRefresh: () async { - sensor.add(const SixSceneInitial()); + _bloc.add(const SixSceneInitial()); }, child: ListView( children: [ @@ -64,11 +69,13 @@ class SixSceneProfilePage extends StatelessWidget { backgroundColor: Colors.white, child: CircleAvatar( radius: 55, - backgroundColor: Colors.grey, + backgroundColor: ColorsManager.graysColor, child: ClipOval( - child: SvgPicture.asset( - Assets.sosProfileIcon, - fit: BoxFit.fill, + child: Center( + child: SvgPicture.asset( + Assets.sixSceneIcon, + fit: BoxFit.cover, + ), ), ), ), @@ -91,11 +98,11 @@ class SixSceneProfilePage extends StatelessWidget { color: Colors.black, ), textAlign: TextAlign.center, - focusNode: sensor.focusNode, - controller: sensor.nameController, - enabled: sensor.editName, + focusNode: _bloc.focusNode, + controller: _bloc.nameController, + enabled: _bloc.editName, onEditingComplete: () { - // sensor.add(SaveNameEvent(context: context)); + _bloc.add(const SaveNameEvent()); }, decoration: const InputDecoration( hintText: "Your Name", @@ -109,8 +116,7 @@ class SixSceneProfilePage extends StatelessWidget { const SizedBox(width: 5), InkWell( onTap: () { - sensor - .add(const ChangeNameEvent(value: true)); + _bloc.add(const ChangeNameEvent(value: true)); }, child: const Padding( padding: EdgeInsets.symmetric(horizontal: 10), @@ -134,29 +140,34 @@ class SixSceneProfilePage extends StatelessWidget { DefaultContainer( padding: const EdgeInsets.all(20), child: InkWell( - onTap: () { - Navigator.of(context).push( + onTap: () async { + bool val = await Navigator.of(context).push( MaterialPageRoute( - builder: (context) => LocationSixScenePage( + builder: (context) => LocationFourScenePage( space: spaces!.first, + deviceId: device?.uuid ?? '', )), ); + if (val == true) { + _bloc.add(const SixSceneInitialInfo()); + } }, - child: const Row( + child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - SizedBox( + const SizedBox( child: Text('Location'), ), Row( children: [ SizedBox( child: BodyMedium( - text: 'Syncroom', + text: _bloc + .deviceInfo.subspace.subspaceName, fontColor: ColorsManager.textGray, ), ), - Icon( + const Icon( Icons.arrow_forward_ios, size: 15, color: ColorsManager.textGray, diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_settings.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_settings.dart index cba5cca..9dca157 100644 --- a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_settings.dart +++ b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_settings.dart @@ -15,7 +15,6 @@ import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/6_scene import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_profile_page.dart'; import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_update_dialog.dart'; import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_update_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_medium.dart'; @@ -34,11 +33,13 @@ class SixSceneSettings extends StatelessWidget { title: 'Device Settings', child: BlocProvider( create: (context) => SixSceneBloc(sixSceneId: device?.uuid ?? '') - ..add(const SixSceneInitial()), + ..add(const SixSceneInitial()) + ..add(const SixSceneInitial()) + ..add(SixSceneInitialInfo()), child: BlocBuilder( builder: (context, state) { - final sensor = BlocProvider.of(context); - SixSceneModel model = SixSceneModel( + final _bloc = BlocProvider.of(context); + SixSceneModel model = SixSceneModel( scene_1: '', scene_2: '', scene_3: '', @@ -48,9 +49,9 @@ class SixSceneSettings extends StatelessWidget { scene_id_group_id: '', switch_backlight: ''); if (state is LoadingNewSate) { - model = state.sosSensor; + model = state.device; } else if (state is UpdateState) { - model = state.sensor; + model = state.device; } return state is SixSceneLoadingState ? const Center( @@ -59,378 +60,374 @@ class SixSceneSettings extends StatelessWidget { height: 50, child: CircularProgressIndicator()), ) - : RefreshIndicator( - onRefresh: () async { - sensor.add(const SixSceneInitial()); - }, - child: ListView( - children: [ - Padding( - padding: const EdgeInsets.symmetric( - vertical: 10, - ), - child: InkWell( - onTap: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => - const SixSceneProfilePage(), + : ListView( + children: [ + Padding( + padding: const EdgeInsets.symmetric( + vertical: 10, + ), + child: InkWell( + onTap: () async { + bool val = await Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => SixSceneProfilePage( + device: device, ), - ); - }, - child: Stack( - children: [ - const Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - SizedBox(height: 20), - DefaultContainer( - borderRadius: - BorderRadius.all(Radius.circular(30)), + ), + ); + if (val == true) { + _bloc.add(const SixSceneInitialInfo()); + } + }, + child: Stack( + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + SizedBox(height: 20), + DefaultContainer( + borderRadius: + BorderRadius.all(Radius.circular(30)), + child: Padding( + padding: EdgeInsets.all(10.0), child: Padding( - padding: EdgeInsets.all(10.0), - child: Padding( - padding: EdgeInsets.only(left: 90), - child: Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - BodyMedium( - text: '6 Scene Switch', - fontWeight: FontWeight.bold, - ), - SizedBox( - height: 5, - ), - BodySmall( - text: "Room: Syncrow"), - ], - ), - Icon(Icons.edit_sharp) - ], - ), + padding: EdgeInsets.only(left: 90), + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + BodyMedium( + text: _bloc.deviceInfo.name, + fontWeight: FontWeight.bold, + ), + SizedBox( + height: 5, + ), + BodySmall( + text: _bloc.deviceInfo + .subspace.subspaceName), + ], + ), + Icon(Icons.edit_sharp) + ], ), ), ), - ], - ), - Positioned( - top: 0, - left: 20, - child: CircleAvatar( - radius: 43, + ), + ], + ), + Positioned( + top: 0, + left: 20, + child: CircleAvatar( + radius: 43, + backgroundColor: Colors.white, + child: CircleAvatar( + radius: 40, backgroundColor: Colors.white, child: CircleAvatar( radius: 40, - backgroundColor: Colors.white, - child: CircleAvatar( - radius: 40, - backgroundColor: - ColorsManager.backgroundColor, - child: SvgPicture.asset( - Assets.sixSceneIcon, - fit: BoxFit.fill, - ), - ), - )), - ), - ], - ), - ), - ), - const SizedBox(height: 20), - const BodyMedium( - text: 'Device Management', - fontWeight: FontWeight.w700, - fontSize: 12, - fontColor: ColorsManager.grayColor, - ), - DefaultContainer( - child: Column( - children: [ - SettingWidget( - onTap: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => - const SixSceneInfoPage()), - ); - }, - text: 'Device Information', - icon: Assets.infoIcon, - ), - const Divider( - color: ColorsManager.dividerColor, - ), - SettingWidget( - onTap: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => - ShareSixScenePage(device: device!)), - ); - }, - text: 'Tap-to Run and Automation', - icon: Assets.tapRunIcon, - ), - ], - ), - ), - const SizedBox(height: 20), - const BodyMedium( - text: 'Device Offline Notification', - fontWeight: FontWeight.w700, - fontSize: 12, - fontColor: ColorsManager.grayColor, - ), - DefaultContainer( - child: Column( - children: [ - SettingWidget( - onChanged: (p0) {}, - isNotification: true, - onTap: () {}, - text: 'Offline Notification', - icon: Assets.notificationIcon, - ), - ], - ), - ), - const SizedBox(height: 20), - const BodyMedium( - text: 'Others', - fontWeight: FontWeight.w700, - fontSize: 12, - fontColor: ColorsManager.grayColor, - ), - const SizedBox(height: 5), - DefaultContainer( - child: Column( - children: [ - SettingWidget( - onTap: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => - ShareSixScenePage(device: device!)), - ); - }, - text: 'Share Device', - icon: Assets.shareIcon, - ), - const Divider( - color: ColorsManager.dividerColor, - ), - SettingWidget( - onTap: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => - SixSceneCreateGroup( - device: device!)), - ); - }, - text: 'Create Group', - icon: Assets.createGroupIcon, - ), - const Divider( - color: ColorsManager.dividerColor, - ), - SettingWidget( - onTap: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => - FaqSixScenePage(device: device!)), - ); - }, - text: 'Device FAQ', - icon: Assets.faqIcon, - ), - const Divider( - color: ColorsManager.dividerColor, - ), - SettingWidget( - onTapUpdate: () { - showDialog( - context: context, - builder: (context) { - return UpdateInfoDialog( - cancelTab: () { - Navigator.of(context).pop(); - }, - confirmTab: () { - // context - // .read< - // CreateSceneBloc>() - // .add(DeleteSceneEvent( - // sceneId: sceneId, - // unitUuid: HomeCubit - // .getInstance() - // .selectedSpace! - // .id!, - // )); - Navigator.of(context).pop(); - }, - ); - }, - ); - }, - isUpdate: true, - onTap: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => - const SixSceneUpdatePage()), - ); - }, - text: 'Device Update', - icon: Assets.updateIcon, - ), - ], - ), - ), - const SizedBox(height: 20), - InkWell( - onTap: () { - showModalBottomSheet( - context: context, - builder: (BuildContext context) { - return Container( - height: 200, - padding: const EdgeInsets.all(16.0), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - const BodyMedium( - text: 'Remove Device', - fontWeight: FontWeight.w700, - fontSize: 16, - fontColor: ColorsManager.red, - ), - const SizedBox(height: 10), - const SizedBox( - width: 250, - child: Divider( - color: ColorsManager.dividerColor, + backgroundColor: + ColorsManager.backgroundColor, + child: SvgPicture.asset( + Assets.sixSceneIcon, + fit: BoxFit.fill, ), ), - const SizedBox(height: 10), - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - InkWell( - onTap: () { - showDialog( - context: context, - builder: (context) { - return DisconnectDeviceDialog( - cancelTab: () { - Navigator.of(context) - .pop(); - }, - confirmTab: () { - // context - // .read< - // CreateSceneBloc>() - // .add(DeleteSceneEvent( - // sceneId: sceneId, - // unitUuid: HomeCubit - // .getInstance() - // .selectedSpace! - // .id!, - // )); - Navigator.of(context) - .pop(); - }, - ); - }, - ); - }, - child: const BodyMedium( - text: 'Disconnect Device', - fontWeight: FontWeight.w400, - fontSize: 15, - fontColor: ColorsManager - .textPrimaryColor, - ), - ), - const Icon( - Icons.keyboard_arrow_right, - color: ColorsManager.textGray, - ) - ], - ), - const SizedBox(height: 20), - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - InkWell( - onTap: () { - showDialog( - context: context, - builder: (context) { - return DisconnectWipeData( - cancelTab: () { - Navigator.of(context) - .pop(); - }, - confirmTab: () { - // context - // .read< - // CreateSceneBloc>() - // .add(DeleteSceneEvent( - // sceneId: sceneId, - // unitUuid: HomeCubit - // .getInstance() - // .selectedSpace! - // .id!, - // )); - Navigator.of(context) - .pop(); - }, - ); - }, - ); - }, - child: const BodyMedium( - text: - 'Disconnect Device and Wipe Data', - fontWeight: FontWeight.w400, - fontSize: 15, - fontColor: ColorsManager - .textPrimaryColor, - ), - ), - const Icon( - Icons.keyboard_arrow_right, - color: ColorsManager.textGray, - ) - ], - ), - ], - ), + )), + ), + ], + ), + ), + ), + const SizedBox(height: 20), + const BodyMedium( + text: 'Device Management', + fontWeight: FontWeight.w700, + fontSize: 12, + fontColor: ColorsManager.grayColor, + ), + DefaultContainer( + child: Column( + children: [ + SettingWidget( + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => SixSceneInfoPage( + device: device, + )), ); }, - ); - }, - child: const Center( - child: BodyMedium( - text: 'Remove Device', - fontWeight: FontWeight.w400, - fontSize: 15, - fontColor: ColorsManager.red, + text: 'Device Information', + icon: Assets.infoIcon, ), + const Divider( + color: ColorsManager.dividerColor, + ), + SettingWidget( + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => + ShareSixScenePage(device: device!)), + ); + }, + text: 'Tap-to Run and Automation', + icon: Assets.tapRunIcon, + ), + ], + ), + ), + const SizedBox(height: 20), + const BodyMedium( + text: 'Device Offline Notification', + fontWeight: FontWeight.w700, + fontSize: 12, + fontColor: ColorsManager.grayColor, + ), + DefaultContainer( + child: Column( + children: [ + SettingWidget( + onChanged: (p0) {}, + isNotification: true, + onTap: () {}, + text: 'Offline Notification', + icon: Assets.notificationIcon, + ), + ], + ), + ), + const SizedBox(height: 20), + const BodyMedium( + text: 'Others', + fontWeight: FontWeight.w700, + fontSize: 12, + fontColor: ColorsManager.grayColor, + ), + const SizedBox(height: 5), + DefaultContainer( + child: Column( + children: [ + SettingWidget( + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => + ShareSixScenePage(device: device!)), + ); + }, + text: 'Share Device', + icon: Assets.shareIcon, + ), + const Divider( + color: ColorsManager.dividerColor, + ), + SettingWidget( + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => + SixSceneCreateGroup(device: device!)), + ); + }, + text: 'Create Group', + icon: Assets.createGroupIcon, + ), + const Divider( + color: ColorsManager.dividerColor, + ), + SettingWidget( + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => + FaqSixScenePage(device: device!)), + ); + }, + text: 'Device FAQ', + icon: Assets.faqIcon, + ), + const Divider( + color: ColorsManager.dividerColor, + ), + SettingWidget( + onTapUpdate: () { + showDialog( + context: context, + builder: (context) { + return UpdateInfoDialog( + cancelTab: () { + Navigator.of(context).pop(); + }, + confirmTab: () { + // context + // .read< + // CreateSceneBloc>() + // .add(DeleteSceneEvent( + // sceneId: sceneId, + // unitUuid: HomeCubit + // .getInstance() + // .selectedSpace! + // .id!, + // )); + Navigator.of(context).pop(); + }, + ); + }, + ); + }, + isUpdate: true, + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => + const SixSceneUpdatePage()), + ); + }, + text: 'Device Update', + icon: Assets.updateIcon, + ), + ], + ), + ), + const SizedBox(height: 20), + InkWell( + onTap: () { + showModalBottomSheet( + context: context, + builder: (BuildContext context) { + return Container( + height: 200, + padding: const EdgeInsets.all(16.0), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const BodyMedium( + text: 'Remove Device', + fontWeight: FontWeight.w700, + fontSize: 16, + fontColor: ColorsManager.red, + ), + const SizedBox(height: 10), + const SizedBox( + width: 250, + child: Divider( + color: ColorsManager.dividerColor, + ), + ), + const SizedBox(height: 10), + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + InkWell( + onTap: () { + showDialog( + context: context, + builder: (context) { + return DisconnectDeviceDialog( + cancelTab: () { + Navigator.of(context).pop(); + }, + confirmTab: () { + // context + // .read< + // CreateSceneBloc>() + // .add(DeleteSceneEvent( + // sceneId: sceneId, + // unitUuid: HomeCubit + // .getInstance() + // .selectedSpace! + // .id!, + // )); + Navigator.of(context).pop(); + }, + ); + }, + ); + }, + child: const BodyMedium( + text: 'Disconnect Device', + fontWeight: FontWeight.w400, + fontSize: 15, + fontColor: + ColorsManager.textPrimaryColor, + ), + ), + const Icon( + Icons.keyboard_arrow_right, + color: ColorsManager.textGray, + ) + ], + ), + const SizedBox(height: 20), + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + InkWell( + onTap: () { + showDialog( + context: context, + builder: (context) { + return DisconnectWipeData( + cancelTab: () { + Navigator.of(context).pop(); + }, + confirmTab: () { + // context + // .read< + // CreateSceneBloc>() + // .add(DeleteSceneEvent( + // sceneId: sceneId, + // unitUuid: HomeCubit + // .getInstance() + // .selectedSpace! + // .id!, + // )); + Navigator.of(context).pop(); + }, + ); + }, + ); + }, + child: const BodyMedium( + text: + 'Disconnect Device and Wipe Data', + fontWeight: FontWeight.w400, + fontSize: 15, + fontColor: + ColorsManager.textPrimaryColor, + ), + ), + const Icon( + Icons.keyboard_arrow_right, + color: ColorsManager.textGray, + ) + ], + ), + ], + ), + ); + }, + ); + }, + child: const Center( + child: BodyMedium( + text: 'Remove Device', + fontWeight: FontWeight.w400, + fontSize: 15, + fontColor: ColorsManager.red, ), ), - ], - ), + ), + ], ); }, ), diff --git a/lib/features/devices/view/widgets/6_scene_switch/six_scene_screen.dart b/lib/features/devices/view/widgets/6_scene_switch/six_scene_screen.dart index 715bdf9..a374b4f 100644 --- a/lib/features/devices/view/widgets/6_scene_switch/six_scene_screen.dart +++ b/lib/features/devices/view/widgets/6_scene_switch/six_scene_screen.dart @@ -58,9 +58,9 @@ class SixSceneScreen extends StatelessWidget { switch_backlight: ''); if (state is LoadingNewSate) { - model = state.sosSensor; + model = state.device; } else if (state is UpdateState) { - model = state.sensor; + model = state.device; } return state is SixSceneLoadingState ? const Center( diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_screen.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_screen.dart index 9019fd3..86bc1d3 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_screen.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_screen.dart @@ -162,17 +162,13 @@ class FourSceneScreen extends StatelessWidget { cancelTab: () { Navigator.of(context).pop(); }, - confirmTab: - (switchSelected) async { + confirmTab: (switchSelected) async { Navigator.of(context).push( MaterialPageRoute( builder: (context) => FourSelectSceneFourPage( - switchSelected: - switchSelected, - deviceId: - device! - .uuid)), + switchSelected:switchSelected, + deviceId: device!.uuid)), ); }, ); diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_info_page.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_info_page.dart index d040eea..9b9aea4 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_info_page.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_info_page.dart @@ -25,7 +25,7 @@ class FourSceneInfoPage extends StatelessWidget { child: BlocProvider( create: (context) => FourSceneBloc(fourSceneId: device?.uuid ?? '') ..add(const FourSceneInitial()) - ..add(FourSceneInitialInfo()), + ..add(const FourSceneInitialInfo()), child: BlocBuilder( builder: (context, state) { final _bloc = BlocProvider.of(context); diff --git a/lib/services/api/devices_api.dart b/lib/services/api/devices_api.dart index f7d5409..b6f4fea 100644 --- a/lib/services/api/devices_api.dart +++ b/lib/services/api/devices_api.dart @@ -189,6 +189,7 @@ class DevicesAPI { path: ApiEndpoints.deviceByUuid.replaceAll('{deviceUuid}', deviceId), showServerMessage: false, expectedResponseModel: (json) { + print('json==$json'); return json; }); return response; From fe55d0a914e1d9a342b316fd5eb5db9917aa6427 Mon Sep 17 00:00:00 2001 From: mohammad Date: Thu, 21 Nov 2024 16:57:41 +0300 Subject: [PATCH 09/29] 4&6scene --- .../6_scene_switch_bloc/6_scene_bloc.dart | 35 ++------- .../6_scene_switch_bloc/6_scene_event.dart | 4 - .../bloc/four_scene_bloc/four_scene_bloc.dart | 5 +- .../6_scene_setting/share_six_scene_page.dart | 12 ++- .../6_scene_setting/six_scene_settings.dart | 73 ++++++++++--------- .../6_scene_switch/six_scene_screen.dart | 1 + .../share_four_scene_page.dart | 12 ++- 7 files changed, 70 insertions(+), 72 deletions(-) diff --git a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart index 4ba5bf0..1a9a224 100644 --- a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart +++ b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart @@ -41,10 +41,10 @@ class SixSceneBloc extends Bloc { on(getSceneByName); on(_selectScene); on(fetchDeviceInfo); - on(_controlDevice); on(saveName); on(_assignDevice); on(_fetchRoomsAndDevices); + on(_onSixSceneInitial); } final TextEditingController nameController = @@ -358,12 +358,14 @@ class SixSceneBloc extends Bloc { value: switchStatus), sixSceneId); deviceStatus.switch_backlight = switchStatus; - if (!response['success']) { - add(const SixSceneInitial()); - } - emit(ChangeSwitchState(isEnable: switchStatus)); - } catch (_) { + add(const SixSceneInitial()); + add(const SexSceneSwitchInitial()); + + emit(ChangeSwitchState(isEnable: switchStatus)); + emit(UpdateState(device: deviceStatus)); + } catch (_) { + emit(const SixSceneFailedState(errorMessage: 'Something went wrong')); } } @@ -455,27 +457,6 @@ class SixSceneBloc extends Bloc { emit(UpdateStateList(groupDevices: groupDevices, devices: devices)); } - void _controlDevice( - ControlDeviceScene event, Emitter emit) async { - emit(SixSceneLoadingState()); - try { - deviceStatus.switch_backlight = !event.backLight!; - emit(UpdateState(device: deviceStatus)); - final response = await DevicesAPI.controlDevice( - DeviceControlModel( - deviceId: sixSceneId, - code: 'switch_backlight', - value: !event.backLight!), - sixSceneId); - - if (!response['success']) { - // add(InitialEvent(groupScreen: oneTouchGroup)); - } - } catch (_) { - // add(InitialEvent(groupScreen: oneTouchGroup)); - } - } - bool _validateInputs() { final nameError = fullNameValidator(nameController.text); if (nameError != null) { diff --git a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart index fba85f7..b091103 100644 --- a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart +++ b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart @@ -202,10 +202,6 @@ class AssignDeviceScene extends SixSceneEvent { }); } -class ControlDeviceScene extends SixSceneEvent { - final bool? backLight; - const ControlDeviceScene({this.backLight}); -} class AssignRoomEvent extends SixSceneEvent { final String roomId; diff --git a/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart b/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart index c432bc3..a21c100 100644 --- a/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart +++ b/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart @@ -394,9 +394,8 @@ class FourSceneBloc extends Bloc { value: switchStatus), fourSceneId); deviceStatus.switch_backlight = switchStatus; - if (!response['success']) { - add(const FourSceneInitial()); - } + add(const FourSceneInitial()); + emit(ChangeSwitchState(isEnable: switchStatus)); } catch (_) { add(const FourSceneInitial()); diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/share_six_scene_page.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/share_six_scene_page.dart index 4bc2806..ae38850 100644 --- a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/share_six_scene_page.dart +++ b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/share_six_scene_page.dart @@ -1,16 +1,19 @@ 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/6_scene_switch_bloc/6_scene_bloc.dart'; import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart'; import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart'; import 'package:syncrow_app/features/devices/model/device_model.dart'; import 'package:syncrow_app/features/devices/model/six_scene_model.dart'; +import 'package:syncrow_app/features/menu/view/widgets/manage_home/home_settings.dart'; import 'package:syncrow_app/features/shared_widgets/default_button.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/helpers/custom_page_route.dart'; import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; class ShareSixScenePage extends StatelessWidget { @@ -20,6 +23,8 @@ class ShareSixScenePage extends StatelessWidget { @override Widget build(BuildContext context) { + var spaces = HomeCubit.getInstance().spaces; + return DefaultScaffold( title: 'Share Device', child: BlocProvider( @@ -94,7 +99,12 @@ class ShareSixScenePage extends StatelessWidget { child: DefaultButton( backgroundColor: ColorsManager.blueColor1, borderRadius: 50, - onPressed: () {}, + onPressed: () { + Navigator.of(context).push(CustomPageRoute( + builder: (context) => HomeSettingsView( + space: spaces!.first, + ))); + }, child: Text('Add Home Member')), ), ) diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_settings.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_settings.dart index 9dca157..e06f04d 100644 --- a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_settings.dart +++ b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_settings.dart @@ -35,7 +35,7 @@ class SixSceneSettings extends StatelessWidget { create: (context) => SixSceneBloc(sixSceneId: device?.uuid ?? '') ..add(const SixSceneInitial()) ..add(const SixSceneInitial()) - ..add(SixSceneInitialInfo()), + ..add(const SixSceneInitialInfo()), child: BlocBuilder( builder: (context, state) { final _bloc = BlocProvider.of(context); @@ -84,14 +84,15 @@ class SixSceneSettings extends StatelessWidget { Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - SizedBox(height: 20), + const SizedBox(height: 20), DefaultContainer( - borderRadius: - BorderRadius.all(Radius.circular(30)), + borderRadius: const BorderRadius.all( + Radius.circular(30)), child: Padding( - padding: EdgeInsets.all(10.0), + padding: const EdgeInsets.all(10.0), child: Padding( - padding: EdgeInsets.only(left: 90), + padding: + const EdgeInsets.only(left: 90), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -104,7 +105,7 @@ class SixSceneSettings extends StatelessWidget { text: _bloc.deviceInfo.name, fontWeight: FontWeight.bold, ), - SizedBox( + const SizedBox( height: 5, ), BodySmall( @@ -112,7 +113,7 @@ class SixSceneSettings extends StatelessWidget { .subspace.subspaceName), ], ), - Icon(Icons.edit_sharp) + const Icon(Icons.edit_sharp) ], ), ), @@ -166,20 +167,20 @@ class SixSceneSettings extends StatelessWidget { text: 'Device Information', icon: Assets.infoIcon, ), - const Divider( - color: ColorsManager.dividerColor, - ), - SettingWidget( - onTap: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => - ShareSixScenePage(device: device!)), - ); - }, - text: 'Tap-to Run and Automation', - icon: Assets.tapRunIcon, - ), + // const Divider( + // color: ColorsManager.dividerColor, + // ), + // SettingWidget( + // onTap: () { + // Navigator.of(context).push( + // MaterialPageRoute( + // builder: (context) => + // ShareSixScenePage(device: device!)), + // ); + // }, + // text: 'Tap-to Run and Automation', + // icon: Assets.tapRunIcon, + // ), ], ), ), @@ -225,20 +226,20 @@ class SixSceneSettings extends StatelessWidget { text: 'Share Device', icon: Assets.shareIcon, ), - const Divider( - color: ColorsManager.dividerColor, - ), - SettingWidget( - onTap: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => - SixSceneCreateGroup(device: device!)), - ); - }, - text: 'Create Group', - icon: Assets.createGroupIcon, - ), + // const Divider( + // color: ColorsManager.dividerColor, + // ), + // SettingWidget( + // onTap: () { + // Navigator.of(context).push( + // MaterialPageRoute( + // builder: (context) => + // SixSceneCreateGroup(device: device!)), + // ); + // }, + // text: 'Create Group', + // icon: Assets.createGroupIcon, + // ), const Divider( color: ColorsManager.dividerColor, ), diff --git a/lib/features/devices/view/widgets/6_scene_switch/six_scene_screen.dart b/lib/features/devices/view/widgets/6_scene_switch/six_scene_screen.dart index a374b4f..60ea4c8 100644 --- a/lib/features/devices/view/widgets/6_scene_switch/six_scene_screen.dart +++ b/lib/features/devices/view/widgets/6_scene_switch/six_scene_screen.dart @@ -136,6 +136,7 @@ class SixSceneScreen extends StatelessWidget { child: DefaultContainer( onTap: () { _bloc.add(ChangeSwitchStatusEvent()); + }, child: Column( crossAxisAlignment: diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/share_four_scene_page.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/share_four_scene_page.dart index 890ef9d..e0db463 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/share_four_scene_page.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/share_four_scene_page.dart @@ -1,15 +1,18 @@ 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/four_scene_bloc/four_scene_bloc.dart'; import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_event.dart'; import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_state.dart'; import 'package:syncrow_app/features/devices/model/device_model.dart'; import 'package:syncrow_app/features/devices/model/four_scene_model.dart'; +import 'package:syncrow_app/features/menu/view/widgets/manage_home/home_settings.dart'; import 'package:syncrow_app/features/shared_widgets/default_button.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/helpers/custom_page_route.dart'; import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; class ShareFourScenePage extends StatelessWidget { @@ -17,6 +20,8 @@ class ShareFourScenePage extends StatelessWidget { const ShareFourScenePage({super.key, this.device}); @override Widget build(BuildContext context) { + var spaces = HomeCubit.getInstance().spaces; + return DefaultScaffold( title: 'Share Device', child: BlocProvider( @@ -89,7 +94,12 @@ class ShareFourScenePage extends StatelessWidget { child: DefaultButton( backgroundColor: ColorsManager.blueColor1, borderRadius: 50, - onPressed: () {}, + onPressed: () { + Navigator.of(context).push(CustomPageRoute( + builder: (context) => HomeSettingsView( + space: spaces!.first, + ))); + }, child: Text('Add Home Member')), ), ) From 9f02ce8a311b93bc971546a1fab435b539b7ee9b Mon Sep 17 00:00:00 2001 From: mohammad Date: Thu, 21 Nov 2024 17:05:58 +0300 Subject: [PATCH 10/29] 4&6scene --- assets/icons/four_scene_icon.svg | 67 ++ .../6_scene_switch_bloc/6_scene_bloc.dart | 1 - .../four_scene_settings.dart | 758 +++++++++--------- 3 files changed, 439 insertions(+), 387 deletions(-) create mode 100644 assets/icons/four_scene_icon.svg diff --git a/assets/icons/four_scene_icon.svg b/assets/icons/four_scene_icon.svg new file mode 100644 index 0000000..414d952 --- /dev/null +++ b/assets/icons/four_scene_icon.svg @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart index 1a9a224..9d4c3f4 100644 --- a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart +++ b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart @@ -268,7 +268,6 @@ class SixSceneBloc extends Bloc { void _onSearchFaq(SearchFaqEvent event, Emitter emit) { emit(SixSceneLoadingState()); - // Filter FAQ questions based on search query List _faqQuestions = faqQuestions.where((question) { return question.question .toLowerCase() diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart index 454036e..f500bed 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart @@ -8,7 +8,6 @@ import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_sta import 'package:syncrow_app/features/devices/model/device_model.dart'; import 'package:syncrow_app/features/devices/model/four_scene_model.dart'; import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_scene_setting/faq_four_scene_page.dart'; -import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_create_group.dart'; import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_delete_dialog.dart'; import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_info_page.dart'; import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_profile_page.dart'; @@ -34,7 +33,7 @@ class FourSceneSettings extends StatelessWidget { child: BlocProvider( create: (context) => FourSceneBloc(fourSceneId: device?.uuid ?? '') ..add(const FourSceneInitial()) - ..add(FourSceneInitialInfo()), + ..add(const FourSceneInitialInfo()), child: BlocBuilder( builder: (context, state) { final _bloc = BlocProvider.of(context); @@ -57,405 +56,392 @@ class FourSceneSettings extends StatelessWidget { height: 50, child: CircularProgressIndicator()), ) - : RefreshIndicator( - onRefresh: () async { - _bloc.add(const FourSceneInitial()); - }, - child: ListView( - children: [ - Padding( - padding: const EdgeInsets.symmetric( - vertical: 10, - ), - child: InkWell( - onTap: () async { - bool val = await Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => FourSceneProfilePage( - device: device, - ), + : ListView( + children: [ + Padding( + padding: const EdgeInsets.symmetric( + vertical: 10, + ), + child: InkWell( + onTap: () async { + bool val = await Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => FourSceneProfilePage( + device: device, ), - ); - if (val == true) { - _bloc.add(FourSceneInitialInfo()); - } - }, - child: Stack( - children: [ - Column( - crossAxisAlignment: - CrossAxisAlignment.stretch, - children: [ - const SizedBox(height: 20), - DefaultContainer( - borderRadius: const BorderRadius.all( - Radius.circular(30)), + ), + ); + if (val == true) { + _bloc.add(FourSceneInitialInfo()); + } + }, + child: Stack( + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + const SizedBox(height: 20), + DefaultContainer( + borderRadius: const BorderRadius.all( + Radius.circular(30)), + child: Padding( + padding: const EdgeInsets.all(10.0), child: Padding( - padding: const EdgeInsets.all(10.0), - child: Padding( - padding: - const EdgeInsets.only(left: 90), - child: Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - BodyMedium( - text: _bloc.deviceInfo.name, - fontWeight: FontWeight.bold, - ), - const SizedBox( - height: 5, - ), - BodySmall( - text: _bloc - .deviceInfo - .subspace - .subspaceName), - ], - ), - const Icon(Icons.edit_sharp) - ], - ), + padding: + const EdgeInsets.only(left: 90), + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + BodyMedium( + text: _bloc.deviceInfo.name, + fontWeight: FontWeight.bold, + ), + const SizedBox( + height: 5, + ), + BodySmall( + text: _bloc.deviceInfo + .subspace.subspaceName), + ], + ), + const Icon(Icons.edit_sharp) + ], ), ), ), - ], - ), - Positioned( - top: 0, - left: 20, - child: CircleAvatar( - radius: 43, + ), + ], + ), + Positioned( + top: 0, + left: 20, + child: CircleAvatar( + radius: 43, + backgroundColor: Colors.white, + child: CircleAvatar( + radius: 40, backgroundColor: Colors.white, child: CircleAvatar( radius: 40, - backgroundColor: Colors.white, - child: CircleAvatar( - radius: 40, - backgroundColor: - ColorsManager.backgroundColor, - child: Column( - crossAxisAlignment: - CrossAxisAlignment.center, - mainAxisAlignment: - MainAxisAlignment.center, - children: [ - Padding( - padding: const EdgeInsets.only( - top: 8), - child: SizedBox( - height: 70, - child: SvgPicture.asset( - Assets.fourSceneIcon, - fit: BoxFit.contain, - ), + backgroundColor: + ColorsManager.backgroundColor, + child: Column( + crossAxisAlignment: + CrossAxisAlignment.center, + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + Padding( + padding: + const EdgeInsets.only(top: 8), + child: SizedBox( + height: 70, + child: SvgPicture.asset( + Assets.fourSceneIcon, + fit: BoxFit.contain, ), ), - ], - ), - ), - )), - ), - ], - ), - ), - ), - const SizedBox(height: 20), - const BodyMedium( - text: 'Device Management', - fontWeight: FontWeight.w700, - fontSize: 12, - fontColor: ColorsManager.grayColor, - ), - DefaultContainer( - child: Column( - children: [ - SettingWidget( - onTap: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => FourSceneInfoPage( - device: device!, - )), - ); - }, - text: 'Device Information', - icon: Assets.infoIcon, - ), - const Divider( - color: ColorsManager.dividerColor, - ), - SettingWidget( - onTap: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => - ShareFourScenePage( - device: device!)), - ); - }, - text: 'Tap-to Run and Automation', - icon: Assets.tapRunIcon, - ), - ], - ), - ), - const SizedBox(height: 20), - const BodyMedium( - text: 'Device Offline Notification', - fontWeight: FontWeight.w700, - fontSize: 12, - fontColor: ColorsManager.grayColor, - ), - DefaultContainer( - child: Column( - children: [ - SettingWidget( - onChanged: (p0) {}, - isNotification: true, - onTap: () {}, - text: 'Offline Notification', - icon: Assets.notificationIcon, - ), - ], - ), - ), - const SizedBox(height: 20), - const BodyMedium( - text: 'Others', - fontWeight: FontWeight.w700, - fontSize: 12, - fontColor: ColorsManager.grayColor, - ), - const SizedBox(height: 5), - DefaultContainer( - child: Column( - children: [ - SettingWidget( - onTap: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => - ShareFourScenePage( - device: device!)), - ); - }, - text: 'Share Device', - icon: Assets.shareIcon, - ), - const Divider( - color: ColorsManager.dividerColor, - ), - SettingWidget( - onTap: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => - FourSceneCreateGroup( - device: device!)), - ); - }, - text: 'Create Group', - icon: Assets.createGroupIcon, - ), - const Divider( - color: ColorsManager.dividerColor, - ), - SettingWidget( - onTap: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => - FaqFourScenePage(device: device!)), - ); - }, - text: 'Device FAQ', - icon: Assets.faqIcon, - ), - const Divider( - color: ColorsManager.dividerColor, - ), - SettingWidget( - onTapUpdate: () { - showDialog( - context: context, - builder: (context) { - return UpdateInfoDialog( - cancelTab: () { - Navigator.of(context).pop(); - }, - confirmTab: () { - // context - // .read< - // CreateSceneBloc>() - // .add(DeleteSceneEvent( - // sceneId: sceneId, - // unitUuid: HomeCubit - // .getInstance() - // .selectedSpace! - // .id!, - // )); - Navigator.of(context).pop(); - }, - ); - }, - ); - }, - isUpdate: true, - onTap: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => - const FourSceneUpdatePage()), - ); - }, - text: 'Device Update', - icon: Assets.updateIcon, - ), - ], - ), - ), - const SizedBox(height: 20), - InkWell( - onTap: () { - showModalBottomSheet( - context: context, - builder: (BuildContext context) { - return Container( - height: 200, - padding: const EdgeInsets.all(16.0), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - const BodyMedium( - text: 'Remove Device', - fontWeight: FontWeight.w700, - fontSize: 16, - fontColor: ColorsManager.red, - ), - const SizedBox(height: 10), - const SizedBox( - width: 250, - child: Divider( - color: ColorsManager.dividerColor, + ), + ], ), ), - const SizedBox(height: 10), - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - InkWell( - onTap: () { - showDialog( - context: context, - builder: (context) { - return DisconnectDeviceDialog( - cancelTab: () { - Navigator.of(context) - .pop(); - }, - confirmTab: () { - // context - // .read< - // CreateSceneBloc>() - // .add(DeleteSceneEvent( - // sceneId: sceneId, - // unitUuid: HomeCubit - // .getInstance() - // .selectedSpace! - // .id!, - // )); - Navigator.of(context) - .pop(); - }, - ); - }, - ); - }, - child: const BodyMedium( - text: 'Disconnect Device', - fontWeight: FontWeight.w400, - fontSize: 15, - fontColor: ColorsManager - .textPrimaryColor, - ), - ), - const Icon( - Icons.keyboard_arrow_right, - color: ColorsManager.textGray, - ) - ], - ), - const SizedBox(height: 20), - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - InkWell( - onTap: () { - showDialog( - context: context, - builder: (context) { - return DisconnectWipeData( - cancelTab: () { - Navigator.of(context) - .pop(); - }, - confirmTab: () { - // context - // .read< - // CreateSceneBloc>() - // .add(DeleteSceneEvent( - // sceneId: sceneId, - // unitUuid: HomeCubit - // .getInstance() - // .selectedSpace! - // .id!, - // )); - Navigator.of(context) - .pop(); - }, - ); - }, - ); - }, - child: const BodyMedium( - text: - 'Disconnect Device and Wipe Data', - fontWeight: FontWeight.w400, - fontSize: 15, - fontColor: ColorsManager - .textPrimaryColor, - ), - ), - const Icon( - Icons.keyboard_arrow_right, - color: ColorsManager.textGray, - ) - ], - ), - ], - ), + )), + ), + ], + ), + ), + ), + const SizedBox(height: 20), + const BodyMedium( + text: 'Device Management', + fontWeight: FontWeight.w700, + fontSize: 12, + fontColor: ColorsManager.grayColor, + ), + DefaultContainer( + child: Column( + children: [ + SettingWidget( + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => FourSceneInfoPage( + device: device!, + )), ); }, - ); - }, - child: const Center( - child: BodyMedium( - text: 'Remove Device', - fontWeight: FontWeight.w400, - fontSize: 15, - fontColor: ColorsManager.red, + text: 'Device Information', + icon: Assets.infoIcon, ), + // const Divider( + // color: ColorsManager.dividerColor, + // ), + // SettingWidget( + // onTap: () { + // Navigator.of(context).push( + // MaterialPageRoute( + // builder: (context) => + // ShareFourScenePage( + // device: device!)), + // ); + // }, + // text: 'Tap-to Run and Automation', + // icon: Assets.tapRunIcon, + // ), + ], + ), + ), + const SizedBox(height: 20), + const BodyMedium( + text: 'Device Offline Notification', + fontWeight: FontWeight.w700, + fontSize: 12, + fontColor: ColorsManager.grayColor, + ), + DefaultContainer( + child: Column( + children: [ + SettingWidget( + onChanged: (p0) {}, + isNotification: true, + onTap: () {}, + text: 'Offline Notification', + icon: Assets.notificationIcon, + ), + ], + ), + ), + const SizedBox(height: 20), + const BodyMedium( + text: 'Others', + fontWeight: FontWeight.w700, + fontSize: 12, + fontColor: ColorsManager.grayColor, + ), + const SizedBox(height: 5), + DefaultContainer( + child: Column( + children: [ + SettingWidget( + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => + ShareFourScenePage(device: device!)), + ); + }, + text: 'Share Device', + icon: Assets.shareIcon, + ), + // const Divider( + // color: ColorsManager.dividerColor, + // ), + // SettingWidget( + // onTap: () { + // Navigator.of(context).push( + // MaterialPageRoute( + // builder: (context) => + // FourSceneCreateGroup( + // device: device!)), + // ); + // }, + // text: 'Create Group', + // icon: Assets.createGroupIcon, + // ), + const Divider( + color: ColorsManager.dividerColor, + ), + SettingWidget( + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => + FaqFourScenePage(device: device!)), + ); + }, + text: 'Device FAQ', + icon: Assets.faqIcon, + ), + const Divider( + color: ColorsManager.dividerColor, + ), + SettingWidget( + onTapUpdate: () { + showDialog( + context: context, + builder: (context) { + return UpdateInfoDialog( + cancelTab: () { + Navigator.of(context).pop(); + }, + confirmTab: () { + // context + // .read< + // CreateSceneBloc>() + // .add(DeleteSceneEvent( + // sceneId: sceneId, + // unitUuid: HomeCubit + // .getInstance() + // .selectedSpace! + // .id!, + // )); + Navigator.of(context).pop(); + }, + ); + }, + ); + }, + isUpdate: true, + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => + const FourSceneUpdatePage()), + ); + }, + text: 'Device Update', + icon: Assets.updateIcon, + ), + ], + ), + ), + const SizedBox(height: 20), + InkWell( + onTap: () { + showModalBottomSheet( + context: context, + builder: (BuildContext context) { + return Container( + height: 200, + padding: const EdgeInsets.all(16.0), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const BodyMedium( + text: 'Remove Device', + fontWeight: FontWeight.w700, + fontSize: 16, + fontColor: ColorsManager.red, + ), + const SizedBox(height: 10), + const SizedBox( + width: 250, + child: Divider( + color: ColorsManager.dividerColor, + ), + ), + const SizedBox(height: 10), + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + InkWell( + onTap: () { + showDialog( + context: context, + builder: (context) { + return DisconnectDeviceDialog( + cancelTab: () { + Navigator.of(context).pop(); + }, + confirmTab: () { + // context + // .read< + // CreateSceneBloc>() + // .add(DeleteSceneEvent( + // sceneId: sceneId, + // unitUuid: HomeCubit + // .getInstance() + // .selectedSpace! + // .id!, + // )); + Navigator.of(context).pop(); + }, + ); + }, + ); + }, + child: const BodyMedium( + text: 'Disconnect Device', + fontWeight: FontWeight.w400, + fontSize: 15, + fontColor: + ColorsManager.textPrimaryColor, + ), + ), + const Icon( + Icons.keyboard_arrow_right, + color: ColorsManager.textGray, + ) + ], + ), + const SizedBox(height: 20), + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + InkWell( + onTap: () { + showDialog( + context: context, + builder: (context) { + return DisconnectWipeData( + cancelTab: () { + Navigator.of(context).pop(); + }, + confirmTab: () { + // context + // .read< + // CreateSceneBloc>() + // .add(DeleteSceneEvent( + // sceneId: sceneId, + // unitUuid: HomeCubit + // .getInstance() + // .selectedSpace! + // .id!, + // )); + Navigator.of(context).pop(); + }, + ); + }, + ); + }, + child: const BodyMedium( + text: + 'Disconnect Device and Wipe Data', + fontWeight: FontWeight.w400, + fontSize: 15, + fontColor: + ColorsManager.textPrimaryColor, + ), + ), + const Icon( + Icons.keyboard_arrow_right, + color: ColorsManager.textGray, + ) + ], + ), + ], + ), + ); + }, + ); + }, + child: const Center( + child: BodyMedium( + text: 'Remove Device', + fontWeight: FontWeight.w400, + fontSize: 15, + fontColor: ColorsManager.red, ), ), - ], - ), + ), + ], ); }, ), @@ -495,7 +481,7 @@ class SettingWidget extends StatelessWidget { Expanded( flex: 2, child: Container( - padding: EdgeInsets.all(8), + padding: const EdgeInsets.all(8), decoration: const BoxDecoration( color: ColorsManager.primaryColor, borderRadius: BorderRadius.all(Radius.circular(20))), @@ -522,7 +508,7 @@ class SettingWidget extends StatelessWidget { isUpdate == true ? InkWell( onTap: onTapUpdate, - child: BodyMedium( + child: const BodyMedium( text: '1 Update Available', fontSize: 13, fontWeight: FontWeight.w400, From 3d17c588c51992e3a747d5db62a2c88bfb14fdf4 Mon Sep 17 00:00:00 2001 From: mohammad Date: Sun, 24 Nov 2024 10:48:25 +0300 Subject: [PATCH 11/29] 4 and 6 scene --- .../6_scene_switch_bloc/6_scene_bloc.dart | 25 ++++- .../6_scene_switch_bloc/6_scene_event.dart | 1 + .../bloc/four_scene_bloc/four_scene_bloc.dart | 62 +++++++---- .../four_scene_bloc/four_scene_event.dart | 5 +- .../6_scene_setting/faq_six_scene_page.dart | 99 ++++++++--------- .../6_scene_setting/six_scene_settings.dart | 14 +-- .../6_scene_switch/select_switch_dialog.dart | 11 +- .../6_scene_switch/six_scene_screen.dart | 9 +- .../faq_four_scene_page.dart | 100 +++++++++--------- .../four_scene_settings.dart | 13 +-- .../four_select_switch_dialog.dart | 11 +- lib/generated/assets.dart | 2 - lib/services/api/api_links_endpoints.dart | 4 + lib/services/api/devices_api.dart | 16 +++ lib/services/api/spaces_api.dart | 2 + 15 files changed, 210 insertions(+), 164 deletions(-) diff --git a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart index 9d4c3f4..08c1051 100644 --- a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart +++ b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart @@ -34,7 +34,7 @@ class SixSceneBloc extends Bloc { on(searchScene); on(_onSaveSelection); on(_onOptionSelected); - on(_addDeviceToGroup); // Register handler here + on(_addDeviceToGroup); on(_removeDeviceFromGroup); on(_fetchFourSceneSwitches); on(assignScene); @@ -45,6 +45,7 @@ class SixSceneBloc extends Bloc { on(_assignDevice); on(_fetchRoomsAndDevices); on(_onSixSceneInitial); + on(deleteDevice); } final TextEditingController nameController = @@ -138,6 +139,17 @@ class SixSceneBloc extends Bloc { } } + deleteDevice(DeleteDeviceEvent event, Emitter emit) async { + try { + emit(SixSceneLoadingState()); + var response = await DevicesAPI.resetDevise(devicesUuid: sixSceneId); + add(const SixSceneInitialInfo()); + CustomSnackBar.displaySnackBar('Reset Successfully'); + } catch (e) { + emit(SixSceneFailedState(errorMessage: e.toString())); + } + } + Future saveName( SaveNameEvent event, Emitter emit) async { if (_validateInputs()) return; @@ -358,11 +370,14 @@ class SixSceneBloc extends Bloc { sixSceneId); deviceStatus.switch_backlight = switchStatus; - add(const SixSceneInitial()); - add(const SexSceneSwitchInitial()); + Future.delayed(const Duration(milliseconds: 250), () { + add(const SexSceneSwitchInitial()); + }); - emit(ChangeSwitchState(isEnable: switchStatus)); - emit(UpdateState(device: deviceStatus)); + Future.delayed(const Duration(milliseconds: 250), () { + emit(ChangeSwitchState(isEnable: switchStatus)); + emit(UpdateState(device: deviceStatus)); + }); } catch (_) { emit(const SixSceneFailedState(errorMessage: 'Something went wrong')); } diff --git a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart index b091103..7efceb6 100644 --- a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart +++ b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart @@ -116,6 +116,7 @@ class TickTimer extends SixSceneEvent { class StopTimer extends SixSceneEvent {} class OnClose extends SixSceneEvent {} +class DeleteDeviceEvent extends SixSceneEvent {} class ChangeNameEvent extends SixSceneEvent { final bool? value; diff --git a/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart b/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart index a21c100..b5aaad0 100644 --- a/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart +++ b/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart @@ -42,11 +42,11 @@ class FourSceneBloc extends Bloc { on(_removeDeviceFromGroup); on(_onFourSceneInitial); on(_fetchDeviceScene); - on(_controlDevice); on(_fetchFourSceneSwitches); on(assignScene); on(getSceneByName); on(_selectScene); + on(deleteDevice); } final TextEditingController nameController = @@ -190,6 +190,18 @@ class FourSceneBloc extends Bloc { } } + deleteDevice(DeleteDeviceEvent event, Emitter emit) async { + try { + emit(FourSceneLoadingState()); + var response = await DevicesAPI.resetDevise(devicesUuid: fourSceneId); + CustomSnackBar.displaySnackBar('Reset Successfully'); + emit(UpdateState(device: deviceStatus)); + } catch (e) { + emit(FourSceneFailedState(errorMessage: e.toString())); + return; + } + } + void _fetchDeviceStatus( FourSceneInitial event, Emitter emit) async { emit(FourSceneLoadingState()); @@ -246,26 +258,26 @@ class FourSceneBloc extends Bloc { } } - void _controlDevice( - ControlDeviceScene event, Emitter emit) async { - emit(FourSceneLoadingState()); - try { - deviceStatus.switch_backlight = !event.backLight!; - emit(UpdateState(device: deviceStatus)); - final response = await DevicesAPI.controlDevice( - DeviceControlModel( - deviceId: fourSceneId, - code: 'switch_backlight', - value: !event.backLight!), - fourSceneId); + // void _controlDevice( + // ControlDeviceScene event, Emitter emit) async { + // emit(FourSceneLoadingState()); + // try { + // deviceStatus.switch_backlight = !event.backLight!; + // emit(UpdateState(device: deviceStatus)); + // final response = await DevicesAPI.controlDevice( + // DeviceControlModel( + // deviceId: fourSceneId, + // code: 'switch_backlight', + // value: !event.backLight!), + // fourSceneId); - if (!response['success']) { - // add(InitialEvent(groupScreen: oneTouchGroup)); - } - } catch (_) { - // add(InitialEvent(groupScreen: oneTouchGroup)); - } - } + // if (!response['success']) { + // // add(InitialEvent(groupScreen: oneTouchGroup)); + // } + // } catch (_) { + // // add(InitialEvent(groupScreen: oneTouchGroup)); + // } + // } Future fetchDeviceInfo( FourSceneInitialInfo event, Emitter emit) async { @@ -394,9 +406,13 @@ class FourSceneBloc extends Bloc { value: switchStatus), fourSceneId); deviceStatus.switch_backlight = switchStatus; - add(const FourSceneInitial()); - - emit(ChangeSwitchState(isEnable: switchStatus)); + Future.delayed(const Duration(milliseconds: 200), () { + add(const FourSceneSwitchInitial()); + }); + Future.delayed(const Duration(milliseconds: 200), () { + emit(ChangeSwitchState(isEnable: switchStatus)); + emit(UpdateState(device: deviceStatus)); + }); } catch (_) { add(const FourSceneInitial()); } diff --git a/lib/features/devices/bloc/four_scene_bloc/four_scene_event.dart b/lib/features/devices/bloc/four_scene_bloc/four_scene_event.dart index 6e4d9d1..52ed6ee 100644 --- a/lib/features/devices/bloc/four_scene_bloc/four_scene_event.dart +++ b/lib/features/devices/bloc/four_scene_bloc/four_scene_event.dart @@ -108,6 +108,7 @@ class TickTimer extends FourSceneEvent { class StopTimer extends FourSceneEvent {} class OnClose extends FourSceneEvent {} +class DeleteDeviceEvent extends FourSceneEvent {} class ChangeNameEvent extends FourSceneEvent { final bool? value; @@ -206,10 +207,6 @@ class AssignRoomEvent extends FourSceneEvent { class FetchDeviceScene extends FourSceneEvent {} -class ControlDeviceScene extends FourSceneEvent { - final bool? backLight; - const ControlDeviceScene({this.backLight}); -} class FourSceneSwitchInitial extends FourSceneEvent { const FourSceneSwitchInitial(); diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/faq_six_scene_page.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/faq_six_scene_page.dart index e22f0aa..d843fd6 100644 --- a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/faq_six_scene_page.dart +++ b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/faq_six_scene_page.dart @@ -89,57 +89,58 @@ class FaqSixScenePage extends StatelessWidget { fontSize: 12, fontColor: ColorsManager.grayColor, ), - Expanded( - child: DefaultContainer( - child: ListView.builder( - shrinkWrap: true, - itemCount: displayedQuestions.length, - itemBuilder: (context, index) { - final faq = displayedQuestions[index]; - return InkWell( - onTap: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => QuestionPage( - questionModel: faq, - )), + displayedQuestions.isEmpty + ? const SizedBox() + : DefaultContainer( + child: ListView.builder( + shrinkWrap: true, + itemCount: displayedQuestions.length, + itemBuilder: (context, index) { + final faq = displayedQuestions[index]; + return InkWell( + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => QuestionPage( + questionModel: faq, + )), + ); + }, + child: SizedBox( + child: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Row( + children: [ + Expanded( + child: BodyMedium( + fontSize: 14, + fontWeight: FontWeight.w400, + text: faq.question, + ), + ), + const Icon( + Icons.keyboard_arrow_right, + color: ColorsManager.textGray, + ), + ], + ), + ), + const Divider( + color: ColorsManager.dividerColor, + ), + ], + ), + ), ); }, - child: SizedBox( - child: Column( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.all(8.0), - child: Row( - children: [ - Expanded( - child: BodyMedium( - fontSize: 14, - fontWeight: FontWeight.w400, - text: faq.question, - ), - ), - const Icon( - Icons.keyboard_arrow_right, - color: ColorsManager.textGray, - ), - ], - ), - ), - const Divider( - color: ColorsManager.dividerColor, - ), - ], - ), - ), - ); - }, - )), - ), + )), ], ), ); diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_settings.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_settings.dart index e06f04d..43c5fad 100644 --- a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_settings.dart +++ b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_settings.dart @@ -9,7 +9,6 @@ import 'package:syncrow_app/features/devices/model/device_model.dart'; import 'package:syncrow_app/features/devices/model/six_scene_model.dart'; import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/6_scene_setting/faq_six_scene_page.dart'; import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/6_scene_setting/share_six_scene_page.dart'; -import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_create_group.dart'; import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_delete_dialog.dart'; import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_info_page.dart'; import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_profile_page.dart'; @@ -382,17 +381,8 @@ class SixSceneSettings extends StatelessWidget { Navigator.of(context).pop(); }, confirmTab: () { - // context - // .read< - // CreateSceneBloc>() - // .add(DeleteSceneEvent( - // sceneId: sceneId, - // unitUuid: HomeCubit - // .getInstance() - // .selectedSpace! - // .id!, - // )); - Navigator.of(context).pop(); + _bloc.add( + DeleteDeviceEvent()); }, ); }, diff --git a/lib/features/devices/view/widgets/6_scene_switch/select_switch_dialog.dart b/lib/features/devices/view/widgets/6_scene_switch/select_switch_dialog.dart index be9ac7f..7e12cae 100644 --- a/lib/features/devices/view/widgets/6_scene_switch/select_switch_dialog.dart +++ b/lib/features/devices/view/widgets/6_scene_switch/select_switch_dialog.dart @@ -100,10 +100,13 @@ class _SelectSwitchDialogState extends State { ], ), const SizedBox(height: 20), - const Center( - child: Text( - 'Please select one of the switches available to continue', - textAlign: TextAlign.center, + const Padding( + padding: EdgeInsets.only(bottom: 15, left: 5, right: 5, top: 10), + child: Center( + child: Text( + 'Please select one of the switches available to continue', + textAlign: TextAlign.center, + ), ), ), Row( diff --git a/lib/features/devices/view/widgets/6_scene_switch/six_scene_screen.dart b/lib/features/devices/view/widgets/6_scene_switch/six_scene_screen.dart index 60ea4c8..294649d 100644 --- a/lib/features/devices/view/widgets/6_scene_switch/six_scene_screen.dart +++ b/lib/features/devices/view/widgets/6_scene_switch/six_scene_screen.dart @@ -136,7 +136,7 @@ class SixSceneScreen extends StatelessWidget { child: DefaultContainer( onTap: () { _bloc.add(ChangeSwitchStatusEvent()); - + }, child: Column( crossAxisAlignment: @@ -198,6 +198,13 @@ class SixSceneScreen extends StatelessWidget { ); }, ); + if (value == true) { + _bloc.add(const SixSceneInitial()); + _bloc.add( + const SixSceneInitialInfo()); + _bloc.add( + const SexSceneSwitchInitial()); + } }, child: Column( crossAxisAlignment: diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/faq_four_scene_page.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/faq_four_scene_page.dart index 0787e38..d43945a 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/faq_four_scene_page.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/faq_four_scene_page.dart @@ -89,57 +89,59 @@ class FaqFourScenePage extends StatelessWidget { fontSize: 12, fontColor: ColorsManager.grayColor, ), - Expanded( - child: DefaultContainer( - child: ListView.builder( - shrinkWrap: true, - itemCount: displayedQuestions.length, - itemBuilder: (context, index) { - final faq = displayedQuestions[index]; - return InkWell( - onTap: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => QuestionPageFourScene( - questionModel: faq, - )), + displayedQuestions.isEmpty + ? const SizedBox() + : DefaultContainer( + child: ListView.builder( + shrinkWrap: true, + itemCount: displayedQuestions.length, + itemBuilder: (context, index) { + final faq = displayedQuestions[index]; + return InkWell( + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => + QuestionPageFourScene( + questionModel: faq, + )), + ); + }, + child: SizedBox( + child: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Row( + children: [ + Expanded( + child: BodyMedium( + fontSize: 14, + fontWeight: FontWeight.w400, + text: faq.question, + ), + ), + const Icon( + Icons.keyboard_arrow_right, + color: ColorsManager.textGray, + ), + ], + ), + ), + const Divider( + color: ColorsManager.dividerColor, + ), + ], + ), + ), ); }, - child: SizedBox( - child: Column( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.all(8.0), - child: Row( - children: [ - Expanded( - child: BodyMedium( - fontSize: 14, - fontWeight: FontWeight.w400, - text: faq.question, - ), - ), - const Icon( - Icons.keyboard_arrow_right, - color: ColorsManager.textGray, - ), - ], - ), - ), - const Divider( - color: ColorsManager.dividerColor, - ), - ], - ), - ), - ); - }, - )), - ), + )), ], ), ); diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart index f500bed..f012b65 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart @@ -395,17 +395,8 @@ class FourSceneSettings extends StatelessWidget { Navigator.of(context).pop(); }, confirmTab: () { - // context - // .read< - // CreateSceneBloc>() - // .add(DeleteSceneEvent( - // sceneId: sceneId, - // unitUuid: HomeCubit - // .getInstance() - // .selectedSpace! - // .id!, - // )); - Navigator.of(context).pop(); + _bloc.add( + DeleteDeviceEvent()); }, ); }, diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_select_switch_dialog.dart b/lib/features/devices/view/widgets/four_scene_switch/four_select_switch_dialog.dart index 4467569..c41a916 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_select_switch_dialog.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_select_switch_dialog.dart @@ -84,10 +84,13 @@ class _FourSelectSwitchDialogState extends State { ], ), const SizedBox(height: 20), - const Center( - child: Text( - 'Please select one of the switches available to continue', - textAlign: TextAlign.center, + const Padding( + padding: EdgeInsets.only(bottom: 15, left: 5, right: 5, top: 10), + child: Center( + child: Text( + 'Please select one of the switches available to continue', + textAlign: TextAlign.center, + ), ), ), Row( diff --git a/lib/generated/assets.dart b/lib/generated/assets.dart index 30ae693..6e230c0 100644 --- a/lib/generated/assets.dart +++ b/lib/generated/assets.dart @@ -1118,6 +1118,4 @@ class Assets { static const String minusIcon = "assets/icons/minus_icon.svg"; static const String addDevicesIcon = "assets/icons/add_devices_icon.svg"; static const String fourSceneIcon = "assets/icons/four_scene_icon.svg"; - - //powerClampIcon } diff --git a/lib/services/api/api_links_endpoints.dart b/lib/services/api/api_links_endpoints.dart index 1c954e6..1c41a5b 100644 --- a/lib/services/api/api_links_endpoints.dart +++ b/lib/services/api/api_links_endpoints.dart @@ -217,4 +217,8 @@ abstract class ApiEndpoints { static const String fourSceneByName = '/device/{deviceUuid}/scenes?switchName={switchName}'; + + + static const String resetDevice = + '/factory/reset/{deviceUuid}'; } diff --git a/lib/services/api/devices_api.dart b/lib/services/api/devices_api.dart index b6f4fea..bcb87d2 100644 --- a/lib/services/api/devices_api.dart +++ b/lib/services/api/devices_api.dart @@ -513,4 +513,20 @@ class DevicesAPI { ); return response; } + + static Future resetDevise({ + String? devicesUuid, + }) async { + final response = await _httpService.post( + path: ApiEndpoints.resetDevice.replaceAll('{deviceUuid}', devicesUuid!), + showServerMessage: false, + body: { + "devicesUuid": [devicesUuid] + }, + expectedResponseModel: (json) { + return json; + }, + ); + return response; + } } diff --git a/lib/services/api/spaces_api.dart b/lib/services/api/spaces_api.dart index 7a27bf1..7a2402a 100644 --- a/lib/services/api/spaces_api.dart +++ b/lib/services/api/spaces_api.dart @@ -60,6 +60,8 @@ class SpacesAPI { } } + //factory/reset/{deviceUuid} + static Future generateInvitationCode( String unitId, String communityId) async { final response = await _httpService.get( From 6733c4f4ab58f35e1e4077f085ab93c482ca194b Mon Sep 17 00:00:00 2001 From: mohammad Date: Sun, 24 Nov 2024 11:49:56 +0300 Subject: [PATCH 12/29] 4scene_and_6scene --- assets/icons/four_scene_home_icon.svg | 9 +++++++++ assets/icons/six_scene_home_icon.svg | 12 ++++++++++++ .../bloc/6_scene_switch_bloc/6_scene_bloc.dart | 3 ++- .../bloc/four_scene_bloc/four_scene_bloc.dart | 3 ++- lib/features/devices/model/device_model.dart | 4 ++++ lib/generated/assets.dart | 2 ++ pubspec.yaml | 2 +- 7 files changed, 32 insertions(+), 3 deletions(-) create mode 100644 assets/icons/four_scene_home_icon.svg create mode 100644 assets/icons/six_scene_home_icon.svg diff --git a/assets/icons/four_scene_home_icon.svg b/assets/icons/four_scene_home_icon.svg new file mode 100644 index 0000000..8251888 --- /dev/null +++ b/assets/icons/four_scene_home_icon.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/icons/six_scene_home_icon.svg b/assets/icons/six_scene_home_icon.svg new file mode 100644 index 0000000..b4483f3 --- /dev/null +++ b/assets/icons/six_scene_home_icon.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart index 08c1051..6fbfb69 100644 --- a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart +++ b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart @@ -1,6 +1,7 @@ import 'dart:async'; 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/6_scene_switch_bloc/6_scene_event.dart'; import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart'; import 'package:syncrow_app/features/devices/model/device_control_model.dart'; @@ -129,8 +130,8 @@ class SixSceneBloc extends Bloc { allDevices.forEach((element) { allDevicesIds.add(element.uuid!); }); + await HomeCubit.getInstance().fetchUnitsByUserId(); CustomSnackBar.displaySnackBar('Save Successfully'); - emit(SaveSelectionSuccessState()); } } catch (e) { diff --git a/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart b/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart index b5aaad0..469515f 100644 --- a/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart +++ b/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart @@ -1,6 +1,7 @@ import 'dart:async'; 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/four_scene_bloc/four_scene_event.dart'; import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_state.dart'; import 'package:syncrow_app/features/devices/model/device_control_model.dart'; @@ -482,7 +483,6 @@ class FourSceneBloc extends Bloc { } emit(UpdateStateList(groupDevices: groupDevices, devices: devices)); } - void _assignDevice( AssignRoomEvent event, Emitter emit) async { try { @@ -498,6 +498,7 @@ class FourSceneBloc extends Bloc { allDevices.forEach((element) { allDevicesIds.add(element.uuid!); }); + await HomeCubit.getInstance().fetchUnitsByUserId(); CustomSnackBar.displaySnackBar('Save Successfully'); emit(SaveSelectionSuccessState()); diff --git a/lib/features/devices/model/device_model.dart b/lib/features/devices/model/device_model.dart index f1af2f3..aee7fbc 100644 --- a/lib/features/devices/model/device_model.dart +++ b/lib/features/devices/model/device_model.dart @@ -78,6 +78,10 @@ class DeviceModel { tempIcon = Assets.waterLeakIcon; } else if (type == DeviceType.PC) { tempIcon = Assets.powerClampIcon; + } else if (type == DeviceType.FourScene) { + tempIcon = Assets.fourSceneHomeIcon; + } else if (type == DeviceType.SixScene) { + tempIcon = Assets.sixSceneHomeIcon; } else { tempIcon = Assets.assetsIconsLogo; } diff --git a/lib/generated/assets.dart b/lib/generated/assets.dart index 6e230c0..7e7ed11 100644 --- a/lib/generated/assets.dart +++ b/lib/generated/assets.dart @@ -1118,4 +1118,6 @@ class Assets { static const String minusIcon = "assets/icons/minus_icon.svg"; static const String addDevicesIcon = "assets/icons/add_devices_icon.svg"; static const String fourSceneIcon = "assets/icons/four_scene_icon.svg"; + static const String fourSceneHomeIcon = "assets/icons/four_scene_home_icon.svg"; + static const String sixSceneHomeIcon = "assets/icons/six_scene_home_icon.svg"; } diff --git a/pubspec.yaml b/pubspec.yaml index 22267ad..5aaacfe 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.7+40 +version: 1.0.8+41 environment: sdk: ">=3.0.6 <4.0.0" From b365f7e3475e1ccfba9362d5bd19ce6ae79a290c Mon Sep 17 00:00:00 2001 From: mohammad Date: Sun, 24 Nov 2024 15:05:33 +0300 Subject: [PATCH 13/29] sos_device --- assets/icons/edit_name_sos_icon.svg | 4 + .../6_scene_switch_bloc/6_scene_bloc.dart | 6 +- .../6_scene_switch_bloc/6_scene_state.dart | 4 +- .../bloc/four_scene_bloc/four_scene_bloc.dart | 22 +- .../four_scene_bloc/four_scene_state.dart | 10 +- .../devices/bloc/sos_bloc/sos_bloc.dart | 452 ++++++++++++++++ .../devices/bloc/sos_bloc/sos_event.dart | 196 +++++++ .../devices/bloc/sos_bloc/sos_state.dart | 94 ++++ ...itch_model.dart => device_info_model.dart} | 8 +- ...uestion_model.dart => question_model.dart} | 4 +- lib/features/devices/model/sos_model.dart | 28 + .../faq_four_scene_page.dart | 4 +- .../question_page_four_scene.dart | 4 +- .../view/widgets/room_page_switch.dart | 8 + .../sos/sos_alarm_management_page.dart | 112 ++++ .../view/widgets/sos/sos_records_screen.dart | 231 +++++++++ .../devices/view/widgets/sos/sos_screen.dart | 217 ++++++++ .../sos/sos_setting/delete_dialog.dart | 227 ++++++++ .../widgets/sos/sos_setting/faq_sos_page.dart | 151 ++++++ .../sos/sos_setting/location_setting.dart | 219 ++++++++ .../sos/sos_setting/question_page.dart | 143 ++++++ .../sos/sos_setting/share_sos_page.dart | 102 ++++ .../sos/sos_setting/sos_info_page.dart | 145 ++++++ .../sos/sos_setting/sos_profile_page.dart | 191 +++++++ .../sos/sos_setting/sos_update_note.dart | 118 +++++ .../sos/sos_setting/sos_update_page.dart | 344 +++++++++++++ .../sos/sos_setting/update_dialog_sos.dart | 118 +++++ .../view/widgets/sos/sos_settings.dart | 484 ++++++++++++++++++ .../view/widgets/sos/sos_status_bar.dart | 58 +++ lib/generated/assets.dart | 5 +- lib/utils/resource_manager/constants.dart | 15 +- 31 files changed, 3691 insertions(+), 33 deletions(-) create mode 100644 assets/icons/edit_name_sos_icon.svg create mode 100644 lib/features/devices/bloc/sos_bloc/sos_bloc.dart create mode 100644 lib/features/devices/bloc/sos_bloc/sos_event.dart create mode 100644 lib/features/devices/bloc/sos_bloc/sos_state.dart rename lib/features/devices/model/{scene_switch_model.dart => device_info_model.dart} (96%) rename lib/features/devices/model/{four_scene_question_model.dart => question_model.dart} (71%) create mode 100644 lib/features/devices/model/sos_model.dart create mode 100644 lib/features/devices/view/widgets/sos/sos_alarm_management_page.dart create mode 100644 lib/features/devices/view/widgets/sos/sos_records_screen.dart create mode 100644 lib/features/devices/view/widgets/sos/sos_screen.dart create mode 100644 lib/features/devices/view/widgets/sos/sos_setting/delete_dialog.dart create mode 100644 lib/features/devices/view/widgets/sos/sos_setting/faq_sos_page.dart create mode 100644 lib/features/devices/view/widgets/sos/sos_setting/location_setting.dart create mode 100644 lib/features/devices/view/widgets/sos/sos_setting/question_page.dart create mode 100644 lib/features/devices/view/widgets/sos/sos_setting/share_sos_page.dart create mode 100644 lib/features/devices/view/widgets/sos/sos_setting/sos_info_page.dart create mode 100644 lib/features/devices/view/widgets/sos/sos_setting/sos_profile_page.dart create mode 100644 lib/features/devices/view/widgets/sos/sos_setting/sos_update_note.dart create mode 100644 lib/features/devices/view/widgets/sos/sos_setting/sos_update_page.dart create mode 100644 lib/features/devices/view/widgets/sos/sos_setting/update_dialog_sos.dart create mode 100644 lib/features/devices/view/widgets/sos/sos_settings.dart create mode 100644 lib/features/devices/view/widgets/sos/sos_status_bar.dart diff --git a/assets/icons/edit_name_sos_icon.svg b/assets/icons/edit_name_sos_icon.svg new file mode 100644 index 0000000..c9e6a9e --- /dev/null +++ b/assets/icons/edit_name_sos_icon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart index 6fbfb69..68c33ad 100644 --- a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart +++ b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart @@ -8,7 +8,7 @@ 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/group_devices_model.dart'; -import 'package:syncrow_app/features/devices/model/scene_switch_model.dart'; +import 'package:syncrow_app/features/devices/model/device_info_model.dart'; import 'package:syncrow_app/features/devices/model/sex_scene_question_model.dart'; import 'package:syncrow_app/features/devices/model/six_scene_model.dart'; import 'package:syncrow_app/features/devices/model/status_model.dart'; @@ -68,7 +68,7 @@ class SixSceneBloc extends Bloc { scene_id_group_id: '', switch_backlight: false); - SceneSwitch deviceInfo = SceneSwitch( + DeviceInfoModel deviceInfo = DeviceInfoModel( activeTime: 0, category: "", categoryName: "", @@ -175,7 +175,7 @@ class SixSceneBloc extends Bloc { try { emit(SixSceneLoadingState()); var response = await DevicesAPI.getDeviceInfo(sixSceneId); - deviceInfo = SceneSwitch.fromJson(response); + deviceInfo = DeviceInfoModel.fromJson(response); deviceName = deviceInfo.name; emit(LoadingDeviceInfo(deviceInfo: deviceInfo)); } catch (e) { diff --git a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart index d5480f5..318d37a 100644 --- a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart +++ b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart @@ -1,7 +1,7 @@ import 'package:equatable/equatable.dart'; import 'package:syncrow_app/features/devices/model/device_model.dart'; import 'package:syncrow_app/features/devices/model/group_devices_model.dart'; -import 'package:syncrow_app/features/devices/model/scene_switch_model.dart'; +import 'package:syncrow_app/features/devices/model/device_info_model.dart'; import 'package:syncrow_app/features/devices/model/sex_scene_question_model.dart'; import 'package:syncrow_app/features/devices/model/six_scene_model.dart'; import 'package:syncrow_app/features/devices/model/subspace_model.dart'; @@ -121,7 +121,7 @@ class SceneSelectionUpdatedState extends SixSceneState { } class LoadingDeviceInfo extends SixSceneState { - final SceneSwitch deviceInfo; + final DeviceInfoModel deviceInfo; const LoadingDeviceInfo({required this.deviceInfo}); @override diff --git a/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart b/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart index 469515f..4987e7a 100644 --- a/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart +++ b/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart @@ -8,10 +8,10 @@ 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/four_scene_model.dart'; -import 'package:syncrow_app/features/devices/model/four_scene_question_model.dart'; +import 'package:syncrow_app/features/devices/model/question_model.dart'; import 'package:syncrow_app/features/devices/model/four_scene_switch_model.dart'; import 'package:syncrow_app/features/devices/model/group_devices_model.dart'; -import 'package:syncrow_app/features/devices/model/scene_switch_model.dart'; +import 'package:syncrow_app/features/devices/model/device_info_model.dart'; import 'package:syncrow_app/features/devices/model/status_model.dart'; import 'package:syncrow_app/features/devices/model/subspace_model.dart'; import 'package:syncrow_app/features/scene/model/scenes_model.dart'; @@ -68,7 +68,7 @@ class FourSceneBloc extends Bloc { scene_id_group_id: '', switch_backlight: false); - SceneSwitch deviceInfo = SceneSwitch( + DeviceInfoModel deviceInfo = DeviceInfoModel( activeTime: 0, category: "", categoryName: "", @@ -285,7 +285,7 @@ class FourSceneBloc extends Bloc { try { emit(FourSceneLoadingState()); var response = await DevicesAPI.getDeviceInfo(fourSceneId); - deviceInfo = SceneSwitch.fromJson(response); + deviceInfo = DeviceInfoModel.fromJson(response); deviceName = deviceInfo.name; emit(LoadingDeviceInfo(deviceInfo: deviceInfo)); } catch (e) { @@ -295,7 +295,7 @@ class FourSceneBloc extends Bloc { void _onSearchFaq(SearchFaqEvent event, Emitter emit) { emit(FourSceneLoadingState()); - List _faqQuestions = faqQuestions.where((question) { + List _faqQuestions = faqQuestions.where((question) { return question.question .toLowerCase() .contains(event.query.toLowerCase()); @@ -339,31 +339,31 @@ class FourSceneBloc extends Bloc { DeviceReport recordGroups = DeviceReport(startTime: '0', endTime: '0', data: []); - final List faqQuestions = [ - FourSceneQuestionModel( + final List faqQuestions = [ + QuestionModel( id: 1, question: 'How does an SOS emergency button work?', answer: 'The SOS emergency button sends an alert to your contacts when pressed.', ), - FourSceneQuestionModel( + QuestionModel( id: 2, question: 'How long will an SOS alarm persist?', answer: 'The SOS alarm will persist until it is manually turned off or after a set time.', ), - FourSceneQuestionModel( + QuestionModel( id: 3, question: 'What should I do if the SOS button is unresponsive?', answer: 'Try restarting the device. If it persists, contact support.', ), - FourSceneQuestionModel( + QuestionModel( id: 4, question: 'Can I use the SOS feature without a network connection?', answer: 'No, a network connection is required to send the alert to your contacts.', ), - FourSceneQuestionModel( + QuestionModel( id: 5, question: 'How often should I check the SOS battery?', answer: diff --git a/lib/features/devices/bloc/four_scene_bloc/four_scene_state.dart b/lib/features/devices/bloc/four_scene_bloc/four_scene_state.dart index 66c888d..08c849c 100644 --- a/lib/features/devices/bloc/four_scene_bloc/four_scene_state.dart +++ b/lib/features/devices/bloc/four_scene_bloc/four_scene_state.dart @@ -1,9 +1,9 @@ import 'package:equatable/equatable.dart'; import 'package:syncrow_app/features/devices/model/device_model.dart'; import 'package:syncrow_app/features/devices/model/four_scene_model.dart'; -import 'package:syncrow_app/features/devices/model/four_scene_question_model.dart'; +import 'package:syncrow_app/features/devices/model/question_model.dart'; import 'package:syncrow_app/features/devices/model/group_devices_model.dart'; -import 'package:syncrow_app/features/devices/model/scene_switch_model.dart'; +import 'package:syncrow_app/features/devices/model/device_info_model.dart'; import 'package:syncrow_app/features/devices/model/subspace_model.dart'; import 'package:syncrow_app/features/scene/model/scenes_model.dart'; @@ -58,13 +58,13 @@ class NameEditingState extends FourSceneState { } class FaqLoadedState extends FourSceneState { - final List filteredFaqQuestions; + final List filteredFaqQuestions; FaqLoadedState({this.filteredFaqQuestions = const []}); } class FaqSearchState extends FourSceneState { - final List filteredFaqQuestions; + final List filteredFaqQuestions; const FaqSearchState({this.filteredFaqQuestions = const []}); } @@ -116,7 +116,7 @@ class OptionSelectedState extends FourSceneState { } class LoadingDeviceInfo extends FourSceneState { - final SceneSwitch deviceInfo; + final DeviceInfoModel deviceInfo; const LoadingDeviceInfo({required this.deviceInfo}); @override diff --git a/lib/features/devices/bloc/sos_bloc/sos_bloc.dart b/lib/features/devices/bloc/sos_bloc/sos_bloc.dart new file mode 100644 index 0000000..02d385e --- /dev/null +++ b/lib/features/devices/bloc/sos_bloc/sos_bloc.dart @@ -0,0 +1,452 @@ +import 'dart:async'; +import 'package:dio/dio.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/app_layout/model/community_model.dart'; +import 'package:syncrow_app/features/app_layout/model/space_model.dart'; +import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_event.dart'; +import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_state.dart'; +import 'package:syncrow_app/features/devices/model/device_control_model.dart'; +import 'package:syncrow_app/features/devices/model/device_info_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/question_model.dart'; +import 'package:syncrow_app/features/devices/model/sos_model.dart'; +import 'package:syncrow_app/features/devices/model/status_model.dart'; +import 'package:syncrow_app/features/devices/model/subspace_model.dart'; +import 'package:syncrow_app/navigation/routing_constants.dart'; +import 'package:syncrow_app/services/api/devices_api.dart'; +import 'package:syncrow_app/services/api/home_management_api.dart'; +import 'package:syncrow_app/services/api/spaces_api.dart'; +import 'package:syncrow_app/utils/helpers/snack_bar.dart'; + +class SosBloc extends Bloc { + final String sosId; + SosBloc({ + required this.sosId, + }) : super(const SosState()) { + on(_fetchStatus); + on(fetchLogsForLastMonth); + on(_toggleLowBattery); + on(_toggleClosingReminder); + on(_changeName); + on(_onSearchFaq); + on(_onSosInitial); + on(_fetchRoomsAndDevices); + on(_onOptionSelected); + on(_onSaveSelection); + on(_assignDevice); + on(fetchDeviceInfo); + // on(_unassignDevice); + // on(_toggleWaterLeakAlarm); + } + + final TextEditingController nameController = + TextEditingController(text: '${'firstName'}'); + bool isSaving = false; + bool editName = false; + final FocusNode focusNode = FocusNode(); + Timer? _timer; + bool enableAlarm = false; + bool closingReminder = false; + bool waterAlarm = false; + SosModel deviceStatus = + SosModel(sosContactState: 'normal', batteryPercentage: 0); + + void _fetchStatus(SosInitial event, Emitter emit) async { + emit(SosLoadingState()); + try { + var response = await DevicesAPI.getDeviceStatus(sosId); + List statusModelList = []; + for (var status in response['status']) { + statusModelList.add(StatusModel.fromJson(status)); + } + deviceStatus = SosModel.fromJson( + statusModelList, + ); + emit(UpdateState(sensor: deviceStatus)); + + Future.delayed(const Duration(milliseconds: 500)); + // _listenToChanges(); + } catch (e) { + emit(SosFailedState(errorMessage: e.toString())); + return; + } + } + + DeviceInfoModel deviceInfo = DeviceInfoModel( + activeTime: 0, + category: "", + categoryName: "", + createTime: 0, + gatewayId: "", + icon: "", + ip: "", + lat: "", + localKey: "", + lon: "", + model: "", + name: "", + nodeId: "", + online: false, + ownerId: "", + productName: "", + sub: false, + timeZone: "", + updateTime: 0, + uuid: "", + productUuid: "", + productType: "", + permissionType: "", + macAddress: "", + subspace: Subspace( + uuid: "", + createdAt: "", + updatedAt: "", + subspaceName: "", + ), + ); + + void _onSearchFaq(SearchFaqEvent event, Emitter emit) { + emit(SosLoadingState()); + List _faqQuestions = faqQuestions.where((question) { + return question.question + .toLowerCase() + .contains(event.query.toLowerCase()); + }).toList(); + emit(FaqSearchState(filteredFaqQuestions: _faqQuestions)); + } + + void _changeName(ChangeNameEvent event, Emitter emit) { + emit(SosLoadingState()); + editName = event.value!; + if (editName) { + Future.delayed(const Duration(milliseconds: 500), () { + focusNode.requestFocus(); + }); + } else { + focusNode.unfocus(); + } + emit(NameEditingState(editName: editName)); + } + + void _toggleLowBattery( + ToggleEnableAlarmEvent event, Emitter emit) async { + emit(LoadingNewSate(sosSensor: deviceStatus)); + try { + enableAlarm = event.isLowBatteryEnabled; + emit(UpdateState(sensor: deviceStatus)); + await DevicesAPI.controlDevice( + DeviceControlModel( + deviceId: sosId, + code: 'low_battery', + value: enableAlarm, + ), + sosId, + ); + } catch (e) { + emit(SosFailedState(errorMessage: e.toString())); + } + } + + void _toggleClosingReminder( + ToggleClosingReminderEvent event, Emitter emit) async { + emit(LoadingNewSate(sosSensor: deviceStatus)); + try { + closingReminder = event.isClosingReminderEnabled; + emit(UpdateState(sensor: deviceStatus)); + + // API call to update the state, if necessary + // await DevicesAPI.controlDevice( + // DeviceControlModel( + // deviceId: sosId, + // code: 'closing_reminder', + // value: closingReminder, + // ), + // sosId, + // ); + } catch (e) { + emit(SosFailedState(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(SosLoadingState()); + var response = await DevicesAPI.getReportLogs( + startTime: startTime.toString(), + endTime: endTime.toString(), + deviceUuid: sosId, + code: 'sos', + ); + recordGroups = response; + emit(UpdateState(sensor: deviceStatus)); + } on DioException catch (e) { + final errorData = e.response!.data; + String errorMessage = errorData['message']; + emit(SosFailedState(errorMessage: e.toString())); + } + } + + static String deviceName = ''; + + fetchDeviceInfo(SosInitialDeviseInfo event, Emitter emit) async { + try { + emit(SosLoadingState()); + var response = await DevicesAPI.getDeviceInfo(sosId); + deviceInfo = DeviceInfoModel.fromJson(response); + deviceName = deviceInfo.name; + emit(LoadingSosDeviceInfo(deviceInfo: deviceInfo)); + } catch (e) { + emit(SosFailedState(errorMessage: e.toString())); + } + } + + // Demo list of FAQ questions using the QuestionModel class + final List faqQuestions = [ + QuestionModel( + id: 1, + question: 'How does an SOS emergency button work?', + answer: + 'The SOS emergency button sends an alert to your contacts when pressed.', + ), + QuestionModel( + id: 2, + question: 'How long will an SOS alarm persist?', + answer: + 'The SOS alarm will persist until it is manually turned off or after a set time.', + ), + QuestionModel( + id: 3, + question: 'What should I do if the SOS button is unresponsive?', + answer: 'Try restarting the device. If it persists, contact support.', + ), + QuestionModel( + id: 4, + question: 'Can I use the SOS feature without a network connection?', + answer: + 'No, a network connection is required to send the alert to your contacts.', + ), + QuestionModel( + id: 5, + question: 'How often should I check the SOS battery?', + answer: + 'Check the SOS battery at least once a month to ensure it is operational.', + ), + ]; + Future _onSosInitial( + SosInitialQuestion event, Emitter emit) async { + emit(SosLoadingState()); + // SosModel sosModel = await fetchSosData(sosId); // Define this function as needed + emit(FaqLoadedState(filteredFaqQuestions: faqQuestions)); + } + + List allDevices = []; + List roomsList = []; + + void _fetchRoomsAndDevices( + FetchRoomsEvent event, Emitter emit) async { + try { + emit(SosLoadingState()); + roomsList = await SpacesAPI.getSubSpaceBySpaceId( + event.unit.community.uuid, event.unit.id); + emit(FetchRoomsState(devicesList: allDevices, roomsList: roomsList)); + } catch (e) { + emit(const SosFailedState(errorMessage: 'Something went wrong')); + return; + } + } + + String roomId = ''; + SpaceModel unit = + SpaceModel(id: '', name: '', community: Community(uuid: '', name: '')); + + String _selectedOption = ''; + bool _hasSelectionChanged = false; + + void _onOptionSelected(SelectOptionEvent event, Emitter emit) { + emit(SosLoadingState()); + _selectedOption = event.selectedOption; + _hasSelectionChanged = true; + emit(OptionSelectedState( + selectedOption: _selectedOption, + hasSelectionChanged: _hasSelectionChanged)); + } + + void _onSaveSelection(SaveSelectionEvent event, Emitter emit) { + if (_hasSelectionChanged) { + _hasSelectionChanged = false; + add(AssignRoomEvent(roomId: roomId, unit: unit, context: event.context)); + emit(SaveSelectionSuccessState()); + + // Navigator.pushNamedAndRemoveUntil( + // event.context, Routes.homeRoute, (route) => false); + var cubit = HomeCubit.getInstance(); + cubit.updatePageIndex(1); + Navigator.pushReplacementNamed(event.context, Routes.homeRoute); + } + } + + void _assignDevice(AssignRoomEvent event, Emitter emit) async { + try { + // Map roomDevicesId = {}; + emit(SosLoadingState()); + + await HomeManagementAPI.assignDeviceToRoom( + event.unit.community.uuid, event.unit.id, event.roomId, sosId); + final devicesList = await DevicesAPI.getDevicesByRoomId( + communityUuid: event.unit.community.uuid, + spaceUuid: event.unit.id, + roomId: event.roomId); + + List allDevicesIds = []; + + allDevices.forEach((element) { + allDevicesIds.add(element.uuid!); + }); + emit(SaveSelectionSuccessState()); + + // devicesList.forEach((e) { + // if (allDevicesIds.contains(e.uuid!)) { + // roomDevicesId[e.uuid!] = true; + // } else { + // roomDevicesId[e.uuid!] = false; + // } + // }); + // emit(FetchDeviceByRoomIdState( + // roomDevices: devicesList, + // allDevices: allDevices, + // roomDevicesId: roomDevicesId, + // roomId: event.roomId)); + } catch (e) { + emit(const SosFailedState(errorMessage: 'Something went wrong')); + return; + } + } + + void _unassignDevice(UnassignRoomEvent event, Emitter emit) async { + try { + Map roomDevicesId = {}; + emit(SosLoadingState()); + await HomeManagementAPI.unAssignDeviceToRoom( + event.unit.community.uuid, event.unit.id, event.roomId, sosId); + final devicesList = await DevicesAPI.getDevicesByRoomId( + communityUuid: event.unit.community.uuid, + spaceUuid: event.unit.id, + roomId: event.roomId); + + List allDevicesIds = []; + + allDevices.forEach((element) { + allDevicesIds.add(element.uuid!); + }); + + devicesList.forEach((e) { + if (allDevicesIds.contains(e.uuid!)) { + roomDevicesId[e.uuid!] = true; + } else { + roomDevicesId[e.uuid!] = false; + } + }); + // emit(FetchDeviceByRoomIdState( + // roomDevices: devicesList, + // allDevices: allDevices, + // roomDevicesId: roomDevicesId, + // roomId: event.roomId)); + } catch (e) { + emit(const SosFailedState(errorMessage: 'Something went wrong')); + return; + } + } + + Map> devicesByRoom = {}; + +// Your existing function + void _fetchDevicesByRoomId( + FetchDevicesByRoomIdEvent event, Emitter emit) async { + try { + Map roomDevicesId = {}; + emit(SosLoadingState()); + + // Fetch devices for the specified room + final devicesList = await DevicesAPI.getDevicesByRoomId( + communityUuid: event.unit.community.uuid, + spaceUuid: event.unit.id, + roomId: event.roomId); + + // Fetch all devices accessible by the user + allDevices = await HomeManagementAPI.fetchDevicesByUserId(); + + // Map all accessible device IDs + List allDevicesIds = []; + allDevices.forEach((element) { + allDevicesIds.add(element.uuid!); + }); + + // Mark devices as accessible/inaccessible for the room and add to devicesByRoom map + devicesList.forEach((e) { + roomDevicesId[e.uuid!] = allDevicesIds.contains(e.uuid!); + }); + + // Update the devicesByRoom map with the devices in the current room + devicesByRoom[event.roomId] = devicesList; + + // emit(FetchDeviceByRoomIdState( + // roomDevices: devicesList, + // allDevices: allDevices, + // roomDevicesId: roomDevicesId, + // roomId: event.roomId)); + } catch (e) { + emit(const SosFailedState(errorMessage: 'Something went wrong')); + return; + } + } + + Future saveName(SaveNameEvent event, Emitter emit) async { + if (_validateInputs()) return; + try { + add(const ChangeNameEvent(value: false)); + isSaving = true; + emit(SosLoadingState()); + var response = await DevicesAPI.putDeviceName( + deviceId: sosId, deviceName: nameController.text); + add(SosInitialDeviseInfo()); + CustomSnackBar.displaySnackBar('Save Successfully'); + emit(SaveState()); + } catch (e) { + emit(SosFailedState(errorMessage: e.toString())); + } finally { + isSaving = false; + } + } + + bool _validateInputs() { + final nameError = fullNameValidator(nameController.text); + if (nameError != null) { + CustomSnackBar.displaySnackBar(nameError); + return true; + } + return false; + } + + String? fullNameValidator(String? value) { + if (value == null) return 'name is required'; + final withoutExtraSpaces = value.replaceAll(RegExp(r"\s+"), ' ').trim(); + if (withoutExtraSpaces.length < 2 || withoutExtraSpaces.length > 30) { + return 'name must be between 2 and 30 characters long'; + } + if (RegExp(r"/[^ a-zA-Z0-9-\']/").hasMatch(withoutExtraSpaces)) { + return 'Only alphanumeric characters, space, dash and single quote are allowed'; + } + return null; + } +} diff --git a/lib/features/devices/bloc/sos_bloc/sos_event.dart b/lib/features/devices/bloc/sos_bloc/sos_event.dart new file mode 100644 index 0000000..8a882a9 --- /dev/null +++ b/lib/features/devices/bloc/sos_bloc/sos_event.dart @@ -0,0 +1,196 @@ +import 'package:equatable/equatable.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:syncrow_app/features/app_layout/model/space_model.dart'; +import 'package:syncrow_app/features/devices/model/device_info_model.dart'; + +abstract class SosEvent extends Equatable { + const SosEvent(); + + @override + List get props => []; +} + +class SosLoading extends SosEvent {} + +class SosSwitch extends SosEvent { + final String switchD; + final String deviceId; + final String productId; + const SosSwitch( + {required this.switchD, this.deviceId = '', this.productId = ''}); + + @override + List get props => [switchD, deviceId, productId]; +} + +class SosUpdated extends SosEvent {} +class SosInitialDeviseInfo extends SosEvent {} + +class SosInitial extends SosEvent { + const SosInitial(); +} + +class ReportLogsInitial extends SosEvent { + const ReportLogsInitial(); +} + +class SosChangeStatus extends SosEvent {} + +class GetCounterEvent extends SosEvent { + final String deviceCode; + const GetCounterEvent({required this.deviceCode}); + @override + List get props => [deviceCode]; +} + +class ToggleEnableAlarmEvent extends SosEvent { + final bool isLowBatteryEnabled; + + const ToggleEnableAlarmEvent(this.isLowBatteryEnabled); + + @override + List get props => [isLowBatteryEnabled]; +} + +class ToggleClosingReminderEvent extends SosEvent { + final bool isClosingReminderEnabled; + + const ToggleClosingReminderEvent(this.isClosingReminderEnabled); + + @override + List get props => [isClosingReminderEnabled]; +} + +class ToggleSosAlarmEvent extends SosEvent { + final bool isSosAlarmEnabled; + + const ToggleSosAlarmEvent(this.isSosAlarmEnabled); + + @override + List get props => [isSosAlarmEnabled]; +} + +class SetCounterValue extends SosEvent { + final Duration duration; + final String deviceCode; + const SetCounterValue({required this.duration, required this.deviceCode}); + @override + List get props => [duration, deviceCode]; +} + +class StartTimer extends SosEvent { + final int duration; + + const StartTimer(this.duration); + + @override + List get props => [duration]; +} + +class TickTimer extends SosEvent { + final int remainingTime; + + const TickTimer(this.remainingTime); + + @override + List get props => [remainingTime]; +} + +class StopTimer extends SosEvent {} + +class OnClose extends SosEvent {} +class SaveNameEvent extends SosEvent {} + +class ChangeNameEvent extends SosEvent { + final bool? value; + const ChangeNameEvent({this.value}); +} + +class SearchFaqEvent extends SosEvent { + final String query; + + const SearchFaqEvent(this.query); +} + +class SosInitialQuestion extends SosEvent { + const SosInitialQuestion(); +} + +class FetchRoomsEvent extends SosEvent { + final SpaceModel unit; + + const FetchRoomsEvent({required this.unit}); + + @override + List get props => [unit]; +} + + +class SelectOptionEvent extends SosEvent { + dynamic selectedOption; + SelectOptionEvent({ + this.selectedOption, + }); +} + +class SaveSelectionEvent extends SosEvent { + BuildContext context; + SaveSelectionEvent({ + required this.context, + }); +} + +class AssignRoomEvent extends SosEvent { + final String roomId; + final SpaceModel unit; + final BuildContext context; + + const AssignRoomEvent({ + required this.roomId, + required this.unit, + required this.context, + }); + + @override + List get props => [ + roomId, + unit, + context, + ]; +} +class UnassignRoomEvent extends SosEvent { + final String roomId; + final String deviceId; + final SpaceModel unit; + + const UnassignRoomEvent( + {required this.roomId, required this.deviceId, required this.unit}); + + @override + List get props => [roomId, unit]; +} + +class FetchDevicesByRoomIdEvent extends SosEvent { + final SpaceModel unit; // Represents the unit (e.g., room or space) context + final String roomId; // Unique identifier for the room + + // Constructor + FetchDevicesByRoomIdEvent({ + required this.unit, + required this.roomId, + }); + + // Adding properties for Equatable to compare + @override + List get props => [unit, roomId]; +} + + +class LoadingDeviceInfo extends SosEvent { + DeviceInfoModel deviceInfo; + LoadingDeviceInfo({required this.deviceInfo}); + + @override + List get props => [deviceInfo]; +} \ No newline at end of file diff --git a/lib/features/devices/bloc/sos_bloc/sos_state.dart b/lib/features/devices/bloc/sos_bloc/sos_state.dart new file mode 100644 index 0000000..1ffee2d --- /dev/null +++ b/lib/features/devices/bloc/sos_bloc/sos_state.dart @@ -0,0 +1,94 @@ +import 'package:equatable/equatable.dart'; +import 'package:syncrow_app/features/devices/model/device_info_model.dart'; +import 'package:syncrow_app/features/devices/model/device_model.dart'; +import 'package:syncrow_app/features/devices/model/question_model.dart'; +import 'package:syncrow_app/features/devices/model/sos_model.dart'; +import 'package:syncrow_app/features/devices/model/subspace_model.dart'; + +class SosState extends Equatable { + const SosState(); + + @override + List get props => []; +} + +class SosInitialState extends SosState {} + +class SosLoadingState extends SosState {} +class SaveState extends SosState {} + +class LoadingSosDeviceInfo extends SosState { + final DeviceInfoModel? deviceInfo; + const LoadingSosDeviceInfo({this.deviceInfo}); +} + +class SosFailedState extends SosState { + final String errorMessage; + + const SosFailedState({required this.errorMessage}); + + @override + List get props => [errorMessage]; +} + +class UpdateState extends SosState { + final SosModel sensor; + const UpdateState({required this.sensor}); + + @override + List get props => [sensor]; +} + +class LoadingNewSate extends SosState { + final SosModel sosSensor; + const LoadingNewSate({required this.sosSensor}); + + @override + List get props => [sosSensor]; +} + +class NameEditingState extends SosState { + final bool editName; + + NameEditingState({required this.editName}); +} + +class FaqLoadedState extends SosState { + final List filteredFaqQuestions; + + FaqLoadedState({this.filteredFaqQuestions = const []}); +} + +class FaqSearchState extends SosState { + final List filteredFaqQuestions; + + const FaqSearchState({this.filteredFaqQuestions = const []}); +} + +class FetchRoomsState extends SosState { + final List roomsList; + final List devicesList; + + const FetchRoomsState({required this.devicesList, required this.roomsList}); + + @override + List get props => [devicesList]; +} + +class OptionSelectedState extends SosState { + final String selectedOption; + final bool hasSelectionChanged; + + OptionSelectedState({ + required this.selectedOption, + required this.hasSelectionChanged, + }); + + @override + List get props => [selectedOption, hasSelectionChanged]; +} + +class SaveSelectionSuccessState extends SosState { + @override + List get props => []; +} diff --git a/lib/features/devices/model/scene_switch_model.dart b/lib/features/devices/model/device_info_model.dart similarity index 96% rename from lib/features/devices/model/scene_switch_model.dart rename to lib/features/devices/model/device_info_model.dart index f21c1ad..9c01d70 100644 --- a/lib/features/devices/model/scene_switch_model.dart +++ b/lib/features/devices/model/device_info_model.dart @@ -1,6 +1,6 @@ import 'dart:convert'; -class SceneSwitch { +class DeviceInfoModel { final int activeTime; final String category; final String categoryName; @@ -27,7 +27,7 @@ class SceneSwitch { final String macAddress; final Subspace subspace; - SceneSwitch({ + DeviceInfoModel({ required this.activeTime, required this.category, required this.categoryName, @@ -55,8 +55,8 @@ class SceneSwitch { required this.subspace, }); - factory SceneSwitch.fromJson(Map json) { - return SceneSwitch( + factory DeviceInfoModel.fromJson(Map json) { + return DeviceInfoModel( activeTime: json['activeTime'], category: json['category'], categoryName: json['categoryName'], diff --git a/lib/features/devices/model/four_scene_question_model.dart b/lib/features/devices/model/question_model.dart similarity index 71% rename from lib/features/devices/model/four_scene_question_model.dart rename to lib/features/devices/model/question_model.dart index ed4eacc..2965620 100644 --- a/lib/features/devices/model/four_scene_question_model.dart +++ b/lib/features/devices/model/question_model.dart @@ -1,9 +1,9 @@ -class FourSceneQuestionModel { +class QuestionModel { final int id; final String question; final String answer; - FourSceneQuestionModel({ + QuestionModel({ required this.id, required this.question, required this.answer, diff --git a/lib/features/devices/model/sos_model.dart b/lib/features/devices/model/sos_model.dart new file mode 100644 index 0000000..7534b60 --- /dev/null +++ b/lib/features/devices/model/sos_model.dart @@ -0,0 +1,28 @@ +import 'package:syncrow_app/features/devices/model/status_model.dart'; + +class SosModel { + String sosContactState; + int batteryPercentage; + + SosModel({ + required this.sosContactState, + required this.batteryPercentage, + }); + + factory SosModel.fromJson(List jsonList) { + late String _sosContactState; + late int _batteryPercentage; + + for (int i = 0; i < jsonList.length; i++) { + if (jsonList[i].code == 'sos') { + _sosContactState = jsonList[i].value ?? ''; + } else if (jsonList[i].code == 'battery_percentage') { + _batteryPercentage = jsonList[i].value ?? 0; + } + } + return SosModel( + sosContactState: _sosContactState, + batteryPercentage: _batteryPercentage, + ); + } +} diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/faq_four_scene_page.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/faq_four_scene_page.dart index d43945a..30e30e2 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/faq_four_scene_page.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/faq_four_scene_page.dart @@ -5,7 +5,7 @@ import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_blo import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_event.dart'; import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_state.dart'; import 'package:syncrow_app/features/devices/model/device_model.dart'; -import 'package:syncrow_app/features/devices/model/four_scene_question_model.dart'; +import 'package:syncrow_app/features/devices/model/question_model.dart'; import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_scene_setting/question_page_four_scene.dart'; import 'package:syncrow_app/features/shared_widgets/default_container.dart'; import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart'; @@ -30,7 +30,7 @@ class FaqFourScenePage extends StatelessWidget { builder: (context, state) { final sensor = BlocProvider.of(context); - List displayedQuestions = []; + List displayedQuestions = []; if (state is FaqSearchState) { displayedQuestions = state.filteredFaqQuestions; } else if (state is FaqLoadedState) { diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/question_page_four_scene.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/question_page_four_scene.dart index 3d1b495..5ebbc8b 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/question_page_four_scene.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/question_page_four_scene.dart @@ -5,7 +5,7 @@ import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_blo import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_event.dart'; import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_state.dart'; import 'package:syncrow_app/features/devices/model/four_scene_model.dart'; -import 'package:syncrow_app/features/devices/model/four_scene_question_model.dart'; +import 'package:syncrow_app/features/devices/model/question_model.dart'; import 'package:syncrow_app/features/shared_widgets/default_button.dart'; import 'package:syncrow_app/features/shared_widgets/default_container.dart'; import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart'; @@ -15,7 +15,7 @@ import 'package:syncrow_app/generated/assets.dart'; import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; class QuestionPageFourScene extends StatelessWidget { - final FourSceneQuestionModel? questionModel; + final QuestionModel? questionModel; const QuestionPageFourScene({super.key, this.questionModel}); diff --git a/lib/features/devices/view/widgets/room_page_switch.dart b/lib/features/devices/view/widgets/room_page_switch.dart index bb61799..89e6c22 100644 --- a/lib/features/devices/view/widgets/room_page_switch.dart +++ b/lib/features/devices/view/widgets/room_page_switch.dart @@ -18,6 +18,7 @@ import 'package:syncrow_app/features/devices/view/widgets/lights/light_interface import 'package:syncrow_app/features/devices/view/widgets/one_gang/one_gang_Interface.dart'; import 'package:syncrow_app/features/devices/view/widgets/one_touch/one_touch_screen.dart'; import 'package:syncrow_app/features/devices/view/widgets/power_clamp/power_clamp_page.dart'; +import 'package:syncrow_app/features/devices/view/widgets/sos/sos_screen.dart'; import 'package:syncrow_app/features/devices/view/widgets/three_touch/three_touch_interface.dart'; import 'package:syncrow_app/features/devices/view/widgets/two_gang/two_gang_Interface.dart'; import 'package:syncrow_app/features/devices/view/widgets/two_touch/two_touch_Interface.dart'; @@ -228,6 +229,13 @@ void showDeviceInterface(DeviceModel device, BuildContext context) { pageBuilder: (context, animation1, animation2) => FourSceneScreen(device: device))); + case DeviceType.SOS: + Navigator.push( + context, + PageRouteBuilder( + pageBuilder: (context, animation1, animation2) => + SosScreen(device: device))); + break; default: } diff --git a/lib/features/devices/view/widgets/sos/sos_alarm_management_page.dart b/lib/features/devices/view/widgets/sos/sos_alarm_management_page.dart new file mode 100644 index 0000000..c750368 --- /dev/null +++ b/lib/features/devices/view/widgets/sos/sos_alarm_management_page.dart @@ -0,0 +1,112 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_event.dart'; +import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_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 AlarmManagementPage extends StatelessWidget { + const AlarmManagementPage({super.key}); + + @override + Widget build(BuildContext context) { + return DefaultScaffold( + title: 'Alarm Settings', + child: BlocProvider( + create: (context) => SosBloc(sosId: ''), + child: BlocBuilder( + builder: (context, state) { + final _bloc = BlocProvider.of(context); + + return state is LoadingNewSate + ? const Center( + child: DefaultContainer( + width: 50, + height: 50, + child: CircularProgressIndicator()), + ) + : Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox( + height: 10, + ), + const BodyMedium( + text: 'The Alarm Management', + fontWeight: FontWeight.w700, + fontSize: 12, + fontColor: ColorsManager.grayColor, + ), + const SizedBox( + height: 5, + ), + DefaultContainer( + child: Padding( + padding: const EdgeInsets.only(left: 10, right: 10), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + height: 50, + child: ListTile( + contentPadding: EdgeInsets.zero, + leading: const BodyMedium( + text: 'SOS Alarm', + fontWeight: FontWeight.w400, + fontSize: 15, + ), + trailing: Transform.scale( + scale: .8, + child: CupertinoSwitch( + value: _bloc.enableAlarm, + onChanged: (value) { + context.read().add( + ToggleEnableAlarmEvent(value)); + }, + applyTheme: true, + )), + ), + ), + const Divider( + color: ColorsManager.graysColor, + ), + SizedBox( + height: 50, + child: ListTile( + contentPadding: EdgeInsets.zero, + leading: const BodyLarge( + text: 'Low Battery Reminder', + fontWeight: FontWeight.w400, + fontSize: 15, + ), + trailing: Transform.scale( + scale: .8, + child: CupertinoSwitch( + value: _bloc.closingReminder, + onChanged: (value) { + context.read().add( + ToggleClosingReminderEvent( + value)); + }, + applyTheme: true, + )), + ), + ), + ], + ), + ), + ), + ], + ); + }, + ), + )); + } +} diff --git a/lib/features/devices/view/widgets/sos/sos_records_screen.dart b/lib/features/devices/view/widgets/sos/sos_records_screen.dart new file mode 100644 index 0000000..e459226 --- /dev/null +++ b/lib/features/devices/view/widgets/sos/sos_records_screen.dart @@ -0,0 +1,231 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:intl/intl.dart'; +import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_event.dart'; +import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_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/features/shared_widgets/text_widgets/body_small.dart'; +import 'package:syncrow_app/generated/assets.dart'; +import 'package:syncrow_app/utils/context_extension.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +class SosRecordsScreen extends StatefulWidget { + final String sosId; + const SosRecordsScreen({super.key, required this.sosId}); + + @override + State createState() => _SosRecordsScreenState(); +} + +class _SosRecordsScreenState extends State { + int _selectedIndex = 0; + @override + Widget build(BuildContext context) { + return DefaultScaffold( + title: 'Records', + child: BlocProvider( + create: (context) => + SosBloc(sosId: widget.sosId)..add(const ReportLogsInitial()), + child: BlocBuilder( + builder: (context, state) { + final waterSensorBloc = BlocProvider.of(context); + final Map> groupedRecords = {}; + + if (state is LoadingNewSate) { + return const Center( + child: DefaultContainer( + width: 50, height: 50, child: CircularProgressIndicator()), + ); + } else if (state is UpdateState) { + for (var record in waterSensorBloc.recordGroups.data!) { + final DateTime eventDateTime = + DateTime.fromMillisecondsSinceEpoch(record.eventTime!); + final String formattedDate = + DateFormat('EEEE, dd/MM/yyyy').format(eventDateTime); + if (groupedRecords.containsKey(formattedDate)) { + groupedRecords[formattedDate]!.add(record); + } else { + groupedRecords[formattedDate] = [record]; + } + } + } + + return DefaultTabController( + length: 2, + child: Column( + children: [ + Container( + width: MediaQuery.of(context).size.width, + decoration: const ShapeDecoration( + color: ColorsManager.onPrimaryColor, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(30)), + ), + ), + child: TabBar( + onTap: (value) { + setState(() { + _selectedIndex = value; + }); + }, + indicatorColor: Colors.white, + dividerHeight: 0, + indicatorSize: TabBarIndicatorSize.tab, + indicator: const ShapeDecoration( + color: ColorsManager.slidingBlueColor, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(20)), + ), + ), + tabs: [ + Tab( + child: Container( + padding: const EdgeInsets.symmetric(vertical: 10), + child: BodySmall( + text: 'Record', + style: context.bodySmall.copyWith( + color: _selectedIndex == 0 + ? Colors.white + : ColorsManager.blackColor, + fontSize: 12, + fontWeight: FontWeight.w400, + ), + ), + ), + ), + Tab( + child: Container( + padding: const EdgeInsets.symmetric(vertical: 10), + child: Text( + 'Automation Log', + style: context.bodySmall.copyWith( + color: _selectedIndex == 1 + ? Colors.white + : ColorsManager.blackColor, + fontSize: 12, + fontWeight: FontWeight.w400, + ), + ), + ), + ), + ], + ), + ), + Expanded( + child: TabBarView( + physics: const NeverScrollableScrollPhysics(), + children: [ + groupedRecords.isEmpty + ? Center( + child: SvgPicture.asset( + Assets.emptyLog, + fit: BoxFit.fill, + ), + ) + : 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.all(16.0), + 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: [ + ListTile( + leading: SvgPicture.asset( + record.value == 'true' + ? Assets + .leakDetectedIcon + : Assets + .leakNormalIcon, + height: 25, + width: 25, + ), + title: const Text( + "SOS Alert Triggered", + style: const TextStyle( + fontWeight: + FontWeight.bold, + fontSize: 18, + ), + ), + subtitle: + Text(formattedTime), + ), + if (idx != + recordsForDate.length - 1) + const Divider( + color: ColorsManager + .graysColor, + ), + ], + ); + }).toList(), + ], + ), + ), + ], + ); + }, + ), + Container( + height: 10, + width: 20, + child: Center( + child: SvgPicture.asset( + Assets.emptyLog, + fit: BoxFit.fill, + ), + ), + ), + ], + ), + ), + ], + ), + ); + }, + ), + ), + ); + } +} diff --git a/lib/features/devices/view/widgets/sos/sos_screen.dart b/lib/features/devices/view/widgets/sos/sos_screen.dart new file mode 100644 index 0000000..e55ee41 --- /dev/null +++ b/lib/features/devices/view/widgets/sos/sos_screen.dart @@ -0,0 +1,217 @@ +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/sos_bloc/sos_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_event.dart'; +import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_state.dart'; +import 'package:syncrow_app/features/devices/model/device_model.dart'; +import 'package:syncrow_app/features/devices/model/sos_model.dart'; +import 'package:syncrow_app/features/devices/view/widgets/sos/sos_alarm_management_page.dart'; +import 'package:syncrow_app/features/devices/view/widgets/sos/sos_records_screen.dart'; +import 'package:syncrow_app/features/devices/view/widgets/sos/sos_settings.dart'; +import 'package:syncrow_app/features/shared_widgets/battery_bar.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 SosScreen extends StatelessWidget { + final DeviceModel? device; + + + const SosScreen({super.key, this.device}); + + @override + Widget build(BuildContext context) { + return DefaultScaffold( + title: 'SOS', + actions: [ + InkWell( + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => SosSettings(device: device!)), + ); + }, + child: SvgPicture.asset(Assets.assetsIconsSettings)), + const SizedBox( + width: 10, + ) + ], + child: BlocProvider( + create: (context) => + SosBloc(sosId: device?.uuid ?? '')..add(const SosInitial()), + child: BlocBuilder( + builder: (context, state) { + final sensor = BlocProvider.of(context); + SosModel model = + SosModel(batteryPercentage: 0, sosContactState: 'normal'); + if (state is LoadingNewSate) { + model = state.sosSensor; + } else if (state is UpdateState) { + model = state.sensor; + } + return state is SosLoadingState + ? const Center( + child: DefaultContainer( + width: 50, + height: 50, + child: CircularProgressIndicator()), + ) + : RefreshIndicator( + onRefresh: () async { + sensor.add(const SosInitial()); + }, + child: ListView( + children: [ + SizedBox( + height: MediaQuery.sizeOf(context).height * 0.8, + child: Column( + children: [ + BatteryBar( + batteryPercentage: model.batteryPercentage, + ), + 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: SvgPicture.asset( + model.sosContactState == 'normal' + ? Assets.redSos + : Assets.greenSos, + fit: BoxFit.fill, + ), + ), + ], + ), + ), + ), + Flexible( + child: Row( + children: [ + Expanded( + child: DefaultContainer( + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => + SosRecordsScreen( + sosId: 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) => + const AlarmManagementPage()), + ); + }, + child: Column( + crossAxisAlignment: + CrossAxisAlignment.center, + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + ConstrainedBox( + constraints: const BoxConstraints( + maxHeight: 46, maxWidth: 50), + child: SvgPicture.asset(Assets + .doorNotificationSetting), + ), + const SizedBox( + height: 15, + ), + const Flexible( + child: FittedBox( + child: BodySmall( + text: 'Alarm Settings', + textAlign: TextAlign.center, + ), + ), + ), + ], + ), + ), + ), + ], + ), + ) + ], + ), + ), + ], + ), + ); + }, + ), + ), + ); + } +} diff --git a/lib/features/devices/view/widgets/sos/sos_setting/delete_dialog.dart b/lib/features/devices/view/widgets/sos/sos_setting/delete_dialog.dart new file mode 100644 index 0000000..67c62e2 --- /dev/null +++ b/lib/features/devices/view/widgets/sos/sos_setting/delete_dialog.dart @@ -0,0 +1,227 @@ +import 'package:flutter/material.dart'; +import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +class DisconnectDeviceDialog extends StatelessWidget { + final Function()? cancelTab; + final Function()? confirmTab; + + const DisconnectDeviceDialog({ + super.key, + required this.cancelTab, + required this.confirmTab, + }); + + @override + Widget build(BuildContext context) { + return AlertDialog( + contentPadding: EdgeInsets.zero, + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const SizedBox( + height: 10, + ), + const BodyLarge( + text: 'Disconnect Device', + fontWeight: FontWeight.w700, + fontColor: ColorsManager.red, + fontSize: 16, + ), + const Padding( + padding: EdgeInsets.only(left: 15, right: 15), + child: Divider( + color: ColorsManager.textGray, + ), + ), + const Padding( + padding: EdgeInsets.only(left: 15, right: 20, top: 15, bottom: 20), + child: Column( + children: [ + Center( + child: Text( + 'This will disconnect your device from this Application')), + ], + ), + ), + 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: 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: confirmTab, + child: const Padding( + padding: EdgeInsets.all(15), + child: Center( + child: Text( + 'Disconnect', + style: TextStyle( + color: ColorsManager.red, + fontSize: 14, + fontWeight: FontWeight.w400), + ), + ), + )), + )) + ], + ) + ], + ), + ); + } +} + +class DisconnectWipeData extends StatelessWidget { + final Function()? cancelTab; + final Function()? confirmTab; + + const DisconnectWipeData({ + super.key, + required this.cancelTab, + required this.confirmTab, + }); + + @override + Widget build(BuildContext context) { + return AlertDialog( + contentPadding: EdgeInsets.zero, + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const SizedBox( + height: 10, + ), + const BodyLarge( + text: 'Disconnect and Wipe Data', + fontWeight: FontWeight.w700, + fontColor: ColorsManager.red, + fontSize: 16, + ), + const Padding( + padding: EdgeInsets.only(left: 15, right: 15), + child: Divider( + color: ColorsManager.textGray, + ), + ), + const Padding( + padding: EdgeInsets.only(left: 15, right: 20, top: 15, bottom: 20), + child: Column( + children: [ + Center( + child: Text( + 'This will disconnect your device from this Application and wipe all the data')), + ], + ), + ), + 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: 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: confirmTab, + child: const Padding( + padding: EdgeInsets.all(15), + child: Center( + child: Text( + 'Disconnect', + style: TextStyle( + color: ColorsManager.red, + fontSize: 14, + fontWeight: FontWeight.w400), + ), + ), + )), + )) + ], + ) + ], + ), + ); + } +} diff --git a/lib/features/devices/view/widgets/sos/sos_setting/faq_sos_page.dart b/lib/features/devices/view/widgets/sos/sos_setting/faq_sos_page.dart new file mode 100644 index 0000000..bbb75f7 --- /dev/null +++ b/lib/features/devices/view/widgets/sos/sos_setting/faq_sos_page.dart @@ -0,0 +1,151 @@ +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/sos_bloc/sos_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_event.dart'; +import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_state.dart'; +import 'package:syncrow_app/features/devices/model/device_model.dart'; +import 'package:syncrow_app/features/devices/model/question_model.dart'; +import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/question_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_medium.dart'; +import 'package:syncrow_app/generated/assets.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +class FaqSosPage extends StatelessWidget { + final DeviceModel? device; + + const FaqSosPage({super.key, this.device}); + + @override + Widget build(BuildContext context) { + TextEditingController _searchController = TextEditingController(); + return DefaultScaffold( + title: 'FAQ', + child: BlocProvider( + create: (context) => + SosBloc(sosId: device?.uuid ?? '')..add(const SosInitialQuestion()), + child: BlocBuilder( + builder: (context, state) { + final sensor = BlocProvider.of(context); + + List displayedQuestions = []; + if (state is FaqSearchState) { + displayedQuestions = state.filteredFaqQuestions; + } else if (state is FaqLoadedState) { + displayedQuestions = state.filteredFaqQuestions; + } + return state is SosLoadingState + ? const Center( + child: DefaultContainer( + width: 50, + height: 50, + child: CircularProgressIndicator()), + ) + : RefreshIndicator( + onRefresh: () async { + sensor.add(const SosInitial()); + }, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + DefaultContainer( + padding: const EdgeInsets.all(5), + child: TextFormField( + controller: _searchController, + onChanged: (value) { + sensor.add(SearchFaqEvent(value)); + }, + decoration: InputDecoration( + hintText: 'Enter your questions', + hintStyle: const TextStyle( + color: ColorsManager.textGray, + fontSize: 16, + fontWeight: FontWeight.w400), + suffixIcon: Container( + padding: const EdgeInsets.all(5.0), + margin: const EdgeInsets.all(10.0), + child: SvgPicture.asset( + Assets.searchIcon, + fit: BoxFit.contain, + ), + ), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(8.0), + ), + ), + ), + ), + SizedBox( + height: MediaQuery.of(context).size.height * 0.04, + ), + BodyMedium( + text: _searchController.text.isEmpty + ? 'Device Related FAQs' + : '${displayedQuestions.length} Help Topics', + fontWeight: FontWeight.w700, + fontSize: 12, + fontColor: ColorsManager.grayColor, + ), + Expanded( + child: DefaultContainer( + child: ListView.builder( + shrinkWrap: true, + itemCount: displayedQuestions.length, + itemBuilder: (context, index) { + final faq = displayedQuestions[index]; + return InkWell( + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => QuestionPage( + questionModel: faq, + )), + ); + }, + child: SizedBox( + child: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Row( + children: [ + Expanded( + child: BodyMedium( + fontSize: 14, + fontWeight: FontWeight.w400, + text: faq.question, + ), + ), + const Icon( + Icons.keyboard_arrow_right, + color: ColorsManager.textGray, + ), + ], + ), + ), + const Divider( + color: ColorsManager.dividerColor, + ), + ], + ), + ), + ); + }, + )), + ), + ], + ), + ); + }, + ), + ), + ); + } +} diff --git a/lib/features/devices/view/widgets/sos/sos_setting/location_setting.dart b/lib/features/devices/view/widgets/sos/sos_setting/location_setting.dart new file mode 100644 index 0000000..88312db --- /dev/null +++ b/lib/features/devices/view/widgets/sos/sos_setting/location_setting.dart @@ -0,0 +1,219 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_app/features/app_layout/model/space_model.dart'; +import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_event.dart'; +import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_state.dart'; +import 'package:syncrow_app/features/devices/model/sos_model.dart'; +import 'package:syncrow_app/features/devices/model/subspace_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/features/shared_widgets/text_widgets/body_medium.dart'; +import 'package:syncrow_app/navigation/routing_constants.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +class LocationSosPage extends StatelessWidget { + final SpaceModel? space; + final String? deviceId; + + const LocationSosPage({ + super.key, + this.space, + this.deviceId, + }); + + @override + Widget build(BuildContext context) { + String roomIdSelected = ''; + + return Scaffold( + body: BlocProvider( + create: (context) => SosBloc(sosId: deviceId ?? '') + ..add(const SosInitial()) + ..add(SosInitialDeviseInfo()) + ..add(FetchRoomsEvent(unit: space!)), + child: BlocBuilder( + builder: (context, state) { + final _bloc = BlocProvider.of(context); + SosModel model = + SosModel(batteryPercentage: 0, sosContactState: ''); + if (state is SaveSelectionSuccessState) { + new Future.delayed(const Duration(microseconds: 500), () { + _bloc.add(SosInitial()); + Navigator.of(context).pop(true); + }); + } + return state is SosLoadingState + ? const Center( + child: DefaultContainer( + width: 50, + height: 50, + child: CircularProgressIndicator(), + ), + ) + : DefaultScaffold( + actions: [ + BlocBuilder( + builder: (context, state) { + final bool canSave = state is OptionSelectedState && + state.hasSelectionChanged; + return InkWell( + onTap: canSave + ? () { + context.read().add(AssignRoomEvent( + context: context, + roomId: roomIdSelected, + unit: space!)); + } + : null, + child: BodyMedium( + text: 'Save', + fontWeight: FontWeight.w700, + fontSize: 16, + fontColor: canSave + ? ColorsManager.slidingBlueColor + : ColorsManager.primaryTextColor, + ), + ); + }, + ), + const SizedBox(width: 20), + ], + child: RefreshIndicator( + onRefresh: () async { + // sensor.add(const SosInitial()); + }, + child: ListView( + shrinkWrap: true, + padding: const EdgeInsets.symmetric(vertical: 20), + children: [ + const BodyMedium( + text: 'Smart Device Location', + fontWeight: FontWeight.w700, + fontSize: 12, + fontColor: ColorsManager.grayColor, + ), + const SizedBox(height: 5), + DefaultContainer( + padding: const EdgeInsets.all(20), + child: ListView.builder( + physics: const NeverScrollableScrollPhysics(), + shrinkWrap: true, + itemCount: _bloc.roomsList.length, + itemBuilder: (context, index) { + final fromRoom = _bloc.roomsList[index]; + final isSelected = (state + is OptionSelectedState && + state.selectedOption == fromRoom.id) || + (state is! OptionSelectedState && + fromRoom.id == + _bloc.deviceInfo.subspace.uuid); + + return Column( + children: [ + _buildCheckboxOption( + label: fromRoom.name!, + isSelected: isSelected, + onTap: (label) { + context.read().add( + SelectOptionEvent( + selectedOption: fromRoom.id!, + ), + ); + roomIdSelected = fromRoom.id!; + }, + ), + if (index < _bloc.roomsList.length - 1) ...[ + const SizedBox(height: 10), + const Divider( + color: ColorsManager.dividerColor, + ), + const SizedBox(height: 10), + ], + ], + ); + }, + ), + ), + ], + ), + ), + ); + }, + ), + ), + ); + } +} + +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, + ), + ); + } +} + +Widget _buildCheckboxOption({ + required String label, + required bool isSelected, + required 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: isSelected, + onChanged: (bool? value) { + if (value == true) { + onTap(label); + } + }, + ), + ], + ), + ); +} diff --git a/lib/features/devices/view/widgets/sos/sos_setting/question_page.dart b/lib/features/devices/view/widgets/sos/sos_setting/question_page.dart new file mode 100644 index 0000000..0ae5bd8 --- /dev/null +++ b/lib/features/devices/view/widgets/sos/sos_setting/question_page.dart @@ -0,0 +1,143 @@ +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/sos_bloc/sos_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_event.dart'; +import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_state.dart'; +import 'package:syncrow_app/features/devices/model/question_model.dart'; +import 'package:syncrow_app/features/devices/model/sos_model.dart'; +import 'package:syncrow_app/features/shared_widgets/default_button.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/generated/assets.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +class QuestionPage extends StatelessWidget { + final QuestionModel? questionModel; + + const QuestionPage({super.key, this.questionModel}); + + @override + Widget build(BuildContext context) { + return DefaultScaffold( + title: 'FAQ', + child: BlocProvider( + create: (context) => SosBloc(sosId: '')..add(const SosInitial()), + child: BlocBuilder( + builder: (context, state) { + final sensor = BlocProvider.of(context); + SosModel model = + SosModel(batteryPercentage: 0, sosContactState: 'normal'); + if (state is LoadingNewSate) { + model = state.sosSensor; + } else if (state is UpdateState) { + model = state.sensor; + } + return state is SosLoadingState + ? const Center( + child: DefaultContainer( + width: 50, + height: 50, + child: CircularProgressIndicator()), + ) + : RefreshIndicator( + onRefresh: () async { + sensor.add(const SosInitial()); + }, + child: Column( + children: [ + DefaultContainer( + padding: EdgeInsets.all(15), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + BodyLarge( + text: questionModel!.question, + fontSize: 22, + fontWeight: FontWeight.w400, + fontColor: ColorsManager.blackColor, + ), + SizedBox( + height: 15, + ), + BodyMedium( + text: questionModel!.answer, + fontSize: 14, + fontWeight: FontWeight.w400, + fontColor: ColorsManager.secondaryTextColor, + ), + ], + ), + ), + SizedBox( + height: MediaQuery.of(context).size.height * 0.15, + ), + Center( + child: SizedBox( + width: 180, + child: DefaultButton( + backgroundColor: ColorsManager.grayButtonColors, + borderRadius: 50, + onPressed: () {}, + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SvgPicture.asset( + Assets.thumbUp, + fit: BoxFit.fill, + ), + SizedBox( + width: 10, + ), + BodyMedium( + text: 'Helpful', + fontSize: 12, + fontWeight: FontWeight.w400, + fontColor: ColorsManager.blackColor, + ), + ], + )), + ), + ), + SizedBox( + height: 15, + ), + Center( + child: SizedBox( + width: 180, + child: DefaultButton( + backgroundColor: ColorsManager.grayButtonColors, + borderRadius: 50, + onPressed: () {}, + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SvgPicture.asset( + Assets.thumbDown, + fit: BoxFit.fill, + ), + SizedBox( + width: 10, + ), + BodyMedium( + text: 'Not Helpful', + fontSize: 12, + fontWeight: FontWeight.w400, + fontColor: ColorsManager.blackColor, + ), + ], + )), + ), + ), + ], + )); + }, + ), + ), + ); + } +} diff --git a/lib/features/devices/view/widgets/sos/sos_setting/share_sos_page.dart b/lib/features/devices/view/widgets/sos/sos_setting/share_sos_page.dart new file mode 100644 index 0000000..fdbf4d9 --- /dev/null +++ b/lib/features/devices/view/widgets/sos/sos_setting/share_sos_page.dart @@ -0,0 +1,102 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_event.dart'; +import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_state.dart'; +import 'package:syncrow_app/features/devices/model/device_model.dart'; +import 'package:syncrow_app/features/devices/model/sos_model.dart'; +import 'package:syncrow_app/features/shared_widgets/default_button.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 ShareSosPage extends StatelessWidget { + final DeviceModel? device; + + const ShareSosPage({super.key, this.device}); + + @override + Widget build(BuildContext context) { + return DefaultScaffold( + title: 'Share Device', + child: BlocProvider( + create: (context) => + SosBloc(sosId: device?.uuid ?? '')..add(const SosInitial()), + child: BlocBuilder( + builder: (context, state) { + final sensor = BlocProvider.of(context); + SosModel model = + SosModel(batteryPercentage: 0, sosContactState: 'normal'); + if (state is LoadingNewSate) { + model = state.sosSensor; + } else if (state is UpdateState) { + model = state.sensor; + } + return state is SosLoadingState + ? const Center( + child: DefaultContainer( + width: 50, + height: 50, + child: CircularProgressIndicator()), + ) + : RefreshIndicator( + onRefresh: () async { + sensor.add(const SosInitial()); + }, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const BodyLarge( + text: 'Sharing Method Not Supported', + fontSize: 15, + fontWeight: FontWeight.w400, + fontColor: ColorsManager.blackColor, + ), + const BodyMedium( + text: + 'Currently, you cannot use the specified method to share Bluetooth mesh devices Zigbee devices, infrared devices, Bluetooth Beacon Devices, and certain Bluetooth LE devices with other users.', + fontSize: 14, + fontWeight: FontWeight.w400, + fontColor: ColorsManager.secondaryTextColor, + ), + const SizedBox( + height: 10, + ), + const BodyLarge( + text: 'Recommended Sharing Method', + fontSize: 15, + fontWeight: FontWeight.w400, + fontColor: ColorsManager.blackColor, + ), + const BodyMedium( + text: + 'If the recipient is a home member or a reliable user, tap Me > Home Management > Add Member and add the recipient to your home. Then, devices in the home can be shared with the recipient in bulk.', + fontSize: 14, + fontWeight: FontWeight.w400, + fontColor: ColorsManager.secondaryTextColor, + ), + SizedBox( + height: MediaQuery.of(context).size.height * 0.15, + ), + Center( + child: SizedBox( + width: 250, + child: DefaultButton( + backgroundColor: ColorsManager.blueColor1, + borderRadius: 50, + onPressed: () { + + }, + child: Text('Add Home Member')), + ), + ) + ], + )); + }, + ), + ), + ); + } +} diff --git a/lib/features/devices/view/widgets/sos/sos_setting/sos_info_page.dart b/lib/features/devices/view/widgets/sos/sos_setting/sos_info_page.dart new file mode 100644 index 0000000..1055cb1 --- /dev/null +++ b/lib/features/devices/view/widgets/sos/sos_setting/sos_info_page.dart @@ -0,0 +1,145 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_event.dart'; +import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_state.dart'; +import 'package:syncrow_app/features/devices/model/device_model.dart'; +import 'package:syncrow_app/features/devices/model/sos_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/features/shared_widgets/text_widgets/body_large.dart'; +import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart'; +import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +class SosInfoPage extends StatelessWidget { + final DeviceModel? device; + + const SosInfoPage({super.key, this.device}); + + @override + Widget build(BuildContext context) { + return DefaultScaffold( + title: 'Device Information', + child: BlocProvider( + create: (context) => SosBloc(sosId: device?.uuid ?? '') + ..add(const SosInitial()) + ..add(SosInitialDeviseInfo()), + child: BlocBuilder( + builder: (context, state) { + final _bloc = BlocProvider.of(context); + SosModel model = + SosModel(batteryPercentage: 0, sosContactState: ''); + if (state is LoadingNewSate) { + model = state.sosSensor; + } else if (state is UpdateState) { + model = state.sensor; + } + return state is SosLoadingState + ? const Center( + child: DefaultContainer( + width: 50, + height: 50, + child: CircularProgressIndicator()), + ) + : RefreshIndicator( + onRefresh: () async { + _bloc.add(const SosInitial()); + }, + child: DefaultContainer( + child: Padding( + padding: const EdgeInsets.only(left: 5, right: 5), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + const BodyLarge( + text: 'Virtual ID', + fontSize: 15, + fontWeight: FontWeight.w400, + fontColor: ColorsManager.blackColor, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + BodySmall( + text: _bloc.deviceInfo.productUuid, + fontColor: ColorsManager.primaryTextColor, + ), + InkWell( + onTap: () { + Clipboard.setData( + ClipboardData( + text: _bloc.deviceInfo.productUuid, + ), + ); + + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text("Copied to Clipboard"), + ), + ); + }, + child: const Row( + children: [ + Icon( + Icons.copy, + color: ColorsManager.blueColor, + ), + BodyMedium( + text: 'Copy', + fontColor: ColorsManager.blueColor, + ), + ], + ), + ) + ], + ), + const Divider( + color: ColorsManager.dividerColor, + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + const BodyLarge( + text: 'MAC', + fontSize: 15, + fontWeight: FontWeight.w400, + fontColor: ColorsManager.blackColor, + ), + BodySmall( + text: _bloc.deviceInfo.macAddress, + fontColor: ColorsManager.primaryTextColor, + ), + ], + ), + const Divider( + color: ColorsManager.dividerColor, + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + const BodyLarge( + text: 'Time Zone', + fontSize: 15, + fontWeight: FontWeight.w400, + fontColor: ColorsManager.blackColor, + ), + BodySmall( + text: _bloc.deviceInfo.timeZone, + fontColor: ColorsManager.primaryTextColor, + ), + ], + ), + ]), + ))); + }, + ), + ), + ); + } +} diff --git a/lib/features/devices/view/widgets/sos/sos_setting/sos_profile_page.dart b/lib/features/devices/view/widgets/sos/sos_setting/sos_profile_page.dart new file mode 100644 index 0000000..bf1d0f9 --- /dev/null +++ b/lib/features/devices/view/widgets/sos/sos_setting/sos_profile_page.dart @@ -0,0 +1,191 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart'; +import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_event.dart'; +import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_state.dart'; +import 'package:syncrow_app/features/devices/model/device_model.dart'; +import 'package:syncrow_app/features/devices/model/sos_model.dart'; +import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/location_setting.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_medium.dart'; +import 'package:syncrow_app/generated/assets.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +class SosProfilePage extends StatelessWidget { + final DeviceModel? device; + + const SosProfilePage({super.key, this.device}); + + @override + Widget build(BuildContext context) { + var spaces = HomeCubit.getInstance().spaces; + + return DefaultScaffold( + title: 'Device Settings', + leading: IconButton( + onPressed: () { + Navigator.of(context).pop(true); + }, + icon: const Icon(Icons.arrow_back_ios)), + child: BlocProvider( + create: (context) => SosBloc(sosId: device?.uuid ?? '') + ..add(const SosInitial()) + ..add(SosInitialDeviseInfo()), + child: BlocBuilder( + builder: (context, state) { + final _bloc = BlocProvider.of(context); + SosModel model = + SosModel(batteryPercentage: 0, sosContactState: ''); + if (state is LoadingNewSate) { + model = state.sosSensor; + } else if (state is UpdateState) { + model = state.sensor; + } + return state is SosLoadingState + ? const Center( + child: DefaultContainer( + width: 50, + height: 50, + child: CircularProgressIndicator()), + ) + : RefreshIndicator( + onRefresh: () async { + _bloc.add(const SosInitial()); + }, + child: ListView( + children: [ + CircleAvatar( + radius: 60, + backgroundColor: Colors.white, + child: CircleAvatar( + radius: 55, + backgroundColor: ColorsManager.graysColor, + child: ClipOval( + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const SizedBox( + height: 10, + ), + Center( + child: SvgPicture.asset( + Assets.fourSceneIcon, + fit: BoxFit.contain, + ), + ), + ], + ), + ), + ), + ), + const SizedBox( + height: 10, + ), + SizedBox( + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + IntrinsicWidth( + child: ConstrainedBox( + constraints: + const BoxConstraints(maxWidth: 200), + child: TextFormField( + maxLength: 30, + style: const TextStyle( + color: Colors.black, + ), + textAlign: TextAlign.center, + focusNode: _bloc.focusNode, + controller: _bloc.nameController, + enabled: _bloc.editName, + onEditingComplete: () { + _bloc.add(SaveNameEvent()); + }, + decoration: const InputDecoration( + hintText: "Your Name", + border: InputBorder.none, + fillColor: Colors.white10, + counterText: '', + ), + ), + ), + ), + const SizedBox(width: 5), + InkWell( + onTap: () { + _bloc.add(const ChangeNameEvent(value: true)); + }, + child: const Padding( + padding: EdgeInsets.symmetric(horizontal: 10), + child: Icon( + Icons.edit_outlined, + size: 20, + color: ColorsManager.textPrimaryColor, + ), + ), + ), + ], + ), + ), + const SizedBox(height: 20), + const BodyMedium( + text: 'Smart Device Information', + fontWeight: FontWeight.w700, + fontSize: 12, + fontColor: ColorsManager.grayColor, + ), + DefaultContainer( + padding: const EdgeInsets.all(20), + child: InkWell( + onTap: () async { + bool val = await Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => LocationSosPage( + space: spaces!.first, + deviceId: device?.uuid ?? '', + )), + ); + if (val == true) { + _bloc.add(SosInitialDeviseInfo()); + } + }, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + const SizedBox( + child: Text('Location'), + ), + Row( + children: [ + SizedBox( + child: BodyMedium( + text: _bloc + .deviceInfo.subspace.subspaceName, + fontColor: ColorsManager.textGray, + ), + ), + const Icon( + Icons.arrow_forward_ios, + size: 15, + color: ColorsManager.textGray, + ), + ], + ) + ], + ), + ), + ) + ], + ), + ); + }, + ), + ), + ); + } +} diff --git a/lib/features/devices/view/widgets/sos/sos_setting/sos_update_note.dart b/lib/features/devices/view/widgets/sos/sos_setting/sos_update_note.dart new file mode 100644 index 0000000..03e5f85 --- /dev/null +++ b/lib/features/devices/view/widgets/sos/sos_setting/sos_update_note.dart @@ -0,0 +1,118 @@ +import 'package:flutter/material.dart'; +import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +class SosUpdateNote extends StatelessWidget { + final Function()? cancelTab; + final Function()? confirmTab; + + const SosUpdateNote({ + super.key, + required this.cancelTab, + required this.confirmTab, + }); + + @override + Widget build(BuildContext context) { + return AlertDialog( + contentPadding: EdgeInsets.zero, + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const SizedBox( + height: 10, + ), + BodyLarge( + text: 'Update Note', + fontWeight: FontWeight.w700, + fontColor: ColorsManager.switchButton.withOpacity(0.6), + fontSize: 16, + ), + const Padding( + padding: EdgeInsets.only(left: 15, right: 15), + child: Divider( + color: ColorsManager.textGray, + ), + ), + const Padding( + padding: EdgeInsets.only(left: 15, right: 20, top: 15, bottom: 20), + child: Column( + children: [ + Center( + child: Text( + 'This update may take a long time. Make sure that the device is fully charged. The device will be unavailable during the update.', + textAlign: TextAlign.center, + )), + ], + ), + ), + 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: cancelTab, + child: const Padding( + padding: const EdgeInsets.only(top: 15, bottom: 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: confirmTab, + child: Padding( + padding: const EdgeInsets.only(top: 15, bottom: 15), + child: Center( + child: Text( + 'Start Update', + style: TextStyle( + color: + ColorsManager.switchButton.withOpacity(0.6), + fontSize: 14, + fontWeight: FontWeight.w400), + ), + ), + )), + )) + ], + ) + ], + ), + ); + } +} diff --git a/lib/features/devices/view/widgets/sos/sos_setting/sos_update_page.dart b/lib/features/devices/view/widgets/sos/sos_setting/sos_update_page.dart new file mode 100644 index 0000000..fabd7b2 --- /dev/null +++ b/lib/features/devices/view/widgets/sos/sos_setting/sos_update_page.dart @@ -0,0 +1,344 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:percent_indicator/linear_percent_indicator.dart'; +import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_event.dart'; +import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_state.dart'; +import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/sos_update_note.dart'; +import 'package:syncrow_app/features/shared_widgets/default_button.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_medium.dart'; +import 'package:syncrow_app/generated/assets.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +class SosUpdatePage extends StatelessWidget { + const SosUpdatePage({super.key}); + + @override + Widget build(BuildContext context) { + return DefaultScaffold( + title: 'Device Update', + child: BlocProvider( + create: (context) => SosBloc(sosId: '')..add(const SosInitial()), + child: BlocBuilder( + builder: (context, state) { + return state is SosLoadingState + ? const Center( + child: DefaultContainer( + width: 50, + height: 50, + child: CircularProgressIndicator()), + ) + : RefreshIndicator( + onRefresh: () async {}, + child: Column( + children: [ + // SizedBox( + // height: MediaQuery.of(context).size.height * 0.15, + // ), + DefaultContainer( + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + height: 50, + child: ListTile( + contentPadding: EdgeInsets.zero, + leading: SizedBox( + width: 200, + child: Row( + children: [ + Container( + padding: const EdgeInsets.all(10), + decoration: const BoxDecoration( + color: + ColorsManager.primaryColor, + borderRadius: BorderRadius.all( + Radius.circular(50))), + child: SvgPicture.asset( + Assets.checkUpdateIcon, + fit: BoxFit.fill, + height: 25, + ), + ), + const SizedBox( + width: 10, + ), + InkWell( + onTap: () {}, + child: const BodyMedium( + text: 'Automatic Update', + fontWeight: FontWeight.normal, + ), + ), + ], + ), + ), + trailing: Container( + width: 100, + child: Row( + mainAxisAlignment: + MainAxisAlignment.end, + children: [ + const BodyMedium( + text: 'Off', + fontColor: ColorsManager.textGray, + ), + Transform.scale( + scale: .8, + child: CupertinoSwitch( + value: true, + onChanged: (value) {}, + applyTheme: true, + ), + ), + ], + ), + )), + ), + ], + ), + ), + const SizedBox( + height: 10, + ), + UpdateSosContainerWithProgressBar( + sosDescription: + 'Connectivity Issue Resolved Fixed a bug that caused the SOS button to disconnect from the app intermittently.', + sosVersion: 'SOS v2.0.5', + ), + // const UpdatedContainer( + // sosVersion: 'SOS v1.0.13', + // sosDescription: 'SOS is up to date', + // ), + + // const NewUpdateContainer( + // sosVersion: 'SOS v2.0.5', + // sosDescription: + // 'Connectivity Issue Resolved Fixed a bug that caused the SOS button to disconnect from the app intermittently.', + // ), + const SizedBox( + height: 15, + ), + ], + )); + }, + ), + ), + ); + } +} + +class UpdatedContainer extends StatelessWidget { + final String? sosVersion; + final String? sosDescription; + const UpdatedContainer({ + this.sosVersion, + this.sosDescription, + super.key, + }); + + @override + Widget build(BuildContext context) { + return DefaultContainer( + height: MediaQuery.of(context).size.height * 0.35, + child: Padding( + padding: const EdgeInsets.all(25), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SvgPicture.asset( + Assets.emptyUpdateIcon, + fit: BoxFit.fill, + ), + BodyMedium( + text: sosVersion!, + fontColor: ColorsManager.primaryTextColor, + ), + BodyMedium( + text: sosDescription!, + fontColor: ColorsManager.blackColor, + ), + ], + ), + ], + ), + ), + ); + } +} + +class NewUpdateContainer extends StatelessWidget { + final String? sosVersion; + final String? sosDescription; + const NewUpdateContainer({ + this.sosVersion, + this.sosDescription, + super.key, + }); + + @override + Widget build(BuildContext context) { + return DefaultContainer( + height: MediaQuery.of(context).size.height * 0.50, + child: Padding( + padding: const EdgeInsets.all(25), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SvgPicture.asset( + Assets.emptyUpdateIcon, + fit: BoxFit.fill, + ), + const BodyMedium( + text: 'New Update Available Now!', + fontColor: ColorsManager.blueColor, + ), + BodyMedium( + text: sosVersion!, + fontColor: ColorsManager.primaryTextColor, + ), + Container( + width: MediaQuery.of(context).size.width * 0.7, + child: BodyMedium( + text: sosDescription!, + fontColor: ColorsManager.textPrimaryColor, + textAlign: TextAlign.center, + ), + ), + SizedBox( + width: MediaQuery.of(context).size.width * 0.6, + child: DefaultButton( + borderRadius: 25, + backgroundColor: ColorsManager.blueColor1, + height: 150, + onPressed: () { + showDialog( + context: context, + builder: (context) { + return SosUpdateNote( + cancelTab: () { + Navigator.of(context).pop(); + }, + confirmTab: () { + Navigator.of(context).pop(); + }, + ); + }, + ); + }, + child: const BodyMedium( + text: 'Update Now', + fontColor: Colors.white, + fontSize: 16, + fontWeight: FontWeight.w700, + textAlign: TextAlign.center, + ), + ), + ) + ], + ), + ], + ), + ), + ); + } +} + +class UpdateSosContainerWithProgressBar extends StatelessWidget { + final String? sosVersion; + final String? sosDescription; + const UpdateSosContainerWithProgressBar({ + this.sosVersion, + this.sosDescription, + super.key, + }); + + @override + Widget build(BuildContext context) { + return Column( + children: [ + DefaultContainer( + height: MediaQuery.of(context).size.height * 0.50, + child: Padding( + padding: const EdgeInsets.all(25), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SvgPicture.asset( + Assets.emptyUpdateIcon, + fit: BoxFit.fill, + ), + const BodyMedium( + text: 'New Update Available Now!', + fontColor: ColorsManager.blueColor, + ), + BodyMedium( + text: sosVersion!, + fontColor: ColorsManager.primaryTextColor, + ), + SizedBox( + width: MediaQuery.of(context).size.width * 0.7, + child: BodyMedium( + text: sosDescription!, + fontColor: ColorsManager.textPrimaryColor, + textAlign: TextAlign.center, + ), + ), + LinearPercentIndicator( + barRadius: Radius.circular(10), + width: 170.0, + animation: true, + animationDuration: 1000, + lineHeight: 5.0, + percent: 0.2, + linearStrokeCap: LinearStrokeCap.butt, + progressColor: ColorsManager.blueColor1, + ), + SizedBox( + width: MediaQuery.of(context).size.width * 0.7, + child: const BodyMedium( + text: 'Downloading Update please be patient', + fontColor: ColorsManager.textPrimaryColor, + textAlign: TextAlign.center, + ), + ), + ], + ), + ], + ), + ), + ), + SizedBox( + width: MediaQuery.of(context).size.width * 0.7, + child: const BodyMedium( + text: + 'Please keep the power of the device connected during the upgrade process.', + fontColor: ColorsManager.textPrimaryColor, + textAlign: TextAlign.center, + ), + ), + ], + ); + } +} diff --git a/lib/features/devices/view/widgets/sos/sos_setting/update_dialog_sos.dart b/lib/features/devices/view/widgets/sos/sos_setting/update_dialog_sos.dart new file mode 100644 index 0000000..0529161 --- /dev/null +++ b/lib/features/devices/view/widgets/sos/sos_setting/update_dialog_sos.dart @@ -0,0 +1,118 @@ +import 'package:flutter/material.dart'; +import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +class UpdateInfoDialog extends StatelessWidget { + final Function()? cancelTab; + final Function()? confirmTab; + + const UpdateInfoDialog({ + super.key, + required this.cancelTab, + required this.confirmTab, + }); + + @override + Widget build(BuildContext context) { + return AlertDialog( + contentPadding: EdgeInsets.zero, + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const SizedBox( + height: 10, + ), + BodyLarge( + text: 'Update Available', + fontWeight: FontWeight.w700, + fontColor: ColorsManager.switchButton.withOpacity(0.6), + fontSize: 16, + ), + const Padding( + padding: EdgeInsets.only(left: 15, right: 15), + child: Divider( + color: ColorsManager.textGray, + ), + ), + const Padding( + padding: EdgeInsets.only(left: 15, right: 20, top: 15, bottom: 20), + child: Column( + children: [ + Center( + child: Text( + 'An update is available for your device. Version 2.1.0 includes new features and important fixes to enhance performance and security.', + textAlign: TextAlign.center, + )), + ], + ), + ), + 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: cancelTab, + child: const Padding( + padding: const EdgeInsets.only(top: 15, bottom: 15), + child: Center( + child: Text( + 'Remind me later', + 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: confirmTab, + child: Padding( + padding: const EdgeInsets.only(top: 15, bottom: 15), + child: Center( + child: Text( + 'Update Now', + style: TextStyle( + color: + ColorsManager.switchButton.withOpacity(0.6), + fontSize: 14, + fontWeight: FontWeight.w400), + ), + ), + )), + )) + ], + ) + ], + ), + ); + } +} diff --git a/lib/features/devices/view/widgets/sos/sos_settings.dart b/lib/features/devices/view/widgets/sos/sos_settings.dart new file mode 100644 index 0000000..8971452 --- /dev/null +++ b/lib/features/devices/view/widgets/sos/sos_settings.dart @@ -0,0 +1,484 @@ +import 'package:flutter/cupertino.dart'; +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/sos_bloc/sos_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_event.dart'; +import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_state.dart'; +import 'package:syncrow_app/features/devices/model/device_model.dart'; +import 'package:syncrow_app/features/devices/model/sos_model.dart'; +import 'package:syncrow_app/features/devices/model/subspace_model.dart'; +import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/delete_dialog.dart'; +import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/sos_profile_page.dart'; +import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/faq_sos_page.dart'; +import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/share_sos_page.dart'; +import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/sos_info_page.dart'; +import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/sos_update_page.dart'; +import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/update_dialog_sos.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_medium.dart'; +import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart'; +import 'package:syncrow_app/generated/assets.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +class SosSettings extends StatelessWidget { + final DeviceModel? device; + const SosSettings({ + super.key, + this.device, + }); + + @override + Widget build(BuildContext context) { + return DefaultScaffold( + title: 'Device Settings', + child: BlocProvider( + create: (context) => SosBloc(sosId: device?.uuid ?? '') + ..add(const SosInitial()) + ..add(SosInitialDeviseInfo()), + child: BlocBuilder( + builder: (context, state) { + final _bloc = BlocProvider.of(context); + + SosModel model = + SosModel(batteryPercentage: 0, sosContactState: 'normal'); + if (state is LoadingNewSate) { + model = state.sosSensor; + } else if (state is UpdateState) { + model = state.sensor; + } + return state is SosLoadingState + ? const Center( + child: DefaultContainer( + width: 50, + height: 50, + child: CircularProgressIndicator()), + ) + : ListView( + children: [ + Padding( + padding: const EdgeInsets.symmetric( + vertical: 10, + ), + child: InkWell( + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => SosProfilePage( + device: device, + ), + ), + ); + }, + child: Stack( + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + const SizedBox(height: 20), + DefaultContainer( + borderRadius: const BorderRadius.all( + Radius.circular(30)), + child: Padding( + padding: const EdgeInsets.all(10.0), + child: Padding( + padding: + const EdgeInsets.only(left: 90), + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + const BodyMedium( + text: 'SOS', + fontWeight: FontWeight.bold, + ), + const SizedBox( + height: 5, + ), + BodySmall( + text: _bloc.deviceInfo + .subspace.subspaceName), + ], + ), + const Icon( + Icons.edit_outlined, + color: ColorsManager.grayColor, + ), + ], + ), + ), + ), + ), + ], + ), + Positioned( + top: 0, + left: 20, + child: CircleAvatar( + radius: 40, + backgroundColor: Colors.white, + child: CircleAvatar( + radius: 40, + backgroundColor: Colors.grey, + child: ClipOval( + child: SvgPicture.asset( + Assets.sosProfileIcon, + fit: BoxFit.fill, + ), + ), + ), + ), + ), + ], + ), + ), + ), + const SizedBox(height: 20), + const BodyMedium( + text: 'Device Management', + fontWeight: FontWeight.w700, + fontSize: 12, + fontColor: ColorsManager.grayColor, + ), + DefaultContainer( + child: SettingWidget( + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => + SosInfoPage(device: device!)), + ); + }, + text: 'Device Information', + icon: Assets.infoIcon, + ), + ), + const SizedBox(height: 20), + const BodyMedium( + text: 'Device Offline Notification', + fontWeight: FontWeight.w700, + fontSize: 12, + fontColor: ColorsManager.grayColor, + ), + DefaultContainer( + child: Column( + children: [ + SettingWidget( + onChanged: (p0) {}, + isNotification: true, + onTap: () {}, + text: 'Offline Notification', + icon: Assets.notificationIcon, + ), + ], + ), + ), + const SizedBox(height: 20), + const BodyMedium( + text: 'Others', + fontWeight: FontWeight.w700, + fontSize: 12, + fontColor: ColorsManager.grayColor, + ), + const SizedBox(height: 5), + DefaultContainer( + child: Column( + children: [ + SettingWidget( + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => + ShareSosPage(device: device!)), + ); + }, + text: 'Share Device', + icon: Assets.shareIcon, + ), + const Divider( + color: ColorsManager.dividerColor, + ), + SettingWidget( + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => + FaqSosPage(device: device!)), + ); + }, + text: 'Device FAQ', + icon: Assets.faqIcon, + ), + const Divider( + color: ColorsManager.dividerColor, + ), + SettingWidget( + onTapUpdate: () { + showDialog( + context: context, + builder: (context) { + return UpdateInfoDialog( + cancelTab: () { + Navigator.of(context).pop(); + }, + confirmTab: () { + // context + // .read< + // CreateSceneBloc>() + // .add(DeleteSceneEvent( + // sceneId: sceneId, + // unitUuid: HomeCubit + // .getInstance() + // .selectedSpace! + // .id!, + // )); + Navigator.of(context).pop(); + }, + ); + }, + ); + }, + isUpdate: true, + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => + const SosUpdatePage()), + ); + }, + text: 'Device Update', + icon: Assets.updateIcon, + ), + ], + ), + ), + const SizedBox(height: 20), + InkWell( + onTap: () { + showModalBottomSheet( + context: context, + builder: (BuildContext context) { + return Container( + height: 200, + padding: const EdgeInsets.all(16.0), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const BodyMedium( + text: 'Remove Device', + fontWeight: FontWeight.w700, + fontSize: 16, + fontColor: ColorsManager.red, + ), + const SizedBox(height: 10), + const SizedBox( + width: 250, + child: Divider( + color: ColorsManager.dividerColor, + ), + ), + const SizedBox(height: 10), + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + InkWell( + onTap: () { + showDialog( + context: context, + builder: (context) { + return DisconnectDeviceDialog( + cancelTab: () { + Navigator.of(context).pop(); + }, + confirmTab: () { + // context + // .read< + // CreateSceneBloc>() + // .add(DeleteSceneEvent( + // sceneId: sceneId, + // unitUuid: HomeCubit + // .getInstance() + // .selectedSpace! + // .id!, + // )); + Navigator.of(context).pop(); + }, + ); + }, + ); + }, + child: const BodyMedium( + text: 'Disconnect Device', + fontWeight: FontWeight.w400, + fontSize: 15, + fontColor: + ColorsManager.textPrimaryColor, + ), + ), + const Icon( + Icons.keyboard_arrow_right, + color: ColorsManager.textGray, + ) + ], + ), + const SizedBox(height: 20), + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + InkWell( + onTap: () { + showDialog( + context: context, + builder: (context) { + return DisconnectWipeData( + cancelTab: () { + Navigator.of(context).pop(); + }, + confirmTab: () { + // context + // .read< + // CreateSceneBloc>() + // .add(DeleteSceneEvent( + // sceneId: sceneId, + // unitUuid: HomeCubit + // .getInstance() + // .selectedSpace! + // .id!, + // )); + Navigator.of(context).pop(); + }, + ); + }, + ); + }, + child: const BodyMedium( + text: + 'Disconnect Device and Wipe Data', + fontWeight: FontWeight.w400, + fontSize: 15, + fontColor: + ColorsManager.textPrimaryColor, + ), + ), + const Icon( + Icons.keyboard_arrow_right, + color: ColorsManager.textGray, + ) + ], + ), + ], + ), + ); + }, + ); + }, + child: const Center( + child: BodyMedium( + text: 'Remove Device', + fontWeight: FontWeight.w400, + fontSize: 15, + fontColor: ColorsManager.red, + ), + ), + ), + ], + ); + }, + ), + ), + ); + } +} + +class SettingWidget extends StatelessWidget { + final String? text; + final bool? isUpdate; + final bool? isNotification; + final String? icon; + final Function()? onTap; + final Function()? onTapUpdate; + final Function(bool)? onChanged; + const SettingWidget( + {super.key, + this.text, + this.icon, + this.onTap, + this.isUpdate, + this.onChanged, + this.isNotification = false, + this.onTapUpdate}); + + @override + Widget build(BuildContext context) { + return InkWell( + onTap: onTap, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Row( + children: [ + Expanded( + flex: 2, + child: Container( + padding: EdgeInsets.all(8), + decoration: const BoxDecoration( + color: ColorsManager.primaryColor, + borderRadius: BorderRadius.all(Radius.circular(20))), + child: SvgPicture.asset( + icon!, + fit: BoxFit.none, + height: 30, + ), + ), + ), + const SizedBox( + width: 8, + ), + Expanded( + flex: isUpdate == true ? 5 : 10, + child: BodyMedium( + text: text!, + fontSize: 15, + fontWeight: FontWeight.w400, + )), + ], + ), + ), + isUpdate == true + ? InkWell( + onTap: onTapUpdate, + child: const BodyMedium( + text: '1 Update Available', + fontSize: 13, + fontWeight: FontWeight.w400, + fontColor: ColorsManager.blueColor, + ), + ) + : SizedBox(), + isNotification == false + ? const Icon( + Icons.arrow_forward_ios, + color: ColorsManager.graysColor, + size: 20, + ) + : Transform.scale( + scale: .8, + child: CupertinoSwitch( + value: true, + onChanged: onChanged, + applyTheme: true, + ), + ), + ], + ), + ); + } +} diff --git a/lib/features/devices/view/widgets/sos/sos_status_bar.dart b/lib/features/devices/view/widgets/sos/sos_status_bar.dart new file mode 100644 index 0000000..e1be227 --- /dev/null +++ b/lib/features/devices/view/widgets/sos/sos_status_bar.dart @@ -0,0 +1,58 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:syncrow_app/features/devices/model/smart_door_model.dart'; +import 'package:syncrow_app/generated/assets.dart'; + +class SosStatusBar extends StatelessWidget { + const SosStatusBar({ + required this.smartDoorModel, + super.key, + }); + + final SmartDoorModel smartDoorModel; + + @override + Widget build(BuildContext context) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + SvgPicture.asset(Assets.assetsIconsWifi), + Transform.rotate( + angle: 1.5708, // 90 degrees in radians (Ï€/2 or 1.5708) + child: Icon( + _getBatteryIcon(smartDoorModel.residualElectricity), + color: _getBatteryColor(smartDoorModel.residualElectricity), + size: 30, + ), + ), + ], + ); + } + + IconData _getBatteryIcon(int batteryLevel) { + // if (batteryState == BatteryState.charging) { + // return Icons.battery_charging_full; + // } else + if (batteryLevel >= 80) { + return Icons.battery_full; + } else if (batteryLevel >= 60) { + return Icons.battery_4_bar; + } else if (batteryLevel >= 40) { + return Icons.battery_3_bar; + } else if (batteryLevel >= 20) { + return Icons.battery_2_bar; + } else { + return Icons.battery_alert; + } + } + + Color _getBatteryColor(int batteryLevel) { + if (batteryLevel >= 80) { + return Colors.green; + } else if (batteryLevel >= 40) { + return Colors.yellowAccent; + } else { + return Colors.red; + } + } +} diff --git a/lib/generated/assets.dart b/lib/generated/assets.dart index 7e7ed11..b08142a 100644 --- a/lib/generated/assets.dart +++ b/lib/generated/assets.dart @@ -1118,6 +1118,9 @@ class Assets { static const String minusIcon = "assets/icons/minus_icon.svg"; static const String addDevicesIcon = "assets/icons/add_devices_icon.svg"; static const String fourSceneIcon = "assets/icons/four_scene_icon.svg"; - static const String fourSceneHomeIcon = "assets/icons/four_scene_home_icon.svg"; + static const String fourSceneHomeIcon = + "assets/icons/four_scene_home_icon.svg"; static const String sixSceneHomeIcon = "assets/icons/six_scene_home_icon.svg"; + static const String editDeviceNameIcon = + "assets/icons/edit_device_name_icon.svg"; } diff --git a/lib/utils/resource_manager/constants.dart b/lib/utils/resource_manager/constants.dart index e995a16..8ffaa7b 100644 --- a/lib/utils/resource_manager/constants.dart +++ b/lib/utils/resource_manager/constants.dart @@ -58,6 +58,7 @@ enum DeviceType { PC, FourScene, SixScene, + SOS, Other, } @@ -92,7 +93,9 @@ Map devicesTypesMap = { "PC": DeviceType.PC, "4S": DeviceType.FourScene, "6S": DeviceType.SixScene, + "SOS": DeviceType.SOS, }; + Map> devicesFunctionsMap = { DeviceType.AC: [ FunctionModel( @@ -592,7 +595,17 @@ Map> devicesFunctionsMap = { code: 'switch_backlight', type: functionTypesMap['Enum'], values: ValueModel.fromJson({})), - ] + ], + DeviceType.SOS: [ + FunctionModel( + code: 'contact_state', + type: functionTypesMap['Raw'], + values: ValueModel.fromJson({})), + FunctionModel( + code: 'battery_percentage', + type: functionTypesMap['Integer'], + values: ValueModel.fromJson({})), + ], }; enum TempModes { hot, cold, wind } From efe68ecb1a5979cdd837b3f1d41e3ceb4bd7a25a Mon Sep 17 00:00:00 2001 From: mohammad Date: Sun, 24 Nov 2024 17:04:29 +0300 Subject: [PATCH 14/29] issue fixes --- .../6_scene_switch_bloc/6_scene_bloc.dart | 14 ++ .../bloc/four_scene_bloc/four_scene_bloc.dart | 17 +- .../devices/bloc/sos_bloc/sos_bloc.dart | 15 +- .../6_scene_setting/six_scene_info_page.dart | 10 +- .../6_scene_setting/six_scene_settings.dart | 11 +- .../6_scene_switch/six_scene_screen.dart | 169 +++++++++--------- .../four_scene_switch/four_scene_screen.dart | 156 ++++++++-------- .../four_scene_info_page.dart | 10 +- .../four_scene_profile_page.dart | 1 + .../four_scene_settings.dart | 11 +- .../devices/view/widgets/sos/sos_screen.dart | 124 +++++++------ .../sos/sos_setting/sos_info_page.dart | 10 +- .../sos/sos_setting/sos_profile_page.dart | 20 +-- .../view/widgets/sos/sos_settings.dart | 33 +++- 14 files changed, 332 insertions(+), 269 deletions(-) diff --git a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart index 68c33ad..b454060 100644 --- a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart +++ b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart @@ -47,6 +47,7 @@ class SixSceneBloc extends Bloc { on(_fetchRoomsAndDevices); on(_onSixSceneInitial); on(deleteDevice); + on(_toggleLowBattery); } final TextEditingController nameController = @@ -101,6 +102,19 @@ class SixSceneBloc extends Bloc { ), ); + bool enableAlarm = false; + + void _toggleLowBattery( + ToggleEnableAlarmEvent event, Emitter emit) async { + emit(LoadingNewSate(device: deviceStatus)); + try { + enableAlarm = event.isLowBatteryEnabled; + emit(UpdateState(device: deviceStatus)); + } catch (e) { + emit(SixSceneFailedState(errorMessage: e.toString())); + } + } + List roomsList = []; void _fetchRoomsAndDevices( diff --git a/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart b/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart index 4987e7a..efb89dd 100644 --- a/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart +++ b/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart @@ -48,6 +48,7 @@ class FourSceneBloc extends Bloc { on(getSceneByName); on(_selectScene); on(deleteDevice); + on(_toggleLowBattery); } final TextEditingController nameController = @@ -144,6 +145,7 @@ class FourSceneBloc extends Bloc { } bool selecedScene = false; + bool enableAlarm = false; String _selectedOption = ''; bool _hasSelectionChanged = false; @@ -259,6 +261,18 @@ class FourSceneBloc extends Bloc { } } + + void _toggleLowBattery( + ToggleEnableAlarmEvent event, Emitter emit) async { + emit(LoadingNewSate(device: deviceStatus)); + try { + enableAlarm = event.isLowBatteryEnabled; + emit(UpdateState(device: deviceStatus)); + } catch (e) { + emit(FourSceneFailedState(errorMessage: e.toString())); + } + } + // void _controlDevice( // ControlDeviceScene event, Emitter emit) async { // emit(FourSceneLoadingState()); @@ -320,7 +334,7 @@ class FourSceneBloc extends Bloc { ToggleNotificationEvent event, Emitter emit) async { emit(LoadingNewSate(device: deviceStatus)); try { - closingReminder = event.isClosingEnabled; + enableAlarm = event.isClosingEnabled; emit(UpdateState(device: deviceStatus)); // API call to update the state, if necessary // await DevicesAPI.controlDevice( @@ -483,6 +497,7 @@ class FourSceneBloc extends Bloc { } emit(UpdateStateList(groupDevices: groupDevices, devices: devices)); } + void _assignDevice( AssignRoomEvent event, Emitter emit) async { try { diff --git a/lib/features/devices/bloc/sos_bloc/sos_bloc.dart b/lib/features/devices/bloc/sos_bloc/sos_bloc.dart index 02d385e..3fcf131 100644 --- a/lib/features/devices/bloc/sos_bloc/sos_bloc.dart +++ b/lib/features/devices/bloc/sos_bloc/sos_bloc.dart @@ -38,12 +38,13 @@ class SosBloc extends Bloc { on(_onSaveSelection); on(_assignDevice); on(fetchDeviceInfo); + on(saveName); // on(_unassignDevice); // on(_toggleWaterLeakAlarm); } final TextEditingController nameController = - TextEditingController(text: '${'firstName'}'); + TextEditingController(text: deviceName); bool isSaving = false; bool editName = false; final FocusNode focusNode = FocusNode(); @@ -52,7 +53,7 @@ class SosBloc extends Bloc { bool closingReminder = false; bool waterAlarm = false; SosModel deviceStatus = - SosModel(sosContactState: 'normal', batteryPercentage: 0); + SosModel(sosContactState: 'sos', batteryPercentage: 0); void _fetchStatus(SosInitial event, Emitter emit) async { emit(SosLoadingState()); @@ -156,16 +157,6 @@ class SosBloc extends Bloc { try { closingReminder = event.isClosingReminderEnabled; emit(UpdateState(sensor: deviceStatus)); - - // API call to update the state, if necessary - // await DevicesAPI.controlDevice( - // DeviceControlModel( - // deviceId: sosId, - // code: 'closing_reminder', - // value: closingReminder, - // ), - // sosId, - // ); } catch (e) { emit(SosFailedState(errorMessage: e.toString())); } diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_info_page.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_info_page.dart index 4d133c8..a031651 100644 --- a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_info_page.dart +++ b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_info_page.dart @@ -71,9 +71,13 @@ class SixSceneInfoPage extends StatelessWidget { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - BodySmall( - text: _bloc.deviceInfo.productUuid, - fontColor: ColorsManager.primaryTextColor, + SizedBox( + width: + MediaQuery.of(context).size.width * 0.61, + child: BodySmall( + text: _bloc.deviceInfo.productUuid, + fontColor: ColorsManager.primaryTextColor, + ), ), InkWell( onTap: () { diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_settings.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_settings.dart index 43c5fad..60495e4 100644 --- a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_settings.dart +++ b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_settings.dart @@ -194,7 +194,12 @@ class SixSceneSettings extends StatelessWidget { child: Column( children: [ SettingWidget( - onChanged: (p0) {}, + value: _bloc.enableAlarm, + onChanged: (p0) { + context + .read() + .add(ToggleEnableAlarmEvent(p0)); + }, isNotification: true, onTap: () {}, text: 'Offline Notification', @@ -430,6 +435,7 @@ class SixSceneSettings extends StatelessWidget { class SettingWidget extends StatelessWidget { final String? text; final bool? isUpdate; + final bool? value; final bool? isNotification; final String? icon; final Function()? onTap; @@ -440,6 +446,7 @@ class SettingWidget extends StatelessWidget { this.text, this.icon, this.onTap, + this.value, this.isUpdate, this.onChanged, this.isNotification = false, @@ -502,7 +509,7 @@ class SettingWidget extends StatelessWidget { : Transform.scale( scale: .8, child: CupertinoSwitch( - value: true, + value: value!, onChanged: onChanged, applyTheme: true, ), diff --git a/lib/features/devices/view/widgets/6_scene_switch/six_scene_screen.dart b/lib/features/devices/view/widgets/6_scene_switch/six_scene_screen.dart index 294649d..25d929c 100644 --- a/lib/features/devices/view/widgets/6_scene_switch/six_scene_screen.dart +++ b/lib/features/devices/view/widgets/6_scene_switch/six_scene_screen.dart @@ -24,50 +24,54 @@ class SixSceneScreen extends StatelessWidget { @override Widget build(BuildContext context) { - return DefaultScaffold( - title: '6 Scene Switch', - actions: [ - InkWell( - onTap: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => SixSceneSettings(device: device!)), - ); - }, - child: SvgPicture.asset(Assets.assetsIconsSettings)), - const SizedBox( - width: 10, - ) - ], - child: BlocProvider( - create: (context) => SixSceneBloc(sixSceneId: device?.uuid ?? '') - ..add(const SixSceneInitial()) - ..add(const SixSceneInitialInfo()) - ..add(const SexSceneSwitchInitial()), - child: BlocBuilder( - builder: (context, state) { - final _bloc = BlocProvider.of(context); - SixSceneModel model = SixSceneModel( - scene_1: '', - scene_2: '', - scene_3: '', - scene_4: '', - scene_5: '', - scene_6: '', - scene_id_group_id: '', - switch_backlight: ''); + return BlocProvider( + create: (context) => SixSceneBloc(sixSceneId: device?.uuid ?? '') + ..add(const SixSceneInitial()) + ..add(const SixSceneInitialInfo()) + ..add(const SexSceneSwitchInitial()), + child: BlocBuilder( + builder: (context, state) { + final _bloc = BlocProvider.of(context); - if (state is LoadingNewSate) { - model = state.device; - } else if (state is UpdateState) { - model = state.device; - } - return state is SixSceneLoadingState + SixSceneModel model = SixSceneModel( + scene_1: '', + scene_2: '', + scene_3: '', + scene_4: '', + scene_5: '', + scene_6: '', + scene_id_group_id: '', + switch_backlight: '', + ); + + if (state is LoadingNewSate) { + model = state.device; + } else if (state is UpdateState) { + model = state.device; + } + + return DefaultScaffold( + title: _bloc.deviceInfo.subspace.subspaceName, + actions: [ + InkWell( + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => SixSceneSettings(device: device!), + ), + ); + }, + child: SvgPicture.asset(Assets.assetsIconsSettings), + ), + const SizedBox(width: 10), + ], + child: state is SixSceneLoadingState ? const Center( child: DefaultContainer( - width: 50, - height: 50, - child: CircularProgressIndicator()), + width: 50, + height: 50, + child: CircularProgressIndicator(), + ), ) : RefreshIndicator( onRefresh: () async { @@ -86,30 +90,24 @@ class SixSceneScreen extends StatelessWidget { switch4Title: model.scene_4, switch5Title: model.scene_5, switch6Title: model.scene_6, - switch1Down: - _bloc.deviceStatus.switch_backlight == true - ? Assets.switchOn - : Assets.switchOff, - switch1Up: - _bloc.deviceStatus.switch_backlight == true - ? Assets.switchOn - : Assets.switchOff, - switch2Down: - _bloc.deviceStatus.switch_backlight == true - ? Assets.switchOn - : Assets.switchOff, - switch2Up: - _bloc.deviceStatus.switch_backlight == true - ? Assets.switchOn - : Assets.switchOff, - switch3Up: - _bloc.deviceStatus.switch_backlight == true - ? Assets.switchOn - : Assets.switchOff, - switch3Down: - _bloc.deviceStatus.switch_backlight == true - ? Assets.switchOn - : Assets.switchOff, + switch1Down: _bloc.deviceStatus.switch_backlight + ? Assets.switchOn + : Assets.switchOff, + switch1Up: _bloc.deviceStatus.switch_backlight + ? Assets.switchOn + : Assets.switchOff, + switch2Down: _bloc.deviceStatus.switch_backlight + ? Assets.switchOn + : Assets.switchOff, + switch2Up: _bloc.deviceStatus.switch_backlight + ? Assets.switchOn + : Assets.switchOff, + switch3Up: _bloc.deviceStatus.switch_backlight + ? Assets.switchOn + : Assets.switchOff, + switch3Down: _bloc.deviceStatus.switch_backlight + ? Assets.switchOn + : Assets.switchOff, onSwitch3DownTap: () { debugPrint("onSwitch3DownTap"); }, @@ -136,7 +134,6 @@ class SixSceneScreen extends StatelessWidget { child: DefaultContainer( onTap: () { _bloc.add(ChangeSwitchStatusEvent()); - }, child: Column( crossAxisAlignment: @@ -146,13 +143,13 @@ class SixSceneScreen extends StatelessWidget { children: [ ConstrainedBox( constraints: const BoxConstraints( - maxHeight: 46, maxWidth: 50), + maxHeight: 46, + maxWidth: 50, + ), child: SvgPicture.asset( Assets.backlightIcon), ), - const SizedBox( - height: 15, - ), + const SizedBox(height: 15), const Flexible( child: FittedBox( child: BodySmall( @@ -165,9 +162,7 @@ class SixSceneScreen extends StatelessWidget { ), ), ), - const SizedBox( - width: 10, - ), + const SizedBox(width: 10), Expanded( child: DefaultContainer( onTap: () async { @@ -187,12 +182,12 @@ class SixSceneScreen extends StatelessWidget { confirmTab: (v) { Navigator.of(context).push( MaterialPageRoute( - builder: (context) => - SixSelectSceneFourPage( - deviceId: - device!.uuid, - switchSelected: v, - )), + builder: (context) => + SixSelectSceneFourPage( + deviceId: device!.uuid, + switchSelected: v, + ), + ), ); }, ); @@ -214,13 +209,13 @@ class SixSceneScreen extends StatelessWidget { children: [ ConstrainedBox( constraints: const BoxConstraints( - maxHeight: 46, maxWidth: 50), + maxHeight: 46, + maxWidth: 50, + ), child: SvgPicture.asset( Assets.addSceneIcon), ), - const SizedBox( - height: 15, - ), + const SizedBox(height: 15), const Flexible( child: FittedBox( child: BodySmall( @@ -235,15 +230,15 @@ class SixSceneScreen extends StatelessWidget { ), ], ), - ) + ), ], ), ), ], ), - ); - }, - ), + ), + ); + }, ), ); } diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_screen.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_screen.dart index 86bc1d3..224e30b 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_screen.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_screen.dart @@ -24,47 +24,52 @@ class FourSceneScreen extends StatelessWidget { @override Widget build(BuildContext context) { - return DefaultScaffold( - title: '4 Scene Switch', - actions: [ - InkWell( - onTap: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => FourSceneSettings(device: device!)), - ); - }, - child: SvgPicture.asset(Assets.assetsIconsSettings)), - const SizedBox( - width: 10, - ) - ], - child: BlocProvider( - create: (context) => FourSceneBloc(fourSceneId: device?.uuid ?? '') - ..add(const FourSceneInitial()) - ..add(const FourSceneInitialInfo()) - ..add(const FourSceneSwitchInitial()), - child: BlocBuilder( - builder: (context, state) { - final _bloc = BlocProvider.of(context); - FourSceneModelState model = FourSceneModelState( - scene_1: '', - scene_2: '', - scene_3: '', - scene_4: '', - scene_id_group_id: '', - switch_backlight: ''); - if (state is LoadingNewSate) { - model = state.device; - } else if (state is UpdateState) { - model = state.device; - } - return state is FourSceneLoadingState + return BlocProvider( + create: (context) => FourSceneBloc(fourSceneId: device?.uuid ?? '') + ..add(const FourSceneInitial()) + ..add(const FourSceneInitialInfo()) + ..add(const FourSceneSwitchInitial()), + child: BlocBuilder( + builder: (context, state) { + final _bloc = BlocProvider.of(context); + + FourSceneModelState model = FourSceneModelState( + scene_1: '', + scene_2: '', + scene_3: '', + scene_4: '', + scene_id_group_id: '', + switch_backlight: '', + ); + + if (state is LoadingNewSate) { + model = state.device; + } else if (state is UpdateState) { + model = state.device; + } + + return DefaultScaffold( + title: _bloc.deviceInfo.name, + actions: [ + InkWell( + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => FourSceneSettings(device: device!), + ), + ); + }, + child: SvgPicture.asset(Assets.assetsIconsSettings), + ), + const SizedBox(width: 10), + ], + child: state is FourSceneLoadingState ? const Center( child: DefaultContainer( - width: 50, - height: 50, - child: CircularProgressIndicator()), + width: 50, + height: 50, + child: CircularProgressIndicator(), + ), ) : RefreshIndicator( onRefresh: () async { @@ -81,22 +86,18 @@ class FourSceneScreen extends StatelessWidget { title2: model.scene_2, title3: model.scene_3, title4: model.scene_4, - switch1: - _bloc.deviceStatus.switch_backlight == true - ? Assets.switchOn - : Assets.switchOff, - switch2: - _bloc.deviceStatus.switch_backlight == true - ? Assets.switchOn - : Assets.switchOff, - switch3: - _bloc.deviceStatus.switch_backlight == true - ? Assets.switchOn - : Assets.switchOff, - switch4: - _bloc.deviceStatus.switch_backlight == true - ? Assets.switchOn - : Assets.switchOff, + switch1: _bloc.deviceStatus.switch_backlight + ? Assets.switchOn + : Assets.switchOff, + switch2: _bloc.deviceStatus.switch_backlight + ? Assets.switchOn + : Assets.switchOff, + switch3: _bloc.deviceStatus.switch_backlight + ? Assets.switchOn + : Assets.switchOff, + switch4: _bloc.deviceStatus.switch_backlight + ? Assets.switchOn + : Assets.switchOff, onSwitch1UpTap: () { debugPrint("Switch 1 Up tapped"); }, @@ -126,13 +127,13 @@ class FourSceneScreen extends StatelessWidget { children: [ ConstrainedBox( constraints: const BoxConstraints( - maxHeight: 46, maxWidth: 50), + maxHeight: 46, + maxWidth: 50, + ), child: SvgPicture.asset( Assets.backlightIcon), ), - const SizedBox( - height: 15, - ), + const SizedBox(height: 15), const Flexible( child: FittedBox( child: BodySmall( @@ -145,9 +146,7 @@ class FourSceneScreen extends StatelessWidget { ), ), ), - const SizedBox( - width: 10, - ), + const SizedBox(width: 10), Expanded( child: DefaultContainer( onTap: () async { @@ -162,13 +161,17 @@ class FourSceneScreen extends StatelessWidget { cancelTab: () { Navigator.of(context).pop(); }, - confirmTab: (switchSelected) async { + confirmTab: + (switchSelected) async { Navigator.of(context).push( MaterialPageRoute( - builder: (context) => - FourSelectSceneFourPage( - switchSelected:switchSelected, - deviceId: device!.uuid)), + builder: (context) => + FourSelectSceneFourPage( + switchSelected: + switchSelected, + deviceId: device!.uuid, + ), + ), ); }, ); @@ -190,13 +193,13 @@ class FourSceneScreen extends StatelessWidget { children: [ ConstrainedBox( constraints: const BoxConstraints( - maxHeight: 46, maxWidth: 50), + maxHeight: 46, + maxWidth: 50, + ), child: SvgPicture.asset( Assets.addSceneIcon), ), - const SizedBox( - height: 15, - ), + const SizedBox(height: 15), const Flexible( child: FittedBox( child: BodySmall( @@ -211,19 +214,16 @@ class FourSceneScreen extends StatelessWidget { ), ], ), - ) + ), ], ), ), ], ), - ); - }, - ), + ), + ); + }, ), ); } } - - -//MohaM&&&uba1 \ No newline at end of file diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_info_page.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_info_page.dart index 9b9aea4..991fe57 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_info_page.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_info_page.dart @@ -69,9 +69,13 @@ class FourSceneInfoPage extends StatelessWidget { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - BodySmall( - text: _bloc.deviceInfo.productUuid, - fontColor: ColorsManager.primaryTextColor, + Container( + width: + MediaQuery.of(context).size.width * 0.61, + child: BodySmall( + text: _bloc.deviceInfo.productUuid, + fontColor: ColorsManager.primaryTextColor, + ), ), InkWell( onTap: () { diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_profile_page.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_profile_page.dart index 0ded218..29a1272 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_profile_page.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_profile_page.dart @@ -144,6 +144,7 @@ class FourSceneProfilePage extends StatelessWidget { fontSize: 12, fontColor: ColorsManager.grayColor, ), + const SizedBox(height: 7), DefaultContainer( padding: const EdgeInsets.all(20), child: InkWell( diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart index f012b65..33ab7ec 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart @@ -207,7 +207,12 @@ class FourSceneSettings extends StatelessWidget { child: Column( children: [ SettingWidget( - onChanged: (p0) {}, + value: _bloc.enableAlarm, + onChanged: (p0) { + context + .read() + .add(ToggleEnableAlarmEvent(p0)); + }, isNotification: true, onTap: () {}, text: 'Offline Notification', @@ -444,6 +449,7 @@ class FourSceneSettings extends StatelessWidget { class SettingWidget extends StatelessWidget { final String? text; final bool? isUpdate; + final bool? value; final bool? isNotification; final String? icon; final Function()? onTap; @@ -453,6 +459,7 @@ class SettingWidget extends StatelessWidget { {super.key, this.text, this.icon, + this.value, this.onTap, this.isUpdate, this.onChanged, @@ -516,7 +523,7 @@ class SettingWidget extends StatelessWidget { : Transform.scale( scale: .8, child: CupertinoSwitch( - value: true, + value: value!, onChanged: onChanged, applyTheme: true, ), diff --git a/lib/features/devices/view/widgets/sos/sos_screen.dart b/lib/features/devices/view/widgets/sos/sos_screen.dart index e55ee41..ea9e7df 100644 --- a/lib/features/devices/view/widgets/sos/sos_screen.dart +++ b/lib/features/devices/view/widgets/sos/sos_screen.dart @@ -18,45 +18,51 @@ import 'package:syncrow_app/generated/assets.dart'; class SosScreen extends StatelessWidget { final DeviceModel? device; - const SosScreen({super.key, this.device}); @override Widget build(BuildContext context) { - return DefaultScaffold( - title: 'SOS', - actions: [ - InkWell( - onTap: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => SosSettings(device: device!)), - ); - }, - child: SvgPicture.asset(Assets.assetsIconsSettings)), - const SizedBox( - width: 10, - ) - ], - child: BlocProvider( - create: (context) => - SosBloc(sosId: device?.uuid ?? '')..add(const SosInitial()), - child: BlocBuilder( - builder: (context, state) { - final sensor = BlocProvider.of(context); - SosModel model = - SosModel(batteryPercentage: 0, sosContactState: 'normal'); - if (state is LoadingNewSate) { - model = state.sosSensor; - } else if (state is UpdateState) { - model = state.sensor; - } - return state is SosLoadingState + return BlocProvider( + create: (context) => SosBloc(sosId: device?.uuid ?? '') + ..add(const SosInitial()) + ..add(SosInitialDeviseInfo()), + child: BlocBuilder( + builder: (context, state) { + final sensor = BlocProvider.of(context); + // Default SOS model in case no state is loaded + SosModel model = SosModel( + batteryPercentage: 0, + sosContactState: '', + ); + // Update the model based on the state + if (state is LoadingNewSate) { + model = state.sosSensor; + } else if (state is UpdateState) { + model = state.sensor; + } + + return DefaultScaffold( + title: sensor.deviceInfo.name, + actions: [ + InkWell( + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => SosSettings(device: device!), + ), + ); + }, + child: SvgPicture.asset(Assets.assetsIconsSettings), + ), + const SizedBox(width: 10), + ], + child: state is SosLoadingState ? const Center( child: DefaultContainer( - width: 50, - height: 50, - child: CircularProgressIndicator()), + width: 50, + height: 50, + child: CircularProgressIndicator(), + ), ) : RefreshIndicator( onRefresh: () async { @@ -69,14 +75,17 @@ class SosScreen extends StatelessWidget { child: Column( children: [ BatteryBar( - batteryPercentage: model.batteryPercentage, + batteryPercentage: + sensor.deviceStatus.batteryPercentage, ), Expanded( flex: 4, child: InkWell( - overlayColor: WidgetStateProperty.all( + overlayColor: MaterialStateProperty.all( Colors.transparent), - onTap: () {}, + onTap: () { + // Add functionality for the main SOS button here + }, child: Row( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: @@ -111,7 +120,8 @@ class SosScreen extends StatelessWidget { ], ), child: SvgPicture.asset( - model.sosContactState == 'normal' + sensor.deviceStatus.sosContactState != + 'sos' ? Assets.redSos : Assets.greenSos, fit: BoxFit.fill, @@ -129,9 +139,10 @@ class SosScreen extends StatelessWidget { onTap: () { Navigator.of(context).push( MaterialPageRoute( - builder: (context) => - SosRecordsScreen( - sosId: device!.uuid!)), + builder: (context) => + SosRecordsScreen( + sosId: device!.uuid!), + ), ); }, child: Column( @@ -142,13 +153,13 @@ class SosScreen extends StatelessWidget { children: [ ConstrainedBox( constraints: const BoxConstraints( - maxHeight: 46, maxWidth: 50), + maxHeight: 46, + maxWidth: 50, + ), child: SvgPicture.asset( Assets.doorRecordsIcon), ), - const SizedBox( - height: 15, - ), + const SizedBox(height: 15), const Flexible( child: FittedBox( child: BodySmall( @@ -161,16 +172,15 @@ class SosScreen extends StatelessWidget { ), ), ), - const SizedBox( - width: 10, - ), + const SizedBox(width: 10), Expanded( child: DefaultContainer( onTap: () { Navigator.of(context).push( MaterialPageRoute( - builder: (context) => - const AlarmManagementPage()), + builder: (context) => + const AlarmManagementPage(), + ), ); }, child: Column( @@ -181,13 +191,13 @@ class SosScreen extends StatelessWidget { children: [ ConstrainedBox( constraints: const BoxConstraints( - maxHeight: 46, maxWidth: 50), + maxHeight: 46, + maxWidth: 50, + ), child: SvgPicture.asset(Assets .doorNotificationSetting), ), - const SizedBox( - height: 15, - ), + const SizedBox(height: 15), const Flexible( child: FittedBox( child: BodySmall( @@ -202,15 +212,15 @@ class SosScreen extends StatelessWidget { ), ], ), - ) + ), ], ), ), ], ), - ); - }, - ), + ), + ); + }, ), ); } diff --git a/lib/features/devices/view/widgets/sos/sos_setting/sos_info_page.dart b/lib/features/devices/view/widgets/sos/sos_setting/sos_info_page.dart index 1055cb1..09ed1c1 100644 --- a/lib/features/devices/view/widgets/sos/sos_setting/sos_info_page.dart +++ b/lib/features/devices/view/widgets/sos/sos_setting/sos_info_page.dart @@ -64,9 +64,13 @@ class SosInfoPage extends StatelessWidget { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - BodySmall( - text: _bloc.deviceInfo.productUuid, - fontColor: ColorsManager.primaryTextColor, + SizedBox( + width: + MediaQuery.of(context).size.width * 0.61, + child: BodySmall( + text: _bloc.deviceInfo.productUuid, + fontColor: ColorsManager.primaryTextColor, + ), ), InkWell( onTap: () { diff --git a/lib/features/devices/view/widgets/sos/sos_setting/sos_profile_page.dart b/lib/features/devices/view/widgets/sos/sos_setting/sos_profile_page.dart index bf1d0f9..5d9b033 100644 --- a/lib/features/devices/view/widgets/sos/sos_setting/sos_profile_page.dart +++ b/lib/features/devices/view/widgets/sos/sos_setting/sos_profile_page.dart @@ -64,20 +64,11 @@ class SosProfilePage extends StatelessWidget { radius: 55, backgroundColor: ColorsManager.graysColor, child: ClipOval( - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const SizedBox( - height: 10, - ), - Center( - child: SvgPicture.asset( - Assets.fourSceneIcon, - fit: BoxFit.contain, - ), - ), - ], + child: Center( + child: SvgPicture.asset( + Assets.sosProfileIcon, + fit: BoxFit.contain, + ), ), ), ), @@ -139,6 +130,7 @@ class SosProfilePage extends StatelessWidget { fontSize: 12, fontColor: ColorsManager.grayColor, ), + const SizedBox(height: 7), DefaultContainer( padding: const EdgeInsets.all(20), child: InkWell( diff --git a/lib/features/devices/view/widgets/sos/sos_settings.dart b/lib/features/devices/view/widgets/sos/sos_settings.dart index 8971452..dc6487f 100644 --- a/lib/features/devices/view/widgets/sos/sos_settings.dart +++ b/lib/features/devices/view/widgets/sos/sos_settings.dart @@ -7,7 +7,6 @@ import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_event.dart'; import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_state.dart'; import 'package:syncrow_app/features/devices/model/device_model.dart'; import 'package:syncrow_app/features/devices/model/sos_model.dart'; -import 'package:syncrow_app/features/devices/model/subspace_model.dart'; import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/delete_dialog.dart'; import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/sos_profile_page.dart'; import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/faq_sos_page.dart'; @@ -62,14 +61,18 @@ class SosSettings extends StatelessWidget { vertical: 10, ), child: InkWell( - onTap: () { - Navigator.of(context).push( + onTap: () async { + bool val = await Navigator.of(context).push( MaterialPageRoute( builder: (context) => SosProfilePage( device: device, ), ), ); + if (val == true) { + _bloc.add(SosInitialDeviseInfo()); + _bloc.add(const SosInitial()); + } }, child: Stack( children: [ @@ -93,8 +96,8 @@ class SosSettings extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ - const BodyMedium( - text: 'SOS', + BodyMedium( + text: _bloc.deviceInfo.name, fontWeight: FontWeight.bold, ), const SizedBox( @@ -169,7 +172,21 @@ class SosSettings extends StatelessWidget { child: Column( children: [ SettingWidget( - onChanged: (p0) {}, + value: _bloc.enableAlarm, + onChanged: (p0) { + context + .read() + .add(ToggleEnableAlarmEvent(p0)); + // Transform.scale( + // scale: .8, + // child: CupertinoSwitch( + // value: _bloc.enableAlarm, + // onChanged: (value) { + + // }, + // applyTheme: true, + // )), + }, isNotification: true, onTap: () {}, text: 'Offline Notification', @@ -400,6 +417,7 @@ class SosSettings extends StatelessWidget { class SettingWidget extends StatelessWidget { final String? text; final bool? isUpdate; + final bool? value; final bool? isNotification; final String? icon; final Function()? onTap; @@ -409,6 +427,7 @@ class SettingWidget extends StatelessWidget { {super.key, this.text, this.icon, + this.value, this.onTap, this.isUpdate, this.onChanged, @@ -472,7 +491,7 @@ class SettingWidget extends StatelessWidget { : Transform.scale( scale: .8, child: CupertinoSwitch( - value: true, + value: value!, onChanged: onChanged, applyTheme: true, ), From db9ab530ea6e8cae171d9d39932ffadef6473e29 Mon Sep 17 00:00:00 2001 From: mohammad Date: Mon, 25 Nov 2024 10:47:09 +0300 Subject: [PATCH 15/29] 4 scene & 6scene & sos --- .../6_scene_switch_bloc/6_scene_bloc.dart | 30 +++++- .../6_scene_switch_bloc/6_scene_event.dart | 13 +++ .../6_scene_switch_bloc/6_scene_state.dart | 2 +- .../bloc/four_scene_bloc/four_scene_bloc.dart | 31 +++++- .../four_scene_bloc/four_scene_event.dart | 10 ++ .../devices/bloc/sos_bloc/sos_bloc.dart | 27 ++++- .../devices/bloc/sos_bloc/sos_event.dart | 10 ++ .../devices/bloc/sos_bloc/sos_state.dart | 3 + ...del.dart => six_scene_question_model.dart} | 0 .../6_scene_setting/faq_six_scene_page.dart | 14 ++- .../6_scene_setting/question_page.dart | 30 ++++-- .../six_scene_update_page.dart | 15 ++- .../faq_four_scene_page.dart | 12 ++- .../four_scene_update_page.dart | 15 ++- .../question_page_four_scene.dart | 28 +++-- .../widgets/sos/sos_setting/faq_sos_page.dart | 101 ++++++++++-------- .../sos/sos_setting/question_page.dart | 28 +++-- .../sos/sos_setting/sos_update_page.dart | 21 ++-- .../view/widgets/sos/sos_settings.dart | 11 +- 19 files changed, 293 insertions(+), 108 deletions(-) rename lib/features/devices/model/{sex_scene_question_model.dart => six_scene_question_model.dart} (100%) diff --git a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart index b454060..5ce176b 100644 --- a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart +++ b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart @@ -9,7 +9,7 @@ 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/group_devices_model.dart'; import 'package:syncrow_app/features/devices/model/device_info_model.dart'; -import 'package:syncrow_app/features/devices/model/sex_scene_question_model.dart'; +import 'package:syncrow_app/features/devices/model/six_scene_question_model.dart'; import 'package:syncrow_app/features/devices/model/six_scene_model.dart'; import 'package:syncrow_app/features/devices/model/status_model.dart'; import 'package:syncrow_app/features/devices/model/subspace_model.dart'; @@ -48,6 +48,8 @@ class SixSceneBloc extends Bloc { on(_onSixSceneInitial); on(deleteDevice); on(_toggleLowBattery); + on(_toggleUpdate); + on(_toggleHelpful); } final TextEditingController nameController = @@ -506,4 +508,30 @@ class SixSceneBloc extends Bloc { } return null; } + + bool enableUpdate = false; + + void _toggleUpdate( + ToggleUpdateEvent event, Emitter emit) async { + try { + emit(SixSceneLoadingState()); + enableUpdate = event.isUpdateEnabled!; + emit(SaveState()); + } catch (e) { + emit(const SixSceneFailedState(errorMessage: 'Something went wrong')); + } + } + + bool isHelpful = false; + + void _toggleHelpful( + ToggleHelpfulEvent event, Emitter emit) async { + try { + emit(SixSceneLoadingState()); + isHelpful = event.isHelpful!; + emit(SaveState()); + } catch (e) { + emit(const SixSceneFailedState(errorMessage: 'Something went wrong')); + } + } } diff --git a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart index 7efceb6..5600510 100644 --- a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart +++ b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart @@ -222,3 +222,16 @@ class AssignRoomEvent extends SixSceneEvent { context, ]; } + + + +class ToggleUpdateEvent extends SixSceneEvent { + final bool? isUpdateEnabled; + const ToggleUpdateEvent({this.isUpdateEnabled}); +} + + +class ToggleHelpfulEvent extends SixSceneEvent { + final bool? isHelpful; + const ToggleHelpfulEvent({this.isHelpful}); +} \ No newline at end of file diff --git a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart index 318d37a..01f72b0 100644 --- a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart +++ b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart @@ -2,7 +2,7 @@ import 'package:equatable/equatable.dart'; import 'package:syncrow_app/features/devices/model/device_model.dart'; import 'package:syncrow_app/features/devices/model/group_devices_model.dart'; import 'package:syncrow_app/features/devices/model/device_info_model.dart'; -import 'package:syncrow_app/features/devices/model/sex_scene_question_model.dart'; +import 'package:syncrow_app/features/devices/model/six_scene_question_model.dart'; import 'package:syncrow_app/features/devices/model/six_scene_model.dart'; import 'package:syncrow_app/features/devices/model/subspace_model.dart'; import 'package:syncrow_app/features/scene/model/scenes_model.dart'; diff --git a/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart b/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart index efb89dd..9cdf3ef 100644 --- a/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart +++ b/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart @@ -49,6 +49,8 @@ class FourSceneBloc extends Bloc { on(_selectScene); on(deleteDevice); on(_toggleLowBattery); + on(_toggleUpdate); + on(_toggleHelpful); } final TextEditingController nameController = @@ -261,8 +263,7 @@ class FourSceneBloc extends Bloc { } } - - void _toggleLowBattery( + void _toggleLowBattery( ToggleEnableAlarmEvent event, Emitter emit) async { emit(LoadingNewSate(device: deviceStatus)); try { @@ -544,4 +545,30 @@ class FourSceneBloc extends Bloc { } return null; } + + bool enableUpdate = false; + + void _toggleUpdate( + ToggleUpdateEvent event, Emitter emit) async { + try { + emit(FourSceneLoadingState()); + enableUpdate = event.isUpdateEnabled!; + emit(SaveState()); + } catch (e) { + emit(const FourSceneFailedState(errorMessage: 'Something went wrong')); + } + } + + bool isHelpful = false; + + void _toggleHelpful( + ToggleHelpfulEvent event, Emitter emit) async { + try { + emit(FourSceneLoadingState()); + isHelpful = event.isHelpful!; + emit(SaveState()); + } catch (e) { + emit(const FourSceneFailedState(errorMessage: 'Something went wrong')); + } + } } diff --git a/lib/features/devices/bloc/four_scene_bloc/four_scene_event.dart b/lib/features/devices/bloc/four_scene_bloc/four_scene_event.dart index 52ed6ee..9a75285 100644 --- a/lib/features/devices/bloc/four_scene_bloc/four_scene_event.dart +++ b/lib/features/devices/bloc/four_scene_bloc/four_scene_event.dart @@ -232,3 +232,13 @@ class GetSceneBySwitchName extends FourSceneEvent { const GetSceneBySwitchName({this.switchName}); } +class ToggleUpdateEvent extends FourSceneEvent { + final bool? isUpdateEnabled; + const ToggleUpdateEvent({this.isUpdateEnabled}); +} + + +class ToggleHelpfulEvent extends FourSceneEvent { + final bool? isHelpful; + const ToggleHelpfulEvent({this.isHelpful}); +} \ No newline at end of file diff --git a/lib/features/devices/bloc/sos_bloc/sos_bloc.dart b/lib/features/devices/bloc/sos_bloc/sos_bloc.dart index 3fcf131..b2d322a 100644 --- a/lib/features/devices/bloc/sos_bloc/sos_bloc.dart +++ b/lib/features/devices/bloc/sos_bloc/sos_bloc.dart @@ -39,7 +39,8 @@ class SosBloc extends Bloc { on(_assignDevice); on(fetchDeviceInfo); on(saveName); - // on(_unassignDevice); + on(_toggleUpdate); + on(_toggleHelpful); // on(_toggleWaterLeakAlarm); } @@ -440,4 +441,28 @@ class SosBloc extends Bloc { } return null; } + + bool enableUpdate = false; + + void _toggleUpdate(ToggleUpdateEvent event, Emitter emit) async { + try { + emit(SosLoadingState()); + enableUpdate = event.isUpdateEnabled!; + emit(SaveState()); + } catch (e) { + emit(SosFailedState(errorMessage: e.toString())); + } + } + + bool isHelpful = false; + + void _toggleHelpful(ToggleHelpfulEvent event, Emitter emit) async { + try { + emit(SosLoadingState()); + isHelpful = event.isHelpful!; + emit(SaveState()); + } catch (e) { + emit(SosFailedState(errorMessage: e.toString())); + } + } } diff --git a/lib/features/devices/bloc/sos_bloc/sos_event.dart b/lib/features/devices/bloc/sos_bloc/sos_event.dart index 8a882a9..f002304 100644 --- a/lib/features/devices/bloc/sos_bloc/sos_event.dart +++ b/lib/features/devices/bloc/sos_bloc/sos_event.dart @@ -193,4 +193,14 @@ class LoadingDeviceInfo extends SosEvent { @override List get props => [deviceInfo]; +} + +class ToggleUpdateEvent extends SosEvent { + final bool? isUpdateEnabled; + const ToggleUpdateEvent({this.isUpdateEnabled}); +} + +class ToggleHelpfulEvent extends SosEvent { + final bool? isHelpful; + const ToggleHelpfulEvent({this.isHelpful}); } \ No newline at end of file diff --git a/lib/features/devices/bloc/sos_bloc/sos_state.dart b/lib/features/devices/bloc/sos_bloc/sos_state.dart index 1ffee2d..3f125cb 100644 --- a/lib/features/devices/bloc/sos_bloc/sos_state.dart +++ b/lib/features/devices/bloc/sos_bloc/sos_state.dart @@ -15,6 +15,9 @@ class SosState extends Equatable { class SosInitialState extends SosState {} class SosLoadingState extends SosState {} + + + class SaveState extends SosState {} class LoadingSosDeviceInfo extends SosState { diff --git a/lib/features/devices/model/sex_scene_question_model.dart b/lib/features/devices/model/six_scene_question_model.dart similarity index 100% rename from lib/features/devices/model/sex_scene_question_model.dart rename to lib/features/devices/model/six_scene_question_model.dart diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/faq_six_scene_page.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/faq_six_scene_page.dart index d843fd6..5870ecf 100644 --- a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/faq_six_scene_page.dart +++ b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/faq_six_scene_page.dart @@ -5,7 +5,7 @@ import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_bl import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart'; import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart'; import 'package:syncrow_app/features/devices/model/device_model.dart'; -import 'package:syncrow_app/features/devices/model/sex_scene_question_model.dart'; +import 'package:syncrow_app/features/devices/model/six_scene_question_model.dart'; import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/6_scene_setting/question_page.dart'; import 'package:syncrow_app/features/shared_widgets/default_container.dart'; import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart'; @@ -89,6 +89,9 @@ class FaqSixScenePage extends StatelessWidget { fontSize: 12, fontColor: ColorsManager.grayColor, ), + const SizedBox( + height: 8, + ), displayedQuestions.isEmpty ? const SizedBox() : DefaultContainer( @@ -132,9 +135,12 @@ class FaqSixScenePage extends StatelessWidget { ], ), ), - const Divider( - color: ColorsManager.dividerColor, - ), + if (index != + displayedQuestions.length - + 1) // Exclude divider for the last item + const Divider( + color: ColorsManager.dividerColor, + ), ], ), ), diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/question_page.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/question_page.dart index 26fa712..c5b1ce9 100644 --- a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/question_page.dart +++ b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/question_page.dart @@ -4,7 +4,7 @@ import 'package:flutter_svg/flutter_svg.dart'; import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart'; import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart'; import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart'; -import 'package:syncrow_app/features/devices/model/sex_scene_question_model.dart'; +import 'package:syncrow_app/features/devices/model/six_scene_question_model.dart'; import 'package:syncrow_app/features/devices/model/six_scene_model.dart'; import 'package:syncrow_app/features/shared_widgets/default_button.dart'; import 'package:syncrow_app/features/shared_widgets/default_container.dart'; @@ -86,9 +86,14 @@ class QuestionPage extends StatelessWidget { child: SizedBox( width: 180, child: DefaultButton( - backgroundColor: ColorsManager.grayButtonColors, + backgroundColor: sensor.isHelpful == true + ? ColorsManager.grayColor + : ColorsManager.grayButtonColors, borderRadius: 50, - onPressed: () {}, + onPressed: () { + sensor + .add(ToggleHelpfulEvent(isHelpful: true)); + }, child: Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, @@ -97,10 +102,10 @@ class QuestionPage extends StatelessWidget { Assets.thumbUp, fit: BoxFit.fill, ), - SizedBox( + const SizedBox( width: 10, ), - BodyMedium( + const BodyMedium( text: 'Helpful', fontSize: 12, fontWeight: FontWeight.w400, @@ -110,16 +115,21 @@ class QuestionPage extends StatelessWidget { )), ), ), - SizedBox( + const SizedBox( height: 15, ), Center( child: SizedBox( width: 180, child: DefaultButton( - backgroundColor: ColorsManager.grayButtonColors, + backgroundColor: sensor.isHelpful == false + ? ColorsManager.grayColor + : ColorsManager.grayButtonColors, borderRadius: 50, - onPressed: () {}, + onPressed: () { + sensor.add( + ToggleHelpfulEvent(isHelpful: false)); + }, child: Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, @@ -128,10 +138,10 @@ class QuestionPage extends StatelessWidget { Assets.thumbDown, fit: BoxFit.fill, ), - SizedBox( + const SizedBox( width: 10, ), - BodyMedium( + const BodyMedium( text: 'Not Helpful', fontSize: 12, fontWeight: FontWeight.w400, diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_update_page.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_update_page.dart index b8c0019..489f65b 100644 --- a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_update_page.dart +++ b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_update_page.dart @@ -26,6 +26,8 @@ class SixSceneUpdatePage extends StatelessWidget { SixSceneBloc(sixSceneId: '')..add(const SixSceneInitial()), child: BlocBuilder( builder: (context, state) { + final _bloc = BlocProvider.of(context); + return state is SixSceneLoadingState ? const Center( child: DefaultContainer( @@ -87,15 +89,20 @@ class SixSceneUpdatePage extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.end, children: [ - const BodyMedium( - text: 'Off', + BodyMedium( + text: _bloc.enableUpdate + ? 'true' + : 'Off', fontColor: ColorsManager.textGray, ), Transform.scale( scale: .8, child: CupertinoSwitch( - value: true, - onChanged: (value) {}, + value: _bloc.enableUpdate, + onChanged: (value) { + _bloc.add(ToggleUpdateEvent( + isUpdateEnabled: value)); + }, applyTheme: true, ), ), diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/faq_four_scene_page.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/faq_four_scene_page.dart index 30e30e2..7e67462 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/faq_four_scene_page.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/faq_four_scene_page.dart @@ -89,6 +89,9 @@ class FaqFourScenePage extends StatelessWidget { fontSize: 12, fontColor: ColorsManager.grayColor, ), + const SizedBox( + height: 8, + ), displayedQuestions.isEmpty ? const SizedBox() : DefaultContainer( @@ -133,9 +136,12 @@ class FaqFourScenePage extends StatelessWidget { ], ), ), - const Divider( - color: ColorsManager.dividerColor, - ), + if (index != + displayedQuestions.length - + 1) // Exclude divider for the last item + const Divider( + color: ColorsManager.dividerColor, + ), ], ), ), diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_update_page.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_update_page.dart index 8fcee56..b028b52 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_update_page.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_update_page.dart @@ -26,6 +26,8 @@ class FourSceneUpdatePage extends StatelessWidget { FourSceneBloc(fourSceneId: '')..add(const FourSceneInitial()), child: BlocBuilder( builder: (context, state) { + final _bloc = BlocProvider.of(context); + return state is FourSceneLoadingState ? const Center( child: DefaultContainer( @@ -87,15 +89,20 @@ class FourSceneUpdatePage extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.end, children: [ - const BodyMedium( - text: 'Off', + BodyMedium( + text: _bloc.enableUpdate + ? 'true' + : 'Off', fontColor: ColorsManager.textGray, ), Transform.scale( scale: .8, child: CupertinoSwitch( - value: true, - onChanged: (value) {}, + value: _bloc.enableUpdate, + onChanged: (value) { + _bloc.add(ToggleUpdateEvent( + isUpdateEnabled: value)); + }, applyTheme: true, ), ), diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/question_page_four_scene.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/question_page_four_scene.dart index 5ebbc8b..06cd0df 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/question_page_four_scene.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/question_page_four_scene.dart @@ -84,9 +84,14 @@ class QuestionPageFourScene extends StatelessWidget { child: SizedBox( width: 180, child: DefaultButton( - backgroundColor: ColorsManager.grayButtonColors, + backgroundColor: sensor.isHelpful == true + ? ColorsManager.grayColor + : ColorsManager.grayButtonColors, borderRadius: 50, - onPressed: () {}, + onPressed: () { + sensor + .add(ToggleHelpfulEvent(isHelpful: true)); + }, child: Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, @@ -95,10 +100,10 @@ class QuestionPageFourScene extends StatelessWidget { Assets.thumbUp, fit: BoxFit.fill, ), - SizedBox( + const SizedBox( width: 10, ), - BodyMedium( + const BodyMedium( text: 'Helpful', fontSize: 12, fontWeight: FontWeight.w400, @@ -108,16 +113,21 @@ class QuestionPageFourScene extends StatelessWidget { )), ), ), - SizedBox( + const SizedBox( height: 15, ), Center( child: SizedBox( width: 180, child: DefaultButton( - backgroundColor: ColorsManager.grayButtonColors, + backgroundColor: sensor.isHelpful == false + ? ColorsManager.grayColor + : ColorsManager.grayButtonColors, borderRadius: 50, - onPressed: () {}, + onPressed: () { + sensor.add( + ToggleHelpfulEvent(isHelpful: false)); + }, child: Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, @@ -126,10 +136,10 @@ class QuestionPageFourScene extends StatelessWidget { Assets.thumbDown, fit: BoxFit.fill, ), - SizedBox( + const SizedBox( width: 10, ), - BodyMedium( + const BodyMedium( text: 'Not Helpful', fontSize: 12, fontWeight: FontWeight.w400, diff --git a/lib/features/devices/view/widgets/sos/sos_setting/faq_sos_page.dart b/lib/features/devices/view/widgets/sos/sos_setting/faq_sos_page.dart index bbb75f7..aa93159 100644 --- a/lib/features/devices/view/widgets/sos/sos_setting/faq_sos_page.dart +++ b/lib/features/devices/view/widgets/sos/sos_setting/faq_sos_page.dart @@ -89,57 +89,70 @@ class FaqSosPage extends StatelessWidget { fontSize: 12, fontColor: ColorsManager.grayColor, ), - Expanded( - child: DefaultContainer( - child: ListView.builder( - shrinkWrap: true, - itemCount: displayedQuestions.length, - itemBuilder: (context, index) { - final faq = displayedQuestions[index]; - return InkWell( - onTap: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => QuestionPage( - questionModel: faq, - )), - ); - }, - child: SizedBox( - child: Column( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.all(8.0), - child: Row( + const SizedBox( + height: 8, + ), + displayedQuestions.isEmpty + ? const SizedBox() + : DefaultContainer( + child: ListView.builder( + shrinkWrap: true, + itemCount: displayedQuestions.length, + itemBuilder: (context, index) { + final faq = displayedQuestions[index]; + return InkWell( + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => + QuestionPage( + questionModel: faq, + )), + ); + }, + child: SizedBox( + child: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, children: [ - Expanded( - child: BodyMedium( - fontSize: 14, - fontWeight: FontWeight.w400, - text: faq.question, + Padding( + padding: + const EdgeInsets.all(8.0), + child: Row( + children: [ + Expanded( + child: BodyMedium( + fontSize: 14, + fontWeight: + FontWeight.w400, + text: faq.question, + ), + ), + const Icon( + Icons.keyboard_arrow_right, + color: + ColorsManager.textGray, + ), + ], ), ), - const Icon( - Icons.keyboard_arrow_right, - color: ColorsManager.textGray, - ), + if (index != + displayedQuestions.length - + 1) // Exclude divider for the last item + const Divider( + color: + ColorsManager.dividerColor, + ), ], ), ), - const Divider( - color: ColorsManager.dividerColor, - ), - ], - ), + ); + }, ), - ); - }, - )), - ), + ) ], ), ); diff --git a/lib/features/devices/view/widgets/sos/sos_setting/question_page.dart b/lib/features/devices/view/widgets/sos/sos_setting/question_page.dart index 0ae5bd8..27da97a 100644 --- a/lib/features/devices/view/widgets/sos/sos_setting/question_page.dart +++ b/lib/features/devices/view/widgets/sos/sos_setting/question_page.dart @@ -78,9 +78,14 @@ class QuestionPage extends StatelessWidget { child: SizedBox( width: 180, child: DefaultButton( - backgroundColor: ColorsManager.grayButtonColors, + backgroundColor: sensor.isHelpful == true + ? ColorsManager.grayColor + : ColorsManager.grayButtonColors, borderRadius: 50, - onPressed: () {}, + onPressed: () { + sensor + .add(ToggleHelpfulEvent(isHelpful: true)); + }, child: Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, @@ -89,10 +94,10 @@ class QuestionPage extends StatelessWidget { Assets.thumbUp, fit: BoxFit.fill, ), - SizedBox( + const SizedBox( width: 10, ), - BodyMedium( + const BodyMedium( text: 'Helpful', fontSize: 12, fontWeight: FontWeight.w400, @@ -102,16 +107,21 @@ class QuestionPage extends StatelessWidget { )), ), ), - SizedBox( + const SizedBox( height: 15, ), Center( child: SizedBox( width: 180, child: DefaultButton( - backgroundColor: ColorsManager.grayButtonColors, + backgroundColor: sensor.isHelpful == false + ? ColorsManager.grayColor + : ColorsManager.grayButtonColors, borderRadius: 50, - onPressed: () {}, + onPressed: () { + sensor.add( + ToggleHelpfulEvent(isHelpful: false)); + }, child: Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, @@ -120,10 +130,10 @@ class QuestionPage extends StatelessWidget { Assets.thumbDown, fit: BoxFit.fill, ), - SizedBox( + const SizedBox( width: 10, ), - BodyMedium( + const BodyMedium( text: 'Not Helpful', fontSize: 12, fontWeight: FontWeight.w400, diff --git a/lib/features/devices/view/widgets/sos/sos_setting/sos_update_page.dart b/lib/features/devices/view/widgets/sos/sos_setting/sos_update_page.dart index fabd7b2..67ab647 100644 --- a/lib/features/devices/view/widgets/sos/sos_setting/sos_update_page.dart +++ b/lib/features/devices/view/widgets/sos/sos_setting/sos_update_page.dart @@ -25,6 +25,8 @@ class SosUpdatePage extends StatelessWidget { create: (context) => SosBloc(sosId: '')..add(const SosInitial()), child: BlocBuilder( builder: (context, state) { + final _bloc = BlocProvider.of(context); + return state is SosLoadingState ? const Center( child: DefaultContainer( @@ -72,6 +74,7 @@ class SosUpdatePage extends StatelessWidget { InkWell( onTap: () {}, child: const BodyMedium( + text: 'Automatic Update', fontWeight: FontWeight.normal, ), @@ -85,21 +88,27 @@ class SosUpdatePage extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.end, children: [ - const BodyMedium( - text: 'Off', + BodyMedium( + text: _bloc.enableUpdate + ? 'true' + : 'Off', fontColor: ColorsManager.textGray, ), Transform.scale( scale: .8, child: CupertinoSwitch( - value: true, - onChanged: (value) {}, + value: _bloc.enableUpdate, + onChanged: (value) { + _bloc.add(ToggleUpdateEvent( + isUpdateEnabled: value)); + }, applyTheme: true, ), ), ], ), - )), + ) + ), ), ], ), @@ -107,7 +116,7 @@ class SosUpdatePage extends StatelessWidget { const SizedBox( height: 10, ), - UpdateSosContainerWithProgressBar( + const UpdateSosContainerWithProgressBar( sosDescription: 'Connectivity Issue Resolved Fixed a bug that caused the SOS button to disconnect from the app intermittently.', sosVersion: 'SOS v2.0.5', diff --git a/lib/features/devices/view/widgets/sos/sos_settings.dart b/lib/features/devices/view/widgets/sos/sos_settings.dart index dc6487f..6d27019 100644 --- a/lib/features/devices/view/widgets/sos/sos_settings.dart +++ b/lib/features/devices/view/widgets/sos/sos_settings.dart @@ -39,7 +39,6 @@ class SosSettings extends StatelessWidget { child: BlocBuilder( builder: (context, state) { final _bloc = BlocProvider.of(context); - SosModel model = SosModel(batteryPercentage: 0, sosContactState: 'normal'); if (state is LoadingNewSate) { @@ -177,15 +176,7 @@ class SosSettings extends StatelessWidget { context .read() .add(ToggleEnableAlarmEvent(p0)); - // Transform.scale( - // scale: .8, - // child: CupertinoSwitch( - // value: _bloc.enableAlarm, - // onChanged: (value) { - - // }, - // applyTheme: true, - // )), + }, isNotification: true, onTap: () {}, From 7ffc67651c62daed31bdb38cec5111e63eb1b333 Mon Sep 17 00:00:00 2001 From: mohammad Date: Mon, 25 Nov 2024 11:17:33 +0300 Subject: [PATCH 16/29] sos --- assets/icons/sos_home_icon.svg | 23 +++ .../devices/bloc/sos_bloc/sos_bloc.dart | 28 +-- .../devices/bloc/sos_bloc/sos_event.dart | 1 + lib/features/devices/model/device_model.dart | 2 + .../6_scene_setting/share_six_scene_page.dart | 3 + .../faq_four_scene_page.dart | 195 +++++++++--------- .../share_four_scene_page.dart | 3 + .../sos/sos_setting/share_sos_page.dart | 13 +- .../sos/sos_setting/sos_profile_page.dart | 7 +- .../view/widgets/sos/sos_settings.dart | 33 ++- lib/generated/assets.dart | 2 + 11 files changed, 172 insertions(+), 138 deletions(-) create mode 100644 assets/icons/sos_home_icon.svg diff --git a/assets/icons/sos_home_icon.svg b/assets/icons/sos_home_icon.svg new file mode 100644 index 0000000..6f36bac --- /dev/null +++ b/assets/icons/sos_home_icon.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/features/devices/bloc/sos_bloc/sos_bloc.dart b/lib/features/devices/bloc/sos_bloc/sos_bloc.dart index b2d322a..b41356c 100644 --- a/lib/features/devices/bloc/sos_bloc/sos_bloc.dart +++ b/lib/features/devices/bloc/sos_bloc/sos_bloc.dart @@ -305,20 +305,10 @@ class SosBloc extends Bloc { allDevices.forEach((element) { allDevicesIds.add(element.uuid!); }); - emit(SaveSelectionSuccessState()); + await HomeCubit.getInstance().fetchUnitsByUserId(); + CustomSnackBar.displaySnackBar('Save Successfully'); - // devicesList.forEach((e) { - // if (allDevicesIds.contains(e.uuid!)) { - // roomDevicesId[e.uuid!] = true; - // } else { - // roomDevicesId[e.uuid!] = false; - // } - // }); - // emit(FetchDeviceByRoomIdState( - // roomDevices: devicesList, - // allDevices: allDevices, - // roomDevicesId: roomDevicesId, - // roomId: event.roomId)); + emit(SaveSelectionSuccessState()); } catch (e) { emit(const SosFailedState(errorMessage: 'Something went wrong')); return; @@ -465,4 +455,16 @@ class SosBloc extends Bloc { emit(SosFailedState(errorMessage: e.toString())); } } + + deleteDevice(DeleteDeviceEvent event, Emitter emit) async { + try { + emit(SosLoadingState()); + var response = await DevicesAPI.resetDevise(devicesUuid: sosId); + add(SosInitialDeviseInfo()); + add(const SosInitial()); + CustomSnackBar.displaySnackBar('Reset Successfully'); + } catch (e) { + emit(SosFailedState(errorMessage: e.toString())); + } + } } diff --git a/lib/features/devices/bloc/sos_bloc/sos_event.dart b/lib/features/devices/bloc/sos_bloc/sos_event.dart index f002304..6556228 100644 --- a/lib/features/devices/bloc/sos_bloc/sos_event.dart +++ b/lib/features/devices/bloc/sos_bloc/sos_event.dart @@ -12,6 +12,7 @@ abstract class SosEvent extends Equatable { } class SosLoading extends SosEvent {} +class DeleteDeviceEvent extends SosLoading {} class SosSwitch extends SosEvent { final String switchD; diff --git a/lib/features/devices/model/device_model.dart b/lib/features/devices/model/device_model.dart index aee7fbc..557e83f 100644 --- a/lib/features/devices/model/device_model.dart +++ b/lib/features/devices/model/device_model.dart @@ -82,6 +82,8 @@ class DeviceModel { tempIcon = Assets.fourSceneHomeIcon; } else if (type == DeviceType.SixScene) { tempIcon = Assets.sixSceneHomeIcon; + } else if (type == DeviceType.SOS) { + tempIcon = Assets.sosHomeIcon; } else { tempIcon = Assets.assetsIconsLogo; } diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/share_six_scene_page.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/share_six_scene_page.dart index ae38850..b3695cc 100644 --- a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/share_six_scene_page.dart +++ b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/share_six_scene_page.dart @@ -61,6 +61,9 @@ class ShareSixScenePage extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ + SizedBox( + height: MediaQuery.of(context).size.height * 0.05, + ), const BodyLarge( text: 'Sharing Method Not Supported', fontSize: 15, diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/faq_four_scene_page.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/faq_four_scene_page.dart index 7e67462..aff8eee 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/faq_four_scene_page.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/faq_four_scene_page.dart @@ -43,113 +43,108 @@ class FaqFourScenePage extends StatelessWidget { height: 50, child: CircularProgressIndicator()), ) - : RefreshIndicator( - onRefresh: () async { - // sensor.add(const SosInitial()); - }, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - DefaultContainer( - padding: const EdgeInsets.all(5), - child: TextFormField( - controller: _searchController, - onChanged: (value) { - sensor.add(SearchFaqEvent(value)); - }, - decoration: InputDecoration( - hintText: 'Enter your questions', - hintStyle: const TextStyle( - color: ColorsManager.textGray, - fontSize: 16, - fontWeight: FontWeight.w400), - suffixIcon: Container( - padding: const EdgeInsets.all(5.0), - margin: const EdgeInsets.all(10.0), - child: SvgPicture.asset( - Assets.searchIcon, - fit: BoxFit.contain, - ), - ), - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(8.0), + : Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + DefaultContainer( + padding: const EdgeInsets.all(5), + child: TextFormField( + controller: _searchController, + onChanged: (value) { + sensor.add(SearchFaqEvent(value)); + }, + decoration: InputDecoration( + hintText: 'Enter your questions', + hintStyle: const TextStyle( + color: ColorsManager.textGray, + fontSize: 16, + fontWeight: FontWeight.w400), + suffixIcon: Container( + padding: const EdgeInsets.all(5.0), + margin: const EdgeInsets.all(10.0), + child: SvgPicture.asset( + Assets.searchIcon, + fit: BoxFit.contain, ), ), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(8.0), + ), ), ), - SizedBox( - height: MediaQuery.of(context).size.height * 0.04, - ), - BodyMedium( - text: _searchController.text.isEmpty - ? 'Device Related FAQs' - : '${displayedQuestions.length} Help Topics', - fontWeight: FontWeight.w700, - fontSize: 12, - fontColor: ColorsManager.grayColor, - ), - const SizedBox( - height: 8, - ), - displayedQuestions.isEmpty - ? const SizedBox() - : DefaultContainer( - child: ListView.builder( - shrinkWrap: true, - itemCount: displayedQuestions.length, - itemBuilder: (context, index) { - final faq = displayedQuestions[index]; - return InkWell( - onTap: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => - QuestionPageFourScene( - questionModel: faq, - )), - ); - }, - child: SizedBox( - child: Column( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: - MainAxisAlignment.start, - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.all(8.0), - child: Row( - children: [ - Expanded( - child: BodyMedium( - fontSize: 14, - fontWeight: FontWeight.w400, - text: faq.question, - ), + ), + SizedBox( + height: MediaQuery.of(context).size.height * 0.04, + ), + BodyMedium( + text: _searchController.text.isEmpty + ? 'Device Related FAQs' + : '${displayedQuestions.length} Help Topics', + fontWeight: FontWeight.w700, + fontSize: 12, + fontColor: ColorsManager.grayColor, + ), + const SizedBox( + height: 8, + ), + displayedQuestions.isEmpty + ? const SizedBox() + : DefaultContainer( + child: ListView.builder( + shrinkWrap: true, + itemCount: displayedQuestions.length, + itemBuilder: (context, index) { + final faq = displayedQuestions[index]; + return InkWell( + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => + QuestionPageFourScene( + questionModel: faq, + )), + ); + }, + child: SizedBox( + child: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Row( + children: [ + Expanded( + child: BodyMedium( + fontSize: 14, + fontWeight: FontWeight.w400, + text: faq.question, ), - const Icon( - Icons.keyboard_arrow_right, - color: ColorsManager.textGray, - ), - ], - ), + ), + const Icon( + Icons.keyboard_arrow_right, + color: ColorsManager.textGray, + ), + ], ), - if (index != - displayedQuestions.length - - 1) // Exclude divider for the last item - const Divider( - color: ColorsManager.dividerColor, - ), - ], - ), + ), + if (index != + displayedQuestions.length - + 1) // Exclude divider for the last item + const Divider( + color: ColorsManager.dividerColor, + ), + ], ), - ); - }, - )), - ], - ), + ), + ); + }, + )), + ], ); }, ), diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/share_four_scene_page.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/share_four_scene_page.dart index e0db463..e0558f1 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/share_four_scene_page.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/share_four_scene_page.dart @@ -56,6 +56,9 @@ class ShareFourScenePage extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ + SizedBox( + height: MediaQuery.of(context).size.height * 0.05, + ), const BodyLarge( text: 'Sharing Method Not Supported', fontSize: 15, diff --git a/lib/features/devices/view/widgets/sos/sos_setting/share_sos_page.dart b/lib/features/devices/view/widgets/sos/sos_setting/share_sos_page.dart index fdbf4d9..0c7b1f4 100644 --- a/lib/features/devices/view/widgets/sos/sos_setting/share_sos_page.dart +++ b/lib/features/devices/view/widgets/sos/sos_setting/share_sos_page.dart @@ -1,15 +1,18 @@ 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/sos_bloc/sos_bloc.dart'; import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_event.dart'; import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_state.dart'; import 'package:syncrow_app/features/devices/model/device_model.dart'; import 'package:syncrow_app/features/devices/model/sos_model.dart'; +import 'package:syncrow_app/features/menu/view/widgets/manage_home/home_settings.dart'; import 'package:syncrow_app/features/shared_widgets/default_button.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/helpers/custom_page_route.dart'; import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; class ShareSosPage extends StatelessWidget { @@ -19,6 +22,8 @@ class ShareSosPage extends StatelessWidget { @override Widget build(BuildContext context) { + var spaces = HomeCubit.getInstance().spaces; + return DefaultScaffold( title: 'Share Device', child: BlocProvider( @@ -48,6 +53,9 @@ class ShareSosPage extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ + SizedBox( + height: MediaQuery.of(context).size.height * 0.05, + ), const BodyLarge( text: 'Sharing Method Not Supported', fontSize: 15, @@ -87,7 +95,10 @@ class ShareSosPage extends StatelessWidget { backgroundColor: ColorsManager.blueColor1, borderRadius: 50, onPressed: () { - + Navigator.of(context).push(CustomPageRoute( + builder: (context) => HomeSettingsView( + space: spaces!.first, + ))); }, child: Text('Add Home Member')), ), diff --git a/lib/features/devices/view/widgets/sos/sos_setting/sos_profile_page.dart b/lib/features/devices/view/widgets/sos/sos_setting/sos_profile_page.dart index 5d9b033..6f9cb52 100644 --- a/lib/features/devices/view/widgets/sos/sos_setting/sos_profile_page.dart +++ b/lib/features/devices/view/widgets/sos/sos_setting/sos_profile_page.dart @@ -59,15 +59,16 @@ class SosProfilePage extends StatelessWidget { children: [ CircleAvatar( radius: 60, - backgroundColor: Colors.white, + backgroundColor: Colors.white.withOpacity(0), child: CircleAvatar( radius: 55, backgroundColor: ColorsManager.graysColor, child: ClipOval( child: Center( child: SvgPicture.asset( - Assets.sosProfileIcon, - fit: BoxFit.contain, + Assets.sosHomeIcon, + fit: BoxFit.fitHeight, + height: 100, ), ), ), diff --git a/lib/features/devices/view/widgets/sos/sos_settings.dart b/lib/features/devices/view/widgets/sos/sos_settings.dart index 6d27019..17dbf46 100644 --- a/lib/features/devices/view/widgets/sos/sos_settings.dart +++ b/lib/features/devices/view/widgets/sos/sos_settings.dart @@ -125,15 +125,16 @@ class SosSettings extends StatelessWidget { radius: 40, backgroundColor: Colors.white, child: CircleAvatar( - radius: 40, - backgroundColor: Colors.grey, - child: ClipOval( - child: SvgPicture.asset( - Assets.sosProfileIcon, - fit: BoxFit.fill, - ), - ), - ), + radius: 40, + backgroundColor: + Colors.white.withOpacity(0), + child: ClipOval( + child: SvgPicture.asset( + Assets.sosHomeIcon, + fit: BoxFit.contain, + height: 80, + ), + )), ), ), ], @@ -176,7 +177,6 @@ class SosSettings extends StatelessWidget { context .read() .add(ToggleEnableAlarmEvent(p0)); - }, isNotification: true, onTap: () {}, @@ -350,17 +350,8 @@ class SosSettings extends StatelessWidget { Navigator.of(context).pop(); }, confirmTab: () { - // context - // .read< - // CreateSceneBloc>() - // .add(DeleteSceneEvent( - // sceneId: sceneId, - // unitUuid: HomeCubit - // .getInstance() - // .selectedSpace! - // .id!, - // )); - Navigator.of(context).pop(); + _bloc.add( + DeleteDeviceEvent()); }, ); }, diff --git a/lib/generated/assets.dart b/lib/generated/assets.dart index b08142a..859ae1c 100644 --- a/lib/generated/assets.dart +++ b/lib/generated/assets.dart @@ -1123,4 +1123,6 @@ class Assets { static const String sixSceneHomeIcon = "assets/icons/six_scene_home_icon.svg"; static const String editDeviceNameIcon = "assets/icons/edit_device_name_icon.svg"; + static const String sosHomeIcon = + "assets/icons/sos_home_icon.svg"; } From c5474c1b10679575b4859031a7cad00f51d01bfe Mon Sep 17 00:00:00 2001 From: mohammad Date: Mon, 25 Nov 2024 12:47:13 +0300 Subject: [PATCH 17/29] sos --- .../devices/bloc/sos_bloc/sos_bloc.dart | 221 +++++++----------- .../devices/bloc/sos_bloc/sos_event.dart | 86 +------ .../devices/bloc/sos_bloc/sos_state.dart | 4 - pubspec.yaml | 2 +- 4 files changed, 93 insertions(+), 220 deletions(-) diff --git a/lib/features/devices/bloc/sos_bloc/sos_bloc.dart b/lib/features/devices/bloc/sos_bloc/sos_bloc.dart index b41356c..7690953 100644 --- a/lib/features/devices/bloc/sos_bloc/sos_bloc.dart +++ b/lib/features/devices/bloc/sos_bloc/sos_bloc.dart @@ -41,7 +41,6 @@ class SosBloc extends Bloc { on(saveName); on(_toggleUpdate); on(_toggleHelpful); - // on(_toggleWaterLeakAlarm); } final TextEditingController nameController = @@ -49,34 +48,11 @@ class SosBloc extends Bloc { bool isSaving = false; bool editName = false; final FocusNode focusNode = FocusNode(); - Timer? _timer; bool enableAlarm = false; bool closingReminder = false; - bool waterAlarm = false; SosModel deviceStatus = SosModel(sosContactState: 'sos', batteryPercentage: 0); - void _fetchStatus(SosInitial event, Emitter emit) async { - emit(SosLoadingState()); - try { - var response = await DevicesAPI.getDeviceStatus(sosId); - List statusModelList = []; - for (var status in response['status']) { - statusModelList.add(StatusModel.fromJson(status)); - } - deviceStatus = SosModel.fromJson( - statusModelList, - ); - emit(UpdateState(sensor: deviceStatus)); - - Future.delayed(const Duration(milliseconds: 500)); - // _listenToChanges(); - } catch (e) { - emit(SosFailedState(errorMessage: e.toString())); - return; - } - } - DeviceInfoModel deviceInfo = DeviceInfoModel( activeTime: 0, category: "", @@ -110,29 +86,6 @@ class SosBloc extends Bloc { ), ); - void _onSearchFaq(SearchFaqEvent event, Emitter emit) { - emit(SosLoadingState()); - List _faqQuestions = faqQuestions.where((question) { - return question.question - .toLowerCase() - .contains(event.query.toLowerCase()); - }).toList(); - emit(FaqSearchState(filteredFaqQuestions: _faqQuestions)); - } - - void _changeName(ChangeNameEvent event, Emitter emit) { - emit(SosLoadingState()); - editName = event.value!; - if (editName) { - Future.delayed(const Duration(milliseconds: 500), () { - focusNode.requestFocus(); - }); - } else { - focusNode.unfocus(); - } - emit(NameEditingState(editName: editName)); - } - void _toggleLowBattery( ToggleEnableAlarmEvent event, Emitter emit) async { emit(LoadingNewSate(sosSensor: deviceStatus)); @@ -189,6 +142,8 @@ class SosBloc extends Bloc { } } +//========================= Device Info & Status ============================= + static String deviceName = ''; fetchDeviceInfo(SosInitialDeviseInfo event, Emitter emit) async { @@ -203,48 +158,29 @@ class SosBloc extends Bloc { } } - // Demo list of FAQ questions using the QuestionModel class - final List faqQuestions = [ - QuestionModel( - id: 1, - question: 'How does an SOS emergency button work?', - answer: - 'The SOS emergency button sends an alert to your contacts when pressed.', - ), - QuestionModel( - id: 2, - question: 'How long will an SOS alarm persist?', - answer: - 'The SOS alarm will persist until it is manually turned off or after a set time.', - ), - QuestionModel( - id: 3, - question: 'What should I do if the SOS button is unresponsive?', - answer: 'Try restarting the device. If it persists, contact support.', - ), - QuestionModel( - id: 4, - question: 'Can I use the SOS feature without a network connection?', - answer: - 'No, a network connection is required to send the alert to your contacts.', - ), - QuestionModel( - id: 5, - question: 'How often should I check the SOS battery?', - answer: - 'Check the SOS battery at least once a month to ensure it is operational.', - ), - ]; - Future _onSosInitial( - SosInitialQuestion event, Emitter emit) async { + void _fetchStatus(SosInitial event, Emitter emit) async { emit(SosLoadingState()); - // SosModel sosModel = await fetchSosData(sosId); // Define this function as needed - emit(FaqLoadedState(filteredFaqQuestions: faqQuestions)); + try { + var response = await DevicesAPI.getDeviceStatus(sosId); + List statusModelList = []; + for (var status in response['status']) { + statusModelList.add(StatusModel.fromJson(status)); + } + deviceStatus = SosModel.fromJson( + statusModelList, + ); + emit(UpdateState(sensor: deviceStatus)); + + Future.delayed(const Duration(milliseconds: 500)); + } catch (e) { + emit(SosFailedState(errorMessage: e.toString())); + return; + } } +//========================= assign & unassign devise to room ============================= List allDevices = []; List roomsList = []; - void _fetchRoomsAndDevices( FetchRoomsEvent event, Emitter emit) async { try { @@ -279,9 +215,6 @@ class SosBloc extends Bloc { _hasSelectionChanged = false; add(AssignRoomEvent(roomId: roomId, unit: unit, context: event.context)); emit(SaveSelectionSuccessState()); - - // Navigator.pushNamedAndRemoveUntil( - // event.context, Routes.homeRoute, (route) => false); var cubit = HomeCubit.getInstance(); cubit.updatePageIndex(1); Navigator.pushReplacementNamed(event.context, Routes.homeRoute); @@ -290,7 +223,6 @@ class SosBloc extends Bloc { void _assignDevice(AssignRoomEvent event, Emitter emit) async { try { - // Map roomDevicesId = {}; emit(SosLoadingState()); await HomeManagementAPI.assignDeviceToRoom( @@ -339,11 +271,6 @@ class SosBloc extends Bloc { roomDevicesId[e.uuid!] = false; } }); - // emit(FetchDeviceByRoomIdState( - // roomDevices: devicesList, - // allDevices: allDevices, - // roomDevicesId: roomDevicesId, - // roomId: event.roomId)); } catch (e) { emit(const SosFailedState(errorMessage: 'Something went wrong')); return; @@ -352,46 +279,7 @@ class SosBloc extends Bloc { Map> devicesByRoom = {}; -// Your existing function - void _fetchDevicesByRoomId( - FetchDevicesByRoomIdEvent event, Emitter emit) async { - try { - Map roomDevicesId = {}; - emit(SosLoadingState()); - - // Fetch devices for the specified room - final devicesList = await DevicesAPI.getDevicesByRoomId( - communityUuid: event.unit.community.uuid, - spaceUuid: event.unit.id, - roomId: event.roomId); - - // Fetch all devices accessible by the user - allDevices = await HomeManagementAPI.fetchDevicesByUserId(); - - // Map all accessible device IDs - List allDevicesIds = []; - allDevices.forEach((element) { - allDevicesIds.add(element.uuid!); - }); - - // Mark devices as accessible/inaccessible for the room and add to devicesByRoom map - devicesList.forEach((e) { - roomDevicesId[e.uuid!] = allDevicesIds.contains(e.uuid!); - }); - - // Update the devicesByRoom map with the devices in the current room - devicesByRoom[event.roomId] = devicesList; - - // emit(FetchDeviceByRoomIdState( - // roomDevices: devicesList, - // allDevices: allDevices, - // roomDevicesId: roomDevicesId, - // roomId: event.roomId)); - } catch (e) { - emit(const SosFailedState(errorMessage: 'Something went wrong')); - return; - } - } +//======================= setting name ====================================== Future saveName(SaveNameEvent event, Emitter emit) async { if (_validateInputs()) return; @@ -432,6 +320,20 @@ class SosBloc extends Bloc { return null; } + void _changeName(ChangeNameEvent event, Emitter emit) { + emit(SosLoadingState()); + editName = event.value!; + if (editName) { + Future.delayed(const Duration(milliseconds: 500), () { + focusNode.requestFocus(); + }); + } else { + focusNode.unfocus(); + } + emit(NameEditingState(editName: editName)); + } + +//============================== update setting =============================== bool enableUpdate = false; void _toggleUpdate(ToggleUpdateEvent event, Emitter emit) async { @@ -444,8 +346,57 @@ class SosBloc extends Bloc { } } - bool isHelpful = false; + //============================ Question and faq ============================ + final List faqQuestions = [ + QuestionModel( + id: 1, + question: 'How does an SOS emergency button work?', + answer: + 'The SOS emergency button sends an alert to your contacts when pressed.', + ), + QuestionModel( + id: 2, + question: 'How long will an SOS alarm persist?', + answer: + 'The SOS alarm will persist until it is manually turned off or after a set time.', + ), + QuestionModel( + id: 3, + question: 'What should I do if the SOS button is unresponsive?', + answer: 'Try restarting the device. If it persists, contact support.', + ), + QuestionModel( + id: 4, + question: 'Can I use the SOS feature without a network connection?', + answer: + 'No, a network connection is required to send the alert to your contacts.', + ), + QuestionModel( + id: 5, + question: 'How often should I check the SOS battery?', + answer: + 'Check the SOS battery at least once a month to ensure it is operational.', + ), + ]; + + Future _onSosInitial( + SosInitialQuestion event, Emitter emit) async { + emit(SosLoadingState()); + emit(FaqLoadedState(filteredFaqQuestions: faqQuestions)); + } + + void _onSearchFaq(SearchFaqEvent event, Emitter emit) { + emit(SosLoadingState()); + List _faqQuestions = faqQuestions.where((question) { + return question.question + .toLowerCase() + .contains(event.query.toLowerCase()); + }).toList(); + emit(FaqSearchState(filteredFaqQuestions: _faqQuestions)); + } + + bool isHelpful = false; void _toggleHelpful(ToggleHelpfulEvent event, Emitter emit) async { try { emit(SosLoadingState()); @@ -456,6 +407,8 @@ class SosBloc extends Bloc { } } +//===================== delete Device =================================== + deleteDevice(DeleteDeviceEvent event, Emitter emit) async { try { emit(SosLoadingState()); diff --git a/lib/features/devices/bloc/sos_bloc/sos_event.dart b/lib/features/devices/bloc/sos_bloc/sos_event.dart index 6556228..79ad27a 100644 --- a/lib/features/devices/bloc/sos_bloc/sos_event.dart +++ b/lib/features/devices/bloc/sos_bloc/sos_event.dart @@ -11,21 +11,8 @@ abstract class SosEvent extends Equatable { List get props => []; } -class SosLoading extends SosEvent {} -class DeleteDeviceEvent extends SosLoading {} +class DeleteDeviceEvent extends SosEvent {} -class SosSwitch extends SosEvent { - final String switchD; - final String deviceId; - final String productId; - const SosSwitch( - {required this.switchD, this.deviceId = '', this.productId = ''}); - - @override - List get props => [switchD, deviceId, productId]; -} - -class SosUpdated extends SosEvent {} class SosInitialDeviseInfo extends SosEvent {} class SosInitial extends SosEvent { @@ -36,15 +23,6 @@ class ReportLogsInitial extends SosEvent { const ReportLogsInitial(); } -class SosChangeStatus extends SosEvent {} - -class GetCounterEvent extends SosEvent { - final String deviceCode; - const GetCounterEvent({required this.deviceCode}); - @override - List get props => [deviceCode]; -} - class ToggleEnableAlarmEvent extends SosEvent { final bool isLowBatteryEnabled; @@ -63,44 +41,6 @@ class ToggleClosingReminderEvent extends SosEvent { List get props => [isClosingReminderEnabled]; } -class ToggleSosAlarmEvent extends SosEvent { - final bool isSosAlarmEnabled; - - const ToggleSosAlarmEvent(this.isSosAlarmEnabled); - - @override - List get props => [isSosAlarmEnabled]; -} - -class SetCounterValue extends SosEvent { - final Duration duration; - final String deviceCode; - const SetCounterValue({required this.duration, required this.deviceCode}); - @override - List get props => [duration, deviceCode]; -} - -class StartTimer extends SosEvent { - final int duration; - - const StartTimer(this.duration); - - @override - List get props => [duration]; -} - -class TickTimer extends SosEvent { - final int remainingTime; - - const TickTimer(this.remainingTime); - - @override - List get props => [remainingTime]; -} - -class StopTimer extends SosEvent {} - -class OnClose extends SosEvent {} class SaveNameEvent extends SosEvent {} class ChangeNameEvent extends SosEvent { @@ -127,7 +67,6 @@ class FetchRoomsEvent extends SosEvent { List get props => [unit]; } - class SelectOptionEvent extends SosEvent { dynamic selectedOption; SelectOptionEvent({ @@ -160,6 +99,7 @@ class AssignRoomEvent extends SosEvent { context, ]; } + class UnassignRoomEvent extends SosEvent { final String roomId; final String deviceId; @@ -172,25 +112,9 @@ class UnassignRoomEvent extends SosEvent { List get props => [roomId, unit]; } -class FetchDevicesByRoomIdEvent extends SosEvent { - final SpaceModel unit; // Represents the unit (e.g., room or space) context - final String roomId; // Unique identifier for the room - - // Constructor - FetchDevicesByRoomIdEvent({ - required this.unit, - required this.roomId, - }); - - // Adding properties for Equatable to compare - @override - List get props => [unit, roomId]; -} - - class LoadingDeviceInfo extends SosEvent { - DeviceInfoModel deviceInfo; - LoadingDeviceInfo({required this.deviceInfo}); + DeviceInfoModel deviceInfo; + LoadingDeviceInfo({required this.deviceInfo}); @override List get props => [deviceInfo]; @@ -204,4 +128,4 @@ class ToggleUpdateEvent extends SosEvent { class ToggleHelpfulEvent extends SosEvent { final bool? isHelpful; const ToggleHelpfulEvent({this.isHelpful}); -} \ No newline at end of file +} diff --git a/lib/features/devices/bloc/sos_bloc/sos_state.dart b/lib/features/devices/bloc/sos_bloc/sos_state.dart index 3f125cb..cd010cc 100644 --- a/lib/features/devices/bloc/sos_bloc/sos_state.dart +++ b/lib/features/devices/bloc/sos_bloc/sos_state.dart @@ -12,12 +12,8 @@ class SosState extends Equatable { List get props => []; } -class SosInitialState extends SosState {} - class SosLoadingState extends SosState {} - - class SaveState extends SosState {} class LoadingSosDeviceInfo extends SosState { diff --git a/pubspec.yaml b/pubspec.yaml index 5aaacfe..42bd7df 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.8+41 +version: 1.0.9+42 environment: sdk: ">=3.0.6 <4.0.0" From a7aa165317dc9f8c91c5909b37df9a40664c11f8 Mon Sep 17 00:00:00 2001 From: mohammad Date: Mon, 25 Nov 2024 13:20:17 +0300 Subject: [PATCH 18/29] sos --- .../six_scene_delete_dialog.dart | 227 ------------------ .../6_scene_setting/six_scene_settings.dart | 112 +-------- .../four_scene_switch/four_scene_screen.dart | 2 - .../four_scene_delete_dialog.dart | 227 ------------------ .../four_scene_settings.dart | 117 +-------- .../sos/sos_setting/delete_dialog.dart | 227 ------------------ .../view/widgets/sos/sos_settings.dart | 112 +-------- .../shared_widgets/delete_device_dialogs.dart | 227 ++++++++++++++++++ .../shared_widgets/setting_widget.dart | 94 ++++++++ 9 files changed, 329 insertions(+), 1016 deletions(-) create mode 100644 lib/features/shared_widgets/delete_device_dialogs.dart create mode 100644 lib/features/shared_widgets/setting_widget.dart diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_delete_dialog.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_delete_dialog.dart index 67c62e2..e69de29 100644 --- a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_delete_dialog.dart +++ b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_delete_dialog.dart @@ -1,227 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart'; -import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; - -class DisconnectDeviceDialog extends StatelessWidget { - final Function()? cancelTab; - final Function()? confirmTab; - - const DisconnectDeviceDialog({ - super.key, - required this.cancelTab, - required this.confirmTab, - }); - - @override - Widget build(BuildContext context) { - return AlertDialog( - contentPadding: EdgeInsets.zero, - content: Column( - mainAxisSize: MainAxisSize.min, - children: [ - const SizedBox( - height: 10, - ), - const BodyLarge( - text: 'Disconnect Device', - fontWeight: FontWeight.w700, - fontColor: ColorsManager.red, - fontSize: 16, - ), - const Padding( - padding: EdgeInsets.only(left: 15, right: 15), - child: Divider( - color: ColorsManager.textGray, - ), - ), - const Padding( - padding: EdgeInsets.only(left: 15, right: 20, top: 15, bottom: 20), - child: Column( - children: [ - Center( - child: Text( - 'This will disconnect your device from this Application')), - ], - ), - ), - 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: 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: confirmTab, - child: const Padding( - padding: EdgeInsets.all(15), - child: Center( - child: Text( - 'Disconnect', - style: TextStyle( - color: ColorsManager.red, - fontSize: 14, - fontWeight: FontWeight.w400), - ), - ), - )), - )) - ], - ) - ], - ), - ); - } -} - -class DisconnectWipeData extends StatelessWidget { - final Function()? cancelTab; - final Function()? confirmTab; - - const DisconnectWipeData({ - super.key, - required this.cancelTab, - required this.confirmTab, - }); - - @override - Widget build(BuildContext context) { - return AlertDialog( - contentPadding: EdgeInsets.zero, - content: Column( - mainAxisSize: MainAxisSize.min, - children: [ - const SizedBox( - height: 10, - ), - const BodyLarge( - text: 'Disconnect and Wipe Data', - fontWeight: FontWeight.w700, - fontColor: ColorsManager.red, - fontSize: 16, - ), - const Padding( - padding: EdgeInsets.only(left: 15, right: 15), - child: Divider( - color: ColorsManager.textGray, - ), - ), - const Padding( - padding: EdgeInsets.only(left: 15, right: 20, top: 15, bottom: 20), - child: Column( - children: [ - Center( - child: Text( - 'This will disconnect your device from this Application and wipe all the data')), - ], - ), - ), - 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: 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: confirmTab, - child: const Padding( - padding: EdgeInsets.all(15), - child: Center( - child: Text( - 'Disconnect', - style: TextStyle( - color: ColorsManager.red, - fontSize: 14, - fontWeight: FontWeight.w400), - ), - ), - )), - )) - ], - ) - ], - ), - ); - } -} diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_settings.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_settings.dart index 60495e4..5b90a37 100644 --- a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_settings.dart +++ b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_settings.dart @@ -1,4 +1,3 @@ -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/flutter_svg.dart'; @@ -9,13 +8,14 @@ import 'package:syncrow_app/features/devices/model/device_model.dart'; import 'package:syncrow_app/features/devices/model/six_scene_model.dart'; import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/6_scene_setting/faq_six_scene_page.dart'; import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/6_scene_setting/share_six_scene_page.dart'; -import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_delete_dialog.dart'; import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_info_page.dart'; import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_profile_page.dart'; import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_update_dialog.dart'; import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_update_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/delete_device_dialogs.dart'; +import 'package:syncrow_app/features/shared_widgets/setting_widget.dart'; import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart'; import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart'; import 'package:syncrow_app/generated/assets.dart'; @@ -271,16 +271,6 @@ class SixSceneSettings extends StatelessWidget { Navigator.of(context).pop(); }, confirmTab: () { - // context - // .read< - // CreateSceneBloc>() - // .add(DeleteSceneEvent( - // sceneId: sceneId, - // unitUuid: HomeCubit - // .getInstance() - // .selectedSpace! - // .id!, - // )); Navigator.of(context).pop(); }, ); @@ -341,16 +331,6 @@ class SixSceneSettings extends StatelessWidget { Navigator.of(context).pop(); }, confirmTab: () { - // context - // .read< - // CreateSceneBloc>() - // .add(DeleteSceneEvent( - // sceneId: sceneId, - // unitUuid: HomeCubit - // .getInstance() - // .selectedSpace! - // .id!, - // )); Navigator.of(context).pop(); }, ); @@ -431,91 +411,3 @@ class SixSceneSettings extends StatelessWidget { ); } } - -class SettingWidget extends StatelessWidget { - final String? text; - final bool? isUpdate; - final bool? value; - final bool? isNotification; - final String? icon; - final Function()? onTap; - final Function()? onTapUpdate; - final Function(bool)? onChanged; - const SettingWidget( - {super.key, - this.text, - this.icon, - this.onTap, - this.value, - this.isUpdate, - this.onChanged, - this.isNotification = false, - this.onTapUpdate}); - - @override - Widget build(BuildContext context) { - return InkWell( - onTap: onTap, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Row( - children: [ - Expanded( - flex: 2, - child: Container( - padding: EdgeInsets.all(8), - decoration: const BoxDecoration( - color: ColorsManager.primaryColor, - borderRadius: BorderRadius.all(Radius.circular(20))), - child: SvgPicture.asset( - icon!, - fit: BoxFit.none, - height: 30, - ), - ), - ), - const SizedBox( - width: 8, - ), - Expanded( - flex: isUpdate == true ? 5 : 10, - child: BodyMedium( - text: text!, - fontSize: 15, - fontWeight: FontWeight.w400, - )), - ], - ), - ), - isUpdate == true - ? InkWell( - onTap: onTapUpdate, - child: BodyMedium( - text: '1 Update Available', - fontSize: 13, - fontWeight: FontWeight.w400, - fontColor: ColorsManager.blueColor, - ), - ) - : SizedBox(), - isNotification == false - ? const Icon( - Icons.arrow_forward_ios, - color: ColorsManager.graysColor, - size: 20, - ) - : Transform.scale( - scale: .8, - child: CupertinoSwitch( - value: value!, - onChanged: onChanged, - applyTheme: true, - ), - ), - ], - ), - ); - } -} diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_screen.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_screen.dart index 224e30b..30d6ddd 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_screen.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_screen.dart @@ -1,6 +1,4 @@ -import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart'; diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_delete_dialog.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_delete_dialog.dart index 67c62e2..e69de29 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_delete_dialog.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_delete_dialog.dart @@ -1,227 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart'; -import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; - -class DisconnectDeviceDialog extends StatelessWidget { - final Function()? cancelTab; - final Function()? confirmTab; - - const DisconnectDeviceDialog({ - super.key, - required this.cancelTab, - required this.confirmTab, - }); - - @override - Widget build(BuildContext context) { - return AlertDialog( - contentPadding: EdgeInsets.zero, - content: Column( - mainAxisSize: MainAxisSize.min, - children: [ - const SizedBox( - height: 10, - ), - const BodyLarge( - text: 'Disconnect Device', - fontWeight: FontWeight.w700, - fontColor: ColorsManager.red, - fontSize: 16, - ), - const Padding( - padding: EdgeInsets.only(left: 15, right: 15), - child: Divider( - color: ColorsManager.textGray, - ), - ), - const Padding( - padding: EdgeInsets.only(left: 15, right: 20, top: 15, bottom: 20), - child: Column( - children: [ - Center( - child: Text( - 'This will disconnect your device from this Application')), - ], - ), - ), - 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: 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: confirmTab, - child: const Padding( - padding: EdgeInsets.all(15), - child: Center( - child: Text( - 'Disconnect', - style: TextStyle( - color: ColorsManager.red, - fontSize: 14, - fontWeight: FontWeight.w400), - ), - ), - )), - )) - ], - ) - ], - ), - ); - } -} - -class DisconnectWipeData extends StatelessWidget { - final Function()? cancelTab; - final Function()? confirmTab; - - const DisconnectWipeData({ - super.key, - required this.cancelTab, - required this.confirmTab, - }); - - @override - Widget build(BuildContext context) { - return AlertDialog( - contentPadding: EdgeInsets.zero, - content: Column( - mainAxisSize: MainAxisSize.min, - children: [ - const SizedBox( - height: 10, - ), - const BodyLarge( - text: 'Disconnect and Wipe Data', - fontWeight: FontWeight.w700, - fontColor: ColorsManager.red, - fontSize: 16, - ), - const Padding( - padding: EdgeInsets.only(left: 15, right: 15), - child: Divider( - color: ColorsManager.textGray, - ), - ), - const Padding( - padding: EdgeInsets.only(left: 15, right: 20, top: 15, bottom: 20), - child: Column( - children: [ - Center( - child: Text( - 'This will disconnect your device from this Application and wipe all the data')), - ], - ), - ), - 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: 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: confirmTab, - child: const Padding( - padding: EdgeInsets.all(15), - child: Center( - child: Text( - 'Disconnect', - style: TextStyle( - color: ColorsManager.red, - fontSize: 14, - fontWeight: FontWeight.w400), - ), - ), - )), - )) - ], - ) - ], - ), - ); - } -} diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart index 33ab7ec..a6cea79 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart @@ -1,4 +1,3 @@ -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/flutter_svg.dart'; @@ -8,7 +7,6 @@ import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_sta import 'package:syncrow_app/features/devices/model/device_model.dart'; import 'package:syncrow_app/features/devices/model/four_scene_model.dart'; import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_scene_setting/faq_four_scene_page.dart'; -import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_delete_dialog.dart'; import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_info_page.dart'; import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_profile_page.dart'; import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_update_dialog.dart'; @@ -16,6 +14,8 @@ import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_scene_setting/share_four_scene_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/delete_device_dialogs.dart'; +import 'package:syncrow_app/features/shared_widgets/setting_widget.dart'; import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart'; import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart'; import 'package:syncrow_app/generated/assets.dart'; @@ -72,7 +72,7 @@ class FourSceneSettings extends StatelessWidget { ), ); if (val == true) { - _bloc.add(FourSceneInitialInfo()); + _bloc.add(const FourSceneInitialInfo()); } }, child: Stack( @@ -285,16 +285,6 @@ class FourSceneSettings extends StatelessWidget { Navigator.of(context).pop(); }, confirmTab: () { - // context - // .read< - // CreateSceneBloc>() - // .add(DeleteSceneEvent( - // sceneId: sceneId, - // unitUuid: HomeCubit - // .getInstance() - // .selectedSpace! - // .id!, - // )); Navigator.of(context).pop(); }, ); @@ -355,16 +345,6 @@ class FourSceneSettings extends StatelessWidget { Navigator.of(context).pop(); }, confirmTab: () { - // context - // .read< - // CreateSceneBloc>() - // .add(DeleteSceneEvent( - // sceneId: sceneId, - // unitUuid: HomeCubit - // .getInstance() - // .selectedSpace! - // .id!, - // )); Navigator.of(context).pop(); }, ); @@ -387,8 +367,7 @@ class FourSceneSettings extends StatelessWidget { ), const SizedBox(height: 20), Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, + mainAxisAlignment:MainAxisAlignment.spaceBetween, children: [ InkWell( onTap: () { @@ -445,91 +424,3 @@ class FourSceneSettings extends StatelessWidget { ); } } - -class SettingWidget extends StatelessWidget { - final String? text; - final bool? isUpdate; - final bool? value; - final bool? isNotification; - final String? icon; - final Function()? onTap; - final Function()? onTapUpdate; - final Function(bool)? onChanged; - const SettingWidget( - {super.key, - this.text, - this.icon, - this.value, - this.onTap, - this.isUpdate, - this.onChanged, - this.isNotification = false, - this.onTapUpdate}); - - @override - Widget build(BuildContext context) { - return InkWell( - onTap: onTap, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Row( - children: [ - Expanded( - flex: 2, - child: Container( - padding: const EdgeInsets.all(8), - decoration: const BoxDecoration( - color: ColorsManager.primaryColor, - borderRadius: BorderRadius.all(Radius.circular(20))), - child: SvgPicture.asset( - icon!, - fit: BoxFit.none, - height: 30, - ), - ), - ), - const SizedBox( - width: 8, - ), - Expanded( - flex: isUpdate == true ? 5 : 10, - child: BodyMedium( - text: text!, - fontSize: 15, - fontWeight: FontWeight.w400, - )), - ], - ), - ), - isUpdate == true - ? InkWell( - onTap: onTapUpdate, - child: const BodyMedium( - text: '1 Update Available', - fontSize: 13, - fontWeight: FontWeight.w400, - fontColor: ColorsManager.blueColor, - ), - ) - : SizedBox(), - isNotification == false - ? const Icon( - Icons.arrow_forward_ios, - color: ColorsManager.graysColor, - size: 20, - ) - : Transform.scale( - scale: .8, - child: CupertinoSwitch( - value: value!, - onChanged: onChanged, - applyTheme: true, - ), - ), - ], - ), - ); - } -} diff --git a/lib/features/devices/view/widgets/sos/sos_setting/delete_dialog.dart b/lib/features/devices/view/widgets/sos/sos_setting/delete_dialog.dart index 67c62e2..e69de29 100644 --- a/lib/features/devices/view/widgets/sos/sos_setting/delete_dialog.dart +++ b/lib/features/devices/view/widgets/sos/sos_setting/delete_dialog.dart @@ -1,227 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart'; -import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; - -class DisconnectDeviceDialog extends StatelessWidget { - final Function()? cancelTab; - final Function()? confirmTab; - - const DisconnectDeviceDialog({ - super.key, - required this.cancelTab, - required this.confirmTab, - }); - - @override - Widget build(BuildContext context) { - return AlertDialog( - contentPadding: EdgeInsets.zero, - content: Column( - mainAxisSize: MainAxisSize.min, - children: [ - const SizedBox( - height: 10, - ), - const BodyLarge( - text: 'Disconnect Device', - fontWeight: FontWeight.w700, - fontColor: ColorsManager.red, - fontSize: 16, - ), - const Padding( - padding: EdgeInsets.only(left: 15, right: 15), - child: Divider( - color: ColorsManager.textGray, - ), - ), - const Padding( - padding: EdgeInsets.only(left: 15, right: 20, top: 15, bottom: 20), - child: Column( - children: [ - Center( - child: Text( - 'This will disconnect your device from this Application')), - ], - ), - ), - 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: 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: confirmTab, - child: const Padding( - padding: EdgeInsets.all(15), - child: Center( - child: Text( - 'Disconnect', - style: TextStyle( - color: ColorsManager.red, - fontSize: 14, - fontWeight: FontWeight.w400), - ), - ), - )), - )) - ], - ) - ], - ), - ); - } -} - -class DisconnectWipeData extends StatelessWidget { - final Function()? cancelTab; - final Function()? confirmTab; - - const DisconnectWipeData({ - super.key, - required this.cancelTab, - required this.confirmTab, - }); - - @override - Widget build(BuildContext context) { - return AlertDialog( - contentPadding: EdgeInsets.zero, - content: Column( - mainAxisSize: MainAxisSize.min, - children: [ - const SizedBox( - height: 10, - ), - const BodyLarge( - text: 'Disconnect and Wipe Data', - fontWeight: FontWeight.w700, - fontColor: ColorsManager.red, - fontSize: 16, - ), - const Padding( - padding: EdgeInsets.only(left: 15, right: 15), - child: Divider( - color: ColorsManager.textGray, - ), - ), - const Padding( - padding: EdgeInsets.only(left: 15, right: 20, top: 15, bottom: 20), - child: Column( - children: [ - Center( - child: Text( - 'This will disconnect your device from this Application and wipe all the data')), - ], - ), - ), - 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: 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: confirmTab, - child: const Padding( - padding: EdgeInsets.all(15), - child: Center( - child: Text( - 'Disconnect', - style: TextStyle( - color: ColorsManager.red, - fontSize: 14, - fontWeight: FontWeight.w400), - ), - ), - )), - )) - ], - ) - ], - ), - ); - } -} diff --git a/lib/features/devices/view/widgets/sos/sos_settings.dart b/lib/features/devices/view/widgets/sos/sos_settings.dart index 17dbf46..0a41e67 100644 --- a/lib/features/devices/view/widgets/sos/sos_settings.dart +++ b/lib/features/devices/view/widgets/sos/sos_settings.dart @@ -1,4 +1,3 @@ -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/flutter_svg.dart'; @@ -7,7 +6,6 @@ import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_event.dart'; import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_state.dart'; import 'package:syncrow_app/features/devices/model/device_model.dart'; import 'package:syncrow_app/features/devices/model/sos_model.dart'; -import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/delete_dialog.dart'; import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/sos_profile_page.dart'; import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/faq_sos_page.dart'; import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/share_sos_page.dart'; @@ -16,6 +14,8 @@ import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/sos_up import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/update_dialog_sos.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/delete_device_dialogs.dart'; +import 'package:syncrow_app/features/shared_widgets/setting_widget.dart'; import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart'; import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart'; import 'package:syncrow_app/generated/assets.dart'; @@ -235,16 +235,6 @@ class SosSettings extends StatelessWidget { Navigator.of(context).pop(); }, confirmTab: () { - // context - // .read< - // CreateSceneBloc>() - // .add(DeleteSceneEvent( - // sceneId: sceneId, - // unitUuid: HomeCubit - // .getInstance() - // .selectedSpace! - // .id!, - // )); Navigator.of(context).pop(); }, ); @@ -305,16 +295,6 @@ class SosSettings extends StatelessWidget { Navigator.of(context).pop(); }, confirmTab: () { - // context - // .read< - // CreateSceneBloc>() - // .add(DeleteSceneEvent( - // sceneId: sceneId, - // unitUuid: HomeCubit - // .getInstance() - // .selectedSpace! - // .id!, - // )); Navigator.of(context).pop(); }, ); @@ -395,91 +375,3 @@ class SosSettings extends StatelessWidget { ); } } - -class SettingWidget extends StatelessWidget { - final String? text; - final bool? isUpdate; - final bool? value; - final bool? isNotification; - final String? icon; - final Function()? onTap; - final Function()? onTapUpdate; - final Function(bool)? onChanged; - const SettingWidget( - {super.key, - this.text, - this.icon, - this.value, - this.onTap, - this.isUpdate, - this.onChanged, - this.isNotification = false, - this.onTapUpdate}); - - @override - Widget build(BuildContext context) { - return InkWell( - onTap: onTap, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Row( - children: [ - Expanded( - flex: 2, - child: Container( - padding: EdgeInsets.all(8), - decoration: const BoxDecoration( - color: ColorsManager.primaryColor, - borderRadius: BorderRadius.all(Radius.circular(20))), - child: SvgPicture.asset( - icon!, - fit: BoxFit.none, - height: 30, - ), - ), - ), - const SizedBox( - width: 8, - ), - Expanded( - flex: isUpdate == true ? 5 : 10, - child: BodyMedium( - text: text!, - fontSize: 15, - fontWeight: FontWeight.w400, - )), - ], - ), - ), - isUpdate == true - ? InkWell( - onTap: onTapUpdate, - child: const BodyMedium( - text: '1 Update Available', - fontSize: 13, - fontWeight: FontWeight.w400, - fontColor: ColorsManager.blueColor, - ), - ) - : SizedBox(), - isNotification == false - ? const Icon( - Icons.arrow_forward_ios, - color: ColorsManager.graysColor, - size: 20, - ) - : Transform.scale( - scale: .8, - child: CupertinoSwitch( - value: value!, - onChanged: onChanged, - applyTheme: true, - ), - ), - ], - ), - ); - } -} diff --git a/lib/features/shared_widgets/delete_device_dialogs.dart b/lib/features/shared_widgets/delete_device_dialogs.dart new file mode 100644 index 0000000..67c62e2 --- /dev/null +++ b/lib/features/shared_widgets/delete_device_dialogs.dart @@ -0,0 +1,227 @@ +import 'package:flutter/material.dart'; +import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +class DisconnectDeviceDialog extends StatelessWidget { + final Function()? cancelTab; + final Function()? confirmTab; + + const DisconnectDeviceDialog({ + super.key, + required this.cancelTab, + required this.confirmTab, + }); + + @override + Widget build(BuildContext context) { + return AlertDialog( + contentPadding: EdgeInsets.zero, + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const SizedBox( + height: 10, + ), + const BodyLarge( + text: 'Disconnect Device', + fontWeight: FontWeight.w700, + fontColor: ColorsManager.red, + fontSize: 16, + ), + const Padding( + padding: EdgeInsets.only(left: 15, right: 15), + child: Divider( + color: ColorsManager.textGray, + ), + ), + const Padding( + padding: EdgeInsets.only(left: 15, right: 20, top: 15, bottom: 20), + child: Column( + children: [ + Center( + child: Text( + 'This will disconnect your device from this Application')), + ], + ), + ), + 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: 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: confirmTab, + child: const Padding( + padding: EdgeInsets.all(15), + child: Center( + child: Text( + 'Disconnect', + style: TextStyle( + color: ColorsManager.red, + fontSize: 14, + fontWeight: FontWeight.w400), + ), + ), + )), + )) + ], + ) + ], + ), + ); + } +} + +class DisconnectWipeData extends StatelessWidget { + final Function()? cancelTab; + final Function()? confirmTab; + + const DisconnectWipeData({ + super.key, + required this.cancelTab, + required this.confirmTab, + }); + + @override + Widget build(BuildContext context) { + return AlertDialog( + contentPadding: EdgeInsets.zero, + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const SizedBox( + height: 10, + ), + const BodyLarge( + text: 'Disconnect and Wipe Data', + fontWeight: FontWeight.w700, + fontColor: ColorsManager.red, + fontSize: 16, + ), + const Padding( + padding: EdgeInsets.only(left: 15, right: 15), + child: Divider( + color: ColorsManager.textGray, + ), + ), + const Padding( + padding: EdgeInsets.only(left: 15, right: 20, top: 15, bottom: 20), + child: Column( + children: [ + Center( + child: Text( + 'This will disconnect your device from this Application and wipe all the data')), + ], + ), + ), + 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: 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: confirmTab, + child: const Padding( + padding: EdgeInsets.all(15), + child: Center( + child: Text( + 'Disconnect', + style: TextStyle( + color: ColorsManager.red, + fontSize: 14, + fontWeight: FontWeight.w400), + ), + ), + )), + )) + ], + ) + ], + ), + ); + } +} diff --git a/lib/features/shared_widgets/setting_widget.dart b/lib/features/shared_widgets/setting_widget.dart new file mode 100644 index 0000000..066ec6f --- /dev/null +++ b/lib/features/shared_widgets/setting_widget.dart @@ -0,0 +1,94 @@ + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +class SettingWidget extends StatelessWidget { + final String? text; + final bool? isUpdate; + final bool? value; + final bool? isNotification; + final String? icon; + final Function()? onTap; + final Function()? onTapUpdate; + final Function(bool)? onChanged; + const SettingWidget( + {super.key, + this.text, + this.icon, + this.value, + this.onTap, + this.isUpdate, + this.onChanged, + this.isNotification = false, + this.onTapUpdate}); + + @override + Widget build(BuildContext context) { + return InkWell( + onTap: onTap, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Row( + children: [ + Expanded( + flex: 2, + child: Container( + padding: const EdgeInsets.all(8), + decoration: const BoxDecoration( + color: ColorsManager.primaryColor, + borderRadius: BorderRadius.all(Radius.circular(20))), + child: SvgPicture.asset( + icon!, + fit: BoxFit.none, + height: 30, + ), + ), + ), + const SizedBox( + width: 8, + ), + Expanded( + flex: isUpdate == true ? 5 : 10, + child: BodyMedium( + text: text!, + fontSize: 15, + fontWeight: FontWeight.w400, + )), + ], + ), + ), + isUpdate == true + ? InkWell( + onTap: onTapUpdate, + child: const BodyMedium( + text: '1 Update Available', + fontSize: 13, + fontWeight: FontWeight.w400, + fontColor: ColorsManager.blueColor, + ), + ) + : const SizedBox(), + isNotification == false + ? const Icon( + Icons.arrow_forward_ios, + color: ColorsManager.graysColor, + size: 20, + ) + : Transform.scale( + scale: .8, + child: CupertinoSwitch( + value: value!, + onChanged: onChanged, + applyTheme: true, + ), + ), + ], + ), + ); + } +} From 3406a7eba16b7626198b57c82a13118eab9b9fd1 Mon Sep 17 00:00:00 2001 From: mohammad Date: Mon, 25 Nov 2024 14:21:36 +0300 Subject: [PATCH 19/29] changes --- .../view/widgets/6_scene_switch/six_scene_screen.dart | 7 +++++-- .../four_scene_setting/four_scene_settings.dart | 2 +- lib/features/devices/view/widgets/sos/sos_screen.dart | 7 +++++-- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/features/devices/view/widgets/6_scene_switch/six_scene_screen.dart b/lib/features/devices/view/widgets/6_scene_switch/six_scene_screen.dart index 25d929c..31a9130 100644 --- a/lib/features/devices/view/widgets/6_scene_switch/six_scene_screen.dart +++ b/lib/features/devices/view/widgets/6_scene_switch/six_scene_screen.dart @@ -54,12 +54,15 @@ class SixSceneScreen extends StatelessWidget { title: _bloc.deviceInfo.subspace.subspaceName, actions: [ InkWell( - onTap: () { - Navigator.of(context).push( + onTap: () async { + bool val = await Navigator.of(context).push( MaterialPageRoute( builder: (context) => SixSceneSettings(device: device!), ), ); + if (val == true) { + _bloc.add(const SixSceneInitialInfo()); + } }, child: SvgPicture.asset(Assets.assetsIconsSettings), ), diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart index a6cea79..99f9f39 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart @@ -367,7 +367,7 @@ class FourSceneSettings extends StatelessWidget { ), const SizedBox(height: 20), Row( - mainAxisAlignment:MainAxisAlignment.spaceBetween, + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ InkWell( onTap: () { diff --git a/lib/features/devices/view/widgets/sos/sos_screen.dart b/lib/features/devices/view/widgets/sos/sos_screen.dart index ea9e7df..4a3b765 100644 --- a/lib/features/devices/view/widgets/sos/sos_screen.dart +++ b/lib/features/devices/view/widgets/sos/sos_screen.dart @@ -45,12 +45,15 @@ class SosScreen extends StatelessWidget { title: sensor.deviceInfo.name, actions: [ InkWell( - onTap: () { - Navigator.of(context).push( + onTap: () async { + var val = await Navigator.of(context).push( MaterialPageRoute( builder: (context) => SosSettings(device: device!), ), ); + + sensor.add(SosInitialDeviseInfo()); + sensor.add(const SosInitial()); }, child: SvgPicture.asset(Assets.assetsIconsSettings), ), From 946f806a7187b4792bafe834f496099bf7a2d2c6 Mon Sep 17 00:00:00 2001 From: mohammad Date: Mon, 25 Nov 2024 14:42:03 +0300 Subject: [PATCH 20/29] code changes --- lib/features/app_layout/bloc/home_cubit.dart | 84 ++++--- .../four_scene_bloc/four_scene_event.dart | 4 +- .../four_scene_create_group.dart | 17 +- .../four_scene_delete_dialog.dart | 0 .../four_scene_info_page.dart | 15 +- .../four_scene_profile_page.dart | 17 +- .../four_scene_settings.dart | 3 +- .../four_scene_update_note.dart | 4 +- .../four_scene_update_page.dart | 13 +- .../location_setting_four_scene.dart | 122 +++++----- .../question_page_four_scene.dart | 209 ++++++++---------- .../share_four_scene_page.dart | 16 +- .../devices/view/widgets/sos/sos_screen.dart | 7 +- 13 files changed, 222 insertions(+), 289 deletions(-) delete mode 100644 lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_delete_dialog.dart diff --git a/lib/features/app_layout/bloc/home_cubit.dart b/lib/features/app_layout/bloc/home_cubit.dart index 625bab0..9e7b353 100644 --- a/lib/features/app_layout/bloc/home_cubit.dart +++ b/lib/features/app_layout/bloc/home_cubit.dart @@ -34,7 +34,7 @@ part 'home_state.dart'; class HomeCubit extends Cubit { HomeCubit._() : super(HomeInitial()) { - checkIfNotificationPermissionGranted(); + // checkIfNotificationPermissionGranted(); fetchUserInfo(); if (selectedSpace == null) { fetchUnitsByUserId(); @@ -55,7 +55,7 @@ class HomeCubit extends Cubit { Future fetchUserInfo() async { try { - var uuid = await const FlutterSecureStorage().read(key: UserModel.userUuidKey); + var uuid=await const FlutterSecureStorage().read(key: UserModel.userUuidKey); user = await ProfileApi().fetchUserInfo(uuid); emit(HomeUserInfoLoaded(user!)); // Emit state after fetching user info } catch (e) { @@ -76,9 +76,12 @@ class HomeCubit extends Cubit { selectedSpace = null; selectedRoom = null; pageIndex = 0; - OneSignal.User.pushSubscription.removeObserver((stateChanges) => oneSignalSubscriptionObserver); - OneSignal.Notifications.removePermissionObserver((permission) => oneSignalPermissionObserver); - OneSignal.Notifications.removeClickListener((event) => oneSignalClickListenerObserver); + // OneSignal.User.pushSubscription + // .removeObserver((stateChanges) => oneSignalSubscriptionObserver); + // OneSignal.Notifications.removePermissionObserver( + // (permission) => oneSignalPermissionObserver); + // OneSignal.Notifications.removeClickListener( + // (event) => oneSignalClickListenerObserver); return super.close(); } @@ -96,9 +99,9 @@ class HomeCubit extends Cubit { var duration = const Duration(milliseconds: 300); - void oneSignalPermissionObserver; - void oneSignalSubscriptionObserver; - void oneSignalClickListenerObserver; + // void oneSignalPermissionObserver; + // void oneSignalSubscriptionObserver; + // void oneSignalClickListenerObserver; // selectSpace(SpaceModel space) async { // selectedSpace = space; @@ -120,31 +123,36 @@ class HomeCubit extends Cubit { return; } - var userUuid = await const FlutterSecureStorage().read(key: UserModel.userUuidKey) ?? ''; + var userUuid = + await const FlutterSecureStorage().read(key: UserModel.userUuidKey) ?? + ''; if (userUuid.isNotEmpty) { await OneSignal.login(userUuid); } //Enable push notifications await OneSignal.User.pushSubscription.optIn(); - //this function will be called once a user is subscribed - oneSignalSubscriptionObserver = OneSignal.User.pushSubscription.addObserver((state) async { - if (state.current.optedIn) { - await _sendSubscriptionId(); - } - }); + // //this function will be called once a user is subscribed + // oneSignalSubscriptionObserver = + // OneSignal.User.pushSubscription.addObserver((state) async { + // if (state.current.optedIn) { + // await _sendSubscriptionId(); + // } + // }); - // Send the player id when a user allows notifications - oneSignalPermissionObserver = OneSignal.Notifications.addPermissionObserver((state) async { - await _sendSubscriptionId(); - }); + // // Send the player id when a user allows notifications + // oneSignalPermissionObserver = + // OneSignal.Notifications.addPermissionObserver((state) async { + // await _sendSubscriptionId(); + // }); - //check if the player id is sent, if not send it again - await _sendSubscriptionId(); + // //check if the player id is sent, if not send it again + // await _sendSubscriptionId(); - oneSignalClickListenerObserver = OneSignal.Notifications.addClickListener((event) async { - //Once the user clicks on the notification - }); + // oneSignalClickListenerObserver = + // OneSignal.Notifications.addClickListener((event) async { + // //Once the user clicks on the notification + // }); } catch (err) { debugPrint("******* Error"); debugPrint(err.toString()); @@ -213,7 +221,8 @@ class HomeCubit extends Cubit { //////////////////////////////////////// API //////////////////////////////////////// generateInvitation(SpaceModel unit) async { try { - final invitationCode = await SpacesAPI.generateInvitationCode(unit.id, unit.community.uuid); + final invitationCode = + await SpacesAPI.generateInvitationCode(unit.id, unit.community.uuid); if (invitationCode.isNotEmpty) { Share.share('The invitation code is $invitationCode'); CustomSnackBar.displaySnackBar( @@ -229,7 +238,9 @@ class HomeCubit extends Cubit { Future joinAUnit(String code) async { try { - var userUuid = await const FlutterSecureStorage().read(key: UserModel.userUuidKey) ?? ''; + var userUuid = + await const FlutterSecureStorage().read(key: UserModel.userUuidKey) ?? + ''; Map body = {'inviteCode': code}; final success = await SpacesAPI.joinUnit(userUuid, body); @@ -265,7 +276,8 @@ class HomeCubit extends Cubit { fetchRoomsByUnitId(SpaceModel space) async { emitSafe(GetSpaceRoomsLoading()); try { - space.subspaces = await SpacesAPI.getSubSpaceBySpaceId(space.community.uuid, space.id); + space.subspaces = + await SpacesAPI.getSubSpaceBySpaceId(space.community.uuid, space.id); } catch (failure) { emitSafe(GetSpaceRoomsError(failure.toString())); return; @@ -347,7 +359,8 @@ class HomeCubit extends Cubit { size: 32, ), style: ButtonStyle( - foregroundColor: WidgetStateProperty.all(ColorsManager.textPrimaryColor), + foregroundColor: + WidgetStateProperty.all(ColorsManager.textPrimaryColor), ), onPressed: () { Navigator.pushNamed( @@ -368,7 +381,8 @@ class HomeCubit extends Cubit { NavigationService.navigatorKey.currentContext! .read() .add(const SmartSceneClearEvent()); - BlocProvider.of(NavigationService.navigatorKey.currentState!.context) + BlocProvider.of( + NavigationService.navigatorKey.currentState!.context) .add(ResetEffectivePeriod()); NavigationService.navigatorKey.currentContext! .read() @@ -381,7 +395,8 @@ class HomeCubit extends Cubit { size: 28, ), style: ButtonStyle( - foregroundColor: WidgetStateProperty.all(ColorsManager.textPrimaryColor), + foregroundColor: + WidgetStateProperty.all(ColorsManager.textPrimaryColor), ), onPressed: () {}, ), @@ -414,7 +429,8 @@ class HomeCubit extends Cubit { }; static var bottomNavItems = [ - defaultBottomNavBarItem(icon: Assets.assetsIconsDashboard, label: 'Dashboard'), + defaultBottomNavBarItem( + icon: Assets.assetsIconsDashboard, label: 'Dashboard'), // defaultBottomNavBarItem(icon: Assets.assetsIconslayout, label: 'Layout'), defaultBottomNavBarItem(icon: Assets.assetsIconsDevices, label: 'Devices'), defaultBottomNavBarItem(icon: Assets.assetsIconsRoutines, label: 'Routine'), @@ -440,7 +456,8 @@ class HomeCubit extends Cubit { void updateDevice(String deviceId) async { try { - final response = await DevicesAPI.firmwareDevice(deviceId: deviceId, firmwareVersion: '0'); + final response = await DevicesAPI.firmwareDevice( + deviceId: deviceId, firmwareVersion: '0'); if (response['success'] ?? false) { CustomSnackBar.displaySnackBar('No updates available'); } @@ -448,7 +465,8 @@ class HomeCubit extends Cubit { } } -BottomNavigationBarItem defaultBottomNavBarItem({required String icon, required String label}) { +BottomNavigationBarItem defaultBottomNavBarItem( + {required String icon, required String label}) { return BottomNavigationBarItem( icon: SvgPicture.asset(icon), activeIcon: SvgPicture.asset( diff --git a/lib/features/devices/bloc/four_scene_bloc/four_scene_event.dart b/lib/features/devices/bloc/four_scene_bloc/four_scene_event.dart index 9a75285..3083b04 100644 --- a/lib/features/devices/bloc/four_scene_bloc/four_scene_event.dart +++ b/lib/features/devices/bloc/four_scene_bloc/four_scene_event.dart @@ -167,8 +167,8 @@ class SearchScenesEvent extends FourSceneEvent { class SaveLocationSelectionEvent extends FourSceneEvent {} class SelectOptionEvent extends FourSceneEvent { - dynamic selectedOption; - SelectOptionEvent({ + final dynamic selectedOption; + const SelectOptionEvent({ this.selectedOption, }); } diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_create_group.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_create_group.dart index 5c3cb20..cb27656 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_create_group.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_create_group.dart @@ -5,7 +5,6 @@ import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_blo import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_event.dart'; import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_state.dart'; import 'package:syncrow_app/features/devices/model/device_model.dart'; -import 'package:syncrow_app/features/devices/model/four_scene_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/features/shared_widgets/text_widgets/body_large.dart'; @@ -29,18 +28,6 @@ class FourSceneCreateGroup extends StatelessWidget { child: BlocBuilder( builder: (context, state) { final sensor = BlocProvider.of(context); - FourSceneModelState model = FourSceneModelState( - scene_1: '', - scene_2: '', - scene_3: '', - scene_4: '', - scene_id_group_id: '', - switch_backlight: ''); - if (state is LoadingNewSate) { - model = state.device; - } else if (state is UpdateState) { - model = state.device; - } return state is LoadingNewSate ? const Center( child: DefaultContainer( @@ -49,7 +36,7 @@ class FourSceneCreateGroup extends StatelessWidget { child: CircularProgressIndicator()), ) : Padding( - padding: EdgeInsets.all(8.0), + padding: const EdgeInsets.all(8.0), child: Column( children: [ const Padding( @@ -201,7 +188,7 @@ class FourSceneCreateGroup extends StatelessWidget { ], ), ), - Spacer() + const Spacer() ], ), ); diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_delete_dialog.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_delete_dialog.dart deleted file mode 100644 index e69de29..0000000 diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_info_page.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_info_page.dart index 991fe57..d6ccfc5 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_info_page.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_info_page.dart @@ -5,7 +5,6 @@ import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_blo import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_event.dart'; import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_state.dart'; import 'package:syncrow_app/features/devices/model/device_model.dart'; -import 'package:syncrow_app/features/devices/model/four_scene_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/features/shared_widgets/text_widgets/body_large.dart'; @@ -29,18 +28,6 @@ class FourSceneInfoPage extends StatelessWidget { child: BlocBuilder( builder: (context, state) { final _bloc = BlocProvider.of(context); - FourSceneModelState model = FourSceneModelState( - scene_1: '', - scene_2: '', - scene_3: '', - scene_4: '', - scene_id_group_id: '', - switch_backlight: ''); - if (state is LoadingNewSate) { - model = state.device; - } else if (state is UpdateState) { - model = state.device; - } return state is FourSceneLoadingState ? const Center( child: DefaultContainer( @@ -69,7 +56,7 @@ class FourSceneInfoPage extends StatelessWidget { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Container( + SizedBox( width: MediaQuery.of(context).size.width * 0.61, child: BodySmall( diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_profile_page.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_profile_page.dart index 29a1272..cc70c8a 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_profile_page.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_profile_page.dart @@ -6,7 +6,6 @@ import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_blo import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_event.dart'; import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_state.dart'; import 'package:syncrow_app/features/devices/model/device_model.dart'; -import 'package:syncrow_app/features/devices/model/four_scene_model.dart'; import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_scene_setting/location_setting_four_scene.dart'; import 'package:syncrow_app/features/shared_widgets/default_container.dart'; import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart'; @@ -37,18 +36,6 @@ class FourSceneProfilePage extends StatelessWidget { child: BlocBuilder( builder: (context, state) { final _bloc = BlocProvider.of(context); - FourSceneModelState model = FourSceneModelState( - scene_1: '', - scene_2: '', - scene_3: '', - scene_4: '', - scene_id_group_id: '', - switch_backlight: ''); - if (state is LoadingNewSate) { - model = state.device; - } else if (state is UpdateState) { - model = state.device; - } return state is FourSceneLoadingState ? const Center( child: DefaultContainer( @@ -73,7 +60,7 @@ class FourSceneProfilePage extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [ - SizedBox( + const SizedBox( height: 10, ), Center( @@ -157,7 +144,7 @@ class FourSceneProfilePage extends StatelessWidget { )), ); if (val == true) { - _bloc.add(FourSceneInitialInfo()); + _bloc.add(const FourSceneInitialInfo()); } }, child: Row( diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart index 99f9f39..d81caac 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart @@ -367,7 +367,8 @@ class FourSceneSettings extends StatelessWidget { ), const SizedBox(height: 20), Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, + mainAxisAlignment: + MainAxisAlignment.spaceBetween, children: [ InkWell( onTap: () { diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_update_note.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_update_note.dart index 3023d3e..5ef211b 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_update_note.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_update_note.dart @@ -2,11 +2,11 @@ import 'package:flutter/material.dart'; import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart'; import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; -class upDateNote extends StatelessWidget { +class UpDateNote extends StatelessWidget { final Function()? cancelTab; final Function()? confirmTab; - const upDateNote({ + const UpDateNote({ super.key, required this.cancelTab, required this.confirmTab, diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_update_page.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_update_page.dart index b028b52..81f6a03 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_update_page.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_update_page.dart @@ -39,9 +39,6 @@ class FourSceneUpdatePage extends StatelessWidget { onRefresh: () async {}, child: Column( children: [ - // SizedBox( - // height: MediaQuery.of(context).size.height * 0.15, - // ), DefaultContainer( child: Column( mainAxisAlignment: MainAxisAlignment.start, @@ -116,7 +113,7 @@ class FourSceneUpdatePage extends StatelessWidget { const SizedBox( height: 10, ), - UpdateSosContainerWithProgressBar( + const UpdateSosContainerWithProgressBar( sosDescription: 'Connectivity Issue Resolved Fixed a bug that caused the SOS button to disconnect from the app intermittently.', sosVersion: 'SOS v2.0.5', @@ -221,7 +218,7 @@ class NewUpdateContainer extends StatelessWidget { text: sosVersion!, fontColor: ColorsManager.primaryTextColor, ), - Container( + SizedBox( width: MediaQuery.of(context).size.width * 0.7, child: BodyMedium( text: sosDescription!, @@ -239,7 +236,7 @@ class NewUpdateContainer extends StatelessWidget { showDialog( context: context, builder: (context) { - return upDateNote( + return UpDateNote( cancelTab: () { Navigator.of(context).pop(); }, @@ -297,7 +294,7 @@ class UpdateSosContainerWithProgressBar extends StatelessWidget { Assets.emptyUpdateIcon, fit: BoxFit.fill, ), - BodyMedium( + const BodyMedium( text: 'New Update Available Now!', fontColor: ColorsManager.blueColor, ), @@ -314,7 +311,7 @@ class UpdateSosContainerWithProgressBar extends StatelessWidget { ), ), LinearPercentIndicator( - barRadius: Radius.circular(10), + barRadius: const Radius.circular(10), width: 170.0, animation: true, animationDuration: 1000, diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/location_setting_four_scene.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/location_setting_four_scene.dart index 0828fbc..452f7d1 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/location_setting_four_scene.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/location_setting_four_scene.dart @@ -1,11 +1,9 @@ -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_app/features/app_layout/model/space_model.dart'; import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart'; import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_event.dart'; import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_state.dart'; -import 'package:syncrow_app/features/devices/model/four_scene_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/features/shared_widgets/text_widgets/body_medium.dart'; @@ -29,21 +27,14 @@ class LocationFourScenePage extends StatelessWidget { body: BlocProvider( create: (context) => FourSceneBloc(fourSceneId: deviceId ?? '') ..add(const FourSceneInitial()) - ..add(FourSceneInitialInfo()) + ..add(const FourSceneInitialInfo()) ..add(FetchRoomsEvent(unit: space!)), child: BlocBuilder( builder: (context, state) { final _bloc = BlocProvider.of(context); - FourSceneModelState model = FourSceneModelState( - scene_1: '', - scene_2: '', - scene_3: '', - scene_4: '', - scene_id_group_id: '', - switch_backlight: ''); if (state is SaveSelectionSuccessState) { - new Future.delayed(const Duration(microseconds: 500), () { - _bloc.add(FourSceneInitialInfo()); + Future.delayed(const Duration(microseconds: 500), () { + _bloc.add(const FourSceneInitialInfo()); Navigator.of(context).pop(true); }); } @@ -84,65 +75,59 @@ class LocationFourScenePage extends StatelessWidget { ), const SizedBox(width: 20), ], - - child: RefreshIndicator( - onRefresh: () async { - // sensor.add(const SosInitial()); - }, - child: ListView( - shrinkWrap: true, - padding: const EdgeInsets.symmetric(vertical: 20), - children: [ - const BodyMedium( - text: 'Smart Device Location', - fontWeight: FontWeight.w700, - fontSize: 12, - fontColor: ColorsManager.grayColor, - ), - const SizedBox(height: 5), - DefaultContainer( - padding: const EdgeInsets.all(20), - child: ListView.builder( - physics: const NeverScrollableScrollPhysics(), - shrinkWrap: true, - itemCount: _bloc.roomsList.length, - itemBuilder: (context, index) { - final fromRoom = _bloc.roomsList[index]; - final isSelected = (state - is OptionSelectedState && - state.selectedOption == fromRoom.id) || - (state is! OptionSelectedState && - fromRoom.id == - _bloc.deviceInfo.subspace.uuid); + child: ListView( + shrinkWrap: true, + padding: const EdgeInsets.symmetric(vertical: 20), + children: [ + const BodyMedium( + text: 'Smart Device Location', + fontWeight: FontWeight.w700, + fontSize: 12, + fontColor: ColorsManager.grayColor, + ), + const SizedBox(height: 5), + DefaultContainer( + padding: const EdgeInsets.all(20), + child: ListView.builder( + physics: const NeverScrollableScrollPhysics(), + shrinkWrap: true, + itemCount: _bloc.roomsList.length, + itemBuilder: (context, index) { + final fromRoom = _bloc.roomsList[index]; + final isSelected = (state + is OptionSelectedState && + state.selectedOption == fromRoom.id) || + (state is! OptionSelectedState && + fromRoom.id == + _bloc.deviceInfo.subspace.uuid); - return Column( - children: [ - _buildCheckboxOption( - label: fromRoom.name!, - isSelected: isSelected, - onTap: (label) { - context.read().add( - SelectOptionEvent( - selectedOption: fromRoom.id!, - ), - ); - roomIdSelected = fromRoom.id!; - }, + return Column( + children: [ + _buildCheckboxOption( + label: fromRoom.name!, + isSelected: isSelected, + onTap: (label) { + context.read().add( + SelectOptionEvent( + selectedOption: fromRoom.id!, + ), + ); + roomIdSelected = fromRoom.id!; + }, + ), + if (index < _bloc.roomsList.length - 1) ...[ + const SizedBox(height: 10), + const Divider( + color: ColorsManager.dividerColor, ), - if (index < _bloc.roomsList.length - 1) ...[ - const SizedBox(height: 10), - const Divider( - color: ColorsManager.dividerColor, - ), - const SizedBox(height: 10), - ], + const SizedBox(height: 10), ], - ); - }, - ), + ], + ); + }, ), - ], - ), + ), + ], ), ); }, @@ -156,7 +141,8 @@ class CircularCheckbox extends StatefulWidget { final bool value; final ValueChanged onChanged; - CircularCheckbox({required this.value, required this.onChanged}); + const CircularCheckbox( + {super.key, required this.value, required this.onChanged}); @override _CircularCheckboxState createState() => _CircularCheckboxState(); diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/question_page_four_scene.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/question_page_four_scene.dart index 06cd0df..389b358 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/question_page_four_scene.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/question_page_four_scene.dart @@ -4,7 +4,6 @@ import 'package:flutter_svg/flutter_svg.dart'; import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart'; import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_event.dart'; import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_state.dart'; -import 'package:syncrow_app/features/devices/model/four_scene_model.dart'; import 'package:syncrow_app/features/devices/model/question_model.dart'; import 'package:syncrow_app/features/shared_widgets/default_button.dart'; import 'package:syncrow_app/features/shared_widgets/default_container.dart'; @@ -29,18 +28,6 @@ class QuestionPageFourScene extends StatelessWidget { child: BlocBuilder( builder: (context, state) { final sensor = BlocProvider.of(context); - FourSceneModelState model = FourSceneModelState( - scene_1: '', - scene_2: '', - scene_3: '', - scene_4: '', - scene_id_group_id: '', - switch_backlight: ''); - if (state is LoadingNewSate) { - model = state.device; - } else if (state is UpdateState) { - model = state.device; - } return state is FourSceneLoadingState ? const Center( child: DefaultContainer( @@ -48,109 +35,105 @@ class QuestionPageFourScene extends StatelessWidget { height: 50, child: CircularProgressIndicator()), ) - : RefreshIndicator( - onRefresh: () async { - sensor.add(const FourSceneInitial()); - }, - child: Column( - children: [ - DefaultContainer( - padding: EdgeInsets.all(15), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - BodyLarge( - text: questionModel!.question, - fontSize: 22, - fontWeight: FontWeight.w400, - fontColor: ColorsManager.blackColor, - ), - SizedBox( - height: 15, - ), - BodyMedium( - text: questionModel!.answer, - fontSize: 14, - fontWeight: FontWeight.w400, - fontColor: ColorsManager.secondaryTextColor, - ), - ], - ), + : Column( + children: [ + DefaultContainer( + padding: const EdgeInsets.all(15), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + BodyLarge( + text: questionModel!.question, + fontSize: 22, + fontWeight: FontWeight.w400, + fontColor: ColorsManager.blackColor, + ), + const SizedBox( + height: 15, + ), + BodyMedium( + text: questionModel!.answer, + fontSize: 14, + fontWeight: FontWeight.w400, + fontColor: ColorsManager.secondaryTextColor, + ), + ], ), - SizedBox( - height: MediaQuery.of(context).size.height * 0.15, + ), + SizedBox( + height: MediaQuery.of(context).size.height * 0.15, + ), + Center( + child: SizedBox( + width: 180, + child: DefaultButton( + backgroundColor: sensor.isHelpful == true + ? ColorsManager.grayColor + : ColorsManager.grayButtonColors, + borderRadius: 50, + onPressed: () { + sensor.add( + const ToggleHelpfulEvent(isHelpful: true)); + }, + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SvgPicture.asset( + Assets.thumbUp, + fit: BoxFit.fill, + ), + const SizedBox( + width: 10, + ), + const BodyMedium( + text: 'Helpful', + fontSize: 12, + fontWeight: FontWeight.w400, + fontColor: ColorsManager.blackColor, + ), + ], + )), ), - Center( - child: SizedBox( - width: 180, - child: DefaultButton( - backgroundColor: sensor.isHelpful == true - ? ColorsManager.grayColor - : ColorsManager.grayButtonColors, - borderRadius: 50, - onPressed: () { - sensor - .add(ToggleHelpfulEvent(isHelpful: true)); - }, - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - SvgPicture.asset( - Assets.thumbUp, - fit: BoxFit.fill, - ), - const SizedBox( - width: 10, - ), - const BodyMedium( - text: 'Helpful', - fontSize: 12, - fontWeight: FontWeight.w400, - fontColor: ColorsManager.blackColor, - ), - ], - )), - ), + ), + const SizedBox( + height: 15, + ), + Center( + child: SizedBox( + width: 180, + child: DefaultButton( + backgroundColor: sensor.isHelpful == false + ? ColorsManager.grayColor + : ColorsManager.grayButtonColors, + borderRadius: 50, + onPressed: () { + sensor.add( + const ToggleHelpfulEvent(isHelpful: false)); + }, + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SvgPicture.asset( + Assets.thumbDown, + fit: BoxFit.fill, + ), + const SizedBox( + width: 10, + ), + const BodyMedium( + text: 'Not Helpful', + fontSize: 12, + fontWeight: FontWeight.w400, + fontColor: ColorsManager.blackColor, + ), + ], + )), ), - const SizedBox( - height: 15, - ), - Center( - child: SizedBox( - width: 180, - child: DefaultButton( - backgroundColor: sensor.isHelpful == false - ? ColorsManager.grayColor - : ColorsManager.grayButtonColors, - borderRadius: 50, - onPressed: () { - sensor.add( - ToggleHelpfulEvent(isHelpful: false)); - }, - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - SvgPicture.asset( - Assets.thumbDown, - fit: BoxFit.fill, - ), - const SizedBox( - width: 10, - ), - const BodyMedium( - text: 'Not Helpful', - fontSize: 12, - fontWeight: FontWeight.w400, - fontColor: ColorsManager.blackColor, - ), - ], - )), - ), - ), - ], - )); + ), + ], + ); }, ), ), diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/share_four_scene_page.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/share_four_scene_page.dart index e0558f1..e96ec77 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/share_four_scene_page.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/share_four_scene_page.dart @@ -5,7 +5,6 @@ import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_blo import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_event.dart'; import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_state.dart'; import 'package:syncrow_app/features/devices/model/device_model.dart'; -import 'package:syncrow_app/features/devices/model/four_scene_model.dart'; import 'package:syncrow_app/features/menu/view/widgets/manage_home/home_settings.dart'; import 'package:syncrow_app/features/shared_widgets/default_button.dart'; import 'package:syncrow_app/features/shared_widgets/default_container.dart'; @@ -21,7 +20,6 @@ class ShareFourScenePage extends StatelessWidget { @override Widget build(BuildContext context) { var spaces = HomeCubit.getInstance().spaces; - return DefaultScaffold( title: 'Share Device', child: BlocProvider( @@ -30,18 +28,6 @@ class ShareFourScenePage extends StatelessWidget { child: BlocBuilder( builder: (context, state) { final sensor = BlocProvider.of(context); - FourSceneModelState model = FourSceneModelState( - scene_1: '', - scene_2: '', - scene_3: '', - scene_4: '', - scene_id_group_id: '', - switch_backlight: ''); - if (state is LoadingNewSate) { - model = state.device; - } else if (state is UpdateState) { - model = state.device; - } return state is LoadingNewSate ? const Center( child: DefaultContainer( @@ -103,7 +89,7 @@ class ShareFourScenePage extends StatelessWidget { space: spaces!.first, ))); }, - child: Text('Add Home Member')), + child: const Text('Add Home Member')), ), ) ], diff --git a/lib/features/devices/view/widgets/sos/sos_screen.dart b/lib/features/devices/view/widgets/sos/sos_screen.dart index 4a3b765..355f6e7 100644 --- a/lib/features/devices/view/widgets/sos/sos_screen.dart +++ b/lib/features/devices/view/widgets/sos/sos_screen.dart @@ -51,9 +51,10 @@ class SosScreen extends StatelessWidget { builder: (context) => SosSettings(device: device!), ), ); - - sensor.add(SosInitialDeviseInfo()); - sensor.add(const SosInitial()); + if (val == true) { + sensor.add(SosInitialDeviseInfo()); + sensor.add(const SosInitial()); + } }, child: SvgPicture.asset(Assets.assetsIconsSettings), ), From 4527ec15ee4c943095ca3cc748cebd0615a89474 Mon Sep 17 00:00:00 2001 From: mohammad Date: Mon, 25 Nov 2024 15:45:40 +0300 Subject: [PATCH 21/29] code changes --- .../bloc/four_scene_bloc/four_scene_bloc.dart | 244 ++++++++---------- .../four_scene_bloc/four_scene_event.dart | 85 +----- .../four_scene_bloc/four_scene_state.dart | 12 +- .../sos/sos_alarm_management_page.dart | 3 +- .../devices/view/widgets/sos/sos_screen.dart | 7 +- .../sos/sos_setting/location_setting.dart | 110 ++++---- .../sos/sos_setting/question_page.dart | 205 +++++++-------- .../sos/sos_setting/share_sos_page.dart | 10 +- .../sos/sos_setting/sos_info_page.dart | 8 - 9 files changed, 274 insertions(+), 410 deletions(-) diff --git a/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart b/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart index 9cdf3ef..4a66410 100644 --- a/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart +++ b/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart @@ -62,6 +62,12 @@ class FourSceneBloc extends Bloc { bool waterAlarm = false; static String deviceName = ''; static String selectedRoomId = ''; + bool selecedScene = false; + bool enableAlarm = false; + List fourScene = []; + + String _selectedOption = ''; + bool _hasSelectionChanged = false; FourSceneModelState deviceStatus = FourSceneModelState( scene_1: '', @@ -103,36 +109,17 @@ class FourSceneBloc extends Bloc { subspaceName: "", ), ); - String selectedFormApiSceneId = ''; +//============================ get Scene and assign scene ===================== + String selectedFormApiSceneId = ''; String selectedSceneId = ''; _selectScene(SelectSceneEvent event, Emitter emit) { emit(FourSceneLoadingState()); - selectedSceneId = event.selectedSceneId; emit(SceneSelectionUpdatedState(selectedSceneId: selectedSceneId)); } - Future saveName( - SaveNameEvent event, Emitter emit) async { - if (_validateInputs()) return; - try { - add(const ChangeNameEvent(value: false)); - isSaving = true; - emit(FourSceneLoadingState()); - var response = await DevicesAPI.putDeviceName( - deviceId: fourSceneId, deviceName: nameController.text); - add(const FourSceneInitialInfo()); - CustomSnackBar.displaySnackBar('Save Successfully'); - emit(SaveState()); - } catch (e) { - emit(FourSceneFailedState(errorMessage: e.toString())); - } finally { - isSaving = false; - } - } - void getSceneByName( GetSceneBySwitchName event, Emitter emit) async { emit(FourSceneLoadingState()); @@ -146,12 +133,6 @@ class FourSceneBloc extends Bloc { } } - bool selecedScene = false; - bool enableAlarm = false; - - String _selectedOption = ''; - bool _hasSelectionChanged = false; - void _onOptionSelected( SelectOptionEvent event, Emitter emit) { emit(FourSceneLoadingState()); @@ -162,8 +143,6 @@ class FourSceneBloc extends Bloc { hasSelectionChanged: _hasSelectionChanged)); } - List fourScene = []; - void _fetchFourSceneSwitches( FourSceneSwitchInitial event, Emitter emit) async { emit(FourSceneLoadingState()); @@ -195,37 +174,6 @@ class FourSceneBloc extends Bloc { } } - deleteDevice(DeleteDeviceEvent event, Emitter emit) async { - try { - emit(FourSceneLoadingState()); - var response = await DevicesAPI.resetDevise(devicesUuid: fourSceneId); - CustomSnackBar.displaySnackBar('Reset Successfully'); - emit(UpdateState(device: deviceStatus)); - } catch (e) { - emit(FourSceneFailedState(errorMessage: e.toString())); - return; - } - } - - void _fetchDeviceStatus( - FourSceneInitial event, Emitter emit) async { - emit(FourSceneLoadingState()); - try { - var response = await DevicesAPI.getDeviceStatus(fourSceneId); - List statusModelList = []; - for (var status in response['status']) { - statusModelList.add(StatusModel.fromJson(status)); - } - deviceStatus = FourSceneModelState.fromJson( - statusModelList, - ); - add(const FourSceneSwitchInitial()); - } catch (e) { - emit(FourSceneFailedState(errorMessage: e.toString())); - return; - } - } - void assignScene( AssignDeviceScene event, Emitter emit) async { emit(FourSceneLoadingState()); @@ -263,6 +211,8 @@ class FourSceneBloc extends Bloc { } } +//===================== fetch Device Status and info ======================= + void _toggleLowBattery( ToggleEnableAlarmEvent event, Emitter emit) async { emit(LoadingNewSate(device: deviceStatus)); @@ -274,26 +224,24 @@ class FourSceneBloc extends Bloc { } } - // void _controlDevice( - // ControlDeviceScene event, Emitter emit) async { - // emit(FourSceneLoadingState()); - // try { - // deviceStatus.switch_backlight = !event.backLight!; - // emit(UpdateState(device: deviceStatus)); - // final response = await DevicesAPI.controlDevice( - // DeviceControlModel( - // deviceId: fourSceneId, - // code: 'switch_backlight', - // value: !event.backLight!), - // fourSceneId); - - // if (!response['success']) { - // // add(InitialEvent(groupScreen: oneTouchGroup)); - // } - // } catch (_) { - // // add(InitialEvent(groupScreen: oneTouchGroup)); - // } - // } + void _fetchDeviceStatus( + FourSceneInitial event, Emitter emit) async { + emit(FourSceneLoadingState()); + try { + var response = await DevicesAPI.getDeviceStatus(fourSceneId); + List statusModelList = []; + for (var status in response['status']) { + statusModelList.add(StatusModel.fromJson(status)); + } + deviceStatus = FourSceneModelState.fromJson( + statusModelList, + ); + add(const FourSceneSwitchInitial()); + } catch (e) { + emit(FourSceneFailedState(errorMessage: e.toString())); + return; + } + } Future fetchDeviceInfo( FourSceneInitialInfo event, Emitter emit) async { @@ -318,18 +266,8 @@ class FourSceneBloc extends Bloc { emit(FaqSearchState(filteredFaqQuestions: _faqQuestions)); } - void _changeName(ChangeNameEvent event, Emitter emit) { - emit(FourSceneLoadingState()); - editName = event.value!; - if (editName) { - Future.delayed(const Duration(milliseconds: 500), () { - focusNode.requestFocus(); - }); - } else { - focusNode.unfocus(); - } - emit(NameEditingState(editName: editName)); - } +//============================ assign Device ================================== +////////////////////////////////////////////////////////////////////////////// void _toggleNotification( ToggleNotificationEvent event, Emitter emit) async { @@ -337,15 +275,6 @@ class FourSceneBloc extends Bloc { try { enableAlarm = event.isClosingEnabled; emit(UpdateState(device: deviceStatus)); - // API call to update the state, if necessary - // await DevicesAPI.controlDevice( - // DeviceControlModel( - // deviceId: sosId, - // code: 'closing_reminder', - // value: closingReminder, - // ), - // sosId, - // ); } catch (e) { emit(FourSceneFailedState(errorMessage: e.toString())); } @@ -354,38 +283,50 @@ class FourSceneBloc extends Bloc { DeviceReport recordGroups = DeviceReport(startTime: '0', endTime: '0', data: []); + //========================= Question and faq ================================ + final List faqQuestions = [ QuestionModel( id: 1, - question: 'How does an SOS emergency button work?', + question: + 'How does an 4 Scene Switch work? How long will an 4 Scene Switch persist?', answer: - 'The SOS emergency button sends an alert to your contacts when pressed.', + 'Yes. In scenes with high detection requirements, we recommend that you choose phone or message notification in Automation.', ), QuestionModel( id: 2, - question: 'How long will an SOS alarm persist?', + question: 'Does the 4 Scene Switch support sending notifications?', answer: 'The SOS alarm will persist until it is manually turned off or after a set time.', ), QuestionModel( id: 3, - question: 'What should I do if the SOS button is unresponsive?', + question: + 'Why does the data statistics in the device panel not show the correct data?', answer: 'Try restarting the device. If it persists, contact support.', ), QuestionModel( id: 4, - question: 'Can I use the SOS feature without a network connection?', + question: + 'How long will the App show offline after a device (low-power devices and normal devices) is powered...', answer: 'No, a network connection is required to send the alert to your contacts.', ), - QuestionModel( - id: 5, - question: 'How often should I check the SOS battery?', - answer: - 'Check the SOS battery at least once a month to ensure it is operational.', - ), ]; + bool isHelpful = false; + + void _toggleHelpful( + ToggleHelpfulEvent event, Emitter emit) async { + try { + emit(FourSceneLoadingState()); + isHelpful = event.isHelpful!; + emit(SaveState()); + } catch (e) { + emit(const FourSceneFailedState(errorMessage: 'Something went wrong')); + } + } + Future _onFourSceneInitial( FourSceneInitialQuestion event, Emitter emit) async { emit(FourSceneLoadingState()); @@ -394,20 +335,6 @@ class FourSceneBloc extends Bloc { List allDevices = []; List roomsList = []; - - void _fetchRoomsAndDevices( - FetchRoomsEvent event, Emitter emit) async { - try { - emit(FourSceneLoadingState()); - roomsList = await SpacesAPI.getSubSpaceBySpaceId( - event.unit.community.uuid, event.unit.id); - emit(FetchRoomsState(devicesList: allDevices, roomsList: roomsList)); - } catch (e) { - emit(const FourSceneFailedState(errorMessage: 'Something went wrong')); - return; - } - } - bool switchStatus = true; Future changeSwitchStatus( ChangeSwitchStatusEvent event, Emitter emit) async { @@ -499,6 +426,8 @@ class FourSceneBloc extends Bloc { emit(UpdateStateList(groupDevices: groupDevices, devices: devices)); } + //=========================== assign device to room ========================== + void _assignDevice( AssignRoomEvent event, Emitter emit) async { try { @@ -525,6 +454,35 @@ class FourSceneBloc extends Bloc { } } + void _fetchRoomsAndDevices( + FetchRoomsEvent event, Emitter emit) async { + try { + emit(FourSceneLoadingState()); + roomsList = await SpacesAPI.getSubSpaceBySpaceId( + event.unit.community.uuid, event.unit.id); + emit(FetchRoomsState(devicesList: allDevices, roomsList: roomsList)); + } catch (e) { + emit(const FourSceneFailedState(errorMessage: 'Something went wrong')); + return; + } + } + +//============================ setting name ================================== +////////////////////////////////////////////////////////////////////////////// + + void _changeName(ChangeNameEvent event, Emitter emit) { + emit(FourSceneLoadingState()); + editName = event.value!; + if (editName) { + Future.delayed(const Duration(milliseconds: 500), () { + focusNode.requestFocus(); + }); + } else { + focusNode.unfocus(); + } + emit(NameEditingState(editName: editName)); + } + bool _validateInputs() { final nameError = fullNameValidator(nameController.text); if (nameError != null) { @@ -546,6 +504,27 @@ class FourSceneBloc extends Bloc { return null; } + Future saveName( + SaveNameEvent event, Emitter emit) async { + if (_validateInputs()) return; + try { + add(const ChangeNameEvent(value: false)); + isSaving = true; + emit(FourSceneLoadingState()); + var response = await DevicesAPI.putDeviceName( + deviceId: fourSceneId, deviceName: nameController.text); + add(const FourSceneInitialInfo()); + CustomSnackBar.displaySnackBar('Save Successfully'); + emit(SaveState()); + } catch (e) { + emit(FourSceneFailedState(errorMessage: e.toString())); + } finally { + isSaving = false; + } + } + +//====================== update device ============================== + bool enableUpdate = false; void _toggleUpdate( @@ -559,16 +538,15 @@ class FourSceneBloc extends Bloc { } } - bool isHelpful = false; - - void _toggleHelpful( - ToggleHelpfulEvent event, Emitter emit) async { + deleteDevice(DeleteDeviceEvent event, Emitter emit) async { try { emit(FourSceneLoadingState()); - isHelpful = event.isHelpful!; - emit(SaveState()); + var response = await DevicesAPI.resetDevise(devicesUuid: fourSceneId); + CustomSnackBar.displaySnackBar('Reset Successfully'); + emit(UpdateState(device: deviceStatus)); } catch (e) { - emit(const FourSceneFailedState(errorMessage: 'Something went wrong')); + emit(FourSceneFailedState(errorMessage: e.toString())); + return; } } } diff --git a/lib/features/devices/bloc/four_scene_bloc/four_scene_event.dart b/lib/features/devices/bloc/four_scene_bloc/four_scene_event.dart index 3083b04..f96fc61 100644 --- a/lib/features/devices/bloc/four_scene_bloc/four_scene_event.dart +++ b/lib/features/devices/bloc/four_scene_bloc/four_scene_event.dart @@ -10,21 +10,6 @@ abstract class FourSceneEvent extends Equatable { List get props => []; } -class FourSceneLoading extends FourSceneEvent {} - -class FourSceneSwitch extends FourSceneEvent { - final String switchD; - final String deviceId; - final String productId; - const FourSceneSwitch( - {required this.switchD, this.deviceId = '', this.productId = ''}); - - @override - List get props => [switchD, deviceId, productId]; -} - -class FourSceneUpdated extends FourSceneEvent {} - class FourSceneInitialInfo extends FourSceneEvent { const FourSceneInitialInfo(); } @@ -39,19 +24,6 @@ class SaveNameEvent extends FourSceneEvent { const SaveNameEvent({this.deviceName}); } -class ReportLogsInitial extends FourSceneEvent { - const ReportLogsInitial(); -} - -class FourSceneChangeStatus extends FourSceneEvent {} - -class GetCounterEvent extends FourSceneEvent { - final String deviceCode; - const GetCounterEvent({required this.deviceCode}); - @override - List get props => [deviceCode]; -} - class ToggleEnableAlarmEvent extends FourSceneEvent { final bool isLowBatteryEnabled; @@ -70,44 +42,6 @@ class ToggleNotificationEvent extends FourSceneEvent { List get props => [isClosingEnabled]; } -class ToggleFourSceneAlarmEvent extends FourSceneEvent { - final bool isFourSceneAlarmEnabled; - - const ToggleFourSceneAlarmEvent(this.isFourSceneAlarmEnabled); - - @override - List get props => [isFourSceneAlarmEnabled]; -} - -class SetCounterValue extends FourSceneEvent { - final Duration duration; - final String deviceCode; - const SetCounterValue({required this.duration, required this.deviceCode}); - @override - List get props => [duration, deviceCode]; -} - -class StartTimer extends FourSceneEvent { - final int duration; - - const StartTimer(this.duration); - - @override - List get props => [duration]; -} - -class TickTimer extends FourSceneEvent { - final int remainingTime; - - const TickTimer(this.remainingTime); - - @override - List get props => [remainingTime]; -} - -class StopTimer extends FourSceneEvent {} - -class OnClose extends FourSceneEvent {} class DeleteDeviceEvent extends FourSceneEvent {} class ChangeNameEvent extends FourSceneEvent { @@ -164,11 +98,9 @@ class SearchScenesEvent extends FourSceneEvent { }); } -class SaveLocationSelectionEvent extends FourSceneEvent {} - class SelectOptionEvent extends FourSceneEvent { - final dynamic selectedOption; - const SelectOptionEvent({ + final dynamic selectedOption; + const SelectOptionEvent({ this.selectedOption, }); } @@ -176,14 +108,14 @@ class SelectOptionEvent extends FourSceneEvent { class AddDeviceToGroup extends FourSceneEvent { final GroupDevicesModel device; final String icon; - AddDeviceToGroup(this.device, this.icon); + const AddDeviceToGroup(this.device, this.icon); } class RemoveDeviceFromGroup extends FourSceneEvent { final GroupDevicesModel device; final String icon; - RemoveDeviceFromGroup(this.device, this.icon); + const RemoveDeviceFromGroup(this.device, this.icon); } class AssignRoomEvent extends FourSceneEvent { @@ -207,15 +139,10 @@ class AssignRoomEvent extends FourSceneEvent { class FetchDeviceScene extends FourSceneEvent {} - class FourSceneSwitchInitial extends FourSceneEvent { const FourSceneSwitchInitial(); } -class SaveSelectionSceneEvent extends FourSceneEvent { - const SaveSelectionSceneEvent(); -} - class AssignDeviceScene extends FourSceneEvent { final String? sceneUuid; final String? switchName; @@ -232,13 +159,13 @@ class GetSceneBySwitchName extends FourSceneEvent { const GetSceneBySwitchName({this.switchName}); } + class ToggleUpdateEvent extends FourSceneEvent { final bool? isUpdateEnabled; const ToggleUpdateEvent({this.isUpdateEnabled}); } - class ToggleHelpfulEvent extends FourSceneEvent { final bool? isHelpful; const ToggleHelpfulEvent({this.isHelpful}); -} \ No newline at end of file +} diff --git a/lib/features/devices/bloc/four_scene_bloc/four_scene_state.dart b/lib/features/devices/bloc/four_scene_bloc/four_scene_state.dart index 08c849c..e342989 100644 --- a/lib/features/devices/bloc/four_scene_bloc/four_scene_state.dart +++ b/lib/features/devices/bloc/four_scene_bloc/four_scene_state.dart @@ -14,12 +14,8 @@ class FourSceneState extends Equatable { List get props => []; } -class FourSceneInitialState extends FourSceneState {} - class FourSceneLoadingState extends FourSceneState {} -class FourSceState extends FourSceneState {} - class UpdateStateList extends FourSceneState { final List groupDevices; final List devices; @@ -60,7 +56,7 @@ class NameEditingState extends FourSceneState { class FaqLoadedState extends FourSceneState { final List filteredFaqQuestions; - FaqLoadedState({this.filteredFaqQuestions = const []}); + const FaqLoadedState({this.filteredFaqQuestions = const []}); } class FaqSearchState extends FourSceneState { @@ -94,8 +90,6 @@ class SceneLoaded extends FourSceneState { {this.loadingSceneId, this.loadingStates = const {}}); } -class SelectedSceneState extends FourSceneState {} - class SearchResultsState extends FourSceneState {} class SaveState extends FourSceneState {} @@ -106,7 +100,7 @@ class OptionSelectedState extends FourSceneState { final String selectedOption; final bool hasSelectionChanged; - OptionSelectedState({ + const OptionSelectedState({ required this.selectedOption, required this.hasSelectionChanged, }); @@ -126,5 +120,5 @@ class LoadingDeviceInfo extends FourSceneState { class SceneSelectionUpdatedState extends FourSceneState { final String selectedSceneId; - SceneSelectionUpdatedState({required this.selectedSceneId}); + const SceneSelectionUpdatedState({required this.selectedSceneId}); } diff --git a/lib/features/devices/view/widgets/sos/sos_alarm_management_page.dart b/lib/features/devices/view/widgets/sos/sos_alarm_management_page.dart index c750368..8046e61 100644 --- a/lib/features/devices/view/widgets/sos/sos_alarm_management_page.dart +++ b/lib/features/devices/view/widgets/sos/sos_alarm_management_page.dart @@ -11,7 +11,8 @@ import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dar import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; class AlarmManagementPage extends StatelessWidget { - const AlarmManagementPage({super.key}); + final String sosId; + const AlarmManagementPage({super.key, required this.sosId}); @override Widget build(BuildContext context) { diff --git a/lib/features/devices/view/widgets/sos/sos_screen.dart b/lib/features/devices/view/widgets/sos/sos_screen.dart index 355f6e7..39851a9 100644 --- a/lib/features/devices/view/widgets/sos/sos_screen.dart +++ b/lib/features/devices/view/widgets/sos/sos_screen.dart @@ -29,18 +29,15 @@ class SosScreen extends StatelessWidget { child: BlocBuilder( builder: (context, state) { final sensor = BlocProvider.of(context); - // Default SOS model in case no state is loaded SosModel model = SosModel( batteryPercentage: 0, sosContactState: '', ); - // Update the model based on the state if (state is LoadingNewSate) { model = state.sosSensor; } else if (state is UpdateState) { model = state.sensor; } - return DefaultScaffold( title: sensor.deviceInfo.name, actions: [ @@ -183,7 +180,9 @@ class SosScreen extends StatelessWidget { Navigator.of(context).push( MaterialPageRoute( builder: (context) => - const AlarmManagementPage(), + AlarmManagementPage( + sosId: device!.uuid!, + ), ), ); }, diff --git a/lib/features/devices/view/widgets/sos/sos_setting/location_setting.dart b/lib/features/devices/view/widgets/sos/sos_setting/location_setting.dart index 88312db..0097fe3 100644 --- a/lib/features/devices/view/widgets/sos/sos_setting/location_setting.dart +++ b/lib/features/devices/view/widgets/sos/sos_setting/location_setting.dart @@ -1,4 +1,3 @@ -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_app/features/app_layout/model/space_model.dart'; @@ -6,11 +5,9 @@ import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_bloc.dart'; import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_event.dart'; import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_state.dart'; import 'package:syncrow_app/features/devices/model/sos_model.dart'; -import 'package:syncrow_app/features/devices/model/subspace_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/features/shared_widgets/text_widgets/body_medium.dart'; -import 'package:syncrow_app/navigation/routing_constants.dart'; import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; class LocationSosPage extends StatelessWidget { @@ -39,8 +36,8 @@ class LocationSosPage extends StatelessWidget { SosModel model = SosModel(batteryPercentage: 0, sosContactState: ''); if (state is SaveSelectionSuccessState) { - new Future.delayed(const Duration(microseconds: 500), () { - _bloc.add(SosInitial()); + Future.delayed(const Duration(microseconds: 500), () { + _bloc.add(const SosInitial()); Navigator.of(context).pop(true); }); } @@ -80,64 +77,59 @@ class LocationSosPage extends StatelessWidget { ), const SizedBox(width: 20), ], - child: RefreshIndicator( - onRefresh: () async { - // sensor.add(const SosInitial()); - }, - child: ListView( - shrinkWrap: true, - padding: const EdgeInsets.symmetric(vertical: 20), - children: [ - const BodyMedium( - text: 'Smart Device Location', - fontWeight: FontWeight.w700, - fontSize: 12, - fontColor: ColorsManager.grayColor, - ), - const SizedBox(height: 5), - DefaultContainer( - padding: const EdgeInsets.all(20), - child: ListView.builder( - physics: const NeverScrollableScrollPhysics(), - shrinkWrap: true, - itemCount: _bloc.roomsList.length, - itemBuilder: (context, index) { - final fromRoom = _bloc.roomsList[index]; - final isSelected = (state - is OptionSelectedState && - state.selectedOption == fromRoom.id) || - (state is! OptionSelectedState && - fromRoom.id == - _bloc.deviceInfo.subspace.uuid); + child: ListView( + shrinkWrap: true, + padding: const EdgeInsets.symmetric(vertical: 20), + children: [ + const BodyMedium( + text: 'Smart Device Location', + fontWeight: FontWeight.w700, + fontSize: 12, + fontColor: ColorsManager.grayColor, + ), + const SizedBox(height: 5), + DefaultContainer( + padding: const EdgeInsets.all(20), + child: ListView.builder( + physics: const NeverScrollableScrollPhysics(), + shrinkWrap: true, + itemCount: _bloc.roomsList.length, + itemBuilder: (context, index) { + final fromRoom = _bloc.roomsList[index]; + final isSelected = (state + is OptionSelectedState && + state.selectedOption == fromRoom.id) || + (state is! OptionSelectedState && + fromRoom.id == + _bloc.deviceInfo.subspace.uuid); - return Column( - children: [ - _buildCheckboxOption( - label: fromRoom.name!, - isSelected: isSelected, - onTap: (label) { - context.read().add( - SelectOptionEvent( - selectedOption: fromRoom.id!, - ), - ); - roomIdSelected = fromRoom.id!; - }, + return Column( + children: [ + _buildCheckboxOption( + label: fromRoom.name!, + isSelected: isSelected, + onTap: (label) { + context.read().add( + SelectOptionEvent( + selectedOption: fromRoom.id!, + ), + ); + roomIdSelected = fromRoom.id!; + }, + ), + if (index < _bloc.roomsList.length - 1) ...[ + const SizedBox(height: 10), + const Divider( + color: ColorsManager.dividerColor, ), - if (index < _bloc.roomsList.length - 1) ...[ - const SizedBox(height: 10), - const Divider( - color: ColorsManager.dividerColor, - ), - const SizedBox(height: 10), - ], + const SizedBox(height: 10), ], - ); - }, - ), + ], + ); + }, ), - ], - ), + ), + ], ), ); }, diff --git a/lib/features/devices/view/widgets/sos/sos_setting/question_page.dart b/lib/features/devices/view/widgets/sos/sos_setting/question_page.dart index 27da97a..a6c11bf 100644 --- a/lib/features/devices/view/widgets/sos/sos_setting/question_page.dart +++ b/lib/features/devices/view/widgets/sos/sos_setting/question_page.dart @@ -5,7 +5,6 @@ import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_bloc.dart'; import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_event.dart'; import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_state.dart'; import 'package:syncrow_app/features/devices/model/question_model.dart'; -import 'package:syncrow_app/features/devices/model/sos_model.dart'; import 'package:syncrow_app/features/shared_widgets/default_button.dart'; import 'package:syncrow_app/features/shared_widgets/default_container.dart'; import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart'; @@ -28,13 +27,7 @@ class QuestionPage extends StatelessWidget { child: BlocBuilder( builder: (context, state) { final sensor = BlocProvider.of(context); - SosModel model = - SosModel(batteryPercentage: 0, sosContactState: 'normal'); - if (state is LoadingNewSate) { - model = state.sosSensor; - } else if (state is UpdateState) { - model = state.sensor; - } + return state is SosLoadingState ? const Center( child: DefaultContainer( @@ -42,109 +35,105 @@ class QuestionPage extends StatelessWidget { height: 50, child: CircularProgressIndicator()), ) - : RefreshIndicator( - onRefresh: () async { - sensor.add(const SosInitial()); - }, - child: Column( - children: [ - DefaultContainer( - padding: EdgeInsets.all(15), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - BodyLarge( - text: questionModel!.question, - fontSize: 22, - fontWeight: FontWeight.w400, - fontColor: ColorsManager.blackColor, - ), - SizedBox( - height: 15, - ), - BodyMedium( - text: questionModel!.answer, - fontSize: 14, - fontWeight: FontWeight.w400, - fontColor: ColorsManager.secondaryTextColor, - ), - ], - ), + : Column( + children: [ + DefaultContainer( + padding: const EdgeInsets.all(15), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + BodyLarge( + text: questionModel!.question, + fontSize: 22, + fontWeight: FontWeight.w400, + fontColor: ColorsManager.blackColor, + ), + const SizedBox( + height: 15, + ), + BodyMedium( + text: questionModel!.answer, + fontSize: 14, + fontWeight: FontWeight.w400, + fontColor: ColorsManager.secondaryTextColor, + ), + ], ), - SizedBox( - height: MediaQuery.of(context).size.height * 0.15, + ), + SizedBox( + height: MediaQuery.of(context).size.height * 0.15, + ), + Center( + child: SizedBox( + width: 180, + child: DefaultButton( + backgroundColor: sensor.isHelpful == true + ? ColorsManager.grayColor + : ColorsManager.grayButtonColors, + borderRadius: 50, + onPressed: () { + sensor.add( + const ToggleHelpfulEvent(isHelpful: true)); + }, + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SvgPicture.asset( + Assets.thumbUp, + fit: BoxFit.fill, + ), + const SizedBox( + width: 10, + ), + const BodyMedium( + text: 'Helpful', + fontSize: 12, + fontWeight: FontWeight.w400, + fontColor: ColorsManager.blackColor, + ), + ], + )), ), - Center( - child: SizedBox( - width: 180, - child: DefaultButton( - backgroundColor: sensor.isHelpful == true - ? ColorsManager.grayColor - : ColorsManager.grayButtonColors, - borderRadius: 50, - onPressed: () { - sensor - .add(ToggleHelpfulEvent(isHelpful: true)); - }, - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - SvgPicture.asset( - Assets.thumbUp, - fit: BoxFit.fill, - ), - const SizedBox( - width: 10, - ), - const BodyMedium( - text: 'Helpful', - fontSize: 12, - fontWeight: FontWeight.w400, - fontColor: ColorsManager.blackColor, - ), - ], - )), - ), + ), + const SizedBox( + height: 15, + ), + Center( + child: SizedBox( + width: 180, + child: DefaultButton( + backgroundColor: sensor.isHelpful == false + ? ColorsManager.grayColor + : ColorsManager.grayButtonColors, + borderRadius: 50, + onPressed: () { + sensor.add( + const ToggleHelpfulEvent(isHelpful: false)); + }, + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SvgPicture.asset( + Assets.thumbDown, + fit: BoxFit.fill, + ), + const SizedBox( + width: 10, + ), + const BodyMedium( + text: 'Not Helpful', + fontSize: 12, + fontWeight: FontWeight.w400, + fontColor: ColorsManager.blackColor, + ), + ], + )), ), - const SizedBox( - height: 15, - ), - Center( - child: SizedBox( - width: 180, - child: DefaultButton( - backgroundColor: sensor.isHelpful == false - ? ColorsManager.grayColor - : ColorsManager.grayButtonColors, - borderRadius: 50, - onPressed: () { - sensor.add( - ToggleHelpfulEvent(isHelpful: false)); - }, - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - SvgPicture.asset( - Assets.thumbDown, - fit: BoxFit.fill, - ), - const SizedBox( - width: 10, - ), - const BodyMedium( - text: 'Not Helpful', - fontSize: 12, - fontWeight: FontWeight.w400, - fontColor: ColorsManager.blackColor, - ), - ], - )), - ), - ), - ], - )); + ), + ], + ); }, ), ), diff --git a/lib/features/devices/view/widgets/sos/sos_setting/share_sos_page.dart b/lib/features/devices/view/widgets/sos/sos_setting/share_sos_page.dart index 0c7b1f4..c102b19 100644 --- a/lib/features/devices/view/widgets/sos/sos_setting/share_sos_page.dart +++ b/lib/features/devices/view/widgets/sos/sos_setting/share_sos_page.dart @@ -5,7 +5,6 @@ import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_bloc.dart'; import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_event.dart'; import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_state.dart'; import 'package:syncrow_app/features/devices/model/device_model.dart'; -import 'package:syncrow_app/features/devices/model/sos_model.dart'; import 'package:syncrow_app/features/menu/view/widgets/manage_home/home_settings.dart'; import 'package:syncrow_app/features/shared_widgets/default_button.dart'; import 'package:syncrow_app/features/shared_widgets/default_container.dart'; @@ -32,13 +31,6 @@ class ShareSosPage extends StatelessWidget { child: BlocBuilder( builder: (context, state) { final sensor = BlocProvider.of(context); - SosModel model = - SosModel(batteryPercentage: 0, sosContactState: 'normal'); - if (state is LoadingNewSate) { - model = state.sosSensor; - } else if (state is UpdateState) { - model = state.sensor; - } return state is SosLoadingState ? const Center( child: DefaultContainer( @@ -100,7 +92,7 @@ class ShareSosPage extends StatelessWidget { space: spaces!.first, ))); }, - child: Text('Add Home Member')), + child: const Text('Add Home Member')), ), ) ], diff --git a/lib/features/devices/view/widgets/sos/sos_setting/sos_info_page.dart b/lib/features/devices/view/widgets/sos/sos_setting/sos_info_page.dart index 09ed1c1..f38b8b7 100644 --- a/lib/features/devices/view/widgets/sos/sos_setting/sos_info_page.dart +++ b/lib/features/devices/view/widgets/sos/sos_setting/sos_info_page.dart @@ -5,7 +5,6 @@ import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_bloc.dart'; import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_event.dart'; import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_state.dart'; import 'package:syncrow_app/features/devices/model/device_model.dart'; -import 'package:syncrow_app/features/devices/model/sos_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/features/shared_widgets/text_widgets/body_large.dart'; @@ -29,13 +28,6 @@ class SosInfoPage extends StatelessWidget { child: BlocBuilder( builder: (context, state) { final _bloc = BlocProvider.of(context); - SosModel model = - SosModel(batteryPercentage: 0, sosContactState: ''); - if (state is LoadingNewSate) { - model = state.sosSensor; - } else if (state is UpdateState) { - model = state.sensor; - } return state is SosLoadingState ? const Center( child: DefaultContainer( From e55ff17148a0016e21bd6c2da1816bc831e04d60 Mon Sep 17 00:00:00 2001 From: mohammad Date: Mon, 25 Nov 2024 16:30:16 +0300 Subject: [PATCH 22/29] code changes --- .../6_scene_switch_bloc/6_scene_bloc.dart | 181 ++++++++++-------- .../6_scene_switch_bloc/6_scene_event.dart | 76 +------- .../6_scene_switch_bloc/6_scene_state.dart | 15 +- .../bloc/four_scene_bloc/four_scene_bloc.dart | 2 +- .../view/widgets/sos/sos_records_screen.dart | 1 - .../sos/sos_setting/delete_dialog.dart | 0 6 files changed, 107 insertions(+), 168 deletions(-) delete mode 100644 lib/features/devices/view/widgets/sos/sos_setting/delete_dialog.dart diff --git a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart index 5ce176b..ca63e87 100644 --- a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart +++ b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart @@ -167,24 +167,8 @@ class SixSceneBloc extends Bloc { } } - Future saveName( - SaveNameEvent event, Emitter emit) async { - if (_validateInputs()) return; - try { - add(const ChangeNameEvent(value: false)); - isSaving = true; - emit(SixSceneLoadingState()); - var response = await DevicesAPI.putDeviceName( - deviceId: sixSceneId, deviceName: nameController.text); - add(const SixSceneInitialInfo()); - CustomSnackBar.displaySnackBar('Save Successfully'); - emit(SaveState()); - } catch (e) { - emit(SixSceneFailedState(errorMessage: e.toString())); - } finally { - isSaving = false; - } - } +//============================ fitch devise info and status ======================= +///////////////////////////////////////////////////////////////////////////////////// Future fetchDeviceInfo( SixSceneInitialInfo event, Emitter emit) async { @@ -219,6 +203,9 @@ class SixSceneBloc extends Bloc { } } + //============================ assign Scene ======================= +///////////////////////////////////////////////////////////////////////////////////// + String selectedFormApiSceneId = ''; void getSceneByName( @@ -332,44 +319,6 @@ class SixSceneBloc extends Bloc { DeviceReport recordGroups = DeviceReport(startTime: '0', endTime: '0', data: []); - final List faqQuestions = [ - SixSceneQuestionModel( - id: 1, - question: 'How does an SOS emergency button work?', - answer: - 'The SOS emergency button sends an alert to your contacts when pressed.', - ), - SixSceneQuestionModel( - id: 2, - question: 'How long will an SOS alarm persist?', - answer: - 'The SOS alarm will persist until it is manually turned off or after a set time.', - ), - SixSceneQuestionModel( - id: 3, - question: 'What should I do if the SOS button is unresponsive?', - answer: 'Try restarting the device. If it persists, contact support.', - ), - SixSceneQuestionModel( - id: 4, - question: 'Can I use the SOS feature without a network connection?', - answer: - 'No, a network connection is required to send the alert to your contacts.', - ), - SixSceneQuestionModel( - id: 5, - question: 'How often should I check the SOS battery?', - answer: - 'Check the SOS battery at least once a month to ensure it is operational.', - ), - ]; - - Future _onSixSceneInitial( - SixSceneInitialQuestion event, Emitter emit) async { - emit(SixSceneLoadingState()); - emit(FaqLoadedState(filteredFaqQuestions: faqQuestions)); - } - List allDevices = []; bool switchStatus = true; @@ -430,7 +379,7 @@ class SixSceneBloc extends Bloc { filteredScenes = event.query.isEmpty ? allScenes : allScenes.where((scene) { - final sceneName = scene.name?.toLowerCase() ?? ''; + final sceneName = scene.name.toLowerCase() ?? ''; return sceneName.contains(event.query.toLowerCase()); }).toList(); emit(SearchResultsState()); @@ -456,6 +405,7 @@ class SixSceneBloc extends Bloc { } } +//============================= group settings ================================= //addDevicesIcon List groupDevices = [ GroupDevicesModel( @@ -488,6 +438,97 @@ class SixSceneBloc extends Bloc { emit(UpdateStateList(groupDevices: groupDevices, devices: devices)); } + //======================= update device functions ============================ + ////////////////////////////////////////////////////////////////////////////// + + bool enableUpdate = false; + + void _toggleUpdate( + ToggleUpdateEvent event, Emitter emit) async { + try { + emit(SixSceneLoadingState()); + enableUpdate = event.isUpdateEnabled!; + emit(SaveState()); + } catch (e) { + emit(const SixSceneFailedState(errorMessage: 'Something went wrong')); + } + } + +//======================= q&a and questions ==================================== +//////////////////////////////////////////////////////////////////////////////// + bool isHelpful = false; + + void _toggleHelpful( + ToggleHelpfulEvent event, Emitter emit) async { + try { + emit(SixSceneLoadingState()); + isHelpful = event.isHelpful!; + emit(SaveState()); + } catch (e) { + emit(const SixSceneFailedState(errorMessage: 'Something went wrong')); + } + } + + final List faqQuestions = [ + SixSceneQuestionModel( + id: 1, + question: 'How does an SOS emergency button work?', + answer: + 'The SOS emergency button sends an alert to your contacts when pressed.', + ), + SixSceneQuestionModel( + id: 2, + question: 'How long will an SOS alarm persist?', + answer: + 'The SOS alarm will persist until it is manually turned off or after a set time.', + ), + SixSceneQuestionModel( + id: 3, + question: 'What should I do if the SOS button is unresponsive?', + answer: 'Try restarting the device. If it persists, contact support.', + ), + SixSceneQuestionModel( + id: 4, + question: 'Can I use the SOS feature without a network connection?', + answer: + 'No, a network connection is required to send the alert to your contacts.', + ), + SixSceneQuestionModel( + id: 5, + question: 'How often should I check the SOS battery?', + answer: + 'Check the SOS battery at least once a month to ensure it is operational.', + ), + ]; + + Future _onSixSceneInitial( + SixSceneInitialQuestion event, Emitter emit) async { + emit(SixSceneLoadingState()); + emit(FaqLoadedState(filteredFaqQuestions: faqQuestions)); + } + + //=========================== name setting =================================== + //////////////////////////////////////////////////////////////////////////////// + + Future saveName( + SaveNameEvent event, Emitter emit) async { + if (_validateInputs()) return; + try { + add(const ChangeNameEvent(value: false)); + isSaving = true; + emit(SixSceneLoadingState()); + var response = await DevicesAPI.putDeviceName( + deviceId: sixSceneId, deviceName: nameController.text); + add(const SixSceneInitialInfo()); + CustomSnackBar.displaySnackBar('Save Successfully'); + emit(SaveState()); + } catch (e) { + emit(SixSceneFailedState(errorMessage: e.toString())); + } finally { + isSaving = false; + } + } + bool _validateInputs() { final nameError = fullNameValidator(nameController.text); if (nameError != null) { @@ -508,30 +549,4 @@ class SixSceneBloc extends Bloc { } return null; } - - bool enableUpdate = false; - - void _toggleUpdate( - ToggleUpdateEvent event, Emitter emit) async { - try { - emit(SixSceneLoadingState()); - enableUpdate = event.isUpdateEnabled!; - emit(SaveState()); - } catch (e) { - emit(const SixSceneFailedState(errorMessage: 'Something went wrong')); - } - } - - bool isHelpful = false; - - void _toggleHelpful( - ToggleHelpfulEvent event, Emitter emit) async { - try { - emit(SixSceneLoadingState()); - isHelpful = event.isHelpful!; - emit(SaveState()); - } catch (e) { - emit(const SixSceneFailedState(errorMessage: 'Something went wrong')); - } - } } diff --git a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart index 5600510..7f95867 100644 --- a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart +++ b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart @@ -10,21 +10,6 @@ abstract class SixSceneEvent extends Equatable { List get props => []; } -class SixSceneLoading extends SixSceneEvent {} - -class SixSceneSwitch extends SixSceneEvent { - final String switchD; - final String deviceId; - final String productId; - const SixSceneSwitch( - {required this.switchD, this.deviceId = '', this.productId = ''}); - - @override - List get props => [switchD, deviceId, productId]; -} - -class SixSceneUpdated extends SixSceneEvent {} - class GetSceneBySwitchName extends SixSceneEvent { final String? switchName; @@ -47,19 +32,6 @@ class SexSceneSwitchInitial extends SixSceneEvent { const SexSceneSwitchInitial(); } -class ReportLogsInitial extends SixSceneEvent { - const ReportLogsInitial(); -} - -class SixSceneChangeStatus extends SixSceneEvent {} - -class GetCounterEvent extends SixSceneEvent { - final String deviceCode; - const GetCounterEvent({required this.deviceCode}); - @override - List get props => [deviceCode]; -} - class ToggleEnableAlarmEvent extends SixSceneEvent { final bool isLowBatteryEnabled; @@ -78,44 +50,6 @@ class ToggleNotificationEvent extends SixSceneEvent { List get props => [isClosingEnabled]; } -class ToggleSixSceneAlarmEvent extends SixSceneEvent { - final bool isSixSceneAlarmEnabled; - - const ToggleSixSceneAlarmEvent(this.isSixSceneAlarmEnabled); - - @override - List get props => [isSixSceneAlarmEnabled]; -} - -class SetCounterValue extends SixSceneEvent { - final Duration duration; - final String deviceCode; - const SetCounterValue({required this.duration, required this.deviceCode}); - @override - List get props => [duration, deviceCode]; -} - -class StartTimer extends SixSceneEvent { - final int duration; - - const StartTimer(this.duration); - - @override - List get props => [duration]; -} - -class TickTimer extends SixSceneEvent { - final int remainingTime; - - const TickTimer(this.remainingTime); - - @override - List get props => [remainingTime]; -} - -class StopTimer extends SixSceneEvent {} - -class OnClose extends SixSceneEvent {} class DeleteDeviceEvent extends SixSceneEvent {} class ChangeNameEvent extends SixSceneEvent { @@ -182,14 +116,14 @@ class SelectOptionEvent extends SixSceneEvent { class AddDeviceToGroup extends SixSceneEvent { final GroupDevicesModel device; final String icon; - AddDeviceToGroup(this.device, this.icon); + const AddDeviceToGroup(this.device, this.icon); } class RemoveDeviceFromGroup extends SixSceneEvent { final GroupDevicesModel device; final String icon; - RemoveDeviceFromGroup(this.device, this.icon); + const RemoveDeviceFromGroup(this.device, this.icon); } class AssignDeviceScene extends SixSceneEvent { @@ -203,7 +137,6 @@ class AssignDeviceScene extends SixSceneEvent { }); } - class AssignRoomEvent extends SixSceneEvent { final String roomId; final SpaceModel unit; @@ -223,15 +156,12 @@ class AssignRoomEvent extends SixSceneEvent { ]; } - - class ToggleUpdateEvent extends SixSceneEvent { final bool? isUpdateEnabled; const ToggleUpdateEvent({this.isUpdateEnabled}); } - class ToggleHelpfulEvent extends SixSceneEvent { final bool? isHelpful; const ToggleHelpfulEvent({this.isHelpful}); -} \ No newline at end of file +} diff --git a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart index 01f72b0..0a4ed56 100644 --- a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart +++ b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart @@ -14,12 +14,9 @@ class SixSceneState extends Equatable { List get props => []; } -class SixSceneInitialState extends SixSceneState {} - class SixSceneLoadingState extends SixSceneState {} -class SaveState extends SixSceneState {} -class SixSceState extends SixSceneState {} +class SaveState extends SixSceneState {} class UpdateStateList extends SixSceneState { final List groupDevices; @@ -55,13 +52,13 @@ class LoadingNewSate extends SixSceneState { class NameEditingState extends SixSceneState { final bool editName; - NameEditingState({required this.editName}); + const NameEditingState({required this.editName}); } class FaqLoadedState extends SixSceneState { final List filteredFaqQuestions; - FaqLoadedState({this.filteredFaqQuestions = const []}); + const FaqLoadedState({this.filteredFaqQuestions = const []}); } class FaqSearchState extends SixSceneState { @@ -95,8 +92,6 @@ class SceneLoaded extends SixSceneState { {this.loadingSceneId, this.loadingStates = const {}}); } -class SelectedSceneState extends SixSceneState {} - class SearchResultsState extends SixSceneState {} class SaveSelectionSuccessState extends SixSceneState {} @@ -105,7 +100,7 @@ class OptionSelectedState extends SixSceneState { final String selectedOption; final bool hasSelectionChanged; - OptionSelectedState({ + const OptionSelectedState({ required this.selectedOption, required this.hasSelectionChanged, }); @@ -117,7 +112,7 @@ class OptionSelectedState extends SixSceneState { class SceneSelectionUpdatedState extends SixSceneState { final String selectedSceneId; - SceneSelectionUpdatedState({required this.selectedSceneId}); + const SceneSelectionUpdatedState({required this.selectedSceneId}); } class LoadingDeviceInfo extends SixSceneState { diff --git a/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart b/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart index 4a66410..95a5132 100644 --- a/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart +++ b/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart @@ -110,7 +110,7 @@ class FourSceneBloc extends Bloc { ), ); -//============================ get Scene and assign scene ===================== +//============================ get Scene and assign scene ======================= String selectedFormApiSceneId = ''; String selectedSceneId = ''; diff --git a/lib/features/devices/view/widgets/sos/sos_records_screen.dart b/lib/features/devices/view/widgets/sos/sos_records_screen.dart index e459226..c85c3a8 100644 --- a/lib/features/devices/view/widgets/sos/sos_records_screen.dart +++ b/lib/features/devices/view/widgets/sos/sos_records_screen.dart @@ -5,7 +5,6 @@ import 'package:intl/intl.dart'; import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_bloc.dart'; import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_event.dart'; import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_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'; diff --git a/lib/features/devices/view/widgets/sos/sos_setting/delete_dialog.dart b/lib/features/devices/view/widgets/sos/sos_setting/delete_dialog.dart deleted file mode 100644 index e69de29..0000000 From f24a32ec7b1cc0cdf5a010d51d8672345c985376 Mon Sep 17 00:00:00 2001 From: mohammad Date: Tue, 26 Nov 2024 11:43:18 +0300 Subject: [PATCH 23/29] fixes issues --- .../6_scene_switch_bloc/6_scene_bloc.dart | 52 ++++---- .../6_scene_switch_bloc/6_scene_state.dart | 1 + .../bloc/four_scene_bloc/four_scene_bloc.dart | 7 +- .../six_scene_update_page.dart | 2 +- .../6_scene_switch/select_scene_page.dart | 116 +++++++++++------- .../6_scene_switch/select_switch_dialog.dart | 1 + .../four_select_scene_page.dart | 114 ++++++++++------- .../devices/view/widgets/sos/sos_screen.dart | 10 +- 8 files changed, 179 insertions(+), 124 deletions(-) diff --git a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart index ca63e87..add645b 100644 --- a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart +++ b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart @@ -210,11 +210,14 @@ class SixSceneBloc extends Bloc { void getSceneByName( GetSceneBySwitchName event, Emitter emit) async { - emit(SixSceneLoadingState()); try { + // emit(SixSceneLoadingState()); + final response = await DevicesAPI.getSceneBySwitchName( deviceId: sixSceneId, switchName: event.switchName); selectedFormApiSceneId = response['scene']['uuid']; + emit(SuccessState()); + emit(UpdateState(device: deviceStatus)); } catch (e) { emit(SixSceneFailedState(errorMessage: e.toString())); @@ -292,19 +295,6 @@ class SixSceneBloc extends Bloc { emit(FaqSearchState(filteredFaqQuestions: _faqQuestions)); } - void _changeName(ChangeNameEvent event, Emitter emit) { - emit(SixSceneLoadingState()); - editName = event.value!; - if (editName) { - Future.delayed(const Duration(milliseconds: 500), () { - focusNode.requestFocus(); - }); - } else { - focusNode.unfocus(); - } - emit(NameEditingState(editName: editName)); - } - void _toggleNotification( ToggleNotificationEvent event, Emitter emit) async { emit(LoadingNewSate(device: deviceStatus)); @@ -352,21 +342,20 @@ class SixSceneBloc extends Bloc { Future _onLoadScenes( LoadScenes event, Emitter emit) async { emit(SixSceneLoadingState()); + try { - if (event.unitId.isNotEmpty) { - allScenes = await SceneApi.getScenesByUnitId( - event.unitId, event.unit.community.uuid, - showInDevice: event.showInDevice); - emit(SceneLoaded( - allScenes, - )); - filteredScenes = allScenes; - } else { - emit(const SixSceneFailedState(errorMessage: 'Unit ID is empty')); - } + allScenes = await SceneApi.getScenesByUnitId( + event.unitId, event.unit.community.uuid, + showInDevice: event.showInDevice); + + filteredScenes = allScenes; + + emit(SceneLoaded(allScenes)); + emit(UpdateState(device: deviceStatus)); } catch (e) { emit(const SixSceneFailedState(errorMessage: 'Something went wrong')); } + emit(SuccessState()); } bool selecedScene = false; @@ -510,6 +499,19 @@ class SixSceneBloc extends Bloc { //=========================== name setting =================================== //////////////////////////////////////////////////////////////////////////////// + void _changeName(ChangeNameEvent event, Emitter emit) { + emit(SixSceneLoadingState()); + editName = event.value!; + if (editName) { + Future.delayed(const Duration(milliseconds: 500), () { + focusNode.requestFocus(); + }); + } else { + focusNode.unfocus(); + } + emit(NameEditingState(editName: editName)); + } + Future saveName( SaveNameEvent event, Emitter emit) async { if (_validateInputs()) return; diff --git a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart index 0a4ed56..43982ef 100644 --- a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart +++ b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart @@ -93,6 +93,7 @@ class SceneLoaded extends SixSceneState { } class SearchResultsState extends SixSceneState {} +class SuccessState extends SixSceneState {} class SaveSelectionSuccessState extends SixSceneState {} diff --git a/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart b/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart index 95a5132..f664159 100644 --- a/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart +++ b/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart @@ -122,7 +122,7 @@ class FourSceneBloc extends Bloc { void getSceneByName( GetSceneBySwitchName event, Emitter emit) async { - emit(FourSceneLoadingState()); + // emit(FourSceneLoadingState()); try { final response = await DevicesAPI.getSceneBySwitchName( deviceId: fourSceneId, switchName: event.switchName); @@ -369,10 +369,9 @@ class FourSceneBloc extends Bloc { allScenes = await SceneApi.getScenesByUnitId( event.unitId, event.unit.community.uuid, showInDevice: event.showInDevice); - emit(SceneLoaded( - allScenes, - )); + filteredScenes = allScenes; + emit(SceneLoaded(allScenes)); } else { emit(const FourSceneFailedState(errorMessage: 'Unit ID is empty')); } diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_update_page.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_update_page.dart index 489f65b..3a1c011 100644 --- a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_update_page.dart +++ b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_update_page.dart @@ -116,7 +116,7 @@ class SixSceneUpdatePage extends StatelessWidget { const SizedBox( height: 10, ), - UpdateSosContainerWithProgressBar( + const UpdateSosContainerWithProgressBar( sosDescription: 'Connectivity Issue Resolved Fixed a bug that caused the SOS button to disconnect from the app intermittently.', sosVersion: 'SOS v2.0.5', diff --git a/lib/features/devices/view/widgets/6_scene_switch/select_scene_page.dart b/lib/features/devices/view/widgets/6_scene_switch/select_scene_page.dart index c330028..4f0c2da 100644 --- a/lib/features/devices/view/widgets/6_scene_switch/select_scene_page.dart +++ b/lib/features/devices/view/widgets/6_scene_switch/select_scene_page.dart @@ -7,13 +7,11 @@ import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_bl import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart'; import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart'; import 'package:syncrow_app/features/devices/view/widgets/restart_status_dialog.dart'; -import 'package:syncrow_app/features/scene/model/scene_settings_route_arguments.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_medium.dart'; +import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart'; import 'package:syncrow_app/generated/assets.dart'; -import 'package:syncrow_app/navigation/navigation_service.dart'; -import 'package:syncrow_app/navigation/routing_constants.dart'; import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; class SixSelectSceneFourPage extends StatelessWidget { @@ -45,9 +43,7 @@ class SixSelectSceneFourPage extends StatelessWidget { return DefaultScaffold( title: 'Select Scene', actions: [_buildSaveButton(context, state, sensorBloc)], - child: state is SixSceneLoadingState - ? _buildLoadingIndicator() - : _buildSceneContent(context, sensorBloc, state), + child: _buildSceneContent(context, sensorBloc, state), ); }, ), @@ -68,13 +64,16 @@ class SixSelectSceneFourPage extends StatelessWidget { unit: spaces!.first)); } : null, - child: BodyMedium( - text: 'Save', - fontWeight: FontWeight.w700, - fontSize: 16, - fontColor: canSave - ? ColorsManager.slidingBlueColor - : ColorsManager.primaryTextColor, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: BodyMedium( + text: 'Save', + fontWeight: FontWeight.w700, + fontSize: 16, + fontColor: canSave + ? ColorsManager.slidingBlueColor + : ColorsManager.primaryTextColor, + ), ), ); } @@ -98,7 +97,15 @@ class SixSelectSceneFourPage extends StatelessWidget { _buildSearchBar(sensorBloc), const SizedBox(height: 20), Expanded( - child: _buildSceneGrid(sensorBloc, state), + child: state is SixSceneLoadingState + ? _buildLoadingIndicator() + : sensorBloc.filteredScenes.isEmpty + ? const Center( + child: SizedBox( + child: BodySmall(text: 'No Scenes available'), + ), + ) + : _buildSceneGrid(sensorBloc, state), ), ], ); @@ -137,7 +144,7 @@ class SixSelectSceneFourPage extends StatelessWidget { final scenes = sensorBloc.filteredScenes; return GridView.builder( - itemCount: scenes.length + 1, + itemCount: scenes.length, gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 2, mainAxisSpacing: 16, @@ -145,38 +152,55 @@ class SixSelectSceneFourPage extends StatelessWidget { mainAxisExtent: 120, ), itemBuilder: (context, index) { - if (index == scenes.length) { - return InkWell( - onTap: () => Navigator.pushNamed( - NavigationService.navigatorKey.currentContext!, - Routes.sceneTasksRoute, - arguments: SceneSettingsRouteArguments( - sceneType: '', - sceneId: '', - sceneName: '', - ), - ), - child: CreateSceneItem(), - ); - } else { - final scene = scenes[index]; - bool isSelected = scene.id == - (state is SceneSelectionUpdatedState - ? state.selectedSceneId - : sensorBloc.selectedFormApiSceneId); - return SceneItem( - id: scene.id, - value: isSelected, - disablePlayButton: false, - onChanged: (isSelected) { - sensorBloc.add(SelectOptionEvent(selectedOption: scene.id)); + final scene = scenes[index]; + bool isSelected = scene.id == + (state is SceneSelectionUpdatedState + ? state.selectedSceneId + : sensorBloc.selectedFormApiSceneId); + return SceneItem( + id: scene.id, + value: isSelected, + disablePlayButton: false, + onChanged: (isSelected) { + sensorBloc.add(SelectOptionEvent(selectedOption: scene.id)); + sensorBloc.add(SelectSceneEvent(unitId: scene.id)); + }, + icon: scene.iconInBytes, + title: scene.name, + ); - sensorBloc.add(SelectSceneEvent(unitId: scene.id)); - }, - icon: scene.iconInBytes, - title: scene.name, - ); - } + // if (index == scenes.length) { + // return InkWell( + // onTap: () => Navigator.pushNamed( + // NavigationService.navigatorKey.currentContext!, + // Routes.sceneTasksRoute, + // arguments: SceneSettingsRouteArguments( + // sceneType: '', + // sceneId: '', + // sceneName: '', + // ), + // ), + // child: CreateSceneItem(), + // ); + // } else { + // final scene = scenes[index]; + // bool isSelected = scene.id == + // (state is SceneSelectionUpdatedState + // ? state.selectedSceneId + // : sensorBloc.selectedFormApiSceneId); + // return SceneItem( + // id: scene.id, + // value: isSelected, + // disablePlayButton: false, + // onChanged: (isSelected) { + // sensorBloc.add(SelectOptionEvent(selectedOption: scene.id)); + + // sensorBloc.add(SelectSceneEvent(unitId: scene.id)); + // }, + // icon: scene.iconInBytes, + // title: scene.name, + // ); + // } }, ); } diff --git a/lib/features/devices/view/widgets/6_scene_switch/select_switch_dialog.dart b/lib/features/devices/view/widgets/6_scene_switch/select_switch_dialog.dart index 7e12cae..f873634 100644 --- a/lib/features/devices/view/widgets/6_scene_switch/select_switch_dialog.dart +++ b/lib/features/devices/view/widgets/6_scene_switch/select_switch_dialog.dart @@ -4,6 +4,7 @@ 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'; +// ignore: must_be_immutable class SelectSwitchDialog extends StatefulWidget { final Function()? cancelTab; final Function(String)? confirmTab; diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_select_scene_page.dart b/lib/features/devices/view/widgets/four_scene_switch/four_select_scene_page.dart index c43987d..cc2b93f 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_select_scene_page.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_select_scene_page.dart @@ -11,6 +11,7 @@ import 'package:syncrow_app/features/scene/model/scene_settings_route_arguments. 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_medium.dart'; +import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart'; import 'package:syncrow_app/generated/assets.dart'; import 'package:syncrow_app/navigation/navigation_service.dart'; import 'package:syncrow_app/navigation/routing_constants.dart'; @@ -45,9 +46,7 @@ class FourSelectSceneFourPage extends StatelessWidget { return DefaultScaffold( title: 'Select Scene', actions: [_buildSaveButton(context, state, sensorBloc)], - child: state is FourSceneLoadingState - ? _buildLoadingIndicator() - : _buildSceneContent(context, sensorBloc, state), + child: _buildSceneContent(context, sensorBloc, state), ); }, ), @@ -68,13 +67,16 @@ class FourSelectSceneFourPage extends StatelessWidget { unit: spaces!.first)); } : null, - child: BodyMedium( - text: 'Save', - fontWeight: FontWeight.w700, - fontSize: 16, - fontColor: canSave - ? ColorsManager.slidingBlueColor - : ColorsManager.primaryTextColor, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: BodyMedium( + text: 'Save', + fontWeight: FontWeight.w700, + fontSize: 16, + fontColor: canSave + ? ColorsManager.slidingBlueColor + : ColorsManager.primaryTextColor, + ), ), ); } @@ -98,7 +100,15 @@ class FourSelectSceneFourPage extends StatelessWidget { _buildSearchBar(sensorBloc), const SizedBox(height: 20), Expanded( - child: _buildSceneGrid(sensorBloc, state), + child: state is FourSceneLoadingState + ? _buildLoadingIndicator() + : sensorBloc.filteredScenes.isEmpty + ? const Center( + child: SizedBox( + child: BodySmall(text: 'No Scenes available'), + ), + ) + : _buildSceneGrid(sensorBloc, state), ), ], ); @@ -137,7 +147,7 @@ class FourSelectSceneFourPage extends StatelessWidget { final scenes = sensorBloc.filteredScenes; return GridView.builder( - itemCount: scenes.length + 1, + itemCount: scenes.length, gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 2, mainAxisSpacing: 16, @@ -145,38 +155,56 @@ class FourSelectSceneFourPage extends StatelessWidget { mainAxisExtent: 120, ), itemBuilder: (context, index) { - if (index == scenes.length) { - return InkWell( - onTap: () => Navigator.pushNamed( - NavigationService.navigatorKey.currentContext!, - Routes.sceneTasksRoute, - arguments: SceneSettingsRouteArguments( - sceneType: '', - sceneId: '', - sceneName: '', - ), - ), - child: CreateSceneItem(), - ); - } else { - final scene = scenes[index]; - bool isSelected = scene.id == - (state is SceneSelectionUpdatedState - ? state.selectedSceneId - : sensorBloc.selectedFormApiSceneId); - return SceneItem( - id: scene.id, - value: isSelected, - disablePlayButton: false, - onChanged: (isSelected) { - sensorBloc.add(SelectOptionEvent(selectedOption: scene.id)); + final scene = scenes[index]; + bool isSelected = scene.id == + (state is SceneSelectionUpdatedState + ? state.selectedSceneId + : sensorBloc.selectedFormApiSceneId); + return SceneItem( + id: scene.id, + value: isSelected, + disablePlayButton: false, + onChanged: (isSelected) { + sensorBloc.add(SelectOptionEvent(selectedOption: scene.id)); - sensorBloc.add(SelectSceneEvent(selectedSceneId: scene.id)); - }, - icon: scene.iconInBytes, - title: scene.name, - ); - } + sensorBloc.add(SelectSceneEvent(selectedSceneId: scene.id)); + }, + icon: scene.iconInBytes, + title: scene.name, + ); + + // if (index == scenes.length) { + // return InkWell( + // onTap: () => Navigator.pushNamed( + // NavigationService.navigatorKey.currentContext!, + // Routes.sceneTasksRoute, + // arguments: SceneSettingsRouteArguments( + // sceneType: '', + // sceneId: '', + // sceneName: '', + // ), + // ), + // child: CreateSceneItem(), + // ); + // } else { + // final scene = scenes[index]; + // bool isSelected = scene.id == + // (state is SceneSelectionUpdatedState + // ? state.selectedSceneId + // : sensorBloc.selectedFormApiSceneId); + // return SceneItem( + // id: scene.id, + // value: isSelected, + // disablePlayButton: false, + // onChanged: (isSelected) { + // sensorBloc.add(SelectOptionEvent(selectedOption: scene.id)); + + // sensorBloc.add(SelectSceneEvent(selectedSceneId: scene.id)); + // }, + // icon: scene.iconInBytes, + // title: scene.name, + // ); + // } }, ); } diff --git a/lib/features/devices/view/widgets/sos/sos_screen.dart b/lib/features/devices/view/widgets/sos/sos_screen.dart index 39851a9..7c475fb 100644 --- a/lib/features/devices/view/widgets/sos/sos_screen.dart +++ b/lib/features/devices/view/widgets/sos/sos_screen.dart @@ -43,15 +43,15 @@ class SosScreen extends StatelessWidget { actions: [ InkWell( onTap: () async { - var val = await Navigator.of(context).push( + Navigator.of(context).push( MaterialPageRoute( builder: (context) => SosSettings(device: device!), ), ); - if (val == true) { - sensor.add(SosInitialDeviseInfo()); - sensor.add(const SosInitial()); - } + // if (val == null) { + // sensor.add(SosInitialDeviseInfo()); + // sensor.add(const SosInitial()); + // } }, child: SvgPicture.asset(Assets.assetsIconsSettings), ), From bb50918f041a87197f06afb67becc4016e97f26e Mon Sep 17 00:00:00 2001 From: mohammad Date: Tue, 26 Nov 2024 16:47:07 +0300 Subject: [PATCH 24/29] change_settings_code --- .../view/widgets/login_user_agreement.dart | 1 + .../device_scene_bloc.dart | 559 +++++++++++++ .../device_scene_event.dart | 171 ++++ .../device_scene_state.dart | 125 +++ .../devices/bloc/sos_bloc/sos_bloc.dart | 1 - .../create_group.dart} | 0 .../faq_page.dart} | 9 +- .../info_page.dart} | 24 +- .../location_setting.dart} | 30 +- .../profile_page.dart} | 81 +- .../question_page.dart | 22 +- .../settings_page.dart} | 90 +-- .../share_device_page.dart} | 4 +- .../update_dialog.dart} | 0 .../update_note.dart} | 4 +- .../update_page.dart} | 8 +- .../6_scene_setting/faq_six_scene_page.dart | 158 ---- .../6_scene_setting/location_setting.dart | 226 ------ .../6_scene_setting/question_page.dart | 161 ---- .../6_scene_setting/share_six_scene_page.dart | 121 --- .../six_scene_create_group.dart | 215 ----- .../six_scene_delete_dialog.dart | 0 .../6_scene_setting/six_scene_info_page.dart | 156 ---- .../six_scene_profile_page.dart | 189 ----- .../6_scene_setting/six_scene_settings.dart | 413 ---------- .../six_scene_update_note.dart | 118 --- .../six_scene_update_page.dart | 352 -------- .../6_scene_switch/six_scene_screen.dart | 4 +- .../four_scene_switch/four_scene_screen.dart | 4 +- .../four_scene_update_dialog.dart | 118 --- .../four_scene_update_note.dart | 118 --- .../question_page_four_scene.dart | 142 ---- .../four_select_scene_page.dart | 3 - .../view/widgets/room_page_switch.dart | 2 +- .../devices/view/widgets/sos/sos_screen.dart | 14 +- .../widgets/sos/sos_setting/faq_sos_page.dart | 164 ---- .../sos/sos_setting/location_setting.dart | 211 ----- .../sos/sos_setting/share_sos_page.dart | 105 --- .../sos/sos_setting/sos_info_page.dart | 141 ---- .../sos/sos_setting/sos_profile_page.dart | 184 ----- .../sos/sos_setting/sos_update_page.dart | 353 --------- .../sos/sos_setting/update_dialog_sos.dart | 118 --- .../view/widgets/sos/sos_settings.dart | 750 +++++++++--------- lib/services/api/api_links_endpoints.dart | 5 +- 44 files changed, 1384 insertions(+), 4290 deletions(-) create mode 100644 lib/features/devices/bloc/device_settings_bloc/device_scene_bloc.dart create mode 100644 lib/features/devices/bloc/device_settings_bloc/device_scene_event.dart create mode 100644 lib/features/devices/bloc/device_settings_bloc/device_scene_state.dart rename lib/features/devices/view/{widgets/four_scene_switch/four_scene_setting/four_scene_create_group.dart => device_settings/create_group.dart} (100%) rename lib/features/devices/view/{widgets/four_scene_switch/four_scene_setting/faq_four_scene_page.dart => device_settings/faq_page.dart} (95%) rename lib/features/devices/view/{widgets/four_scene_switch/four_scene_setting/four_scene_info_page.dart => device_settings/info_page.dart} (87%) rename lib/features/devices/view/{widgets/four_scene_switch/four_scene_setting/location_setting_four_scene.dart => device_settings/location_setting.dart} (87%) rename lib/features/devices/view/{widgets/four_scene_switch/four_scene_setting/four_scene_profile_page.dart => device_settings/profile_page.dart} (71%) rename lib/features/devices/view/{widgets/sos/sos_setting => device_settings}/question_page.dart (88%) rename lib/features/devices/view/{widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart => device_settings/settings_page.dart} (85%) rename lib/features/devices/view/{widgets/four_scene_switch/four_scene_setting/share_four_scene_page.dart => device_settings/share_device_page.dart} (97%) rename lib/features/devices/view/{widgets/6_scene_switch/6_scene_setting/six_scene_update_dialog.dart => device_settings/update_dialog.dart} (100%) rename lib/features/devices/view/{widgets/sos/sos_setting/sos_update_note.dart => device_settings/update_note.dart} (98%) rename lib/features/devices/view/{widgets/four_scene_switch/four_scene_setting/four_scene_update_page.dart => device_settings/update_page.dart} (98%) delete mode 100644 lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/faq_six_scene_page.dart delete mode 100644 lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/location_setting.dart delete mode 100644 lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/question_page.dart delete mode 100644 lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/share_six_scene_page.dart delete mode 100644 lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_create_group.dart delete mode 100644 lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_delete_dialog.dart delete mode 100644 lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_info_page.dart delete mode 100644 lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_profile_page.dart delete mode 100644 lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_settings.dart delete mode 100644 lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_update_note.dart delete mode 100644 lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_update_page.dart delete mode 100644 lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_update_dialog.dart delete mode 100644 lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_update_note.dart delete mode 100644 lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/question_page_four_scene.dart delete mode 100644 lib/features/devices/view/widgets/sos/sos_setting/faq_sos_page.dart delete mode 100644 lib/features/devices/view/widgets/sos/sos_setting/location_setting.dart delete mode 100644 lib/features/devices/view/widgets/sos/sos_setting/share_sos_page.dart delete mode 100644 lib/features/devices/view/widgets/sos/sos_setting/sos_info_page.dart delete mode 100644 lib/features/devices/view/widgets/sos/sos_setting/sos_profile_page.dart delete mode 100644 lib/features/devices/view/widgets/sos/sos_setting/sos_update_page.dart delete mode 100644 lib/features/devices/view/widgets/sos/sos_setting/update_dialog_sos.dart diff --git a/lib/features/auth/view/widgets/login_user_agreement.dart b/lib/features/auth/view/widgets/login_user_agreement.dart index a4e7ee8..978ccad 100644 --- a/lib/features/auth/view/widgets/login_user_agreement.dart +++ b/lib/features/auth/view/widgets/login_user_agreement.dart @@ -2,6 +2,7 @@ import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_app/features/auth/bloc/auth_cubit.dart'; +import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart'; import 'package:syncrow_app/navigation/routing_constants.dart'; import 'package:syncrow_app/utils/context_extension.dart'; diff --git a/lib/features/devices/bloc/device_settings_bloc/device_scene_bloc.dart b/lib/features/devices/bloc/device_settings_bloc/device_scene_bloc.dart new file mode 100644 index 0000000..4c034b7 --- /dev/null +++ b/lib/features/devices/bloc/device_settings_bloc/device_scene_bloc.dart @@ -0,0 +1,559 @@ +import 'dart:async'; +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/device_settings_bloc/device_scene_event.dart'; +import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_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/four_scene_model.dart'; +import 'package:syncrow_app/features/devices/model/four_scene_switch_model.dart'; +import 'package:syncrow_app/features/devices/model/question_model.dart'; +import 'package:syncrow_app/features/devices/model/group_devices_model.dart'; +import 'package:syncrow_app/features/devices/model/device_info_model.dart'; +import 'package:syncrow_app/features/devices/model/status_model.dart'; +import 'package:syncrow_app/features/devices/model/subspace_model.dart'; +import 'package:syncrow_app/features/scene/model/scenes_model.dart'; +import 'package:syncrow_app/generated/assets.dart'; +import 'package:syncrow_app/services/api/devices_api.dart'; +import 'package:syncrow_app/services/api/home_management_api.dart'; +import 'package:syncrow_app/services/api/scene_api.dart'; +import 'package:syncrow_app/services/api/spaces_api.dart'; +import 'package:syncrow_app/utils/helpers/snack_bar.dart'; + +class DeviceSettingBloc extends Bloc { + final String deviceId; + DeviceSettingBloc({ + required this.deviceId, + }) : super(const DeviceSettingState()) { + on(_fetchDeviceStatus); + on(fetchDeviceInfo); + on(saveName); + on(_toggleNotification); + on(_changeName); + on(_onSearchFaq); + on(_fetchRoomsAndDevices); + on(changeSwitchStatus); + on(_onLoadSettings); + on(searchSetting); + on(_assignDevice); + on(_onOptionSelected); + on(_addDeviceToGroup); + on(_removeDeviceFromGroup); + on(_onDeviceSettingInitial); + on(_fetchDeviceSetting); + on(_fetchDeviceSettingSwitches); + on(assignSetting); + on(getSettingByName); + on(_selectSetting); + on(deleteDevice); + on(_toggleLowBattery); + on(_toggleUpdate); + on(_toggleHelpful); + } + + final TextEditingController nameController = + TextEditingController(text: deviceName); + bool isSaving = false; + bool editName = false; + final FocusNode focusNode = FocusNode(); + bool closingReminder = false; + bool waterAlarm = false; + static String deviceName = ''; + static String selectedRoomId = ''; + bool selecedSetting = false; + bool enableAlarm = false; + List fourSetting = []; + + String _selectedOption = ''; + bool _hasSelectionChanged = false; + + FourSceneModelState deviceStatus = FourSceneModelState( + scene_1: '', + scene_2: '', + scene_3: '', + scene_4: '', + scene_id_group_id: '', + switch_backlight: false); + + DeviceInfoModel deviceInfo = DeviceInfoModel( + activeTime: 0, + category: "", + categoryName: "", + createTime: 0, + gatewayId: "", + icon: "", + ip: "", + lat: "", + localKey: "", + lon: "", + model: "", + name: "", + nodeId: "", + online: false, + ownerId: "", + productName: "", + sub: false, + timeZone: "", + updateTime: 0, + uuid: "", + productUuid: "", + productType: "", + permissionType: "", + macAddress: "", + subspace: Subspace( + uuid: "", + createdAt: "", + updatedAt: "", + subspaceName: "", + ), + ); + +//============================ get Setting and assign scene ======================= + String selectedFormApiSettingId = ''; + String selectedSettingId = ''; + + _selectSetting(SelectSettingEvent event, Emitter emit) { + emit(DeviceSettingLoadingState()); + selectedSettingId = event.selectedSettingId; + emit(SettingSelectionUpdatedState(selectedSettingId: selectedSettingId)); + } + + void getSettingByName( + GetSettingBySwitchName event, Emitter emit) async { + // emit(DeviceSettingLoadingState()); + try { + final response = await DevicesAPI.getSceneBySwitchName( + deviceId: deviceId, switchName: event.switchName); + selectedFormApiSettingId = response['scene']['uuid']; + emit(UpdateState(device: deviceStatus)); + } catch (e) { + emit(DeviceSettingFailedState(errorMessage: e.toString())); + } + } + + void _onOptionSelected( + SelectOptionEvent event, Emitter emit) { + emit(DeviceSettingLoadingState()); + _selectedOption = event.selectedOption; + _hasSelectionChanged = true; + emit(OptionSelectedState( + selectedOption: _selectedOption, + hasSelectionChanged: _hasSelectionChanged)); + } + + void _fetchDeviceSettingSwitches(DeviceSettingSwitchInitial event, + Emitter emit) async { + emit(DeviceSettingLoadingState()); + try { + var response = await DevicesAPI.getFourSceneInfo(deviceId); + Map sceneTitles = { + "scene_1": '', + "scene_2": '', + "scene_3": '', + "scene_4": '', + }; + for (var item in response) { + if (item["switchName"] != null) { + sceneTitles[item["switchName"]] = item["scene"]["name"] ?? ''; + } + } + FourSceneModelState deviceStatus = FourSceneModelState( + scene_1: sceneTitles["scene_1"] ?? '', + scene_2: sceneTitles["scene_2"] ?? '', + scene_3: sceneTitles["scene_3"] ?? '', + scene_4: sceneTitles["scene_4"] ?? '', + scene_id_group_id: '', + switch_backlight: '', + ); + emit(UpdateState(device: deviceStatus)); + } catch (e) { + emit(DeviceSettingFailedState(errorMessage: e.toString())); + return; + } + } + + void assignSetting( + AssignDeviceSetting event, Emitter emit) async { + emit(DeviceSettingLoadingState()); + try { + final response = await DevicesAPI.postFourSceneInfo( + deviceId: deviceId, + sceneUuid: event.sceneUuid, + spaceUuid: event.unit!.id, + switchName: event.switchName); + + emit(SaveSelectionSuccessState()); + CustomSnackBar.displaySnackBar('Save Successfully'); + } catch (e) { + emit(DeviceSettingFailedState(errorMessage: e.toString())); + } + } + + void _fetchDeviceSetting( + FetchDeviceSetting event, Emitter emit) async { + emit(DeviceSettingLoadingState()); + try { + var response = await DevicesAPI.getDeviceStatus(deviceId); + List statusModelList = []; + for (var status in response['status']) { + statusModelList.add(StatusModel.fromJson(status)); + } + deviceStatus = FourSceneModelState.fromJson( + statusModelList, + ); + emit(UpdateState(device: deviceStatus)); + Future.delayed(const Duration(milliseconds: 500)); + } catch (e) { + emit(DeviceSettingFailedState(errorMessage: e.toString())); + return; + } + } + +//===================== fetch Device Status and info ======================= + + void _toggleLowBattery( + ToggleEnableAlarmEvent event, Emitter emit) async { + emit(LoadingNewSate(device: deviceStatus)); + try { + enableAlarm = event.isLowBatteryEnabled; + emit(UpdateState(device: deviceStatus)); + } catch (e) { + emit(DeviceSettingFailedState(errorMessage: e.toString())); + } + } + + void _fetchDeviceStatus( + DeviceSettingInitial event, Emitter emit) async { + emit(DeviceSettingLoadingState()); + try { + var response = await DevicesAPI.getDeviceStatus(deviceId); + List statusModelList = []; + for (var status in response['status']) { + statusModelList.add(StatusModel.fromJson(status)); + } + deviceStatus = FourSceneModelState.fromJson( + statusModelList, + ); + emit(SuccessState()); + // add(const DeviceSettingSwitchInitial()); + } catch (e) { + emit(DeviceSettingFailedState(errorMessage: e.toString())); + return; + } + } + + Future fetchDeviceInfo( + DeviceSettingInitialInfo event, Emitter emit) async { + try { + emit(DeviceSettingLoadingState()); + var response = await DevicesAPI.getDeviceInfo(deviceId); + deviceInfo = DeviceInfoModel.fromJson(response); + deviceName = deviceInfo.name; + emit(LoadingDeviceInfo(deviceInfo: deviceInfo)); + } catch (e) { + emit(DeviceSettingFailedState(errorMessage: e.toString())); + } + } + + void _onSearchFaq(SearchFaqEvent event, Emitter emit) { + emit(DeviceSettingLoadingState()); + List _faqQuestions = faqQuestions.where((question) { + return question.question + .toLowerCase() + .contains(event.query.toLowerCase()); + }).toList(); + emit(FaqSearchState(filteredFaqQuestions: _faqQuestions)); + } + +//============================ assign Device ================================== +////////////////////////////////////////////////////////////////////////////// + + void _toggleNotification( + ToggleNotificationEvent event, Emitter emit) async { + emit(LoadingNewSate(device: deviceStatus)); + try { + enableAlarm = event.isClosingEnabled; + emit(UpdateState(device: deviceStatus)); + } catch (e) { + emit(DeviceSettingFailedState(errorMessage: e.toString())); + } + } + + DeviceReport recordGroups = + DeviceReport(startTime: '0', endTime: '0', data: []); + + //========================= Question and faq ================================ + + final List faqQuestions = [ + QuestionModel( + id: 1, + question: + 'How does an 4 Setting Switch work? How long will an 4 Setting Switch persist?', + answer: + 'Yes. In scenes with high detection requirements, we recommend that you choose phone or message notification in Automation.', + ), + QuestionModel( + id: 2, + question: 'Does the 4 Setting Switch support sending notifications?', + answer: + 'The SOS alarm will persist until it is manually turned off or after a set time.', + ), + QuestionModel( + id: 3, + question: + 'Why does the data statistics in the device panel not show the correct data?', + answer: 'Try restarting the device. If it persists, contact support.', + ), + QuestionModel( + id: 4, + question: + 'How long will the App show offline after a device (low-power devices and normal devices) is powered...', + answer: + 'No, a network connection is required to send the alert to your contacts.', + ), + ]; + + bool isHelpful = false; + + void _toggleHelpful( + ToggleHelpfulEvent event, Emitter emit) async { + try { + emit(DeviceSettingLoadingState()); + isHelpful = event.isHelpful!; + emit(SaveState()); + } catch (e) { + emit( + const DeviceSettingFailedState(errorMessage: 'Something went wrong')); + } + } + + Future _onDeviceSettingInitial(DeviceSettingInitialQuestion event, + Emitter emit) async { + emit(DeviceSettingLoadingState()); + emit(FaqLoadedState(filteredFaqQuestions: faqQuestions)); + } + + List allDevices = []; + List roomsList = []; + bool switchStatus = true; + Future changeSwitchStatus( + ChangeSwitchStatusEvent event, Emitter emit) async { + try { + emit(DeviceSettingLoadingState()); + switchStatus = deviceStatus.switch_backlight; + switchStatus = !switchStatus; + final response = await DevicesAPI.controlDevice( + DeviceControlModel( + deviceId: deviceId, + code: 'switch_backlight', + value: switchStatus), + deviceId); + deviceStatus.switch_backlight = switchStatus; + Future.delayed(const Duration(milliseconds: 200), () { + add(const DeviceSettingSwitchInitial()); + }); + Future.delayed(const Duration(milliseconds: 200), () { + emit(ChangeSwitchState(isEnable: switchStatus)); + emit(UpdateState(device: deviceStatus)); + }); + } catch (_) { + add(const DeviceSettingInitial()); + } + } + + Future _onLoadSettings( + LoadSettings event, Emitter emit) async { + emit(DeviceSettingLoadingState()); + try { + if (event.unitId.isNotEmpty) { + // allSettings = await DevicesAPI.getDveByUnitId( + // event.unitId, event.unit.community.uuid, + // showInDevice: event.showInDevice); + + filteredSettings = allSettings; + emit(SettingLoaded(allSettings)); + } else { + emit(const DeviceSettingFailedState(errorMessage: 'Unit ID is empty')); + } + } catch (e) { + emit( + const DeviceSettingFailedState(errorMessage: 'Something went wrong')); + } + } + + List allSettings = []; + List filteredSettings = []; + + void searchSetting( + SearchSettingsEvent event, Emitter emit) { + emit(DeviceSettingLoadingState()); + filteredSettings = event.query.isEmpty + ? allSettings + : allSettings.where((scene) { + final sceneName = scene.name?.toLowerCase() ?? ''; + return sceneName.contains(event.query.toLowerCase()); + }).toList(); + emit(SearchResultsState()); + } + + List groupDevices = [ + GroupDevicesModel( + dec: 'Syncroom', icon: Assets.minusIcon, name: '6 Setting Switch') + ]; + + List devices = [ + GroupDevicesModel( + dec: 'Syncroom', icon: Assets.addDevicesIcon, name: '6 Setting Switch') + ]; + + // Handler for AddDeviceToGroup + void _addDeviceToGroup( + AddDeviceToGroup event, Emitter emit) { + devices.remove(event.device); + groupDevices.add(event.device); + for (var device in groupDevices) { + device.icon = event.icon; + } + emit(UpdateStateList(groupDevices: groupDevices, devices: devices)); + } + + // Handler for RemoveDeviceFromGroup + void _removeDeviceFromGroup( + RemoveDeviceFromGroup event, Emitter emit) { + groupDevices.remove(event.device); + devices.add(event.device); + for (var device in groupDevices) { + device.icon = event.icon; + } + emit(UpdateStateList(groupDevices: groupDevices, devices: devices)); + } + + //=========================== assign device to room ========================== + + void _assignDevice( + AssignRoomEvent event, Emitter emit) async { + try { + emit(DeviceSettingLoadingState()); + if (_hasSelectionChanged) { + await HomeManagementAPI.assignDeviceToRoom( + event.unit.community.uuid, event.unit.id, event.roomId, deviceId); + final devicesList = await DevicesAPI.getDevicesByRoomId( + communityUuid: event.unit.community.uuid, + spaceUuid: event.unit.id, + roomId: event.roomId); + List allDevicesIds = []; + allDevices.forEach((element) { + allDevicesIds.add(element.uuid!); + }); + await HomeCubit.getInstance().fetchUnitsByUserId(); + CustomSnackBar.displaySnackBar('Save Successfully'); + emit(SaveSelectionSuccessState()); + } + } catch (e) { + emit( + const DeviceSettingFailedState(errorMessage: 'Something went wrong')); + return; + } + } + + void _fetchRoomsAndDevices( + FetchRoomsEvent event, Emitter emit) async { + try { + emit(DeviceSettingLoadingState()); + roomsList = await SpacesAPI.getSubSpaceBySpaceId( + event.unit.community.uuid, event.unit.id); + emit(FetchRoomsState(devicesList: allDevices, roomsList: roomsList)); + } catch (e) { + emit( + const DeviceSettingFailedState(errorMessage: 'Something went wrong')); + return; + } + } + +//============================ setting name ================================== +////////////////////////////////////////////////////////////////////////////// + + void _changeName(ChangeNameEvent event, Emitter emit) { + emit(DeviceSettingLoadingState()); + editName = event.value!; + if (editName) { + Future.delayed(const Duration(milliseconds: 500), () { + focusNode.requestFocus(); + }); + } else { + focusNode.unfocus(); + } + emit(NameEditingState(editName: editName)); + } + + bool _validateInputs() { + final nameError = fullNameValidator(nameController.text); + if (nameError != null) { + CustomSnackBar.displaySnackBar(nameError); + return true; + } + return false; + } + + String? fullNameValidator(String? value) { + if (value == null) return 'name is required'; + final withoutExtraSpaces = value.replaceAll(RegExp(r"\s+"), ' ').trim(); + if (withoutExtraSpaces.length < 2 || withoutExtraSpaces.length > 30) { + return 'name must be between 2 and 30 characters long'; + } + if (RegExp(r"/[^ a-zA-Z0-9-\']/").hasMatch(withoutExtraSpaces)) { + return 'Only alphanumeric characters, space, dash and single quote are allowed'; + } + return null; + } + + Future saveName( + SaveNameEvent event, Emitter emit) async { + if (_validateInputs()) return; + try { + add(const ChangeNameEvent(value: false)); + isSaving = true; + emit(DeviceSettingLoadingState()); + var response = await DevicesAPI.putDeviceName( + deviceId: deviceId, deviceName: nameController.text); + add(const DeviceSettingInitialInfo()); + CustomSnackBar.displaySnackBar('Save Successfully'); + emit(SaveState()); + } catch (e) { + emit(DeviceSettingFailedState(errorMessage: e.toString())); + } finally { + isSaving = false; + } + } + +//====================== update device ============================== + + bool enableUpdate = false; + + void _toggleUpdate( + ToggleUpdateEvent event, Emitter emit) async { + try { + emit(DeviceSettingLoadingState()); + enableUpdate = event.isUpdateEnabled!; + emit(SaveState()); + } catch (e) { + emit( + const DeviceSettingFailedState(errorMessage: 'Something went wrong')); + } + } + + deleteDevice( + DeleteDeviceEvent event, Emitter emit) async { + try { + emit(DeviceSettingLoadingState()); + var response = await DevicesAPI.resetDevise(devicesUuid: deviceId); + CustomSnackBar.displaySnackBar('Reset Successfully'); + emit(UpdateState(device: deviceStatus)); + } catch (e) { + emit(DeviceSettingFailedState(errorMessage: e.toString())); + return; + } + } +} diff --git a/lib/features/devices/bloc/device_settings_bloc/device_scene_event.dart b/lib/features/devices/bloc/device_settings_bloc/device_scene_event.dart new file mode 100644 index 0000000..5b6330f --- /dev/null +++ b/lib/features/devices/bloc/device_settings_bloc/device_scene_event.dart @@ -0,0 +1,171 @@ +import 'package:equatable/equatable.dart'; +import 'package:flutter/material.dart'; +import 'package:syncrow_app/features/app_layout/model/space_model.dart'; +import 'package:syncrow_app/features/devices/model/group_devices_model.dart'; + +abstract class DeviceSettingEvent extends Equatable { + const DeviceSettingEvent(); + + @override + List get props => []; +} + +class DeviceSettingInitialInfo extends DeviceSettingEvent { + const DeviceSettingInitialInfo(); +} + +class DeviceSettingInitial extends DeviceSettingEvent { + const DeviceSettingInitial(); +} + +class SaveNameEvent extends DeviceSettingEvent { + final String? deviceName; + + const SaveNameEvent({this.deviceName}); +} + +class ToggleEnableAlarmEvent extends DeviceSettingEvent { + final bool isLowBatteryEnabled; + + const ToggleEnableAlarmEvent(this.isLowBatteryEnabled); + + @override + List get props => [isLowBatteryEnabled]; +} + +class ToggleNotificationEvent extends DeviceSettingEvent { + final bool isClosingEnabled; + + const ToggleNotificationEvent(this.isClosingEnabled); + + @override + List get props => [isClosingEnabled]; +} + +class DeleteDeviceEvent extends DeviceSettingEvent {} + +class ChangeNameEvent extends DeviceSettingEvent { + final bool? value; + const ChangeNameEvent({this.value}); +} + +class SearchFaqEvent extends DeviceSettingEvent { + final String query; + + const SearchFaqEvent(this.query); +} + +class DeviceSettingInitialQuestion extends DeviceSettingEvent { + const DeviceSettingInitialQuestion(); +} + +class ChangeSwitchStatusEvent extends DeviceSettingEvent {} + +class FetchRoomsEvent extends DeviceSettingEvent { + final SpaceModel unit; + + const FetchRoomsEvent({required this.unit}); + + @override + List get props => [unit]; +} + +class LoadSettings extends DeviceSettingEvent { + final String unitId; + final bool showInDevice; + final SpaceModel unit; + + const LoadSettings( + {required this.unitId, required this.unit, this.showInDevice = false}); + + @override + List get props => [unitId, showInDevice]; +} + +class SelectSettingEvent extends DeviceSettingEvent { + final String selectedSettingId; + // final String unitId; + const SelectSettingEvent({ + // required this.unitId, + required this.selectedSettingId, + }); +} + +class SearchSettingsEvent extends DeviceSettingEvent { + final String query; + const SearchSettingsEvent({ + required this.query, + }); +} + +class SelectOptionEvent extends DeviceSettingEvent { + final dynamic selectedOption; + const SelectOptionEvent({ + this.selectedOption, + }); +} + +class AddDeviceToGroup extends DeviceSettingEvent { + final GroupDevicesModel device; + final String icon; + const AddDeviceToGroup(this.device, this.icon); +} + +class RemoveDeviceFromGroup extends DeviceSettingEvent { + final GroupDevicesModel device; + final String icon; + + const RemoveDeviceFromGroup(this.device, this.icon); +} + +class AssignRoomEvent extends DeviceSettingEvent { + final String roomId; + final SpaceModel unit; + final BuildContext context; + + const AssignRoomEvent({ + required this.roomId, + required this.unit, + required this.context, + }); + + @override + List get props => [ + roomId, + unit, + context, + ]; +} + +class FetchDeviceSetting extends DeviceSettingEvent {} + +class DeviceSettingSwitchInitial extends DeviceSettingEvent { + const DeviceSettingSwitchInitial(); +} + +class AssignDeviceSetting extends DeviceSettingEvent { + final String? sceneUuid; + final String? switchName; + final SpaceModel? unit; + const AssignDeviceSetting({ + this.sceneUuid, + this.unit, + this.switchName, + }); +} + +class GetSettingBySwitchName extends DeviceSettingEvent { + final String? switchName; + + const GetSettingBySwitchName({this.switchName}); +} + +class ToggleUpdateEvent extends DeviceSettingEvent { + final bool? isUpdateEnabled; + const ToggleUpdateEvent({this.isUpdateEnabled}); +} + +class ToggleHelpfulEvent extends DeviceSettingEvent { + final bool? isHelpful; + const ToggleHelpfulEvent({this.isHelpful}); +} diff --git a/lib/features/devices/bloc/device_settings_bloc/device_scene_state.dart b/lib/features/devices/bloc/device_settings_bloc/device_scene_state.dart new file mode 100644 index 0000000..b3325af --- /dev/null +++ b/lib/features/devices/bloc/device_settings_bloc/device_scene_state.dart @@ -0,0 +1,125 @@ +import 'package:equatable/equatable.dart'; +import 'package:syncrow_app/features/devices/model/device_model.dart'; +import 'package:syncrow_app/features/devices/model/four_scene_model.dart'; +import 'package:syncrow_app/features/devices/model/question_model.dart'; +import 'package:syncrow_app/features/devices/model/group_devices_model.dart'; +import 'package:syncrow_app/features/devices/model/device_info_model.dart'; +import 'package:syncrow_app/features/devices/model/subspace_model.dart'; +import 'package:syncrow_app/features/scene/model/scenes_model.dart'; + +class DeviceSettingState extends Equatable { + const DeviceSettingState(); + + @override + List get props => []; +} + +class DeviceSettingLoadingState extends DeviceSettingState {} + +class UpdateStateList extends DeviceSettingState { + final List groupDevices; + final List devices; + const UpdateStateList({required this.groupDevices, required this.devices}); +} + +class DeviceSettingFailedState extends DeviceSettingState { + final String errorMessage; + + const DeviceSettingFailedState({required this.errorMessage}); + + @override + List get props => [errorMessage]; +} + +class UpdateState extends DeviceSettingState { + final FourSceneModelState device; + const UpdateState({required this.device}); + + @override + List get props => [device]; +} + +class LoadingNewSate extends DeviceSettingState { + final FourSceneModelState device; + const LoadingNewSate({required this.device}); + + @override + List get props => [device]; +} + +class NameEditingState extends DeviceSettingState { + final bool editName; + + const NameEditingState({required this.editName}); +} + +class FaqLoadedState extends DeviceSettingState { + final List filteredFaqQuestions; + + const FaqLoadedState({this.filteredFaqQuestions = const []}); +} + +class FaqSearchState extends DeviceSettingState { + final List filteredFaqQuestions; + + const FaqSearchState({this.filteredFaqQuestions = const []}); +} + +class FetchRoomsState extends DeviceSettingState { + final List roomsList; + final List devicesList; + + const FetchRoomsState({required this.devicesList, required this.roomsList}); + + @override + List get props => [devicesList]; +} + +class ChangeSwitchState extends DeviceSettingState { + final bool isEnable; + + const ChangeSwitchState({required this.isEnable}); +} + +class SettingLoaded extends DeviceSettingState { + final List scenes; + final String? loadingSettingId; + final Map loadingStates; + + const SettingLoaded(this.scenes, + {this.loadingSettingId, this.loadingStates = const {}}); +} + +class SearchResultsState extends DeviceSettingState {} + +class SaveState extends DeviceSettingState {} +class SuccessState extends DeviceSettingState {} + +class SaveSelectionSuccessState extends DeviceSettingState {} + +class OptionSelectedState extends DeviceSettingState { + final String selectedOption; + final bool hasSelectionChanged; + + const OptionSelectedState({ + required this.selectedOption, + required this.hasSelectionChanged, + }); + + @override + List get props => [selectedOption, hasSelectionChanged]; +} + +class LoadingDeviceInfo extends DeviceSettingState { + final DeviceInfoModel deviceInfo; + const LoadingDeviceInfo({required this.deviceInfo}); + + @override + List get props => [deviceInfo]; +} + +class SettingSelectionUpdatedState extends DeviceSettingState { + final String selectedSettingId; + + const SettingSelectionUpdatedState({required this.selectedSettingId}); +} diff --git a/lib/features/devices/bloc/sos_bloc/sos_bloc.dart b/lib/features/devices/bloc/sos_bloc/sos_bloc.dart index 7690953..63082fa 100644 --- a/lib/features/devices/bloc/sos_bloc/sos_bloc.dart +++ b/lib/features/devices/bloc/sos_bloc/sos_bloc.dart @@ -170,7 +170,6 @@ class SosBloc extends Bloc { statusModelList, ); emit(UpdateState(sensor: deviceStatus)); - Future.delayed(const Duration(milliseconds: 500)); } catch (e) { emit(SosFailedState(errorMessage: e.toString())); diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_create_group.dart b/lib/features/devices/view/device_settings/create_group.dart similarity index 100% rename from lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_create_group.dart rename to lib/features/devices/view/device_settings/create_group.dart diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/faq_four_scene_page.dart b/lib/features/devices/view/device_settings/faq_page.dart similarity index 95% rename from lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/faq_four_scene_page.dart rename to lib/features/devices/view/device_settings/faq_page.dart index aff8eee..542e47b 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/faq_four_scene_page.dart +++ b/lib/features/devices/view/device_settings/faq_page.dart @@ -6,17 +6,17 @@ import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_eve import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_state.dart'; import 'package:syncrow_app/features/devices/model/device_model.dart'; import 'package:syncrow_app/features/devices/model/question_model.dart'; -import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_scene_setting/question_page_four_scene.dart'; +import 'package:syncrow_app/features/devices/view/device_settings/question_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_medium.dart'; import 'package:syncrow_app/generated/assets.dart'; import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; -class FaqFourScenePage extends StatelessWidget { +class FaqSettingPage extends StatelessWidget { final DeviceModel? device; - const FaqFourScenePage({super.key, this.device}); + const FaqSettingPage({super.key, this.device}); @override Widget build(BuildContext context) { @@ -101,7 +101,8 @@ class FaqFourScenePage extends StatelessWidget { Navigator.of(context).push( MaterialPageRoute( builder: (context) => - QuestionPageFourScene( + QuestionPageSetting( + deviceId: device!.uuid, questionModel: faq, )), ); diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_info_page.dart b/lib/features/devices/view/device_settings/info_page.dart similarity index 87% rename from lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_info_page.dart rename to lib/features/devices/view/device_settings/info_page.dart index d6ccfc5..9deac99 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_info_page.dart +++ b/lib/features/devices/view/device_settings/info_page.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart'; -import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_event.dart'; -import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_state.dart'; +import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_event.dart'; +import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_state.dart'; import 'package:syncrow_app/features/devices/model/device_model.dart'; import 'package:syncrow_app/features/shared_widgets/default_container.dart'; import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart'; @@ -12,23 +12,23 @@ import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dar import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart'; import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; -class FourSceneInfoPage extends StatelessWidget { +class SettingInfoPage extends StatelessWidget { final DeviceModel? device; - const FourSceneInfoPage({super.key, this.device}); + const SettingInfoPage({super.key, this.device}); @override Widget build(BuildContext context) { return DefaultScaffold( title: 'Device Information', child: BlocProvider( - create: (context) => FourSceneBloc(fourSceneId: device?.uuid ?? '') - ..add(const FourSceneInitial()) - ..add(const FourSceneInitialInfo()), - child: BlocBuilder( + create: (context) => DeviceSettingBloc(deviceId: device?.uuid ?? '') + ..add(const DeviceSettingInitial()) + ..add(const DeviceSettingInitialInfo()), + child: BlocBuilder( builder: (context, state) { - final _bloc = BlocProvider.of(context); - return state is FourSceneLoadingState + final _bloc = BlocProvider.of(context); + return state is DeviceSettingLoadingState ? const Center( child: DefaultContainer( width: 50, @@ -37,7 +37,7 @@ class FourSceneInfoPage extends StatelessWidget { ) : RefreshIndicator( onRefresh: () async { - _bloc.add(const FourSceneInitial()); + _bloc.add(const DeviceSettingInitial()); }, child: DefaultContainer( child: Padding( diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/location_setting_four_scene.dart b/lib/features/devices/view/device_settings/location_setting.dart similarity index 87% rename from lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/location_setting_four_scene.dart rename to lib/features/devices/view/device_settings/location_setting.dart index 452f7d1..ba668e8 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/location_setting_four_scene.dart +++ b/lib/features/devices/view/device_settings/location_setting.dart @@ -1,19 +1,19 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_app/features/app_layout/model/space_model.dart'; -import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart'; -import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_event.dart'; -import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_state.dart'; +import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_event.dart'; +import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_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_medium.dart'; import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; -class LocationFourScenePage extends StatelessWidget { +class LocationSettingPage extends StatelessWidget { final SpaceModel? space; final String? deviceId; - const LocationFourScenePage({ + const LocationSettingPage({ super.key, this.space, this.deviceId, @@ -25,20 +25,20 @@ class LocationFourScenePage extends StatelessWidget { return Scaffold( body: BlocProvider( - create: (context) => FourSceneBloc(fourSceneId: deviceId ?? '') - ..add(const FourSceneInitial()) - ..add(const FourSceneInitialInfo()) + create: (context) => DeviceSettingBloc(deviceId: deviceId ?? '') + ..add(const DeviceSettingInitial()) + ..add(const DeviceSettingInitialInfo()) ..add(FetchRoomsEvent(unit: space!)), - child: BlocBuilder( + child: BlocBuilder( builder: (context, state) { - final _bloc = BlocProvider.of(context); + final _bloc = BlocProvider.of(context); if (state is SaveSelectionSuccessState) { Future.delayed(const Duration(microseconds: 500), () { - _bloc.add(const FourSceneInitialInfo()); + _bloc.add(const DeviceSettingInitialInfo()); Navigator.of(context).pop(true); }); } - return state is FourSceneLoadingState + return state is DeviceSettingLoadingState ? const Center( child: DefaultContainer( width: 50, @@ -48,14 +48,14 @@ class LocationFourScenePage extends StatelessWidget { ) : DefaultScaffold( actions: [ - BlocBuilder( + BlocBuilder( builder: (context, state) { final bool canSave = state is OptionSelectedState && state.hasSelectionChanged; return InkWell( onTap: canSave ? () { - context.read().add( + context.read().add( AssignRoomEvent( context: context, roomId: roomIdSelected, @@ -107,7 +107,7 @@ class LocationFourScenePage extends StatelessWidget { label: fromRoom.name!, isSelected: isSelected, onTap: (label) { - context.read().add( + context.read().add( SelectOptionEvent( selectedOption: fromRoom.id!, ), diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_profile_page.dart b/lib/features/devices/view/device_settings/profile_page.dart similarity index 71% rename from lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_profile_page.dart rename to lib/features/devices/view/device_settings/profile_page.dart index cc70c8a..216ab12 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_profile_page.dart +++ b/lib/features/devices/view/device_settings/profile_page.dart @@ -2,21 +2,21 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart'; -import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart'; -import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_event.dart'; -import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_state.dart'; +import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_event.dart'; +import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_state.dart'; import 'package:syncrow_app/features/devices/model/device_model.dart'; -import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_scene_setting/location_setting_four_scene.dart'; +import 'package:syncrow_app/features/devices/view/device_settings/location_setting.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_medium.dart'; import 'package:syncrow_app/generated/assets.dart'; import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; -class FourSceneProfilePage extends StatelessWidget { +class SettingProfilePage extends StatelessWidget { final DeviceModel? device; - const FourSceneProfilePage({super.key, this.device}); + const SettingProfilePage({super.key, this.device}); @override Widget build(BuildContext context) { @@ -30,13 +30,13 @@ class FourSceneProfilePage extends StatelessWidget { }, icon: const Icon(Icons.arrow_back_ios)), child: BlocProvider( - create: (context) => FourSceneBloc(fourSceneId: device?.uuid ?? '') - ..add(const FourSceneInitial()) - ..add(const FourSceneInitialInfo()), - child: BlocBuilder( + create: (context) => DeviceSettingBloc(deviceId: device?.uuid ?? '') + ..add(const DeviceSettingInitial()) + ..add(const DeviceSettingInitialInfo()), + child: BlocBuilder( builder: (context, state) { - final _bloc = BlocProvider.of(context); - return state is FourSceneLoadingState + final _bloc = BlocProvider.of(context); + return state is DeviceSettingLoadingState ? const Center( child: DefaultContainer( width: 50, @@ -45,34 +45,45 @@ class FourSceneProfilePage extends StatelessWidget { ) : RefreshIndicator( onRefresh: () async { - _bloc.add(const FourSceneInitial()); + _bloc.add(const DeviceSettingInitial()); }, child: ListView( children: [ CircleAvatar( - radius: 60, + radius: device!.type != "SOS" ? 60 : 52, backgroundColor: Colors.white, - child: CircleAvatar( - radius: 55, - backgroundColor: ColorsManager.graysColor, - child: ClipOval( - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const SizedBox( - height: 10, - ), - Center( - child: SvgPicture.asset( - Assets.fourSceneIcon, - fit: BoxFit.contain, + child: device!.type == "SOS" + ? ClipOval( + child: SvgPicture.asset( + Assets.sosHomeIcon, + fit: BoxFit.fitHeight, + height: 100, + )) + : CircleAvatar( + radius: 55, + backgroundColor: ColorsManager.graysColor, + child: ClipOval( + child: Column( + crossAxisAlignment: + CrossAxisAlignment.center, + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + const SizedBox( + height: 10, + ), + Center( + child: SvgPicture.asset( + device!.type == "4S" + ? Assets.fourSceneIcon + : Assets.sixSceneIcon, + fit: BoxFit.contain, + ), + ), + ], ), ), - ], - ), - ), - ), + ), ), const SizedBox( height: 10, @@ -138,13 +149,13 @@ class FourSceneProfilePage extends StatelessWidget { onTap: () async { bool val = await Navigator.of(context).push( MaterialPageRoute( - builder: (context) => LocationFourScenePage( + builder: (context) => LocationSettingPage( space: spaces!.first, deviceId: device?.uuid ?? '', )), ); if (val == true) { - _bloc.add(const FourSceneInitialInfo()); + _bloc.add(const DeviceSettingInitialInfo()); } }, child: Row( diff --git a/lib/features/devices/view/widgets/sos/sos_setting/question_page.dart b/lib/features/devices/view/device_settings/question_page.dart similarity index 88% rename from lib/features/devices/view/widgets/sos/sos_setting/question_page.dart rename to lib/features/devices/view/device_settings/question_page.dart index a6c11bf..7e23f88 100644 --- a/lib/features/devices/view/widgets/sos/sos_setting/question_page.dart +++ b/lib/features/devices/view/device_settings/question_page.dart @@ -1,9 +1,9 @@ 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/sos_bloc/sos_bloc.dart'; -import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_event.dart'; -import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_state.dart'; +import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_event.dart'; +import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_state.dart'; import 'package:syncrow_app/features/devices/model/question_model.dart'; import 'package:syncrow_app/features/shared_widgets/default_button.dart'; import 'package:syncrow_app/features/shared_widgets/default_container.dart'; @@ -13,22 +13,22 @@ import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dar import 'package:syncrow_app/generated/assets.dart'; import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; -class QuestionPage extends StatelessWidget { +class QuestionPageSetting extends StatelessWidget { final QuestionModel? questionModel; - - const QuestionPage({super.key, this.questionModel}); + final String? deviceId; + const QuestionPageSetting({super.key, this.questionModel, this.deviceId}); @override Widget build(BuildContext context) { return DefaultScaffold( title: 'FAQ', child: BlocProvider( - create: (context) => SosBloc(sosId: '')..add(const SosInitial()), - child: BlocBuilder( + create: (context) => DeviceSettingBloc(deviceId: deviceId!) + ..add(const DeviceSettingInitial()), + child: BlocBuilder( builder: (context, state) { - final sensor = BlocProvider.of(context); - - return state is SosLoadingState + final sensor = BlocProvider.of(context); + return state is DeviceSettingLoadingState ? const Center( child: DefaultContainer( width: 50, diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart b/lib/features/devices/view/device_settings/settings_page.dart similarity index 85% rename from lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart rename to lib/features/devices/view/device_settings/settings_page.dart index d81caac..43c220c 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart +++ b/lib/features/devices/view/device_settings/settings_page.dart @@ -1,17 +1,16 @@ 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/four_scene_bloc/four_scene_bloc.dart'; -import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_event.dart'; -import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_state.dart'; +import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_event.dart'; +import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_state.dart'; import 'package:syncrow_app/features/devices/model/device_model.dart'; -import 'package:syncrow_app/features/devices/model/four_scene_model.dart'; -import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_scene_setting/faq_four_scene_page.dart'; -import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_info_page.dart'; -import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_profile_page.dart'; -import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_update_dialog.dart'; -import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_update_page.dart'; -import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_scene_setting/share_four_scene_page.dart'; +import 'package:syncrow_app/features/devices/view/device_settings/faq_page.dart'; +import 'package:syncrow_app/features/devices/view/device_settings/info_page.dart'; +import 'package:syncrow_app/features/devices/view/device_settings/profile_page.dart'; +import 'package:syncrow_app/features/devices/view/device_settings/share_Device_page.dart'; +import 'package:syncrow_app/features/devices/view/device_settings/update_dialog.dart'; +import 'package:syncrow_app/features/devices/view/device_settings/update_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/delete_device_dialogs.dart'; @@ -21,35 +20,24 @@ import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart import 'package:syncrow_app/generated/assets.dart'; import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; -class FourSceneSettings extends StatelessWidget { +class SettingsPage extends StatelessWidget { final DeviceModel? device; - const FourSceneSettings({super.key, this.device}); + const SettingsPage({super.key, this.device}); @override Widget build(BuildContext context) { return DefaultScaffold( title: 'Device Settings', child: BlocProvider( - create: (context) => FourSceneBloc(fourSceneId: device?.uuid ?? '') - ..add(const FourSceneInitial()) - ..add(const FourSceneInitialInfo()), - child: BlocBuilder( + create: (context) => DeviceSettingBloc(deviceId: device?.uuid ?? '') + ..add(const DeviceSettingInitial()) + ..add(const DeviceSettingInitialInfo()), + child: BlocBuilder( builder: (context, state) { - final _bloc = BlocProvider.of(context); - FourSceneModelState model = FourSceneModelState( - scene_1: '', - scene_2: '', - scene_3: '', - scene_4: '', - scene_id_group_id: '', - switch_backlight: ''); - if (state is LoadingNewSate) { - model = state.device; - } else if (state is UpdateState) { - model = state.device; - } - return state is FourSceneLoadingState + final _bloc = BlocProvider.of(context); + + return state is DeviceSettingLoadingState ? const Center( child: DefaultContainer( width: 50, @@ -66,13 +54,13 @@ class FourSceneSettings extends StatelessWidget { onTap: () async { bool val = await Navigator.of(context).push( MaterialPageRoute( - builder: (context) => FourSceneProfilePage( + builder: (context) => SettingProfilePage( device: device, ), ), ); if (val == true) { - _bloc.add(const FourSceneInitialInfo()); + _bloc.add(const DeviceSettingInitialInfo()); } }, child: Stack( @@ -136,17 +124,23 @@ class FourSceneSettings extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, children: [ - Padding( - padding: - const EdgeInsets.only(top: 8), - child: SizedBox( - height: 70, - child: SvgPicture.asset( - Assets.fourSceneIcon, - fit: BoxFit.contain, - ), - ), - ), + device!.type == "SOS" + ? ClipOval( + child: SvgPicture.asset( + Assets.sosHomeIcon, + fit: BoxFit.contain, + height: 70, + ), + ) + : SizedBox( + height: 70, + child: SvgPicture.asset( + device!.type == "4S" + ? Assets.fourSceneIcon + : Assets.sixSceneIcon, + fit: BoxFit.contain, + ), + ), ], ), ), @@ -170,7 +164,7 @@ class FourSceneSettings extends StatelessWidget { onTap: () { Navigator.of(context).push( MaterialPageRoute( - builder: (context) => FourSceneInfoPage( + builder: (context) => SettingInfoPage( device: device!, )), ); @@ -210,7 +204,7 @@ class FourSceneSettings extends StatelessWidget { value: _bloc.enableAlarm, onChanged: (p0) { context - .read() + .read() .add(ToggleEnableAlarmEvent(p0)); }, isNotification: true, @@ -237,7 +231,7 @@ class FourSceneSettings extends StatelessWidget { Navigator.of(context).push( MaterialPageRoute( builder: (context) => - ShareFourScenePage(device: device!)), + ShareDevicePage(device: device!)), ); }, text: 'Share Device', @@ -266,7 +260,7 @@ class FourSceneSettings extends StatelessWidget { Navigator.of(context).push( MaterialPageRoute( builder: (context) => - FaqFourScenePage(device: device!)), + FaqSettingPage(device: device!)), ); }, text: 'Device FAQ', @@ -296,7 +290,7 @@ class FourSceneSettings extends StatelessWidget { Navigator.of(context).push( MaterialPageRoute( builder: (context) => - const FourSceneUpdatePage()), + const UpdatePageSetting()), ); }, text: 'Device Update', diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/share_four_scene_page.dart b/lib/features/devices/view/device_settings/share_device_page.dart similarity index 97% rename from lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/share_four_scene_page.dart rename to lib/features/devices/view/device_settings/share_device_page.dart index e96ec77..0064f99 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/share_four_scene_page.dart +++ b/lib/features/devices/view/device_settings/share_device_page.dart @@ -14,9 +14,9 @@ import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dar import 'package:syncrow_app/utils/helpers/custom_page_route.dart'; import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; -class ShareFourScenePage extends StatelessWidget { +class ShareDevicePage extends StatelessWidget { final DeviceModel? device; - const ShareFourScenePage({super.key, this.device}); + const ShareDevicePage({super.key, this.device}); @override Widget build(BuildContext context) { var spaces = HomeCubit.getInstance().spaces; diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_update_dialog.dart b/lib/features/devices/view/device_settings/update_dialog.dart similarity index 100% rename from lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_update_dialog.dart rename to lib/features/devices/view/device_settings/update_dialog.dart diff --git a/lib/features/devices/view/widgets/sos/sos_setting/sos_update_note.dart b/lib/features/devices/view/device_settings/update_note.dart similarity index 98% rename from lib/features/devices/view/widgets/sos/sos_setting/sos_update_note.dart rename to lib/features/devices/view/device_settings/update_note.dart index 03e5f85..04f5c3e 100644 --- a/lib/features/devices/view/widgets/sos/sos_setting/sos_update_note.dart +++ b/lib/features/devices/view/device_settings/update_note.dart @@ -2,11 +2,11 @@ import 'package:flutter/material.dart'; import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart'; import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; -class SosUpdateNote extends StatelessWidget { +class UpDateNoteSetting extends StatelessWidget { final Function()? cancelTab; final Function()? confirmTab; - const SosUpdateNote({ + const UpDateNoteSetting({ super.key, required this.cancelTab, required this.confirmTab, diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_update_page.dart b/lib/features/devices/view/device_settings/update_page.dart similarity index 98% rename from lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_update_page.dart rename to lib/features/devices/view/device_settings/update_page.dart index 81f6a03..f77e913 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_update_page.dart +++ b/lib/features/devices/view/device_settings/update_page.dart @@ -6,7 +6,7 @@ import 'package:percent_indicator/linear_percent_indicator.dart'; import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart'; import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_event.dart'; import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_state.dart'; -import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_update_note.dart'; +import 'package:syncrow_app/features/devices/view/device_settings/update_note.dart'; import 'package:syncrow_app/features/shared_widgets/default_button.dart'; import 'package:syncrow_app/features/shared_widgets/default_container.dart'; import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart'; @@ -14,8 +14,8 @@ import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dar import 'package:syncrow_app/generated/assets.dart'; import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; -class FourSceneUpdatePage extends StatelessWidget { - const FourSceneUpdatePage({super.key}); +class UpdatePageSetting extends StatelessWidget { + const UpdatePageSetting({super.key}); @override Widget build(BuildContext context) { @@ -236,7 +236,7 @@ class NewUpdateContainer extends StatelessWidget { showDialog( context: context, builder: (context) { - return UpDateNote( + return UpDateNoteSetting( cancelTab: () { Navigator.of(context).pop(); }, diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/faq_six_scene_page.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/faq_six_scene_page.dart deleted file mode 100644 index 5870ecf..0000000 --- a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/faq_six_scene_page.dart +++ /dev/null @@ -1,158 +0,0 @@ -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/6_scene_switch_bloc/6_scene_bloc.dart'; -import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart'; -import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart'; -import 'package:syncrow_app/features/devices/model/device_model.dart'; -import 'package:syncrow_app/features/devices/model/six_scene_question_model.dart'; -import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/6_scene_setting/question_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_medium.dart'; -import 'package:syncrow_app/generated/assets.dart'; -import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; - -class FaqSixScenePage extends StatelessWidget { - final DeviceModel? device; - - const FaqSixScenePage({super.key, this.device}); - - @override - Widget build(BuildContext context) { - TextEditingController _searchController = TextEditingController(); - return DefaultScaffold( - title: 'FAQ', - child: BlocProvider( - create: (context) => SixSceneBloc(sixSceneId: device?.uuid ?? '') - ..add(const SixSceneInitialQuestion()), - child: BlocBuilder( - builder: (context, state) { - final sensor = BlocProvider.of(context); - - List displayedQuestions = []; - if (state is FaqSearchState) { - displayedQuestions = state.filteredFaqQuestions; - } else if (state is FaqLoadedState) { - displayedQuestions = state.filteredFaqQuestions; - } - return state is SixSceneLoadingState - ? const Center( - child: DefaultContainer( - width: 50, - height: 50, - child: CircularProgressIndicator()), - ) - : RefreshIndicator( - onRefresh: () async { - // sensor.add(const SosInitial()); - }, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - DefaultContainer( - padding: const EdgeInsets.all(5), - child: TextFormField( - controller: _searchController, - onChanged: (value) { - sensor.add(SearchFaqEvent(value)); - }, - decoration: InputDecoration( - hintText: 'Enter your questions', - hintStyle: const TextStyle( - color: ColorsManager.textGray, - fontSize: 16, - fontWeight: FontWeight.w400), - suffixIcon: Container( - padding: const EdgeInsets.all(5.0), - margin: const EdgeInsets.all(10.0), - child: SvgPicture.asset( - Assets.searchIcon, - fit: BoxFit.contain, - ), - ), - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(8.0), - ), - ), - ), - ), - SizedBox( - height: MediaQuery.of(context).size.height * 0.04, - ), - BodyMedium( - text: _searchController.text.isEmpty - ? 'Device Related FAQs' - : '${displayedQuestions.length} Help Topics', - fontWeight: FontWeight.w700, - fontSize: 12, - fontColor: ColorsManager.grayColor, - ), - const SizedBox( - height: 8, - ), - displayedQuestions.isEmpty - ? const SizedBox() - : DefaultContainer( - child: ListView.builder( - shrinkWrap: true, - itemCount: displayedQuestions.length, - itemBuilder: (context, index) { - final faq = displayedQuestions[index]; - return InkWell( - onTap: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => QuestionPage( - questionModel: faq, - )), - ); - }, - child: SizedBox( - child: Column( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: - MainAxisAlignment.start, - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.all(8.0), - child: Row( - children: [ - Expanded( - child: BodyMedium( - fontSize: 14, - fontWeight: FontWeight.w400, - text: faq.question, - ), - ), - const Icon( - Icons.keyboard_arrow_right, - color: ColorsManager.textGray, - ), - ], - ), - ), - if (index != - displayedQuestions.length - - 1) // Exclude divider for the last item - const Divider( - color: ColorsManager.dividerColor, - ), - ], - ), - ), - ); - }, - )), - ], - ), - ); - }, - ), - ), - ); - } -} diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/location_setting.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/location_setting.dart deleted file mode 100644 index 2890ea2..0000000 --- a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/location_setting.dart +++ /dev/null @@ -1,226 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:syncrow_app/features/app_layout/model/space_model.dart'; -import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart'; -import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart'; -import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart'; -import 'package:syncrow_app/features/devices/model/four_scene_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/features/shared_widgets/text_widgets/body_medium.dart'; -import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; - -class LocationSixScenePage extends StatelessWidget { - final SpaceModel? space; - final String? deviceId; - - const LocationSixScenePage({ - super.key, - this.space, - this.deviceId, - }); - - @override - Widget build(BuildContext context) { - String roomIdSelected = ''; - - return Scaffold( - body: BlocProvider( - create: (context) => SixSceneBloc(sixSceneId: deviceId ?? '') - ..add(const SixSceneInitial()) - ..add(const SixSceneInitialInfo()) - ..add(FetchRoomsEvent(unit: space!)), - child: BlocBuilder( - builder: (context, state) { - final _bloc = BlocProvider.of(context); - FourSceneModelState model = FourSceneModelState( - scene_1: '', - scene_2: '', - scene_3: '', - scene_4: '', - scene_id_group_id: '', - switch_backlight: ''); - if (state is SaveSelectionSuccessState) { - new Future.delayed(const Duration(microseconds: 500), () { - _bloc.add(SixSceneInitialInfo()); - Navigator.of(context).pop(true); - }); - } - return state is SixSceneLoadingState - ? const Center( - child: DefaultContainer( - width: 50, - height: 50, - child: CircularProgressIndicator(), - ), - ) - : DefaultScaffold( - actions: [ - BlocBuilder( - builder: (context, state) { - final bool canSave = state is OptionSelectedState && - state.hasSelectionChanged; - return InkWell( - onTap: canSave - ? () { - context.read().add( - AssignRoomEvent( - context: context, - roomId: roomIdSelected, - unit: space!)); - } - : null, - child: BodyMedium( - text: 'Save', - fontWeight: FontWeight.w700, - fontSize: 16, - fontColor: canSave - ? ColorsManager.slidingBlueColor - : ColorsManager.primaryTextColor, - ), - ); - }, - ), - const SizedBox(width: 20), - ], - child: RefreshIndicator( - onRefresh: () async { - // sensor.add(const SosInitial()); - }, - child: ListView( - shrinkWrap: true, - padding: const EdgeInsets.symmetric(vertical: 20), - children: [ - const BodyMedium( - text: 'Smart Device Location', - fontWeight: FontWeight.w700, - fontSize: 12, - fontColor: ColorsManager.grayColor, - ), - const SizedBox(height: 5), - DefaultContainer( - padding: const EdgeInsets.all(20), - child: ListView.builder( - physics: const NeverScrollableScrollPhysics(), - shrinkWrap: true, - itemCount: _bloc.roomsList.length, - itemBuilder: (context, index) { - final fromRoom = _bloc.roomsList[index]; - final isSelected = (state - is OptionSelectedState && - state.selectedOption == fromRoom.id) || - (state is! OptionSelectedState && - fromRoom.id == - _bloc.deviceInfo.subspace.uuid); - - return Column( - children: [ - _buildCheckboxOption( - label: fromRoom.name!, - isSelected: isSelected, - onTap: (label) { - context.read().add( - SelectOptionEvent( - selectedOption: fromRoom.id!, - ), - ); - roomIdSelected = fromRoom.id!; - }, - ), - if (index < _bloc.roomsList.length - 1) ...[ - const SizedBox(height: 10), - const Divider( - color: ColorsManager.dividerColor, - ), - const SizedBox(height: 10), - ], - ], - ); - }, - ), - ), - ], - ), - ), - ); - }, - ), - ), - ); - } -} - -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, - ), - ); - } -} - -Widget _buildCheckboxOption({ - required String label, - required bool isSelected, - required 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: isSelected, - onChanged: (bool? value) { - if (value == true) { - onTap(label); - } - }, - ), - ], - ), - ); -} - - -//LocationSixScenePage \ No newline at end of file diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/question_page.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/question_page.dart deleted file mode 100644 index c5b1ce9..0000000 --- a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/question_page.dart +++ /dev/null @@ -1,161 +0,0 @@ -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/6_scene_switch_bloc/6_scene_bloc.dart'; -import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart'; -import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart'; -import 'package:syncrow_app/features/devices/model/six_scene_question_model.dart'; -import 'package:syncrow_app/features/devices/model/six_scene_model.dart'; -import 'package:syncrow_app/features/shared_widgets/default_button.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/generated/assets.dart'; -import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; - -class QuestionPage extends StatelessWidget { - final SixSceneQuestionModel? questionModel; - - const QuestionPage({super.key, this.questionModel}); - - @override - Widget build(BuildContext context) { - return DefaultScaffold( - title: 'FAQ', - child: BlocProvider( - create: (context) => - SixSceneBloc(sixSceneId: '')..add(const SixSceneInitial()), - child: BlocBuilder( - builder: (context, state) { - final sensor = BlocProvider.of(context); - SixSceneModel model = SixSceneModel( - scene_1: '', - scene_2: '', - scene_3: '', - scene_4: '', - scene_5: '', - scene_6: '', - scene_id_group_id: '', - switch_backlight: ''); - if (state is LoadingNewSate) { - model = state.device; - } else if (state is UpdateState) { - model = state.device; - } - return state is SixSceneLoadingState - ? const Center( - child: DefaultContainer( - width: 50, - height: 50, - child: CircularProgressIndicator()), - ) - : RefreshIndicator( - onRefresh: () async { - sensor.add(const SixSceneInitial()); - }, - child: Column( - children: [ - DefaultContainer( - padding: EdgeInsets.all(15), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - BodyLarge( - text: questionModel!.question, - fontSize: 22, - fontWeight: FontWeight.w400, - fontColor: ColorsManager.blackColor, - ), - SizedBox( - height: 15, - ), - BodyMedium( - text: questionModel!.answer, - fontSize: 14, - fontWeight: FontWeight.w400, - fontColor: ColorsManager.secondaryTextColor, - ), - ], - ), - ), - SizedBox( - height: MediaQuery.of(context).size.height * 0.15, - ), - Center( - child: SizedBox( - width: 180, - child: DefaultButton( - backgroundColor: sensor.isHelpful == true - ? ColorsManager.grayColor - : ColorsManager.grayButtonColors, - borderRadius: 50, - onPressed: () { - sensor - .add(ToggleHelpfulEvent(isHelpful: true)); - }, - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - SvgPicture.asset( - Assets.thumbUp, - fit: BoxFit.fill, - ), - const SizedBox( - width: 10, - ), - const BodyMedium( - text: 'Helpful', - fontSize: 12, - fontWeight: FontWeight.w400, - fontColor: ColorsManager.blackColor, - ), - ], - )), - ), - ), - const SizedBox( - height: 15, - ), - Center( - child: SizedBox( - width: 180, - child: DefaultButton( - backgroundColor: sensor.isHelpful == false - ? ColorsManager.grayColor - : ColorsManager.grayButtonColors, - borderRadius: 50, - onPressed: () { - sensor.add( - ToggleHelpfulEvent(isHelpful: false)); - }, - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - SvgPicture.asset( - Assets.thumbDown, - fit: BoxFit.fill, - ), - const SizedBox( - width: 10, - ), - const BodyMedium( - text: 'Not Helpful', - fontSize: 12, - fontWeight: FontWeight.w400, - fontColor: ColorsManager.blackColor, - ), - ], - )), - ), - ), - ], - )); - }, - ), - ), - ); - } -} diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/share_six_scene_page.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/share_six_scene_page.dart deleted file mode 100644 index b3695cc..0000000 --- a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/share_six_scene_page.dart +++ /dev/null @@ -1,121 +0,0 @@ -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/6_scene_switch_bloc/6_scene_bloc.dart'; -import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart'; -import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart'; - -import 'package:syncrow_app/features/devices/model/device_model.dart'; -import 'package:syncrow_app/features/devices/model/six_scene_model.dart'; -import 'package:syncrow_app/features/menu/view/widgets/manage_home/home_settings.dart'; -import 'package:syncrow_app/features/shared_widgets/default_button.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/helpers/custom_page_route.dart'; -import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; - -class ShareSixScenePage extends StatelessWidget { - final DeviceModel? device; - - const ShareSixScenePage({super.key, this.device}); - - @override - Widget build(BuildContext context) { - var spaces = HomeCubit.getInstance().spaces; - - return DefaultScaffold( - title: 'Share Device', - child: BlocProvider( - create: (context) => SixSceneBloc(sixSceneId: device?.uuid ?? '') - ..add(const SixSceneInitial()), - child: BlocBuilder( - builder: (context, state) { - final sensor = BlocProvider.of(context); - SixSceneModel model = SixSceneModel( - scene_1: '', - scene_2: '', - scene_3: '', - scene_4: '', - scene_5: '', - scene_6: '', - scene_id_group_id: '', - switch_backlight: ''); - if (state is LoadingNewSate) { - model = state.device; - } else if (state is UpdateState) { - model = state.device; - } - return state is LoadingNewSate - ? const Center( - child: DefaultContainer( - width: 50, - height: 50, - child: CircularProgressIndicator()), - ) - : RefreshIndicator( - onRefresh: () async { - sensor.add(const SixSceneInitial()); - }, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: MediaQuery.of(context).size.height * 0.05, - ), - const BodyLarge( - text: 'Sharing Method Not Supported', - fontSize: 15, - fontWeight: FontWeight.w400, - fontColor: ColorsManager.blackColor, - ), - const BodyMedium( - text: - 'Currently, you cannot use the specified method to share Bluetooth mesh devices Zigbee devices, infrared devices, Bluetooth Beacon Devices, and certain Bluetooth LE devices with other users.', - fontSize: 14, - fontWeight: FontWeight.w400, - fontColor: ColorsManager.secondaryTextColor, - ), - const SizedBox( - height: 10, - ), - const BodyLarge( - text: 'Recommended Sharing Method', - fontSize: 15, - fontWeight: FontWeight.w400, - fontColor: ColorsManager.blackColor, - ), - const BodyMedium( - text: - 'If the recipient is a home member or a reliable user, tap Me > Home Management > Add Member and add the recipient to your home. Then, devices in the home can be shared with the recipient in bulk.', - fontSize: 14, - fontWeight: FontWeight.w400, - fontColor: ColorsManager.secondaryTextColor, - ), - SizedBox( - height: MediaQuery.of(context).size.height * 0.15, - ), - Center( - child: SizedBox( - width: 250, - child: DefaultButton( - backgroundColor: ColorsManager.blueColor1, - borderRadius: 50, - onPressed: () { - Navigator.of(context).push(CustomPageRoute( - builder: (context) => HomeSettingsView( - space: spaces!.first, - ))); - }, - child: Text('Add Home Member')), - ), - ) - ], - )); - }, - ), - ), - ); - } -} diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_create_group.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_create_group.dart deleted file mode 100644 index 70dd76f..0000000 --- a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_create_group.dart +++ /dev/null @@ -1,215 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:flutter_svg/svg.dart'; -import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart'; -import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart'; -import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart'; -import 'package:syncrow_app/features/devices/model/device_model.dart'; -import 'package:syncrow_app/features/devices/model/six_scene_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/features/shared_widgets/text_widgets/body_large.dart'; -import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart'; -import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart'; -import 'package:syncrow_app/generated/assets.dart'; -import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; - -class SixSceneCreateGroup extends StatelessWidget { - final DeviceModel? device; - - const SixSceneCreateGroup({super.key, this.device}); - - @override - Widget build(BuildContext context) { - return DefaultScaffold( - title: 'Create Group', - child: BlocProvider( - create: (context) => SixSceneBloc(sixSceneId: device?.uuid ?? '') - ..add(const SixSceneInitial()), - child: BlocBuilder( - builder: (context, state) { - final sensor = BlocProvider.of(context); - SixSceneModel model = SixSceneModel( - scene_1: '', - scene_2: '', - scene_3: '', - scene_4: '', - scene_5: '', - scene_6: '', - scene_id_group_id: '', - switch_backlight: ''); - if (state is LoadingNewSate) { - model = state.device; - } else if (state is UpdateState) { - model = state.device; - } - return state is LoadingNewSate - ? const Center( - child: DefaultContainer( - width: 50, - height: 50, - child: CircularProgressIndicator()), - ) - : Padding( - padding: EdgeInsets.all(8.0), - child: Column( - children: [ - const Padding( - padding: EdgeInsets.only(left: 25, right: 25), - child: BodySmall( - text: - 'Devices in the same group can be controlled together', - fontColor: ColorsManager.primaryTextColor, - textAlign: TextAlign.center, - ), - ), - Flexible( - child: ListView.builder( - itemCount: sensor.groupDevices.length, - itemBuilder: (context, index) { - return InkWell( - onTap: () { - BlocProvider.of(context).add( - RemoveDeviceFromGroup( - sensor.groupDevices[index], - Assets.addDevicesIcon)); - }, - child: DefaultContainer( - child: Padding( - padding: const EdgeInsets.all(5.0), - child: Row( - crossAxisAlignment: - CrossAxisAlignment.start, - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Row( - children: [ - SvgPicture.asset( - sensor.groupDevices[index].icon!, - fit: BoxFit.contain, - ), - const SizedBox( - width: 15, - ), - BodyMedium( - text: sensor - .groupDevices[index].name!, - fontColor: - ColorsManager.primaryTextColor, - textAlign: TextAlign.center, - fontSize: 15, - ), - ], - ), - BodyMedium( - text: sensor.groupDevices[index].dec!, - fontColor: ColorsManager.grayColor, - textAlign: TextAlign.center, - fontSize: 15, - ), - ], - ), - )), - ); - }, - ), - ), - Flexible( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const BodyLarge( - text: 'Devices to be added', - fontColor: ColorsManager.grayColor, - textAlign: TextAlign.center, - fontSize: 12, - fontWeight: FontWeight.w700, - ), - const SizedBox( - height: 5, - ), - sensor.devices.isNotEmpty - ? Expanded( - child: ListView.builder( - itemCount: sensor.devices.length, - itemBuilder: (context, index) { - final device = sensor.devices[index]; - return GestureDetector( - onTap: () { - BlocProvider.of( - context) - .add(AddDeviceToGroup(device, - Assets.minusIcon)); - }, - child: DefaultContainer( - child: Padding( - padding: - const EdgeInsets.all(5.0), - child: Row( - crossAxisAlignment: - CrossAxisAlignment.start, - mainAxisAlignment: - MainAxisAlignment - .spaceBetween, - children: [ - Row( - children: [ - SvgPicture.asset( - device.icon!, - fit: BoxFit.contain, - ), - const SizedBox( - width: 15, - ), - BodyMedium( - text: device.name!, - fontColor: ColorsManager - .primaryTextColor, - textAlign: - TextAlign.center, - fontSize: 15, - ), - ], - ), - BodyMedium( - text: device.dec!, - fontColor: ColorsManager - .grayColor, - textAlign: - TextAlign.center, - fontSize: 15, - ), - ], - ), - ), - ), - ); - }, - ), - ) - : const Column( - children: [ - BodySmall( - text: - 'Currently no devices available to create group', - fontColor: ColorsManager.grayColor, - textAlign: TextAlign.center, - fontSize: 12, - fontWeight: FontWeight.w400, - ), - ], - ), - ], - ), - ), - Spacer() - ], - ), - ); - }, - ), - ), - ); - } -} diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_delete_dialog.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_delete_dialog.dart deleted file mode 100644 index e69de29..0000000 diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_info_page.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_info_page.dart deleted file mode 100644 index a031651..0000000 --- a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_info_page.dart +++ /dev/null @@ -1,156 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart'; -import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart'; -import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart'; -import 'package:syncrow_app/features/devices/model/device_model.dart'; -import 'package:syncrow_app/features/devices/model/six_scene_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/features/shared_widgets/text_widgets/body_large.dart'; -import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart'; -import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart'; -import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; - -class SixSceneInfoPage extends StatelessWidget { - final DeviceModel? device; - - const SixSceneInfoPage({super.key, this.device}); - - @override - Widget build(BuildContext context) { - return DefaultScaffold( - title: 'Device Information', - child: BlocProvider( - create: (context) => SixSceneBloc(sixSceneId: device?.uuid ?? '') - ..add(const SixSceneInitial()) - ..add(const SixSceneInitialInfo()), - child: BlocBuilder( - builder: (context, state) { - final _bloc = BlocProvider.of(context); - SixSceneModel model = SixSceneModel( - scene_1: '', - scene_2: '', - scene_3: '', - scene_4: '', - scene_5: '', - scene_6: '', - scene_id_group_id: '', - switch_backlight: ''); - if (state is LoadingNewSate) { - model = state.device; - } else if (state is UpdateState) { - model = state.device; - } - return state is SixSceneLoadingState - ? const Center( - child: DefaultContainer( - width: 50, - height: 50, - child: CircularProgressIndicator()), - ) - : RefreshIndicator( - onRefresh: () async { - _bloc.add(const SixSceneInitial()); - }, - child: DefaultContainer( - child: Padding( - padding: const EdgeInsets.only(left: 5, right: 5), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - const BodyLarge( - text: 'Virtual ID', - fontSize: 15, - fontWeight: FontWeight.w400, - fontColor: ColorsManager.blackColor, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - SizedBox( - width: - MediaQuery.of(context).size.width * 0.61, - child: BodySmall( - text: _bloc.deviceInfo.productUuid, - fontColor: ColorsManager.primaryTextColor, - ), - ), - InkWell( - onTap: () { - Clipboard.setData( - ClipboardData( - text: _bloc.deviceInfo.productUuid, - ), - ); - - ScaffoldMessenger.of(context).showSnackBar( - const SnackBar( - content: Text("Copied to Clipboard"), - ), - ); - }, - child: const Row( - children: [ - Icon( - Icons.copy, - color: ColorsManager.blueColor, - ), - BodyMedium( - text: 'Copy', - fontColor: ColorsManager.blueColor, - ), - ], - ), - ) - ], - ), - const Divider( - color: ColorsManager.dividerColor, - ), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - const BodyLarge( - text: 'MAC', - fontSize: 15, - fontWeight: FontWeight.w400, - fontColor: ColorsManager.blackColor, - ), - BodySmall( - text: _bloc.deviceInfo.macAddress, - fontColor: ColorsManager.primaryTextColor, - ), - ], - ), - const Divider( - color: ColorsManager.dividerColor, - ), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - const BodyLarge( - text: 'Time Zone', - fontSize: 15, - fontWeight: FontWeight.w400, - fontColor: ColorsManager.blackColor, - ), - BodySmall( - text: _bloc.deviceInfo.timeZone, - fontColor: ColorsManager.primaryTextColor, - ), - ], - ), - ]), - ))); - }, - ), - ), - ); - } -} diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_profile_page.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_profile_page.dart deleted file mode 100644 index e7c8738..0000000 --- a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_profile_page.dart +++ /dev/null @@ -1,189 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:flutter_svg/flutter_svg.dart'; -import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart'; -import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart'; -import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart'; -import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart'; -import 'package:syncrow_app/features/devices/model/device_model.dart'; -import 'package:syncrow_app/features/devices/model/six_scene_model.dart'; -import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_scene_setting/location_setting_four_scene.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_medium.dart'; -import 'package:syncrow_app/generated/assets.dart'; -import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; - -class SixSceneProfilePage extends StatelessWidget { - final DeviceModel? device; - - const SixSceneProfilePage({super.key, this.device}); - - @override - Widget build(BuildContext context) { - var spaces = HomeCubit.getInstance().spaces; - - return DefaultScaffold( - title: 'Device Settings', - leading: IconButton( - onPressed: () { - Navigator.of(context).pop(true); - }, - icon: const Icon(Icons.arrow_back_ios)), - child: BlocProvider( - create: (context) => SixSceneBloc(sixSceneId: device?.uuid ?? '') - ..add(const SixSceneInitial()) - ..add(const SixSceneInitialInfo()), - child: BlocBuilder( - builder: (context, state) { - final _bloc = BlocProvider.of(context); - SixSceneModel model = SixSceneModel( - scene_1: '', - scene_2: '', - scene_3: '', - scene_4: '', - scene_5: '', - scene_6: '', - scene_id_group_id: '', - switch_backlight: ''); - if (state is LoadingNewSate) { - model = state.device; - } else if (state is UpdateState) { - model = state.device; - } - return state is SixSceneLoadingState - ? const Center( - child: DefaultContainer( - width: 50, - height: 50, - child: CircularProgressIndicator()), - ) - : RefreshIndicator( - onRefresh: () async { - _bloc.add(const SixSceneInitial()); - }, - child: ListView( - children: [ - CircleAvatar( - radius: 60, - backgroundColor: Colors.white, - child: CircleAvatar( - radius: 55, - backgroundColor: ColorsManager.graysColor, - child: ClipOval( - child: Center( - child: SvgPicture.asset( - Assets.sixSceneIcon, - fit: BoxFit.cover, - ), - ), - ), - ), - ), - const SizedBox( - height: 10, - ), - SizedBox( - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - IntrinsicWidth( - child: ConstrainedBox( - constraints: - const BoxConstraints(maxWidth: 200), - child: TextFormField( - maxLength: 30, - style: const TextStyle( - color: Colors.black, - ), - textAlign: TextAlign.center, - focusNode: _bloc.focusNode, - controller: _bloc.nameController, - enabled: _bloc.editName, - onEditingComplete: () { - _bloc.add(const SaveNameEvent()); - }, - decoration: const InputDecoration( - hintText: "Your Name", - border: InputBorder.none, - fillColor: Colors.white10, - counterText: '', - ), - ), - ), - ), - const SizedBox(width: 5), - InkWell( - onTap: () { - _bloc.add(const ChangeNameEvent(value: true)); - }, - child: const Padding( - padding: EdgeInsets.symmetric(horizontal: 10), - child: Icon( - Icons.edit_outlined, - size: 20, - color: ColorsManager.textPrimaryColor, - ), - ), - ), - ], - ), - ), - const SizedBox(height: 20), - const BodyMedium( - text: 'Smart Device Information', - fontWeight: FontWeight.w700, - fontSize: 12, - fontColor: ColorsManager.grayColor, - ), - DefaultContainer( - padding: const EdgeInsets.all(20), - child: InkWell( - onTap: () async { - bool val = await Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => LocationFourScenePage( - space: spaces!.first, - deviceId: device?.uuid ?? '', - )), - ); - if (val == true) { - _bloc.add(const SixSceneInitialInfo()); - } - }, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - const SizedBox( - child: Text('Location'), - ), - Row( - children: [ - SizedBox( - child: BodyMedium( - text: _bloc - .deviceInfo.subspace.subspaceName, - fontColor: ColorsManager.textGray, - ), - ), - const Icon( - Icons.arrow_forward_ios, - size: 15, - color: ColorsManager.textGray, - ), - ], - ) - ], - ), - ), - ) - ], - ), - ); - }, - ), - ), - ); - } -} diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_settings.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_settings.dart deleted file mode 100644 index 5b90a37..0000000 --- a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_settings.dart +++ /dev/null @@ -1,413 +0,0 @@ -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/6_scene_switch_bloc/6_scene_bloc.dart'; -import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart'; -import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart'; -import 'package:syncrow_app/features/devices/model/device_model.dart'; -import 'package:syncrow_app/features/devices/model/six_scene_model.dart'; -import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/6_scene_setting/faq_six_scene_page.dart'; -import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/6_scene_setting/share_six_scene_page.dart'; -import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_info_page.dart'; -import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_profile_page.dart'; -import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_update_dialog.dart'; -import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_update_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/delete_device_dialogs.dart'; -import 'package:syncrow_app/features/shared_widgets/setting_widget.dart'; -import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart'; -import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart'; -import 'package:syncrow_app/generated/assets.dart'; -import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; - -class SixSceneSettings extends StatelessWidget { - final DeviceModel? device; - - const SixSceneSettings({super.key, this.device}); - - @override - Widget build(BuildContext context) { - return DefaultScaffold( - title: 'Device Settings', - child: BlocProvider( - create: (context) => SixSceneBloc(sixSceneId: device?.uuid ?? '') - ..add(const SixSceneInitial()) - ..add(const SixSceneInitial()) - ..add(const SixSceneInitialInfo()), - child: BlocBuilder( - builder: (context, state) { - final _bloc = BlocProvider.of(context); - SixSceneModel model = SixSceneModel( - scene_1: '', - scene_2: '', - scene_3: '', - scene_4: '', - scene_5: '', - scene_6: '', - scene_id_group_id: '', - switch_backlight: ''); - if (state is LoadingNewSate) { - model = state.device; - } else if (state is UpdateState) { - model = state.device; - } - return state is SixSceneLoadingState - ? const Center( - child: DefaultContainer( - width: 50, - height: 50, - child: CircularProgressIndicator()), - ) - : ListView( - children: [ - Padding( - padding: const EdgeInsets.symmetric( - vertical: 10, - ), - child: InkWell( - onTap: () async { - bool val = await Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => SixSceneProfilePage( - device: device, - ), - ), - ); - if (val == true) { - _bloc.add(const SixSceneInitialInfo()); - } - }, - child: Stack( - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - const SizedBox(height: 20), - DefaultContainer( - borderRadius: const BorderRadius.all( - Radius.circular(30)), - child: Padding( - padding: const EdgeInsets.all(10.0), - child: Padding( - padding: - const EdgeInsets.only(left: 90), - child: Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - BodyMedium( - text: _bloc.deviceInfo.name, - fontWeight: FontWeight.bold, - ), - const SizedBox( - height: 5, - ), - BodySmall( - text: _bloc.deviceInfo - .subspace.subspaceName), - ], - ), - const Icon(Icons.edit_sharp) - ], - ), - ), - ), - ), - ], - ), - Positioned( - top: 0, - left: 20, - child: CircleAvatar( - radius: 43, - backgroundColor: Colors.white, - child: CircleAvatar( - radius: 40, - backgroundColor: Colors.white, - child: CircleAvatar( - radius: 40, - backgroundColor: - ColorsManager.backgroundColor, - child: SvgPicture.asset( - Assets.sixSceneIcon, - fit: BoxFit.fill, - ), - ), - )), - ), - ], - ), - ), - ), - const SizedBox(height: 20), - const BodyMedium( - text: 'Device Management', - fontWeight: FontWeight.w700, - fontSize: 12, - fontColor: ColorsManager.grayColor, - ), - DefaultContainer( - child: Column( - children: [ - SettingWidget( - onTap: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => SixSceneInfoPage( - device: device, - )), - ); - }, - text: 'Device Information', - icon: Assets.infoIcon, - ), - // const Divider( - // color: ColorsManager.dividerColor, - // ), - // SettingWidget( - // onTap: () { - // Navigator.of(context).push( - // MaterialPageRoute( - // builder: (context) => - // ShareSixScenePage(device: device!)), - // ); - // }, - // text: 'Tap-to Run and Automation', - // icon: Assets.tapRunIcon, - // ), - ], - ), - ), - const SizedBox(height: 20), - const BodyMedium( - text: 'Device Offline Notification', - fontWeight: FontWeight.w700, - fontSize: 12, - fontColor: ColorsManager.grayColor, - ), - DefaultContainer( - child: Column( - children: [ - SettingWidget( - value: _bloc.enableAlarm, - onChanged: (p0) { - context - .read() - .add(ToggleEnableAlarmEvent(p0)); - }, - isNotification: true, - onTap: () {}, - text: 'Offline Notification', - icon: Assets.notificationIcon, - ), - ], - ), - ), - const SizedBox(height: 20), - const BodyMedium( - text: 'Others', - fontWeight: FontWeight.w700, - fontSize: 12, - fontColor: ColorsManager.grayColor, - ), - const SizedBox(height: 5), - DefaultContainer( - child: Column( - children: [ - SettingWidget( - onTap: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => - ShareSixScenePage(device: device!)), - ); - }, - text: 'Share Device', - icon: Assets.shareIcon, - ), - // const Divider( - // color: ColorsManager.dividerColor, - // ), - // SettingWidget( - // onTap: () { - // Navigator.of(context).push( - // MaterialPageRoute( - // builder: (context) => - // SixSceneCreateGroup(device: device!)), - // ); - // }, - // text: 'Create Group', - // icon: Assets.createGroupIcon, - // ), - const Divider( - color: ColorsManager.dividerColor, - ), - SettingWidget( - onTap: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => - FaqSixScenePage(device: device!)), - ); - }, - text: 'Device FAQ', - icon: Assets.faqIcon, - ), - const Divider( - color: ColorsManager.dividerColor, - ), - SettingWidget( - onTapUpdate: () { - showDialog( - context: context, - builder: (context) { - return UpdateInfoDialog( - cancelTab: () { - Navigator.of(context).pop(); - }, - confirmTab: () { - Navigator.of(context).pop(); - }, - ); - }, - ); - }, - isUpdate: true, - onTap: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => - const SixSceneUpdatePage()), - ); - }, - text: 'Device Update', - icon: Assets.updateIcon, - ), - ], - ), - ), - const SizedBox(height: 20), - InkWell( - onTap: () { - showModalBottomSheet( - context: context, - builder: (BuildContext context) { - return Container( - height: 200, - padding: const EdgeInsets.all(16.0), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - const BodyMedium( - text: 'Remove Device', - fontWeight: FontWeight.w700, - fontSize: 16, - fontColor: ColorsManager.red, - ), - const SizedBox(height: 10), - const SizedBox( - width: 250, - child: Divider( - color: ColorsManager.dividerColor, - ), - ), - const SizedBox(height: 10), - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - InkWell( - onTap: () { - showDialog( - context: context, - builder: (context) { - return DisconnectDeviceDialog( - cancelTab: () { - Navigator.of(context).pop(); - }, - confirmTab: () { - Navigator.of(context).pop(); - }, - ); - }, - ); - }, - child: const BodyMedium( - text: 'Disconnect Device', - fontWeight: FontWeight.w400, - fontSize: 15, - fontColor: - ColorsManager.textPrimaryColor, - ), - ), - const Icon( - Icons.keyboard_arrow_right, - color: ColorsManager.textGray, - ) - ], - ), - const SizedBox(height: 20), - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - InkWell( - onTap: () { - showDialog( - context: context, - builder: (context) { - return DisconnectWipeData( - cancelTab: () { - Navigator.of(context).pop(); - }, - confirmTab: () { - _bloc.add( - DeleteDeviceEvent()); - }, - ); - }, - ); - }, - child: const BodyMedium( - text: - 'Disconnect Device and Wipe Data', - fontWeight: FontWeight.w400, - fontSize: 15, - fontColor: - ColorsManager.textPrimaryColor, - ), - ), - const Icon( - Icons.keyboard_arrow_right, - color: ColorsManager.textGray, - ) - ], - ), - ], - ), - ); - }, - ); - }, - child: const Center( - child: BodyMedium( - text: 'Remove Device', - fontWeight: FontWeight.w400, - fontSize: 15, - fontColor: ColorsManager.red, - ), - ), - ), - ], - ); - }, - ), - ), - ); - } -} diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_update_note.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_update_note.dart deleted file mode 100644 index 3023d3e..0000000 --- a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_update_note.dart +++ /dev/null @@ -1,118 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart'; -import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; - -class upDateNote extends StatelessWidget { - final Function()? cancelTab; - final Function()? confirmTab; - - const upDateNote({ - super.key, - required this.cancelTab, - required this.confirmTab, - }); - - @override - Widget build(BuildContext context) { - return AlertDialog( - contentPadding: EdgeInsets.zero, - content: Column( - mainAxisSize: MainAxisSize.min, - children: [ - const SizedBox( - height: 10, - ), - BodyLarge( - text: 'Update Note', - fontWeight: FontWeight.w700, - fontColor: ColorsManager.switchButton.withOpacity(0.6), - fontSize: 16, - ), - const Padding( - padding: EdgeInsets.only(left: 15, right: 15), - child: Divider( - color: ColorsManager.textGray, - ), - ), - const Padding( - padding: EdgeInsets.only(left: 15, right: 20, top: 15, bottom: 20), - child: Column( - children: [ - Center( - child: Text( - 'This update may take a long time. Make sure that the device is fully charged. The device will be unavailable during the update.', - textAlign: TextAlign.center, - )), - ], - ), - ), - 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: cancelTab, - child: const Padding( - padding: const EdgeInsets.only(top: 15, bottom: 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: confirmTab, - child: Padding( - padding: const EdgeInsets.only(top: 15, bottom: 15), - child: Center( - child: Text( - 'Start Update', - style: TextStyle( - color: - ColorsManager.switchButton.withOpacity(0.6), - fontSize: 14, - fontWeight: FontWeight.w400), - ), - ), - )), - )) - ], - ) - ], - ), - ); - } -} diff --git a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_update_page.dart b/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_update_page.dart deleted file mode 100644 index 3a1c011..0000000 --- a/lib/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_update_page.dart +++ /dev/null @@ -1,352 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:flutter_svg/flutter_svg.dart'; -import 'package:percent_indicator/linear_percent_indicator.dart'; -import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart'; -import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart'; -import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart'; -import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_update_note.dart'; -import 'package:syncrow_app/features/shared_widgets/default_button.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_medium.dart'; -import 'package:syncrow_app/generated/assets.dart'; -import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; - -class SixSceneUpdatePage extends StatelessWidget { - const SixSceneUpdatePage({super.key}); - - @override - Widget build(BuildContext context) { - return DefaultScaffold( - title: 'Device Update', - child: BlocProvider( - create: (context) => - SixSceneBloc(sixSceneId: '')..add(const SixSceneInitial()), - child: BlocBuilder( - builder: (context, state) { - final _bloc = BlocProvider.of(context); - - return state is SixSceneLoadingState - ? const Center( - child: DefaultContainer( - width: 50, - height: 50, - child: CircularProgressIndicator()), - ) - : RefreshIndicator( - onRefresh: () async {}, - child: Column( - children: [ - // SizedBox( - // height: MediaQuery.of(context).size.height * 0.15, - // ), - DefaultContainer( - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 50, - child: ListTile( - contentPadding: EdgeInsets.zero, - leading: SizedBox( - width: 200, - child: Row( - children: [ - Container( - padding: const EdgeInsets.all(10), - decoration: const BoxDecoration( - color: ColorsManager - .primaryColor, - borderRadius: - BorderRadius.all( - Radius.circular(50))), - child: SvgPicture.asset( - Assets.checkUpdateIcon, - fit: BoxFit.fill, - height: 25, - ), - ), - const SizedBox( - width: 10, - ), - InkWell( - onTap: () {}, - child: const BodyMedium( - text: 'Automatic Update', - fontWeight: FontWeight.normal, - ), - ), - ], - ), - ), - trailing: Container( - width: 100, - child: Row( - mainAxisAlignment: - MainAxisAlignment.end, - children: [ - BodyMedium( - text: _bloc.enableUpdate - ? 'true' - : 'Off', - fontColor: ColorsManager.textGray, - ), - Transform.scale( - scale: .8, - child: CupertinoSwitch( - value: _bloc.enableUpdate, - onChanged: (value) { - _bloc.add(ToggleUpdateEvent( - isUpdateEnabled: value)); - }, - applyTheme: true, - ), - ), - ], - ), - )), - ), - ], - ), - ), - const SizedBox( - height: 10, - ), - const UpdateSosContainerWithProgressBar( - sosDescription: - 'Connectivity Issue Resolved Fixed a bug that caused the SOS button to disconnect from the app intermittently.', - sosVersion: 'SOS v2.0.5', - ), - // const UpdatedContainer( - // sosVersion: 'SOS v1.0.13', - // sosDescription: 'SOS is up to date', - // ), - - // const NewUpdateContainer( - // sosVersion: 'SOS v2.0.5', - // sosDescription: - // 'Connectivity Issue Resolved Fixed a bug that caused the SOS button to disconnect from the app intermittently.', - // ), - const SizedBox( - height: 15, - ), - ], - )); - }, - ), - )); - } -} - -class UpdatedContainer extends StatelessWidget { - final String? sosVersion; - final String? sosDescription; - const UpdatedContainer({ - this.sosVersion, - this.sosDescription, - super.key, - }); - - @override - Widget build(BuildContext context) { - return DefaultContainer( - height: MediaQuery.of(context).size.height * 0.35, - child: Padding( - padding: const EdgeInsets.all(25), - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - SvgPicture.asset( - Assets.emptyUpdateIcon, - fit: BoxFit.fill, - ), - BodyMedium( - text: sosVersion!, - fontColor: ColorsManager.primaryTextColor, - ), - BodyMedium( - text: sosDescription!, - fontColor: ColorsManager.blackColor, - ), - ], - ), - ], - ), - ), - ); - } -} - -class NewUpdateContainer extends StatelessWidget { - final String? sosVersion; - final String? sosDescription; - const NewUpdateContainer({ - this.sosVersion, - this.sosDescription, - super.key, - }); - - @override - Widget build(BuildContext context) { - return DefaultContainer( - height: MediaQuery.of(context).size.height * 0.50, - child: Padding( - padding: const EdgeInsets.all(25), - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - SvgPicture.asset( - Assets.emptyUpdateIcon, - fit: BoxFit.fill, - ), - const BodyMedium( - text: 'New Update Available Now!', - fontColor: ColorsManager.blueColor, - ), - BodyMedium( - text: sosVersion!, - fontColor: ColorsManager.primaryTextColor, - ), - Container( - width: MediaQuery.of(context).size.width * 0.7, - child: BodyMedium( - text: sosDescription!, - fontColor: ColorsManager.textPrimaryColor, - textAlign: TextAlign.center, - ), - ), - SizedBox( - width: MediaQuery.of(context).size.width * 0.6, - child: DefaultButton( - borderRadius: 25, - backgroundColor: ColorsManager.blueColor1, - height: 150, - onPressed: () { - showDialog( - context: context, - builder: (context) { - return upDateNote( - cancelTab: () { - Navigator.of(context).pop(); - }, - confirmTab: () { - Navigator.of(context).pop(); - }, - ); - }, - ); - }, - child: const BodyMedium( - text: 'Update Now', - fontColor: Colors.white, - fontSize: 16, - fontWeight: FontWeight.w700, - textAlign: TextAlign.center, - ), - ), - ) - ], - ), - ], - ), - ), - ); - } -} - -class UpdateSosContainerWithProgressBar extends StatelessWidget { - final String? sosVersion; - final String? sosDescription; - const UpdateSosContainerWithProgressBar({ - this.sosVersion, - this.sosDescription, - super.key, - }); - - @override - Widget build(BuildContext context) { - return Column( - children: [ - DefaultContainer( - height: MediaQuery.of(context).size.height * 0.50, - child: Padding( - padding: const EdgeInsets.all(25), - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - SvgPicture.asset( - Assets.emptyUpdateIcon, - fit: BoxFit.fill, - ), - BodyMedium( - text: 'New Update Available Now!', - fontColor: ColorsManager.blueColor, - ), - BodyMedium( - text: sosVersion!, - fontColor: ColorsManager.primaryTextColor, - ), - SizedBox( - width: MediaQuery.of(context).size.width * 0.7, - child: BodyMedium( - text: sosDescription!, - fontColor: ColorsManager.textPrimaryColor, - textAlign: TextAlign.center, - ), - ), - LinearPercentIndicator( - barRadius: Radius.circular(10), - width: 170.0, - animation: true, - animationDuration: 1000, - lineHeight: 5.0, - percent: 0.2, - linearStrokeCap: LinearStrokeCap.butt, - progressColor: ColorsManager.blueColor1, - ), - SizedBox( - width: MediaQuery.of(context).size.width * 0.7, - child: const BodyMedium( - text: 'Downloading Update please be patient', - fontColor: ColorsManager.textPrimaryColor, - textAlign: TextAlign.center, - ), - ), - ], - ), - ], - ), - ), - ), - SizedBox( - width: MediaQuery.of(context).size.width * 0.7, - child: const BodyMedium( - text: - 'Please keep the power of the device connected during the upgrade process.', - fontColor: ColorsManager.textPrimaryColor, - textAlign: TextAlign.center, - ), - ), - ], - ); - } -} diff --git a/lib/features/devices/view/widgets/6_scene_switch/six_scene_screen.dart b/lib/features/devices/view/widgets/6_scene_switch/six_scene_screen.dart index 31a9130..f1fcf5d 100644 --- a/lib/features/devices/view/widgets/6_scene_switch/six_scene_screen.dart +++ b/lib/features/devices/view/widgets/6_scene_switch/six_scene_screen.dart @@ -8,7 +8,7 @@ import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_ev import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_state.dart'; import 'package:syncrow_app/features/devices/model/device_model.dart'; import 'package:syncrow_app/features/devices/model/six_scene_model.dart'; -import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/6_scene_setting/six_scene_settings.dart'; +import 'package:syncrow_app/features/devices/view/device_settings/settings_page.dart'; import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/select_scene_page.dart'; import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/select_switch_dialog.dart'; import 'package:syncrow_app/features/devices/view/widgets/6_scene_switch/six_switches_card.dart'; @@ -57,7 +57,7 @@ class SixSceneScreen extends StatelessWidget { onTap: () async { bool val = await Navigator.of(context).push( MaterialPageRoute( - builder: (context) => SixSceneSettings(device: device!), + builder: (context) => SettingsPage(device: device!), ), ); if (val == true) { diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_screen.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_screen.dart index 30d6ddd..238c737 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_screen.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_screen.dart @@ -6,7 +6,7 @@ import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_eve import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_state.dart'; import 'package:syncrow_app/features/devices/model/device_model.dart'; import 'package:syncrow_app/features/devices/model/four_scene_model.dart'; -import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_settings.dart'; +import 'package:syncrow_app/features/devices/view/device_settings/settings_page.dart'; import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_select_scene_page.dart'; import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_select_switch_dialog.dart'; import 'package:syncrow_app/features/devices/view/widgets/four_scene_switch/four_switches_card.dart'; @@ -53,7 +53,7 @@ class FourSceneScreen extends StatelessWidget { onTap: () { Navigator.of(context).push( MaterialPageRoute( - builder: (context) => FourSceneSettings(device: device!), + builder: (context) => SettingsPage(device: device!), ), ); }, diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_update_dialog.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_update_dialog.dart deleted file mode 100644 index 0529161..0000000 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_update_dialog.dart +++ /dev/null @@ -1,118 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart'; -import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; - -class UpdateInfoDialog extends StatelessWidget { - final Function()? cancelTab; - final Function()? confirmTab; - - const UpdateInfoDialog({ - super.key, - required this.cancelTab, - required this.confirmTab, - }); - - @override - Widget build(BuildContext context) { - return AlertDialog( - contentPadding: EdgeInsets.zero, - content: Column( - mainAxisSize: MainAxisSize.min, - children: [ - const SizedBox( - height: 10, - ), - BodyLarge( - text: 'Update Available', - fontWeight: FontWeight.w700, - fontColor: ColorsManager.switchButton.withOpacity(0.6), - fontSize: 16, - ), - const Padding( - padding: EdgeInsets.only(left: 15, right: 15), - child: Divider( - color: ColorsManager.textGray, - ), - ), - const Padding( - padding: EdgeInsets.only(left: 15, right: 20, top: 15, bottom: 20), - child: Column( - children: [ - Center( - child: Text( - 'An update is available for your device. Version 2.1.0 includes new features and important fixes to enhance performance and security.', - textAlign: TextAlign.center, - )), - ], - ), - ), - 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: cancelTab, - child: const Padding( - padding: const EdgeInsets.only(top: 15, bottom: 15), - child: Center( - child: Text( - 'Remind me later', - 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: confirmTab, - child: Padding( - padding: const EdgeInsets.only(top: 15, bottom: 15), - child: Center( - child: Text( - 'Update Now', - style: TextStyle( - color: - ColorsManager.switchButton.withOpacity(0.6), - fontSize: 14, - fontWeight: FontWeight.w400), - ), - ), - )), - )) - ], - ) - ], - ), - ); - } -} diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_update_note.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_update_note.dart deleted file mode 100644 index 5ef211b..0000000 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/four_scene_update_note.dart +++ /dev/null @@ -1,118 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart'; -import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; - -class UpDateNote extends StatelessWidget { - final Function()? cancelTab; - final Function()? confirmTab; - - const UpDateNote({ - super.key, - required this.cancelTab, - required this.confirmTab, - }); - - @override - Widget build(BuildContext context) { - return AlertDialog( - contentPadding: EdgeInsets.zero, - content: Column( - mainAxisSize: MainAxisSize.min, - children: [ - const SizedBox( - height: 10, - ), - BodyLarge( - text: 'Update Note', - fontWeight: FontWeight.w700, - fontColor: ColorsManager.switchButton.withOpacity(0.6), - fontSize: 16, - ), - const Padding( - padding: EdgeInsets.only(left: 15, right: 15), - child: Divider( - color: ColorsManager.textGray, - ), - ), - const Padding( - padding: EdgeInsets.only(left: 15, right: 20, top: 15, bottom: 20), - child: Column( - children: [ - Center( - child: Text( - 'This update may take a long time. Make sure that the device is fully charged. The device will be unavailable during the update.', - textAlign: TextAlign.center, - )), - ], - ), - ), - 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: cancelTab, - child: const Padding( - padding: const EdgeInsets.only(top: 15, bottom: 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: confirmTab, - child: Padding( - padding: const EdgeInsets.only(top: 15, bottom: 15), - child: Center( - child: Text( - 'Start Update', - style: TextStyle( - color: - ColorsManager.switchButton.withOpacity(0.6), - fontSize: 14, - fontWeight: FontWeight.w400), - ), - ), - )), - )) - ], - ) - ], - ), - ); - } -} diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/question_page_four_scene.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/question_page_four_scene.dart deleted file mode 100644 index 389b358..0000000 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_setting/question_page_four_scene.dart +++ /dev/null @@ -1,142 +0,0 @@ -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/four_scene_bloc/four_scene_bloc.dart'; -import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_event.dart'; -import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_state.dart'; -import 'package:syncrow_app/features/devices/model/question_model.dart'; -import 'package:syncrow_app/features/shared_widgets/default_button.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/generated/assets.dart'; -import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; - -class QuestionPageFourScene extends StatelessWidget { - final QuestionModel? questionModel; - - const QuestionPageFourScene({super.key, this.questionModel}); - - @override - Widget build(BuildContext context) { - return DefaultScaffold( - title: 'FAQ', - child: BlocProvider( - create: (context) => - FourSceneBloc(fourSceneId: '')..add(const FourSceneInitial()), - child: BlocBuilder( - builder: (context, state) { - final sensor = BlocProvider.of(context); - return state is FourSceneLoadingState - ? const Center( - child: DefaultContainer( - width: 50, - height: 50, - child: CircularProgressIndicator()), - ) - : Column( - children: [ - DefaultContainer( - padding: const EdgeInsets.all(15), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - BodyLarge( - text: questionModel!.question, - fontSize: 22, - fontWeight: FontWeight.w400, - fontColor: ColorsManager.blackColor, - ), - const SizedBox( - height: 15, - ), - BodyMedium( - text: questionModel!.answer, - fontSize: 14, - fontWeight: FontWeight.w400, - fontColor: ColorsManager.secondaryTextColor, - ), - ], - ), - ), - SizedBox( - height: MediaQuery.of(context).size.height * 0.15, - ), - Center( - child: SizedBox( - width: 180, - child: DefaultButton( - backgroundColor: sensor.isHelpful == true - ? ColorsManager.grayColor - : ColorsManager.grayButtonColors, - borderRadius: 50, - onPressed: () { - sensor.add( - const ToggleHelpfulEvent(isHelpful: true)); - }, - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - SvgPicture.asset( - Assets.thumbUp, - fit: BoxFit.fill, - ), - const SizedBox( - width: 10, - ), - const BodyMedium( - text: 'Helpful', - fontSize: 12, - fontWeight: FontWeight.w400, - fontColor: ColorsManager.blackColor, - ), - ], - )), - ), - ), - const SizedBox( - height: 15, - ), - Center( - child: SizedBox( - width: 180, - child: DefaultButton( - backgroundColor: sensor.isHelpful == false - ? ColorsManager.grayColor - : ColorsManager.grayButtonColors, - borderRadius: 50, - onPressed: () { - sensor.add( - const ToggleHelpfulEvent(isHelpful: false)); - }, - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - SvgPicture.asset( - Assets.thumbDown, - fit: BoxFit.fill, - ), - const SizedBox( - width: 10, - ), - const BodyMedium( - text: 'Not Helpful', - fontSize: 12, - fontWeight: FontWeight.w400, - fontColor: ColorsManager.blackColor, - ), - ], - )), - ), - ), - ], - ); - }, - ), - ), - ); - } -} diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_select_scene_page.dart b/lib/features/devices/view/widgets/four_scene_switch/four_select_scene_page.dart index cc2b93f..f139fb6 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_select_scene_page.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_select_scene_page.dart @@ -7,14 +7,11 @@ import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_blo import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_event.dart'; import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_state.dart'; import 'package:syncrow_app/features/devices/view/widgets/restart_status_dialog.dart'; -import 'package:syncrow_app/features/scene/model/scene_settings_route_arguments.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_medium.dart'; import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart'; import 'package:syncrow_app/generated/assets.dart'; -import 'package:syncrow_app/navigation/navigation_service.dart'; -import 'package:syncrow_app/navigation/routing_constants.dart'; import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; class FourSelectSceneFourPage extends StatelessWidget { diff --git a/lib/features/devices/view/widgets/room_page_switch.dart b/lib/features/devices/view/widgets/room_page_switch.dart index 89e6c22..af1bfd5 100644 --- a/lib/features/devices/view/widgets/room_page_switch.dart +++ b/lib/features/devices/view/widgets/room_page_switch.dart @@ -68,7 +68,7 @@ class RoomPageSwitch extends StatelessWidget { Flexible( child: FittedBox( child: Text( - device.type ?? "", + device.name ?? "", overflow: TextOverflow.ellipsis, maxLines: 2, style: context.bodyLarge.copyWith( diff --git a/lib/features/devices/view/widgets/sos/sos_screen.dart b/lib/features/devices/view/widgets/sos/sos_screen.dart index 7c475fb..c26920d 100644 --- a/lib/features/devices/view/widgets/sos/sos_screen.dart +++ b/lib/features/devices/view/widgets/sos/sos_screen.dart @@ -6,9 +6,9 @@ import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_event.dart'; import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_state.dart'; import 'package:syncrow_app/features/devices/model/device_model.dart'; import 'package:syncrow_app/features/devices/model/sos_model.dart'; +import 'package:syncrow_app/features/devices/view/device_settings/settings_page.dart'; import 'package:syncrow_app/features/devices/view/widgets/sos/sos_alarm_management_page.dart'; import 'package:syncrow_app/features/devices/view/widgets/sos/sos_records_screen.dart'; -import 'package:syncrow_app/features/devices/view/widgets/sos/sos_settings.dart'; import 'package:syncrow_app/features/shared_widgets/battery_bar.dart'; import 'package:syncrow_app/features/shared_widgets/default_container.dart'; import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart'; @@ -43,15 +43,15 @@ class SosScreen extends StatelessWidget { actions: [ InkWell( onTap: () async { - Navigator.of(context).push( + var val = await Navigator.of(context).push( MaterialPageRoute( - builder: (context) => SosSettings(device: device!), + builder: (context) => SettingsPage(device: device!), ), ); - // if (val == null) { - // sensor.add(SosInitialDeviseInfo()); - // sensor.add(const SosInitial()); - // } + if (val == null) { + sensor.add(SosInitialDeviseInfo()); + sensor.add(const SosInitial()); + } }, child: SvgPicture.asset(Assets.assetsIconsSettings), ), diff --git a/lib/features/devices/view/widgets/sos/sos_setting/faq_sos_page.dart b/lib/features/devices/view/widgets/sos/sos_setting/faq_sos_page.dart deleted file mode 100644 index aa93159..0000000 --- a/lib/features/devices/view/widgets/sos/sos_setting/faq_sos_page.dart +++ /dev/null @@ -1,164 +0,0 @@ -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/sos_bloc/sos_bloc.dart'; -import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_event.dart'; -import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_state.dart'; -import 'package:syncrow_app/features/devices/model/device_model.dart'; -import 'package:syncrow_app/features/devices/model/question_model.dart'; -import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/question_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_medium.dart'; -import 'package:syncrow_app/generated/assets.dart'; -import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; - -class FaqSosPage extends StatelessWidget { - final DeviceModel? device; - - const FaqSosPage({super.key, this.device}); - - @override - Widget build(BuildContext context) { - TextEditingController _searchController = TextEditingController(); - return DefaultScaffold( - title: 'FAQ', - child: BlocProvider( - create: (context) => - SosBloc(sosId: device?.uuid ?? '')..add(const SosInitialQuestion()), - child: BlocBuilder( - builder: (context, state) { - final sensor = BlocProvider.of(context); - - List displayedQuestions = []; - if (state is FaqSearchState) { - displayedQuestions = state.filteredFaqQuestions; - } else if (state is FaqLoadedState) { - displayedQuestions = state.filteredFaqQuestions; - } - return state is SosLoadingState - ? const Center( - child: DefaultContainer( - width: 50, - height: 50, - child: CircularProgressIndicator()), - ) - : RefreshIndicator( - onRefresh: () async { - sensor.add(const SosInitial()); - }, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - DefaultContainer( - padding: const EdgeInsets.all(5), - child: TextFormField( - controller: _searchController, - onChanged: (value) { - sensor.add(SearchFaqEvent(value)); - }, - decoration: InputDecoration( - hintText: 'Enter your questions', - hintStyle: const TextStyle( - color: ColorsManager.textGray, - fontSize: 16, - fontWeight: FontWeight.w400), - suffixIcon: Container( - padding: const EdgeInsets.all(5.0), - margin: const EdgeInsets.all(10.0), - child: SvgPicture.asset( - Assets.searchIcon, - fit: BoxFit.contain, - ), - ), - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(8.0), - ), - ), - ), - ), - SizedBox( - height: MediaQuery.of(context).size.height * 0.04, - ), - BodyMedium( - text: _searchController.text.isEmpty - ? 'Device Related FAQs' - : '${displayedQuestions.length} Help Topics', - fontWeight: FontWeight.w700, - fontSize: 12, - fontColor: ColorsManager.grayColor, - ), - const SizedBox( - height: 8, - ), - displayedQuestions.isEmpty - ? const SizedBox() - : DefaultContainer( - child: ListView.builder( - shrinkWrap: true, - itemCount: displayedQuestions.length, - itemBuilder: (context, index) { - final faq = displayedQuestions[index]; - return InkWell( - onTap: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => - QuestionPage( - questionModel: faq, - )), - ); - }, - child: SizedBox( - child: Column( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: - MainAxisAlignment.start, - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Padding( - padding: - const EdgeInsets.all(8.0), - child: Row( - children: [ - Expanded( - child: BodyMedium( - fontSize: 14, - fontWeight: - FontWeight.w400, - text: faq.question, - ), - ), - const Icon( - Icons.keyboard_arrow_right, - color: - ColorsManager.textGray, - ), - ], - ), - ), - if (index != - displayedQuestions.length - - 1) // Exclude divider for the last item - const Divider( - color: - ColorsManager.dividerColor, - ), - ], - ), - ), - ); - }, - ), - ) - ], - ), - ); - }, - ), - ), - ); - } -} diff --git a/lib/features/devices/view/widgets/sos/sos_setting/location_setting.dart b/lib/features/devices/view/widgets/sos/sos_setting/location_setting.dart deleted file mode 100644 index 0097fe3..0000000 --- a/lib/features/devices/view/widgets/sos/sos_setting/location_setting.dart +++ /dev/null @@ -1,211 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:syncrow_app/features/app_layout/model/space_model.dart'; -import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_bloc.dart'; -import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_event.dart'; -import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_state.dart'; -import 'package:syncrow_app/features/devices/model/sos_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/features/shared_widgets/text_widgets/body_medium.dart'; -import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; - -class LocationSosPage extends StatelessWidget { - final SpaceModel? space; - final String? deviceId; - - const LocationSosPage({ - super.key, - this.space, - this.deviceId, - }); - - @override - Widget build(BuildContext context) { - String roomIdSelected = ''; - - return Scaffold( - body: BlocProvider( - create: (context) => SosBloc(sosId: deviceId ?? '') - ..add(const SosInitial()) - ..add(SosInitialDeviseInfo()) - ..add(FetchRoomsEvent(unit: space!)), - child: BlocBuilder( - builder: (context, state) { - final _bloc = BlocProvider.of(context); - SosModel model = - SosModel(batteryPercentage: 0, sosContactState: ''); - if (state is SaveSelectionSuccessState) { - Future.delayed(const Duration(microseconds: 500), () { - _bloc.add(const SosInitial()); - Navigator.of(context).pop(true); - }); - } - return state is SosLoadingState - ? const Center( - child: DefaultContainer( - width: 50, - height: 50, - child: CircularProgressIndicator(), - ), - ) - : DefaultScaffold( - actions: [ - BlocBuilder( - builder: (context, state) { - final bool canSave = state is OptionSelectedState && - state.hasSelectionChanged; - return InkWell( - onTap: canSave - ? () { - context.read().add(AssignRoomEvent( - context: context, - roomId: roomIdSelected, - unit: space!)); - } - : null, - child: BodyMedium( - text: 'Save', - fontWeight: FontWeight.w700, - fontSize: 16, - fontColor: canSave - ? ColorsManager.slidingBlueColor - : ColorsManager.primaryTextColor, - ), - ); - }, - ), - const SizedBox(width: 20), - ], - child: ListView( - shrinkWrap: true, - padding: const EdgeInsets.symmetric(vertical: 20), - children: [ - const BodyMedium( - text: 'Smart Device Location', - fontWeight: FontWeight.w700, - fontSize: 12, - fontColor: ColorsManager.grayColor, - ), - const SizedBox(height: 5), - DefaultContainer( - padding: const EdgeInsets.all(20), - child: ListView.builder( - physics: const NeverScrollableScrollPhysics(), - shrinkWrap: true, - itemCount: _bloc.roomsList.length, - itemBuilder: (context, index) { - final fromRoom = _bloc.roomsList[index]; - final isSelected = (state - is OptionSelectedState && - state.selectedOption == fromRoom.id) || - (state is! OptionSelectedState && - fromRoom.id == - _bloc.deviceInfo.subspace.uuid); - - return Column( - children: [ - _buildCheckboxOption( - label: fromRoom.name!, - isSelected: isSelected, - onTap: (label) { - context.read().add( - SelectOptionEvent( - selectedOption: fromRoom.id!, - ), - ); - roomIdSelected = fromRoom.id!; - }, - ), - if (index < _bloc.roomsList.length - 1) ...[ - const SizedBox(height: 10), - const Divider( - color: ColorsManager.dividerColor, - ), - const SizedBox(height: 10), - ], - ], - ); - }, - ), - ), - ], - ), - ); - }, - ), - ), - ); - } -} - -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, - ), - ); - } -} - -Widget _buildCheckboxOption({ - required String label, - required bool isSelected, - required 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: isSelected, - onChanged: (bool? value) { - if (value == true) { - onTap(label); - } - }, - ), - ], - ), - ); -} diff --git a/lib/features/devices/view/widgets/sos/sos_setting/share_sos_page.dart b/lib/features/devices/view/widgets/sos/sos_setting/share_sos_page.dart deleted file mode 100644 index c102b19..0000000 --- a/lib/features/devices/view/widgets/sos/sos_setting/share_sos_page.dart +++ /dev/null @@ -1,105 +0,0 @@ -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/sos_bloc/sos_bloc.dart'; -import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_event.dart'; -import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_state.dart'; -import 'package:syncrow_app/features/devices/model/device_model.dart'; -import 'package:syncrow_app/features/menu/view/widgets/manage_home/home_settings.dart'; -import 'package:syncrow_app/features/shared_widgets/default_button.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/helpers/custom_page_route.dart'; -import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; - -class ShareSosPage extends StatelessWidget { - final DeviceModel? device; - - const ShareSosPage({super.key, this.device}); - - @override - Widget build(BuildContext context) { - var spaces = HomeCubit.getInstance().spaces; - - return DefaultScaffold( - title: 'Share Device', - child: BlocProvider( - create: (context) => - SosBloc(sosId: device?.uuid ?? '')..add(const SosInitial()), - child: BlocBuilder( - builder: (context, state) { - final sensor = BlocProvider.of(context); - return state is SosLoadingState - ? const Center( - child: DefaultContainer( - width: 50, - height: 50, - child: CircularProgressIndicator()), - ) - : RefreshIndicator( - onRefresh: () async { - sensor.add(const SosInitial()); - }, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: MediaQuery.of(context).size.height * 0.05, - ), - const BodyLarge( - text: 'Sharing Method Not Supported', - fontSize: 15, - fontWeight: FontWeight.w400, - fontColor: ColorsManager.blackColor, - ), - const BodyMedium( - text: - 'Currently, you cannot use the specified method to share Bluetooth mesh devices Zigbee devices, infrared devices, Bluetooth Beacon Devices, and certain Bluetooth LE devices with other users.', - fontSize: 14, - fontWeight: FontWeight.w400, - fontColor: ColorsManager.secondaryTextColor, - ), - const SizedBox( - height: 10, - ), - const BodyLarge( - text: 'Recommended Sharing Method', - fontSize: 15, - fontWeight: FontWeight.w400, - fontColor: ColorsManager.blackColor, - ), - const BodyMedium( - text: - 'If the recipient is a home member or a reliable user, tap Me > Home Management > Add Member and add the recipient to your home. Then, devices in the home can be shared with the recipient in bulk.', - fontSize: 14, - fontWeight: FontWeight.w400, - fontColor: ColorsManager.secondaryTextColor, - ), - SizedBox( - height: MediaQuery.of(context).size.height * 0.15, - ), - Center( - child: SizedBox( - width: 250, - child: DefaultButton( - backgroundColor: ColorsManager.blueColor1, - borderRadius: 50, - onPressed: () { - Navigator.of(context).push(CustomPageRoute( - builder: (context) => HomeSettingsView( - space: spaces!.first, - ))); - }, - child: const Text('Add Home Member')), - ), - ) - ], - )); - }, - ), - ), - ); - } -} diff --git a/lib/features/devices/view/widgets/sos/sos_setting/sos_info_page.dart b/lib/features/devices/view/widgets/sos/sos_setting/sos_info_page.dart deleted file mode 100644 index f38b8b7..0000000 --- a/lib/features/devices/view/widgets/sos/sos_setting/sos_info_page.dart +++ /dev/null @@ -1,141 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_bloc.dart'; -import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_event.dart'; -import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_state.dart'; -import 'package:syncrow_app/features/devices/model/device_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/features/shared_widgets/text_widgets/body_large.dart'; -import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart'; -import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart'; -import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; - -class SosInfoPage extends StatelessWidget { - final DeviceModel? device; - - const SosInfoPage({super.key, this.device}); - - @override - Widget build(BuildContext context) { - return DefaultScaffold( - title: 'Device Information', - child: BlocProvider( - create: (context) => SosBloc(sosId: device?.uuid ?? '') - ..add(const SosInitial()) - ..add(SosInitialDeviseInfo()), - child: BlocBuilder( - builder: (context, state) { - final _bloc = BlocProvider.of(context); - return state is SosLoadingState - ? const Center( - child: DefaultContainer( - width: 50, - height: 50, - child: CircularProgressIndicator()), - ) - : RefreshIndicator( - onRefresh: () async { - _bloc.add(const SosInitial()); - }, - child: DefaultContainer( - child: Padding( - padding: const EdgeInsets.only(left: 5, right: 5), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - const BodyLarge( - text: 'Virtual ID', - fontSize: 15, - fontWeight: FontWeight.w400, - fontColor: ColorsManager.blackColor, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - SizedBox( - width: - MediaQuery.of(context).size.width * 0.61, - child: BodySmall( - text: _bloc.deviceInfo.productUuid, - fontColor: ColorsManager.primaryTextColor, - ), - ), - InkWell( - onTap: () { - Clipboard.setData( - ClipboardData( - text: _bloc.deviceInfo.productUuid, - ), - ); - - ScaffoldMessenger.of(context).showSnackBar( - const SnackBar( - content: Text("Copied to Clipboard"), - ), - ); - }, - child: const Row( - children: [ - Icon( - Icons.copy, - color: ColorsManager.blueColor, - ), - BodyMedium( - text: 'Copy', - fontColor: ColorsManager.blueColor, - ), - ], - ), - ) - ], - ), - const Divider( - color: ColorsManager.dividerColor, - ), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - const BodyLarge( - text: 'MAC', - fontSize: 15, - fontWeight: FontWeight.w400, - fontColor: ColorsManager.blackColor, - ), - BodySmall( - text: _bloc.deviceInfo.macAddress, - fontColor: ColorsManager.primaryTextColor, - ), - ], - ), - const Divider( - color: ColorsManager.dividerColor, - ), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - const BodyLarge( - text: 'Time Zone', - fontSize: 15, - fontWeight: FontWeight.w400, - fontColor: ColorsManager.blackColor, - ), - BodySmall( - text: _bloc.deviceInfo.timeZone, - fontColor: ColorsManager.primaryTextColor, - ), - ], - ), - ]), - ))); - }, - ), - ), - ); - } -} diff --git a/lib/features/devices/view/widgets/sos/sos_setting/sos_profile_page.dart b/lib/features/devices/view/widgets/sos/sos_setting/sos_profile_page.dart deleted file mode 100644 index 6f9cb52..0000000 --- a/lib/features/devices/view/widgets/sos/sos_setting/sos_profile_page.dart +++ /dev/null @@ -1,184 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:flutter_svg/flutter_svg.dart'; -import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart'; -import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_bloc.dart'; -import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_event.dart'; -import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_state.dart'; -import 'package:syncrow_app/features/devices/model/device_model.dart'; -import 'package:syncrow_app/features/devices/model/sos_model.dart'; -import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/location_setting.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_medium.dart'; -import 'package:syncrow_app/generated/assets.dart'; -import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; - -class SosProfilePage extends StatelessWidget { - final DeviceModel? device; - - const SosProfilePage({super.key, this.device}); - - @override - Widget build(BuildContext context) { - var spaces = HomeCubit.getInstance().spaces; - - return DefaultScaffold( - title: 'Device Settings', - leading: IconButton( - onPressed: () { - Navigator.of(context).pop(true); - }, - icon: const Icon(Icons.arrow_back_ios)), - child: BlocProvider( - create: (context) => SosBloc(sosId: device?.uuid ?? '') - ..add(const SosInitial()) - ..add(SosInitialDeviseInfo()), - child: BlocBuilder( - builder: (context, state) { - final _bloc = BlocProvider.of(context); - SosModel model = - SosModel(batteryPercentage: 0, sosContactState: ''); - if (state is LoadingNewSate) { - model = state.sosSensor; - } else if (state is UpdateState) { - model = state.sensor; - } - return state is SosLoadingState - ? const Center( - child: DefaultContainer( - width: 50, - height: 50, - child: CircularProgressIndicator()), - ) - : RefreshIndicator( - onRefresh: () async { - _bloc.add(const SosInitial()); - }, - child: ListView( - children: [ - CircleAvatar( - radius: 60, - backgroundColor: Colors.white.withOpacity(0), - child: CircleAvatar( - radius: 55, - backgroundColor: ColorsManager.graysColor, - child: ClipOval( - child: Center( - child: SvgPicture.asset( - Assets.sosHomeIcon, - fit: BoxFit.fitHeight, - height: 100, - ), - ), - ), - ), - ), - const SizedBox( - height: 10, - ), - SizedBox( - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - IntrinsicWidth( - child: ConstrainedBox( - constraints: - const BoxConstraints(maxWidth: 200), - child: TextFormField( - maxLength: 30, - style: const TextStyle( - color: Colors.black, - ), - textAlign: TextAlign.center, - focusNode: _bloc.focusNode, - controller: _bloc.nameController, - enabled: _bloc.editName, - onEditingComplete: () { - _bloc.add(SaveNameEvent()); - }, - decoration: const InputDecoration( - hintText: "Your Name", - border: InputBorder.none, - fillColor: Colors.white10, - counterText: '', - ), - ), - ), - ), - const SizedBox(width: 5), - InkWell( - onTap: () { - _bloc.add(const ChangeNameEvent(value: true)); - }, - child: const Padding( - padding: EdgeInsets.symmetric(horizontal: 10), - child: Icon( - Icons.edit_outlined, - size: 20, - color: ColorsManager.textPrimaryColor, - ), - ), - ), - ], - ), - ), - const SizedBox(height: 20), - const BodyMedium( - text: 'Smart Device Information', - fontWeight: FontWeight.w700, - fontSize: 12, - fontColor: ColorsManager.grayColor, - ), - const SizedBox(height: 7), - DefaultContainer( - padding: const EdgeInsets.all(20), - child: InkWell( - onTap: () async { - bool val = await Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => LocationSosPage( - space: spaces!.first, - deviceId: device?.uuid ?? '', - )), - ); - if (val == true) { - _bloc.add(SosInitialDeviseInfo()); - } - }, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - const SizedBox( - child: Text('Location'), - ), - Row( - children: [ - SizedBox( - child: BodyMedium( - text: _bloc - .deviceInfo.subspace.subspaceName, - fontColor: ColorsManager.textGray, - ), - ), - const Icon( - Icons.arrow_forward_ios, - size: 15, - color: ColorsManager.textGray, - ), - ], - ) - ], - ), - ), - ) - ], - ), - ); - }, - ), - ), - ); - } -} diff --git a/lib/features/devices/view/widgets/sos/sos_setting/sos_update_page.dart b/lib/features/devices/view/widgets/sos/sos_setting/sos_update_page.dart deleted file mode 100644 index 67ab647..0000000 --- a/lib/features/devices/view/widgets/sos/sos_setting/sos_update_page.dart +++ /dev/null @@ -1,353 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:flutter_svg/flutter_svg.dart'; -import 'package:percent_indicator/linear_percent_indicator.dart'; -import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_bloc.dart'; -import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_event.dart'; -import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_state.dart'; -import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/sos_update_note.dart'; -import 'package:syncrow_app/features/shared_widgets/default_button.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_medium.dart'; -import 'package:syncrow_app/generated/assets.dart'; -import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; - -class SosUpdatePage extends StatelessWidget { - const SosUpdatePage({super.key}); - - @override - Widget build(BuildContext context) { - return DefaultScaffold( - title: 'Device Update', - child: BlocProvider( - create: (context) => SosBloc(sosId: '')..add(const SosInitial()), - child: BlocBuilder( - builder: (context, state) { - final _bloc = BlocProvider.of(context); - - return state is SosLoadingState - ? const Center( - child: DefaultContainer( - width: 50, - height: 50, - child: CircularProgressIndicator()), - ) - : RefreshIndicator( - onRefresh: () async {}, - child: Column( - children: [ - // SizedBox( - // height: MediaQuery.of(context).size.height * 0.15, - // ), - DefaultContainer( - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 50, - child: ListTile( - contentPadding: EdgeInsets.zero, - leading: SizedBox( - width: 200, - child: Row( - children: [ - Container( - padding: const EdgeInsets.all(10), - decoration: const BoxDecoration( - color: - ColorsManager.primaryColor, - borderRadius: BorderRadius.all( - Radius.circular(50))), - child: SvgPicture.asset( - Assets.checkUpdateIcon, - fit: BoxFit.fill, - height: 25, - ), - ), - const SizedBox( - width: 10, - ), - InkWell( - onTap: () {}, - child: const BodyMedium( - - text: 'Automatic Update', - fontWeight: FontWeight.normal, - ), - ), - ], - ), - ), - trailing: Container( - width: 100, - child: Row( - mainAxisAlignment: - MainAxisAlignment.end, - children: [ - BodyMedium( - text: _bloc.enableUpdate - ? 'true' - : 'Off', - fontColor: ColorsManager.textGray, - ), - Transform.scale( - scale: .8, - child: CupertinoSwitch( - value: _bloc.enableUpdate, - onChanged: (value) { - _bloc.add(ToggleUpdateEvent( - isUpdateEnabled: value)); - }, - applyTheme: true, - ), - ), - ], - ), - ) - ), - ), - ], - ), - ), - const SizedBox( - height: 10, - ), - const UpdateSosContainerWithProgressBar( - sosDescription: - 'Connectivity Issue Resolved Fixed a bug that caused the SOS button to disconnect from the app intermittently.', - sosVersion: 'SOS v2.0.5', - ), - // const UpdatedContainer( - // sosVersion: 'SOS v1.0.13', - // sosDescription: 'SOS is up to date', - // ), - - // const NewUpdateContainer( - // sosVersion: 'SOS v2.0.5', - // sosDescription: - // 'Connectivity Issue Resolved Fixed a bug that caused the SOS button to disconnect from the app intermittently.', - // ), - const SizedBox( - height: 15, - ), - ], - )); - }, - ), - ), - ); - } -} - -class UpdatedContainer extends StatelessWidget { - final String? sosVersion; - final String? sosDescription; - const UpdatedContainer({ - this.sosVersion, - this.sosDescription, - super.key, - }); - - @override - Widget build(BuildContext context) { - return DefaultContainer( - height: MediaQuery.of(context).size.height * 0.35, - child: Padding( - padding: const EdgeInsets.all(25), - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - SvgPicture.asset( - Assets.emptyUpdateIcon, - fit: BoxFit.fill, - ), - BodyMedium( - text: sosVersion!, - fontColor: ColorsManager.primaryTextColor, - ), - BodyMedium( - text: sosDescription!, - fontColor: ColorsManager.blackColor, - ), - ], - ), - ], - ), - ), - ); - } -} - -class NewUpdateContainer extends StatelessWidget { - final String? sosVersion; - final String? sosDescription; - const NewUpdateContainer({ - this.sosVersion, - this.sosDescription, - super.key, - }); - - @override - Widget build(BuildContext context) { - return DefaultContainer( - height: MediaQuery.of(context).size.height * 0.50, - child: Padding( - padding: const EdgeInsets.all(25), - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - SvgPicture.asset( - Assets.emptyUpdateIcon, - fit: BoxFit.fill, - ), - const BodyMedium( - text: 'New Update Available Now!', - fontColor: ColorsManager.blueColor, - ), - BodyMedium( - text: sosVersion!, - fontColor: ColorsManager.primaryTextColor, - ), - Container( - width: MediaQuery.of(context).size.width * 0.7, - child: BodyMedium( - text: sosDescription!, - fontColor: ColorsManager.textPrimaryColor, - textAlign: TextAlign.center, - ), - ), - SizedBox( - width: MediaQuery.of(context).size.width * 0.6, - child: DefaultButton( - borderRadius: 25, - backgroundColor: ColorsManager.blueColor1, - height: 150, - onPressed: () { - showDialog( - context: context, - builder: (context) { - return SosUpdateNote( - cancelTab: () { - Navigator.of(context).pop(); - }, - confirmTab: () { - Navigator.of(context).pop(); - }, - ); - }, - ); - }, - child: const BodyMedium( - text: 'Update Now', - fontColor: Colors.white, - fontSize: 16, - fontWeight: FontWeight.w700, - textAlign: TextAlign.center, - ), - ), - ) - ], - ), - ], - ), - ), - ); - } -} - -class UpdateSosContainerWithProgressBar extends StatelessWidget { - final String? sosVersion; - final String? sosDescription; - const UpdateSosContainerWithProgressBar({ - this.sosVersion, - this.sosDescription, - super.key, - }); - - @override - Widget build(BuildContext context) { - return Column( - children: [ - DefaultContainer( - height: MediaQuery.of(context).size.height * 0.50, - child: Padding( - padding: const EdgeInsets.all(25), - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - SvgPicture.asset( - Assets.emptyUpdateIcon, - fit: BoxFit.fill, - ), - const BodyMedium( - text: 'New Update Available Now!', - fontColor: ColorsManager.blueColor, - ), - BodyMedium( - text: sosVersion!, - fontColor: ColorsManager.primaryTextColor, - ), - SizedBox( - width: MediaQuery.of(context).size.width * 0.7, - child: BodyMedium( - text: sosDescription!, - fontColor: ColorsManager.textPrimaryColor, - textAlign: TextAlign.center, - ), - ), - LinearPercentIndicator( - barRadius: Radius.circular(10), - width: 170.0, - animation: true, - animationDuration: 1000, - lineHeight: 5.0, - percent: 0.2, - linearStrokeCap: LinearStrokeCap.butt, - progressColor: ColorsManager.blueColor1, - ), - SizedBox( - width: MediaQuery.of(context).size.width * 0.7, - child: const BodyMedium( - text: 'Downloading Update please be patient', - fontColor: ColorsManager.textPrimaryColor, - textAlign: TextAlign.center, - ), - ), - ], - ), - ], - ), - ), - ), - SizedBox( - width: MediaQuery.of(context).size.width * 0.7, - child: const BodyMedium( - text: - 'Please keep the power of the device connected during the upgrade process.', - fontColor: ColorsManager.textPrimaryColor, - textAlign: TextAlign.center, - ), - ), - ], - ); - } -} diff --git a/lib/features/devices/view/widgets/sos/sos_setting/update_dialog_sos.dart b/lib/features/devices/view/widgets/sos/sos_setting/update_dialog_sos.dart deleted file mode 100644 index 0529161..0000000 --- a/lib/features/devices/view/widgets/sos/sos_setting/update_dialog_sos.dart +++ /dev/null @@ -1,118 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart'; -import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; - -class UpdateInfoDialog extends StatelessWidget { - final Function()? cancelTab; - final Function()? confirmTab; - - const UpdateInfoDialog({ - super.key, - required this.cancelTab, - required this.confirmTab, - }); - - @override - Widget build(BuildContext context) { - return AlertDialog( - contentPadding: EdgeInsets.zero, - content: Column( - mainAxisSize: MainAxisSize.min, - children: [ - const SizedBox( - height: 10, - ), - BodyLarge( - text: 'Update Available', - fontWeight: FontWeight.w700, - fontColor: ColorsManager.switchButton.withOpacity(0.6), - fontSize: 16, - ), - const Padding( - padding: EdgeInsets.only(left: 15, right: 15), - child: Divider( - color: ColorsManager.textGray, - ), - ), - const Padding( - padding: EdgeInsets.only(left: 15, right: 20, top: 15, bottom: 20), - child: Column( - children: [ - Center( - child: Text( - 'An update is available for your device. Version 2.1.0 includes new features and important fixes to enhance performance and security.', - textAlign: TextAlign.center, - )), - ], - ), - ), - 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: cancelTab, - child: const Padding( - padding: const EdgeInsets.only(top: 15, bottom: 15), - child: Center( - child: Text( - 'Remind me later', - 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: confirmTab, - child: Padding( - padding: const EdgeInsets.only(top: 15, bottom: 15), - child: Center( - child: Text( - 'Update Now', - style: TextStyle( - color: - ColorsManager.switchButton.withOpacity(0.6), - fontSize: 14, - fontWeight: FontWeight.w400), - ), - ), - )), - )) - ], - ) - ], - ), - ); - } -} diff --git a/lib/features/devices/view/widgets/sos/sos_settings.dart b/lib/features/devices/view/widgets/sos/sos_settings.dart index 0a41e67..94987a9 100644 --- a/lib/features/devices/view/widgets/sos/sos_settings.dart +++ b/lib/features/devices/view/widgets/sos/sos_settings.dart @@ -1,377 +1,377 @@ -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/sos_bloc/sos_bloc.dart'; -import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_event.dart'; -import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_state.dart'; -import 'package:syncrow_app/features/devices/model/device_model.dart'; -import 'package:syncrow_app/features/devices/model/sos_model.dart'; -import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/sos_profile_page.dart'; -import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/faq_sos_page.dart'; -import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/share_sos_page.dart'; -import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/sos_info_page.dart'; -import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/sos_update_page.dart'; -import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/update_dialog_sos.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/delete_device_dialogs.dart'; -import 'package:syncrow_app/features/shared_widgets/setting_widget.dart'; -import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart'; -import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart'; -import 'package:syncrow_app/generated/assets.dart'; -import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; +// 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/sos_bloc/sos_bloc.dart'; +// import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_event.dart'; +// import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_state.dart'; +// import 'package:syncrow_app/features/devices/model/device_model.dart'; +// import 'package:syncrow_app/features/devices/model/sos_model.dart'; +// import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/sos_profile_page.dart'; +// import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/faq_sos_page.dart'; +// import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/share_sos_page.dart'; +// import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/sos_info_page.dart'; +// import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/sos_update_page.dart'; +// import 'package:syncrow_app/features/devices/view/widgets/sos/sos_setting/update_dialog_sos.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/delete_device_dialogs.dart'; +// import 'package:syncrow_app/features/shared_widgets/setting_widget.dart'; +// import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart'; +// import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart'; +// import 'package:syncrow_app/generated/assets.dart'; +// import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; -class SosSettings extends StatelessWidget { - final DeviceModel? device; - const SosSettings({ - super.key, - this.device, - }); +// class SosSettings extends StatelessWidget { +// final DeviceModel? device; +// const SosSettings({ +// super.key, +// this.device, +// }); - @override - Widget build(BuildContext context) { - return DefaultScaffold( - title: 'Device Settings', - child: BlocProvider( - create: (context) => SosBloc(sosId: device?.uuid ?? '') - ..add(const SosInitial()) - ..add(SosInitialDeviseInfo()), - child: BlocBuilder( - builder: (context, state) { - final _bloc = BlocProvider.of(context); - SosModel model = - SosModel(batteryPercentage: 0, sosContactState: 'normal'); - if (state is LoadingNewSate) { - model = state.sosSensor; - } else if (state is UpdateState) { - model = state.sensor; - } - return state is SosLoadingState - ? const Center( - child: DefaultContainer( - width: 50, - height: 50, - child: CircularProgressIndicator()), - ) - : ListView( - children: [ - Padding( - padding: const EdgeInsets.symmetric( - vertical: 10, - ), - child: InkWell( - onTap: () async { - bool val = await Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => SosProfilePage( - device: device, - ), - ), - ); - if (val == true) { - _bloc.add(SosInitialDeviseInfo()); - _bloc.add(const SosInitial()); - } - }, - child: Stack( - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - const SizedBox(height: 20), - DefaultContainer( - borderRadius: const BorderRadius.all( - Radius.circular(30)), - child: Padding( - padding: const EdgeInsets.all(10.0), - child: Padding( - padding: - const EdgeInsets.only(left: 90), - child: Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - BodyMedium( - text: _bloc.deviceInfo.name, - fontWeight: FontWeight.bold, - ), - const SizedBox( - height: 5, - ), - BodySmall( - text: _bloc.deviceInfo - .subspace.subspaceName), - ], - ), - const Icon( - Icons.edit_outlined, - color: ColorsManager.grayColor, - ), - ], - ), - ), - ), - ), - ], - ), - Positioned( - top: 0, - left: 20, - child: CircleAvatar( - radius: 40, - backgroundColor: Colors.white, - child: CircleAvatar( - radius: 40, - backgroundColor: - Colors.white.withOpacity(0), - child: ClipOval( - child: SvgPicture.asset( - Assets.sosHomeIcon, - fit: BoxFit.contain, - height: 80, - ), - )), - ), - ), - ], - ), - ), - ), - const SizedBox(height: 20), - const BodyMedium( - text: 'Device Management', - fontWeight: FontWeight.w700, - fontSize: 12, - fontColor: ColorsManager.grayColor, - ), - DefaultContainer( - child: SettingWidget( - onTap: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => - SosInfoPage(device: device!)), - ); - }, - text: 'Device Information', - icon: Assets.infoIcon, - ), - ), - const SizedBox(height: 20), - const BodyMedium( - text: 'Device Offline Notification', - fontWeight: FontWeight.w700, - fontSize: 12, - fontColor: ColorsManager.grayColor, - ), - DefaultContainer( - child: Column( - children: [ - SettingWidget( - value: _bloc.enableAlarm, - onChanged: (p0) { - context - .read() - .add(ToggleEnableAlarmEvent(p0)); - }, - isNotification: true, - onTap: () {}, - text: 'Offline Notification', - icon: Assets.notificationIcon, - ), - ], - ), - ), - const SizedBox(height: 20), - const BodyMedium( - text: 'Others', - fontWeight: FontWeight.w700, - fontSize: 12, - fontColor: ColorsManager.grayColor, - ), - const SizedBox(height: 5), - DefaultContainer( - child: Column( - children: [ - SettingWidget( - onTap: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => - ShareSosPage(device: device!)), - ); - }, - text: 'Share Device', - icon: Assets.shareIcon, - ), - const Divider( - color: ColorsManager.dividerColor, - ), - SettingWidget( - onTap: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => - FaqSosPage(device: device!)), - ); - }, - text: 'Device FAQ', - icon: Assets.faqIcon, - ), - const Divider( - color: ColorsManager.dividerColor, - ), - SettingWidget( - onTapUpdate: () { - showDialog( - context: context, - builder: (context) { - return UpdateInfoDialog( - cancelTab: () { - Navigator.of(context).pop(); - }, - confirmTab: () { - Navigator.of(context).pop(); - }, - ); - }, - ); - }, - isUpdate: true, - onTap: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => - const SosUpdatePage()), - ); - }, - text: 'Device Update', - icon: Assets.updateIcon, - ), - ], - ), - ), - const SizedBox(height: 20), - InkWell( - onTap: () { - showModalBottomSheet( - context: context, - builder: (BuildContext context) { - return Container( - height: 200, - padding: const EdgeInsets.all(16.0), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - const BodyMedium( - text: 'Remove Device', - fontWeight: FontWeight.w700, - fontSize: 16, - fontColor: ColorsManager.red, - ), - const SizedBox(height: 10), - const SizedBox( - width: 250, - child: Divider( - color: ColorsManager.dividerColor, - ), - ), - const SizedBox(height: 10), - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - InkWell( - onTap: () { - showDialog( - context: context, - builder: (context) { - return DisconnectDeviceDialog( - cancelTab: () { - Navigator.of(context).pop(); - }, - confirmTab: () { - Navigator.of(context).pop(); - }, - ); - }, - ); - }, - child: const BodyMedium( - text: 'Disconnect Device', - fontWeight: FontWeight.w400, - fontSize: 15, - fontColor: - ColorsManager.textPrimaryColor, - ), - ), - const Icon( - Icons.keyboard_arrow_right, - color: ColorsManager.textGray, - ) - ], - ), - const SizedBox(height: 20), - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - InkWell( - onTap: () { - showDialog( - context: context, - builder: (context) { - return DisconnectWipeData( - cancelTab: () { - Navigator.of(context).pop(); - }, - confirmTab: () { - _bloc.add( - DeleteDeviceEvent()); - }, - ); - }, - ); - }, - child: const BodyMedium( - text: - 'Disconnect Device and Wipe Data', - fontWeight: FontWeight.w400, - fontSize: 15, - fontColor: - ColorsManager.textPrimaryColor, - ), - ), - const Icon( - Icons.keyboard_arrow_right, - color: ColorsManager.textGray, - ) - ], - ), - ], - ), - ); - }, - ); - }, - child: const Center( - child: BodyMedium( - text: 'Remove Device', - fontWeight: FontWeight.w400, - fontSize: 15, - fontColor: ColorsManager.red, - ), - ), - ), - ], - ); - }, - ), - ), - ); - } -} +// @override +// Widget build(BuildContext context) { +// return DefaultScaffold( +// title: 'Device Settings', +// child: BlocProvider( +// create: (context) => SosBloc(sosId: device?.uuid ?? '') +// ..add(const SosInitial()) +// ..add(SosInitialDeviseInfo()), +// child: BlocBuilder( +// builder: (context, state) { +// final _bloc = BlocProvider.of(context); +// SosModel model = +// SosModel(batteryPercentage: 0, sosContactState: 'normal'); +// if (state is LoadingNewSate) { +// model = state.sosSensor; +// } else if (state is UpdateState) { +// model = state.sensor; +// } +// return state is SosLoadingState +// ? const Center( +// child: DefaultContainer( +// width: 50, +// height: 50, +// child: CircularProgressIndicator()), +// ) +// : ListView( +// children: [ +// Padding( +// padding: const EdgeInsets.symmetric( +// vertical: 10, +// ), +// child: InkWell( +// onTap: () async { +// bool val = await Navigator.of(context).push( +// MaterialPageRoute( +// builder: (context) => SosProfilePage( +// device: device, +// ), +// ), +// ); +// if (val == true) { +// _bloc.add(SosInitialDeviseInfo()); +// _bloc.add(const SosInitial()); +// } +// }, +// child: Stack( +// children: [ +// Column( +// crossAxisAlignment: CrossAxisAlignment.stretch, +// children: [ +// const SizedBox(height: 20), +// DefaultContainer( +// borderRadius: const BorderRadius.all( +// Radius.circular(30)), +// child: Padding( +// padding: const EdgeInsets.all(10.0), +// child: Padding( +// padding: +// const EdgeInsets.only(left: 90), +// child: Row( +// mainAxisAlignment: +// MainAxisAlignment.spaceBetween, +// children: [ +// Column( +// crossAxisAlignment: +// CrossAxisAlignment.start, +// children: [ +// BodyMedium( +// text: _bloc.deviceInfo.name, +// fontWeight: FontWeight.bold, +// ), +// const SizedBox( +// height: 5, +// ), +// BodySmall( +// text: _bloc.deviceInfo +// .subspace.subspaceName), +// ], +// ), +// const Icon( +// Icons.edit_outlined, +// color: ColorsManager.grayColor, +// ), +// ], +// ), +// ), +// ), +// ), +// ], +// ), +// Positioned( +// top: 0, +// left: 20, +// child: CircleAvatar( +// radius: 40, +// backgroundColor: Colors.white, +// child: CircleAvatar( +// radius: 40, +// backgroundColor: +// Colors.white.withOpacity(0), +// child: ClipOval( +// child: SvgPicture.asset( +// Assets.sosHomeIcon, +// fit: BoxFit.contain, +// height: 80, +// ), +// )), +// ), +// ), +// ], +// ), +// ), +// ), +// const SizedBox(height: 20), +// const BodyMedium( +// text: 'Device Management', +// fontWeight: FontWeight.w700, +// fontSize: 12, +// fontColor: ColorsManager.grayColor, +// ), +// DefaultContainer( +// child: SettingWidget( +// onTap: () { +// Navigator.of(context).push( +// MaterialPageRoute( +// builder: (context) => +// SosInfoPage(device: device!)), +// ); +// }, +// text: 'Device Information', +// icon: Assets.infoIcon, +// ), +// ), +// const SizedBox(height: 20), +// const BodyMedium( +// text: 'Device Offline Notification', +// fontWeight: FontWeight.w700, +// fontSize: 12, +// fontColor: ColorsManager.grayColor, +// ), +// DefaultContainer( +// child: Column( +// children: [ +// SettingWidget( +// value: _bloc.enableAlarm, +// onChanged: (p0) { +// context +// .read() +// .add(ToggleEnableAlarmEvent(p0)); +// }, +// isNotification: true, +// onTap: () {}, +// text: 'Offline Notification', +// icon: Assets.notificationIcon, +// ), +// ], +// ), +// ), +// const SizedBox(height: 20), +// const BodyMedium( +// text: 'Others', +// fontWeight: FontWeight.w700, +// fontSize: 12, +// fontColor: ColorsManager.grayColor, +// ), +// const SizedBox(height: 5), +// DefaultContainer( +// child: Column( +// children: [ +// SettingWidget( +// onTap: () { +// Navigator.of(context).push( +// MaterialPageRoute( +// builder: (context) => +// ShareSosPage(device: device!)), +// ); +// }, +// text: 'Share Device', +// icon: Assets.shareIcon, +// ), +// const Divider( +// color: ColorsManager.dividerColor, +// ), +// SettingWidget( +// onTap: () { +// Navigator.of(context).push( +// MaterialPageRoute( +// builder: (context) => +// FaqSosPage(device: device!)), +// ); +// }, +// text: 'Device FAQ', +// icon: Assets.faqIcon, +// ), +// const Divider( +// color: ColorsManager.dividerColor, +// ), +// SettingWidget( +// onTapUpdate: () { +// showDialog( +// context: context, +// builder: (context) { +// return UpdateInfoDialog( +// cancelTab: () { +// Navigator.of(context).pop(); +// }, +// confirmTab: () { +// Navigator.of(context).pop(); +// }, +// ); +// }, +// ); +// }, +// isUpdate: true, +// onTap: () { +// Navigator.of(context).push( +// MaterialPageRoute( +// builder: (context) => +// const SosUpdatePage()), +// ); +// }, +// text: 'Device Update', +// icon: Assets.updateIcon, +// ), +// ], +// ), +// ), +// const SizedBox(height: 20), +// InkWell( +// onTap: () { +// showModalBottomSheet( +// context: context, +// builder: (BuildContext context) { +// return Container( +// height: 200, +// padding: const EdgeInsets.all(16.0), +// child: Column( +// mainAxisSize: MainAxisSize.min, +// children: [ +// const BodyMedium( +// text: 'Remove Device', +// fontWeight: FontWeight.w700, +// fontSize: 16, +// fontColor: ColorsManager.red, +// ), +// const SizedBox(height: 10), +// const SizedBox( +// width: 250, +// child: Divider( +// color: ColorsManager.dividerColor, +// ), +// ), +// const SizedBox(height: 10), +// Row( +// mainAxisAlignment: +// MainAxisAlignment.spaceBetween, +// children: [ +// InkWell( +// onTap: () { +// showDialog( +// context: context, +// builder: (context) { +// return DisconnectDeviceDialog( +// cancelTab: () { +// Navigator.of(context).pop(); +// }, +// confirmTab: () { +// Navigator.of(context).pop(); +// }, +// ); +// }, +// ); +// }, +// child: const BodyMedium( +// text: 'Disconnect Device', +// fontWeight: FontWeight.w400, +// fontSize: 15, +// fontColor: +// ColorsManager.textPrimaryColor, +// ), +// ), +// const Icon( +// Icons.keyboard_arrow_right, +// color: ColorsManager.textGray, +// ) +// ], +// ), +// const SizedBox(height: 20), +// Row( +// mainAxisAlignment: +// MainAxisAlignment.spaceBetween, +// children: [ +// InkWell( +// onTap: () { +// showDialog( +// context: context, +// builder: (context) { +// return DisconnectWipeData( +// cancelTab: () { +// Navigator.of(context).pop(); +// }, +// confirmTab: () { +// _bloc.add( +// DeleteDeviceEvent()); +// }, +// ); +// }, +// ); +// }, +// child: const BodyMedium( +// text: +// 'Disconnect Device and Wipe Data', +// fontWeight: FontWeight.w400, +// fontSize: 15, +// fontColor: +// ColorsManager.textPrimaryColor, +// ), +// ), +// const Icon( +// Icons.keyboard_arrow_right, +// color: ColorsManager.textGray, +// ) +// ], +// ), +// ], +// ), +// ); +// }, +// ); +// }, +// child: const Center( +// child: BodyMedium( +// text: 'Remove Device', +// fontWeight: FontWeight.w400, +// fontSize: 15, +// fontColor: ColorsManager.red, +// ), +// ), +// ), +// ], +// ); +// }, +// ), +// ), +// ); +// } +// } diff --git a/lib/services/api/api_links_endpoints.dart b/lib/services/api/api_links_endpoints.dart index 1c41a5b..ec41710 100644 --- a/lib/services/api/api_links_endpoints.dart +++ b/lib/services/api/api_links_endpoints.dart @@ -218,7 +218,6 @@ abstract class ApiEndpoints { static const String fourSceneByName = '/device/{deviceUuid}/scenes?switchName={switchName}'; - - static const String resetDevice = - '/factory/reset/{deviceUuid}'; + static const String resetDevice = '/factory/reset/{deviceUuid}'; + static const String unAssignScenesDevice = '/factory/reset/{deviceUuid}'; } From 80d92de6259e1d370817dada5d81100ee1052020 Mon Sep 17 00:00:00 2001 From: mohammad Date: Tue, 26 Nov 2024 16:57:28 +0300 Subject: [PATCH 25/29] fixes issues --- .../6_scene_switch/select_scene_page.dart | 56 ++++++++++++------- 1 file changed, 35 insertions(+), 21 deletions(-) diff --git a/lib/features/devices/view/widgets/6_scene_switch/select_scene_page.dart b/lib/features/devices/view/widgets/6_scene_switch/select_scene_page.dart index 4f0c2da..df57018 100644 --- a/lib/features/devices/view/widgets/6_scene_switch/select_scene_page.dart +++ b/lib/features/devices/view/widgets/6_scene_switch/select_scene_page.dart @@ -244,34 +244,48 @@ class SceneItem extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Column( - crossAxisAlignment: CrossAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ if (!disablePlayButton) - Image.memory( - icon, - height: 32, - width: 32, - fit: BoxFit.fill, - errorBuilder: (context, error, stackTrace) => Image.asset( - Assets.assetsIconsLogo, - height: 32, - width: 32, - fit: BoxFit.fill), + Expanded( + child: Image.memory( + icon, + height: 32, + width: 32, + fit: BoxFit.fill, + errorBuilder: (context, error, stackTrace) => Image.asset( + Assets.assetsIconsLogo, + height: 32, + width: 32, + fit: BoxFit.fill), + ), + ), + Spacer(), + Expanded( + child: Container( + width: MediaQuery.of(context).size.width * 0.3, + child: Row( + children: [ + BodyMedium( + text: title, + style: const TextStyle( + fontSize: 17, + fontWeight: FontWeight.w700, + color: ColorsManager.secondaryTextColor), + textAlign: TextAlign.center, + ), + ], + ), ), - BodyMedium( - text: title, - style: const TextStyle( - fontSize: 17, - fontWeight: FontWeight.w700, - color: ColorsManager.secondaryTextColor), - textAlign: TextAlign.center, ), ], ), - CircularCheckbox( - value: value, - onChanged: (isSelected) => onChanged(isSelected!), + Expanded( + child: CircularCheckbox( + value: value, + onChanged: (isSelected) => onChanged(isSelected!), + ), ), ], ), From 51b1438d0ead6f372cccdbae60c5c2f79ddcdfca Mon Sep 17 00:00:00 2001 From: mohammad Date: Wed, 27 Nov 2024 14:23:00 +0300 Subject: [PATCH 26/29] fixes issues --- .../6_scene_switch_bloc/6_scene_bloc.dart | 240 ++--------- .../6_scene_switch_bloc/6_scene_event.dart | 14 +- .../device_scene_bloc.dart | 102 +---- .../device_scene_event.dart | 8 +- .../bloc/four_scene_bloc/four_scene_bloc.dart | 260 +----------- .../four_scene_bloc/four_scene_event.dart | 9 + .../view/device_settings/create_group.dart | 394 +++++++++--------- .../view/device_settings/faq_page.dart | 17 +- .../view/device_settings/update_page.dart | 20 +- .../6_scene_switch/select_scene_page.dart | 9 +- .../6_scene_switch/six_scene_screen.dart | 12 +- .../four_scene_switch/four_scene_screen.dart | 12 +- .../four_select_scene_page.dart | 84 ++-- lib/services/api/api_links_endpoints.dart | 5 +- lib/services/api/devices_api.dart | 29 +- 15 files changed, 405 insertions(+), 810 deletions(-) diff --git a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart index add645b..48fe85f 100644 --- a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart +++ b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_bloc.dart @@ -7,14 +7,11 @@ import 'package:syncrow_app/features/devices/bloc/6_scene_switch_bloc/6_scene_st 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/group_devices_model.dart'; import 'package:syncrow_app/features/devices/model/device_info_model.dart'; -import 'package:syncrow_app/features/devices/model/six_scene_question_model.dart'; import 'package:syncrow_app/features/devices/model/six_scene_model.dart'; import 'package:syncrow_app/features/devices/model/status_model.dart'; import 'package:syncrow_app/features/devices/model/subspace_model.dart'; import 'package:syncrow_app/features/scene/model/scenes_model.dart'; -import 'package:syncrow_app/generated/assets.dart'; import 'package:syncrow_app/services/api/devices_api.dart'; import 'package:syncrow_app/services/api/home_management_api.dart'; import 'package:syncrow_app/services/api/scene_api.dart'; @@ -27,29 +24,21 @@ class SixSceneBloc extends Bloc { required this.sixSceneId, }) : super(const SixSceneState()) { on(_fetchDeviceStatus); - on(_toggleNotification); - on(_changeName); - on(_onSearchFaq); on(changeSwitchStatus); on(_onLoadScenes); on(searchScene); on(_onSaveSelection); on(_onOptionSelected); - on(_addDeviceToGroup); - on(_removeDeviceFromGroup); on(_fetchFourSceneSwitches); on(assignScene); on(getSceneByName); on(_selectScene); on(fetchDeviceInfo); - on(saveName); on(_assignDevice); on(_fetchRoomsAndDevices); - on(_onSixSceneInitial); on(deleteDevice); on(_toggleLowBattery); - on(_toggleUpdate); - on(_toggleHelpful); + on(_unAssignScene); } final TextEditingController nameController = @@ -156,6 +145,22 @@ class SixSceneBloc extends Bloc { } } + void _unAssignScene( + UnAssignSceneEvent event, Emitter emit) async { + try { + emit(SixSceneLoadingState()); + if (_hasSelectionChanged) { + var response = await DevicesAPI.unAssignScenesDevice( + deviceUuid: event.switchSceneUuid); + CustomSnackBar.displaySnackBar('Save Successfully'); + emit(SaveSelectionSuccessState()); + } + } catch (e) { + emit(SixSceneFailedState(errorMessage: e.toString())); + return; + } + } + deleteDevice(DeleteDeviceEvent event, Emitter emit) async { try { emit(SixSceneLoadingState()); @@ -226,9 +231,16 @@ class SixSceneBloc extends Bloc { String selectedSceneId = ''; - _selectScene(SelectSceneEvent event, Emitter emit) { + + _selectScene(SelectSceneEvent event, Emitter emit) { emit(SixSceneLoadingState()); - selectedSceneId = event.unitId; + if (event.isSelected == false) { + selectedSceneId = ''; + selectedFormApiSceneId = ''; + emit(SceneSelectionUpdatedState(selectedSceneId: selectedSceneId)); + } else { + selectedSceneId = event.selectedSceneId; + } emit(SceneSelectionUpdatedState(selectedSceneId: selectedSceneId)); } @@ -238,7 +250,8 @@ class SixSceneBloc extends Bloc { SexSceneSwitchInitial event, Emitter emit) async { emit(SixSceneLoadingState()); try { - var response = await DevicesAPI.getFourSceneInfo(sixSceneId); + var response = await DevicesAPI.getDeviceSceneInfo(sixSceneId); + Map sceneTitles = { "scene_1": '', "scene_2": '', @@ -272,11 +285,16 @@ class SixSceneBloc extends Bloc { void assignScene(AssignDeviceScene event, Emitter emit) async { emit(SixSceneLoadingState()); try { - final response = await DevicesAPI.postFourSceneInfo( - deviceId: sixSceneId, - sceneUuid: event.sceneUuid, - spaceUuid: event.unit!.id, - switchName: event.switchName); + if (event.sceneUuid == '') { + final response = await DevicesAPI.unAssignScenesDevice( + deviceUuid: sixSceneId, switchName: event.switchName); + } else { + final response = await DevicesAPI.postDeviceSceneInfo( + deviceId: sixSceneId, + sceneUuid: event.sceneUuid, + spaceUuid: event.unit!.id, + switchName: event.switchName); + } emit(SaveSelectionSuccessState()); CustomSnackBar.displaySnackBar('Save Successfully'); @@ -285,27 +303,6 @@ class SixSceneBloc extends Bloc { } } - void _onSearchFaq(SearchFaqEvent event, Emitter emit) { - emit(SixSceneLoadingState()); - List _faqQuestions = faqQuestions.where((question) { - return question.question - .toLowerCase() - .contains(event.query.toLowerCase()); - }).toList(); - emit(FaqSearchState(filteredFaqQuestions: _faqQuestions)); - } - - void _toggleNotification( - ToggleNotificationEvent event, Emitter emit) async { - emit(LoadingNewSate(device: deviceStatus)); - try { - closingReminder = event.isClosingEnabled; - emit(UpdateState(device: deviceStatus)); - } catch (e) { - emit(SixSceneFailedState(errorMessage: e.toString())); - } - } - DeviceReport recordGroups = DeviceReport(startTime: '0', endTime: '0', data: []); @@ -355,6 +352,7 @@ class SixSceneBloc extends Bloc { } catch (e) { emit(const SixSceneFailedState(errorMessage: 'Something went wrong')); } + emit(SuccessState()); } @@ -368,7 +366,7 @@ class SixSceneBloc extends Bloc { filteredScenes = event.query.isEmpty ? allScenes : allScenes.where((scene) { - final sceneName = scene.name.toLowerCase() ?? ''; + final sceneName = scene.name.toLowerCase(); return sceneName.contains(event.query.toLowerCase()); }).toList(); emit(SearchResultsState()); @@ -393,162 +391,4 @@ class SixSceneBloc extends Bloc { emit(SaveSelectionSuccessState()); } } - -//============================= group settings ================================= -//addDevicesIcon - List groupDevices = [ - GroupDevicesModel( - dec: 'Syncroom', icon: Assets.minusIcon, name: '6 Scene Switch') - ]; - - List devices = [ - GroupDevicesModel( - dec: 'Syncroom', icon: Assets.addDevicesIcon, name: '6 Scene Switch') - ]; - - // Handler for AddDeviceToGroup - void _addDeviceToGroup(AddDeviceToGroup event, Emitter emit) { - devices.remove(event.device); - groupDevices.add(event.device); - for (var device in groupDevices) { - device.icon = event.icon; - } - emit(UpdateStateList(groupDevices: groupDevices, devices: devices)); - } - - // Handler for RemoveDeviceFromGroup - void _removeDeviceFromGroup( - RemoveDeviceFromGroup event, Emitter emit) { - groupDevices.remove(event.device); - devices.add(event.device); - for (var device in groupDevices) { - device.icon = event.icon; - } - emit(UpdateStateList(groupDevices: groupDevices, devices: devices)); - } - - //======================= update device functions ============================ - ////////////////////////////////////////////////////////////////////////////// - - bool enableUpdate = false; - - void _toggleUpdate( - ToggleUpdateEvent event, Emitter emit) async { - try { - emit(SixSceneLoadingState()); - enableUpdate = event.isUpdateEnabled!; - emit(SaveState()); - } catch (e) { - emit(const SixSceneFailedState(errorMessage: 'Something went wrong')); - } - } - -//======================= q&a and questions ==================================== -//////////////////////////////////////////////////////////////////////////////// - bool isHelpful = false; - - void _toggleHelpful( - ToggleHelpfulEvent event, Emitter emit) async { - try { - emit(SixSceneLoadingState()); - isHelpful = event.isHelpful!; - emit(SaveState()); - } catch (e) { - emit(const SixSceneFailedState(errorMessage: 'Something went wrong')); - } - } - - final List faqQuestions = [ - SixSceneQuestionModel( - id: 1, - question: 'How does an SOS emergency button work?', - answer: - 'The SOS emergency button sends an alert to your contacts when pressed.', - ), - SixSceneQuestionModel( - id: 2, - question: 'How long will an SOS alarm persist?', - answer: - 'The SOS alarm will persist until it is manually turned off or after a set time.', - ), - SixSceneQuestionModel( - id: 3, - question: 'What should I do if the SOS button is unresponsive?', - answer: 'Try restarting the device. If it persists, contact support.', - ), - SixSceneQuestionModel( - id: 4, - question: 'Can I use the SOS feature without a network connection?', - answer: - 'No, a network connection is required to send the alert to your contacts.', - ), - SixSceneQuestionModel( - id: 5, - question: 'How often should I check the SOS battery?', - answer: - 'Check the SOS battery at least once a month to ensure it is operational.', - ), - ]; - - Future _onSixSceneInitial( - SixSceneInitialQuestion event, Emitter emit) async { - emit(SixSceneLoadingState()); - emit(FaqLoadedState(filteredFaqQuestions: faqQuestions)); - } - - //=========================== name setting =================================== - //////////////////////////////////////////////////////////////////////////////// - - void _changeName(ChangeNameEvent event, Emitter emit) { - emit(SixSceneLoadingState()); - editName = event.value!; - if (editName) { - Future.delayed(const Duration(milliseconds: 500), () { - focusNode.requestFocus(); - }); - } else { - focusNode.unfocus(); - } - emit(NameEditingState(editName: editName)); - } - - Future saveName( - SaveNameEvent event, Emitter emit) async { - if (_validateInputs()) return; - try { - add(const ChangeNameEvent(value: false)); - isSaving = true; - emit(SixSceneLoadingState()); - var response = await DevicesAPI.putDeviceName( - deviceId: sixSceneId, deviceName: nameController.text); - add(const SixSceneInitialInfo()); - CustomSnackBar.displaySnackBar('Save Successfully'); - emit(SaveState()); - } catch (e) { - emit(SixSceneFailedState(errorMessage: e.toString())); - } finally { - isSaving = false; - } - } - - bool _validateInputs() { - final nameError = fullNameValidator(nameController.text); - if (nameError != null) { - CustomSnackBar.displaySnackBar(nameError); - return true; - } - return false; - } - - String? fullNameValidator(String? value) { - if (value == null) return 'name is required'; - final withoutExtraSpaces = value.replaceAll(RegExp(r"\s+"), ' ').trim(); - if (withoutExtraSpaces.length < 2 || withoutExtraSpaces.length > 30) { - return 'name must be between 2 and 30 characters long'; - } - if (RegExp(r"/[^ a-zA-Z0-9-\']/").hasMatch(withoutExtraSpaces)) { - return 'Only alphanumeric characters, space, dash and single quote are allowed'; - } - return null; - } } diff --git a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart index 7f95867..0cf3437 100644 --- a/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart +++ b/lib/features/devices/bloc/6_scene_switch_bloc/6_scene_event.dart @@ -24,6 +24,11 @@ class SaveNameEvent extends SixSceneEvent { const SaveNameEvent(); } +class UnAssignSceneEvent extends SixSceneEvent { + final String switchSceneUuid; + const UnAssignSceneEvent({required this.switchSceneUuid}); +} + class SixSceneInitialInfo extends SixSceneEvent { const SixSceneInitialInfo(); } @@ -91,12 +96,17 @@ class LoadScenes extends SixSceneEvent { } class SelectSceneEvent extends SixSceneEvent { - final String unitId; + final String selectedSceneId; + final bool isSelected; + // final String unitId; const SelectSceneEvent({ - required this.unitId, + // required this.unitId, + required this.selectedSceneId, + required this.isSelected, }); } + class SearchScenesEvent extends SixSceneEvent { final String query; const SearchScenesEvent({ diff --git a/lib/features/devices/bloc/device_settings_bloc/device_scene_bloc.dart b/lib/features/devices/bloc/device_settings_bloc/device_scene_bloc.dart index 4c034b7..4c91650 100644 --- a/lib/features/devices/bloc/device_settings_bloc/device_scene_bloc.dart +++ b/lib/features/devices/bloc/device_settings_bloc/device_scene_bloc.dart @@ -4,7 +4,6 @@ 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/device_settings_bloc/device_scene_event.dart'; import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_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/four_scene_model.dart'; @@ -18,7 +17,6 @@ import 'package:syncrow_app/features/scene/model/scenes_model.dart'; import 'package:syncrow_app/generated/assets.dart'; import 'package:syncrow_app/services/api/devices_api.dart'; import 'package:syncrow_app/services/api/home_management_api.dart'; -import 'package:syncrow_app/services/api/scene_api.dart'; import 'package:syncrow_app/services/api/spaces_api.dart'; import 'package:syncrow_app/utils/helpers/snack_bar.dart'; @@ -34,23 +32,20 @@ class DeviceSettingBloc extends Bloc { on(_changeName); on(_onSearchFaq); on(_fetchRoomsAndDevices); - on(changeSwitchStatus); on(_onLoadSettings); on(searchSetting); on(_assignDevice); - on(_onOptionSelected); on(_addDeviceToGroup); on(_removeDeviceFromGroup); on(_onDeviceSettingInitial); on(_fetchDeviceSetting); - on(_fetchDeviceSettingSwitches); - on(assignSetting); on(getSettingByName); on(_selectSetting); on(deleteDevice); on(_toggleLowBattery); on(_toggleUpdate); on(_toggleHelpful); + on(_onOptionSelected); } final TextEditingController nameController = @@ -133,64 +128,6 @@ class DeviceSettingBloc extends Bloc { } } - void _onOptionSelected( - SelectOptionEvent event, Emitter emit) { - emit(DeviceSettingLoadingState()); - _selectedOption = event.selectedOption; - _hasSelectionChanged = true; - emit(OptionSelectedState( - selectedOption: _selectedOption, - hasSelectionChanged: _hasSelectionChanged)); - } - - void _fetchDeviceSettingSwitches(DeviceSettingSwitchInitial event, - Emitter emit) async { - emit(DeviceSettingLoadingState()); - try { - var response = await DevicesAPI.getFourSceneInfo(deviceId); - Map sceneTitles = { - "scene_1": '', - "scene_2": '', - "scene_3": '', - "scene_4": '', - }; - for (var item in response) { - if (item["switchName"] != null) { - sceneTitles[item["switchName"]] = item["scene"]["name"] ?? ''; - } - } - FourSceneModelState deviceStatus = FourSceneModelState( - scene_1: sceneTitles["scene_1"] ?? '', - scene_2: sceneTitles["scene_2"] ?? '', - scene_3: sceneTitles["scene_3"] ?? '', - scene_4: sceneTitles["scene_4"] ?? '', - scene_id_group_id: '', - switch_backlight: '', - ); - emit(UpdateState(device: deviceStatus)); - } catch (e) { - emit(DeviceSettingFailedState(errorMessage: e.toString())); - return; - } - } - - void assignSetting( - AssignDeviceSetting event, Emitter emit) async { - emit(DeviceSettingLoadingState()); - try { - final response = await DevicesAPI.postFourSceneInfo( - deviceId: deviceId, - sceneUuid: event.sceneUuid, - spaceUuid: event.unit!.id, - switchName: event.switchName); - - emit(SaveSelectionSuccessState()); - CustomSnackBar.displaySnackBar('Save Successfully'); - } catch (e) { - emit(DeviceSettingFailedState(errorMessage: e.toString())); - } - } - void _fetchDeviceSetting( FetchDeviceSetting event, Emitter emit) async { emit(DeviceSettingLoadingState()); @@ -315,7 +252,7 @@ class DeviceSettingBloc extends Bloc { ), ]; - bool isHelpful = false; + bool? isHelpful; void _toggleHelpful( ToggleHelpfulEvent event, Emitter emit) async { @@ -338,30 +275,6 @@ class DeviceSettingBloc extends Bloc { List allDevices = []; List roomsList = []; bool switchStatus = true; - Future changeSwitchStatus( - ChangeSwitchStatusEvent event, Emitter emit) async { - try { - emit(DeviceSettingLoadingState()); - switchStatus = deviceStatus.switch_backlight; - switchStatus = !switchStatus; - final response = await DevicesAPI.controlDevice( - DeviceControlModel( - deviceId: deviceId, - code: 'switch_backlight', - value: switchStatus), - deviceId); - deviceStatus.switch_backlight = switchStatus; - Future.delayed(const Duration(milliseconds: 200), () { - add(const DeviceSettingSwitchInitial()); - }); - Future.delayed(const Duration(milliseconds: 200), () { - emit(ChangeSwitchState(isEnable: switchStatus)); - emit(UpdateState(device: deviceStatus)); - }); - } catch (_) { - add(const DeviceSettingInitial()); - } - } Future _onLoadSettings( LoadSettings event, Emitter emit) async { @@ -519,6 +432,7 @@ class DeviceSettingBloc extends Bloc { var response = await DevicesAPI.putDeviceName( deviceId: deviceId, deviceName: nameController.text); add(const DeviceSettingInitialInfo()); + await HomeCubit.getInstance().fetchUnitsByUserId(); CustomSnackBar.displaySnackBar('Save Successfully'); emit(SaveState()); } catch (e) { @@ -556,4 +470,14 @@ class DeviceSettingBloc extends Bloc { return; } } + + void _onOptionSelected( + SelectOptionEvent event, Emitter emit) { + emit(DeviceSettingLoadingState()); + _selectedOption = event.selectedOption; + _hasSelectionChanged = true; + emit(OptionSelectedState( + selectedOption: _selectedOption, + hasSelectionChanged: _hasSelectionChanged)); + } } diff --git a/lib/features/devices/bloc/device_settings_bloc/device_scene_event.dart b/lib/features/devices/bloc/device_settings_bloc/device_scene_event.dart index 5b6330f..bca5b97 100644 --- a/lib/features/devices/bloc/device_settings_bloc/device_scene_event.dart +++ b/lib/features/devices/bloc/device_settings_bloc/device_scene_event.dart @@ -59,7 +59,7 @@ class DeviceSettingInitialQuestion extends DeviceSettingEvent { const DeviceSettingInitialQuestion(); } -class ChangeSwitchStatusEvent extends DeviceSettingEvent {} +// class ChangeSwitchStatusEvent extends DeviceSettingEvent {} class FetchRoomsEvent extends DeviceSettingEvent { final SpaceModel unit; @@ -139,9 +139,9 @@ class AssignRoomEvent extends DeviceSettingEvent { class FetchDeviceSetting extends DeviceSettingEvent {} -class DeviceSettingSwitchInitial extends DeviceSettingEvent { - const DeviceSettingSwitchInitial(); -} +// class DeviceSettingSwitchInitial extends DeviceSettingEvent { +// const DeviceSettingSwitchInitial(); +// } class AssignDeviceSetting extends DeviceSettingEvent { final String? sceneUuid; diff --git a/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart b/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart index f664159..d58621b 100644 --- a/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart +++ b/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart @@ -1,25 +1,19 @@ import 'dart:async'; 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/four_scene_bloc/four_scene_event.dart'; import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_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/four_scene_model.dart'; -import 'package:syncrow_app/features/devices/model/question_model.dart'; import 'package:syncrow_app/features/devices/model/four_scene_switch_model.dart'; -import 'package:syncrow_app/features/devices/model/group_devices_model.dart'; import 'package:syncrow_app/features/devices/model/device_info_model.dart'; import 'package:syncrow_app/features/devices/model/status_model.dart'; import 'package:syncrow_app/features/devices/model/subspace_model.dart'; import 'package:syncrow_app/features/scene/model/scenes_model.dart'; -import 'package:syncrow_app/generated/assets.dart'; import 'package:syncrow_app/services/api/devices_api.dart'; -import 'package:syncrow_app/services/api/home_management_api.dart'; import 'package:syncrow_app/services/api/scene_api.dart'; -import 'package:syncrow_app/services/api/spaces_api.dart'; import 'package:syncrow_app/utils/helpers/snack_bar.dart'; class FourSceneBloc extends Bloc { @@ -29,28 +23,17 @@ class FourSceneBloc extends Bloc { }) : super(const FourSceneState()) { on(_fetchDeviceStatus); on(fetchDeviceInfo); - on(saveName); on(_toggleNotification); - on(_changeName); - on(_onSearchFaq); - on(_fetchRoomsAndDevices); on(changeSwitchStatus); on(_onLoadScenes); on(searchScene); - on(_assignDevice); on(_onOptionSelected); - on(_addDeviceToGroup); - on(_removeDeviceFromGroup); - on(_onFourSceneInitial); on(_fetchDeviceScene); on(_fetchFourSceneSwitches); on(assignScene); on(getSceneByName); on(_selectScene); - on(deleteDevice); on(_toggleLowBattery); - on(_toggleUpdate); - on(_toggleHelpful); } final TextEditingController nameController = @@ -116,7 +99,15 @@ class FourSceneBloc extends Bloc { _selectScene(SelectSceneEvent event, Emitter emit) { emit(FourSceneLoadingState()); - selectedSceneId = event.selectedSceneId; + print('-------${event.selectedSceneId}------'); + print('-------${event.isSelected}------'); + if (event.isSelected == false) { + selectedSceneId = ''; + selectedFormApiSceneId = ''; + emit(SceneSelectionUpdatedState(selectedSceneId: selectedSceneId)); + } else { + selectedSceneId = event.selectedSceneId; + } emit(SceneSelectionUpdatedState(selectedSceneId: selectedSceneId)); } @@ -147,7 +138,7 @@ class FourSceneBloc extends Bloc { FourSceneSwitchInitial event, Emitter emit) async { emit(FourSceneLoadingState()); try { - var response = await DevicesAPI.getFourSceneInfo(fourSceneId); + var response = await DevicesAPI.getDeviceSceneInfo(fourSceneId); Map sceneTitles = { "scene_1": '', "scene_2": '', @@ -178,11 +169,16 @@ class FourSceneBloc extends Bloc { AssignDeviceScene event, Emitter emit) async { emit(FourSceneLoadingState()); try { - final response = await DevicesAPI.postFourSceneInfo( - deviceId: fourSceneId, - sceneUuid: event.sceneUuid, - spaceUuid: event.unit!.id, - switchName: event.switchName); + if (event.sceneUuid == '') { + final response = await DevicesAPI.unAssignScenesDevice( + deviceUuid: fourSceneId, switchName: event.switchName); + } else { + final response = await DevicesAPI.postDeviceSceneInfo( + deviceId: fourSceneId, + sceneUuid: event.sceneUuid, + spaceUuid: event.unit!.id, + switchName: event.switchName); + } emit(SaveSelectionSuccessState()); CustomSnackBar.displaySnackBar('Save Successfully'); @@ -191,6 +187,7 @@ class FourSceneBloc extends Bloc { } } + void _fetchDeviceScene( FetchDeviceScene event, Emitter emit) async { emit(FourSceneLoadingState()); @@ -256,16 +253,6 @@ class FourSceneBloc extends Bloc { } } - void _onSearchFaq(SearchFaqEvent event, Emitter emit) { - emit(FourSceneLoadingState()); - List _faqQuestions = faqQuestions.where((question) { - return question.question - .toLowerCase() - .contains(event.query.toLowerCase()); - }).toList(); - emit(FaqSearchState(filteredFaqQuestions: _faqQuestions)); - } - //============================ assign Device ================================== ////////////////////////////////////////////////////////////////////////////// @@ -283,56 +270,6 @@ class FourSceneBloc extends Bloc { DeviceReport recordGroups = DeviceReport(startTime: '0', endTime: '0', data: []); - //========================= Question and faq ================================ - - final List faqQuestions = [ - QuestionModel( - id: 1, - question: - 'How does an 4 Scene Switch work? How long will an 4 Scene Switch persist?', - answer: - 'Yes. In scenes with high detection requirements, we recommend that you choose phone or message notification in Automation.', - ), - QuestionModel( - id: 2, - question: 'Does the 4 Scene Switch support sending notifications?', - answer: - 'The SOS alarm will persist until it is manually turned off or after a set time.', - ), - QuestionModel( - id: 3, - question: - 'Why does the data statistics in the device panel not show the correct data?', - answer: 'Try restarting the device. If it persists, contact support.', - ), - QuestionModel( - id: 4, - question: - 'How long will the App show offline after a device (low-power devices and normal devices) is powered...', - answer: - 'No, a network connection is required to send the alert to your contacts.', - ), - ]; - - bool isHelpful = false; - - void _toggleHelpful( - ToggleHelpfulEvent event, Emitter emit) async { - try { - emit(FourSceneLoadingState()); - isHelpful = event.isHelpful!; - emit(SaveState()); - } catch (e) { - emit(const FourSceneFailedState(errorMessage: 'Something went wrong')); - } - } - - Future _onFourSceneInitial( - FourSceneInitialQuestion event, Emitter emit) async { - emit(FourSceneLoadingState()); - emit(FaqLoadedState(filteredFaqQuestions: faqQuestions)); - } - List allDevices = []; List roomsList = []; bool switchStatus = true; @@ -393,159 +330,4 @@ class FourSceneBloc extends Bloc { }).toList(); emit(SearchResultsState()); } - - List groupDevices = [ - GroupDevicesModel( - dec: 'Syncroom', icon: Assets.minusIcon, name: '6 Scene Switch') - ]; - - List devices = [ - GroupDevicesModel( - dec: 'Syncroom', icon: Assets.addDevicesIcon, name: '6 Scene Switch') - ]; - - // Handler for AddDeviceToGroup - void _addDeviceToGroup(AddDeviceToGroup event, Emitter emit) { - devices.remove(event.device); - groupDevices.add(event.device); - for (var device in groupDevices) { - device.icon = event.icon; - } - emit(UpdateStateList(groupDevices: groupDevices, devices: devices)); - } - - // Handler for RemoveDeviceFromGroup - void _removeDeviceFromGroup( - RemoveDeviceFromGroup event, Emitter emit) { - groupDevices.remove(event.device); - devices.add(event.device); - for (var device in groupDevices) { - device.icon = event.icon; - } - emit(UpdateStateList(groupDevices: groupDevices, devices: devices)); - } - - //=========================== assign device to room ========================== - - void _assignDevice( - AssignRoomEvent event, Emitter emit) async { - try { - emit(FourSceneLoadingState()); - if (_hasSelectionChanged) { - await HomeManagementAPI.assignDeviceToRoom(event.unit.community.uuid, - event.unit.id, event.roomId, fourSceneId); - final devicesList = await DevicesAPI.getDevicesByRoomId( - communityUuid: event.unit.community.uuid, - spaceUuid: event.unit.id, - roomId: event.roomId); - List allDevicesIds = []; - allDevices.forEach((element) { - allDevicesIds.add(element.uuid!); - }); - await HomeCubit.getInstance().fetchUnitsByUserId(); - CustomSnackBar.displaySnackBar('Save Successfully'); - - emit(SaveSelectionSuccessState()); - } - } catch (e) { - emit(const FourSceneFailedState(errorMessage: 'Something went wrong')); - return; - } - } - - void _fetchRoomsAndDevices( - FetchRoomsEvent event, Emitter emit) async { - try { - emit(FourSceneLoadingState()); - roomsList = await SpacesAPI.getSubSpaceBySpaceId( - event.unit.community.uuid, event.unit.id); - emit(FetchRoomsState(devicesList: allDevices, roomsList: roomsList)); - } catch (e) { - emit(const FourSceneFailedState(errorMessage: 'Something went wrong')); - return; - } - } - -//============================ setting name ================================== -////////////////////////////////////////////////////////////////////////////// - - void _changeName(ChangeNameEvent event, Emitter emit) { - emit(FourSceneLoadingState()); - editName = event.value!; - if (editName) { - Future.delayed(const Duration(milliseconds: 500), () { - focusNode.requestFocus(); - }); - } else { - focusNode.unfocus(); - } - emit(NameEditingState(editName: editName)); - } - - bool _validateInputs() { - final nameError = fullNameValidator(nameController.text); - if (nameError != null) { - CustomSnackBar.displaySnackBar(nameError); - return true; - } - return false; - } - - String? fullNameValidator(String? value) { - if (value == null) return 'name is required'; - final withoutExtraSpaces = value.replaceAll(RegExp(r"\s+"), ' ').trim(); - if (withoutExtraSpaces.length < 2 || withoutExtraSpaces.length > 30) { - return 'name must be between 2 and 30 characters long'; - } - if (RegExp(r"/[^ a-zA-Z0-9-\']/").hasMatch(withoutExtraSpaces)) { - return 'Only alphanumeric characters, space, dash and single quote are allowed'; - } - return null; - } - - Future saveName( - SaveNameEvent event, Emitter emit) async { - if (_validateInputs()) return; - try { - add(const ChangeNameEvent(value: false)); - isSaving = true; - emit(FourSceneLoadingState()); - var response = await DevicesAPI.putDeviceName( - deviceId: fourSceneId, deviceName: nameController.text); - add(const FourSceneInitialInfo()); - CustomSnackBar.displaySnackBar('Save Successfully'); - emit(SaveState()); - } catch (e) { - emit(FourSceneFailedState(errorMessage: e.toString())); - } finally { - isSaving = false; - } - } - -//====================== update device ============================== - - bool enableUpdate = false; - - void _toggleUpdate( - ToggleUpdateEvent event, Emitter emit) async { - try { - emit(FourSceneLoadingState()); - enableUpdate = event.isUpdateEnabled!; - emit(SaveState()); - } catch (e) { - emit(const FourSceneFailedState(errorMessage: 'Something went wrong')); - } - } - - deleteDevice(DeleteDeviceEvent event, Emitter emit) async { - try { - emit(FourSceneLoadingState()); - var response = await DevicesAPI.resetDevise(devicesUuid: fourSceneId); - CustomSnackBar.displaySnackBar('Reset Successfully'); - emit(UpdateState(device: deviceStatus)); - } catch (e) { - emit(FourSceneFailedState(errorMessage: e.toString())); - return; - } - } } diff --git a/lib/features/devices/bloc/four_scene_bloc/four_scene_event.dart b/lib/features/devices/bloc/four_scene_bloc/four_scene_event.dart index f96fc61..a543ac3 100644 --- a/lib/features/devices/bloc/four_scene_bloc/four_scene_event.dart +++ b/lib/features/devices/bloc/four_scene_bloc/four_scene_event.dart @@ -84,10 +84,12 @@ class LoadScenes extends FourSceneEvent { class SelectSceneEvent extends FourSceneEvent { final String selectedSceneId; + final bool isSelected; // final String unitId; const SelectSceneEvent({ // required this.unitId, required this.selectedSceneId, + required this.isSelected, }); } @@ -143,6 +145,13 @@ class FourSceneSwitchInitial extends FourSceneEvent { const FourSceneSwitchInitial(); } +class UnAssignSceneEvent extends FourSceneEvent { + final String deviceUuid; + final String switchName; + const UnAssignSceneEvent( + {required this.deviceUuid, required this.switchName}); +} + class AssignDeviceScene extends FourSceneEvent { final String? sceneUuid; final String? switchName; diff --git a/lib/features/devices/view/device_settings/create_group.dart b/lib/features/devices/view/device_settings/create_group.dart index cb27656..a756ca1 100644 --- a/lib/features/devices/view/device_settings/create_group.dart +++ b/lib/features/devices/view/device_settings/create_group.dart @@ -1,200 +1,200 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:flutter_svg/svg.dart'; -import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart'; -import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_event.dart'; -import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_state.dart'; -import 'package:syncrow_app/features/devices/model/device_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/features/shared_widgets/text_widgets/body_large.dart'; -import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart'; -import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart'; -import 'package:syncrow_app/generated/assets.dart'; -import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; +// import 'package:flutter/material.dart'; +// import 'package:flutter_bloc/flutter_bloc.dart'; +// import 'package:flutter_svg/svg.dart'; +// import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart'; +// import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_event.dart'; +// import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_state.dart'; +// import 'package:syncrow_app/features/devices/model/device_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/features/shared_widgets/text_widgets/body_large.dart'; +// import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart'; +// import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart'; +// import 'package:syncrow_app/generated/assets.dart'; +// import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; -class FourSceneCreateGroup extends StatelessWidget { - final DeviceModel? device; +// class FourSceneCreateGroup extends StatelessWidget { +// final DeviceModel? device; - const FourSceneCreateGroup({super.key, this.device}); +// const FourSceneCreateGroup({super.key, this.device}); - @override - Widget build(BuildContext context) { - return DefaultScaffold( - title: 'Create Group', - child: BlocProvider( - create: (context) => FourSceneBloc(fourSceneId: device?.uuid ?? '') - ..add(const FourSceneInitial()), - child: BlocBuilder( - builder: (context, state) { - final sensor = BlocProvider.of(context); - return state is LoadingNewSate - ? const Center( - child: DefaultContainer( - width: 50, - height: 50, - child: CircularProgressIndicator()), - ) - : Padding( - padding: const EdgeInsets.all(8.0), - child: Column( - children: [ - const Padding( - padding: EdgeInsets.only(left: 25, right: 25), - child: BodySmall( - text: - 'Devices in the same group can be controlled together', - fontColor: ColorsManager.primaryTextColor, - textAlign: TextAlign.center, - ), - ), - Flexible( - child: ListView.builder( - itemCount: sensor.groupDevices.length, - itemBuilder: (context, index) { - return InkWell( - onTap: () { - BlocProvider.of(context).add( - RemoveDeviceFromGroup( - sensor.groupDevices[index], - Assets.addDevicesIcon)); - }, - child: DefaultContainer( - child: Padding( - padding: const EdgeInsets.all(5.0), - child: Row( - crossAxisAlignment: - CrossAxisAlignment.start, - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Row( - children: [ - SvgPicture.asset( - sensor.groupDevices[index].icon!, - fit: BoxFit.contain, - ), - const SizedBox( - width: 15, - ), - BodyMedium( - text: sensor - .groupDevices[index].name!, - fontColor: - ColorsManager.primaryTextColor, - textAlign: TextAlign.center, - fontSize: 15, - ), - ], - ), - BodyMedium( - text: sensor.groupDevices[index].dec!, - fontColor: ColorsManager.grayColor, - textAlign: TextAlign.center, - fontSize: 15, - ), - ], - ), - )), - ); - }, - ), - ), - Flexible( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const BodyLarge( - text: 'Devices to be added', - fontColor: ColorsManager.grayColor, - textAlign: TextAlign.center, - fontSize: 12, - fontWeight: FontWeight.w700, - ), - const SizedBox( - height: 5, - ), - sensor.devices.isNotEmpty - ? Expanded( - child: ListView.builder( - itemCount: sensor.devices.length, - itemBuilder: (context, index) { - final device = sensor.devices[index]; - return GestureDetector( - onTap: () { - BlocProvider.of( - context) - .add(AddDeviceToGroup(device, - Assets.minusIcon)); - }, - child: DefaultContainer( - child: Padding( - padding: - const EdgeInsets.all(5.0), - child: Row( - crossAxisAlignment: - CrossAxisAlignment.start, - mainAxisAlignment: - MainAxisAlignment - .spaceBetween, - children: [ - Row( - children: [ - SvgPicture.asset( - device.icon!, - fit: BoxFit.contain, - ), - const SizedBox( - width: 15, - ), - BodyMedium( - text: device.name!, - fontColor: ColorsManager - .primaryTextColor, - textAlign: - TextAlign.center, - fontSize: 15, - ), - ], - ), - BodyMedium( - text: device.dec!, - fontColor: ColorsManager - .grayColor, - textAlign: - TextAlign.center, - fontSize: 15, - ), - ], - ), - ), - ), - ); - }, - ), - ) - : const Column( - children: [ - BodySmall( - text: - 'Currently no devices available to create group', - fontColor: ColorsManager.grayColor, - textAlign: TextAlign.center, - fontSize: 12, - fontWeight: FontWeight.w400, - ), - ], - ), - ], - ), - ), - const Spacer() - ], - ), - ); - }, - ), - ), - ); - } -} +// @override +// Widget build(BuildContext context) { +// return DefaultScaffold( +// title: 'Create Group', +// child: BlocProvider( +// create: (context) => FourSceneBloc(fourSceneId: device?.uuid ?? '') +// ..add(const FourSceneInitial()), +// child: BlocBuilder( +// builder: (context, state) { +// final sensor = BlocProvider.of(context); +// return state is LoadingNewSate +// ? const Center( +// child: DefaultContainer( +// width: 50, +// height: 50, +// child: CircularProgressIndicator()), +// ) +// : Padding( +// padding: const EdgeInsets.all(8.0), +// child: Column( +// children: [ +// const Padding( +// padding: EdgeInsets.only(left: 25, right: 25), +// child: BodySmall( +// text: +// 'Devices in the same group can be controlled together', +// fontColor: ColorsManager.primaryTextColor, +// textAlign: TextAlign.center, +// ), +// ), +// Flexible( +// child: ListView.builder( +// itemCount: sensor.groupDevices.length, +// itemBuilder: (context, index) { +// return InkWell( +// onTap: () { +// BlocProvider.of(context).add( +// RemoveDeviceFromGroup( +// sensor.groupDevices[index], +// Assets.addDevicesIcon)); +// }, +// child: DefaultContainer( +// child: Padding( +// padding: const EdgeInsets.all(5.0), +// child: Row( +// crossAxisAlignment: +// CrossAxisAlignment.start, +// mainAxisAlignment: +// MainAxisAlignment.spaceBetween, +// children: [ +// Row( +// children: [ +// SvgPicture.asset( +// sensor.groupDevices[index].icon!, +// fit: BoxFit.contain, +// ), +// const SizedBox( +// width: 15, +// ), +// BodyMedium( +// text: sensor +// .groupDevices[index].name!, +// fontColor: +// ColorsManager.primaryTextColor, +// textAlign: TextAlign.center, +// fontSize: 15, +// ), +// ], +// ), +// BodyMedium( +// text: sensor.groupDevices[index].dec!, +// fontColor: ColorsManager.grayColor, +// textAlign: TextAlign.center, +// fontSize: 15, +// ), +// ], +// ), +// )), +// ); +// }, +// ), +// ), +// Flexible( +// child: Column( +// crossAxisAlignment: CrossAxisAlignment.start, +// children: [ +// const BodyLarge( +// text: 'Devices to be added', +// fontColor: ColorsManager.grayColor, +// textAlign: TextAlign.center, +// fontSize: 12, +// fontWeight: FontWeight.w700, +// ), +// const SizedBox( +// height: 5, +// ), +// sensor.devices.isNotEmpty +// ? Expanded( +// child: ListView.builder( +// itemCount: sensor.devices.length, +// itemBuilder: (context, index) { +// final device = sensor.devices[index]; +// return GestureDetector( +// onTap: () { +// BlocProvider.of( +// context) +// .add(AddDeviceToGroup(device, +// Assets.minusIcon)); +// }, +// child: DefaultContainer( +// child: Padding( +// padding: +// const EdgeInsets.all(5.0), +// child: Row( +// crossAxisAlignment: +// CrossAxisAlignment.start, +// mainAxisAlignment: +// MainAxisAlignment +// .spaceBetween, +// children: [ +// Row( +// children: [ +// SvgPicture.asset( +// device.icon!, +// fit: BoxFit.contain, +// ), +// const SizedBox( +// width: 15, +// ), +// BodyMedium( +// text: device.name!, +// fontColor: ColorsManager +// .primaryTextColor, +// textAlign: +// TextAlign.center, +// fontSize: 15, +// ), +// ], +// ), +// BodyMedium( +// text: device.dec!, +// fontColor: ColorsManager +// .grayColor, +// textAlign: +// TextAlign.center, +// fontSize: 15, +// ), +// ], +// ), +// ), +// ), +// ); +// }, +// ), +// ) +// : const Column( +// children: [ +// BodySmall( +// text: +// 'Currently no devices available to create group', +// fontColor: ColorsManager.grayColor, +// textAlign: TextAlign.center, +// fontSize: 12, +// fontWeight: FontWeight.w400, +// ), +// ], +// ), +// ], +// ), +// ), +// const Spacer() +// ], +// ), +// ); +// }, +// ), +// ), +// ); +// } +// } diff --git a/lib/features/devices/view/device_settings/faq_page.dart b/lib/features/devices/view/device_settings/faq_page.dart index 542e47b..c1f64a3 100644 --- a/lib/features/devices/view/device_settings/faq_page.dart +++ b/lib/features/devices/view/device_settings/faq_page.dart @@ -1,9 +1,9 @@ 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/four_scene_bloc/four_scene_bloc.dart'; -import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_event.dart'; -import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_state.dart'; +import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_event.dart'; +import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_state.dart'; import 'package:syncrow_app/features/devices/model/device_model.dart'; import 'package:syncrow_app/features/devices/model/question_model.dart'; import 'package:syncrow_app/features/devices/view/device_settings/question_page.dart'; @@ -24,19 +24,18 @@ class FaqSettingPage extends StatelessWidget { return DefaultScaffold( title: 'FAQ', child: BlocProvider( - create: (context) => FourSceneBloc(fourSceneId: device?.uuid ?? '') - ..add(const FourSceneInitialQuestion()), - child: BlocBuilder( + create: (context) => DeviceSettingBloc(deviceId: device?.uuid ?? '') + ..add(const DeviceSettingInitialQuestion()), + child: BlocBuilder( builder: (context, state) { - final sensor = BlocProvider.of(context); - + final sensor = BlocProvider.of(context); List displayedQuestions = []; if (state is FaqSearchState) { displayedQuestions = state.filteredFaqQuestions; } else if (state is FaqLoadedState) { displayedQuestions = state.filteredFaqQuestions; } - return state is FourSceneLoadingState + return state is DeviceSettingLoadingState ? const Center( child: DefaultContainer( width: 50, diff --git a/lib/features/devices/view/device_settings/update_page.dart b/lib/features/devices/view/device_settings/update_page.dart index f77e913..60f9313 100644 --- a/lib/features/devices/view/device_settings/update_page.dart +++ b/lib/features/devices/view/device_settings/update_page.dart @@ -3,9 +3,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:percent_indicator/linear_percent_indicator.dart'; -import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart'; -import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_event.dart'; -import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_state.dart'; +import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_bloc.dart'; +import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_event.dart'; +import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_state.dart'; import 'package:syncrow_app/features/devices/view/device_settings/update_note.dart'; import 'package:syncrow_app/features/shared_widgets/default_button.dart'; import 'package:syncrow_app/features/shared_widgets/default_container.dart'; @@ -15,20 +15,22 @@ import 'package:syncrow_app/generated/assets.dart'; import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; class UpdatePageSetting extends StatelessWidget { - const UpdatePageSetting({super.key}); + final String? deviceId; + const UpdatePageSetting({super.key, this.deviceId}); @override Widget build(BuildContext context) { return DefaultScaffold( title: 'Device Update', child: BlocProvider( - create: (context) => - FourSceneBloc(fourSceneId: '')..add(const FourSceneInitial()), - child: BlocBuilder( + create: (context) => DeviceSettingBloc(deviceId: deviceId ?? '') + ..add(const DeviceSettingInitial()) + ..add(const DeviceSettingInitialInfo()), + child: BlocBuilder( builder: (context, state) { - final _bloc = BlocProvider.of(context); + final _bloc = BlocProvider.of(context); - return state is FourSceneLoadingState + return state is DeviceSettingLoadingState ? const Center( child: DefaultContainer( width: 50, diff --git a/lib/features/devices/view/widgets/6_scene_switch/select_scene_page.dart b/lib/features/devices/view/widgets/6_scene_switch/select_scene_page.dart index df57018..1257133 100644 --- a/lib/features/devices/view/widgets/6_scene_switch/select_scene_page.dart +++ b/lib/features/devices/view/widgets/6_scene_switch/select_scene_page.dart @@ -37,8 +37,10 @@ class SixSelectSceneFourPage extends StatelessWidget { builder: (context, state) { final sensorBloc = BlocProvider.of(context); if (state is SaveSelectionSuccessState) { - Navigator.of(context).pop(true); - Navigator.of(context).pop(true); + Future.delayed(const Duration(milliseconds: 250), () { + Navigator.of(context).pop(true); + Navigator.of(context).pop(true); + }); } return DefaultScaffold( title: 'Select Scene', @@ -163,7 +165,8 @@ class SixSelectSceneFourPage extends StatelessWidget { disablePlayButton: false, onChanged: (isSelected) { sensorBloc.add(SelectOptionEvent(selectedOption: scene.id)); - sensorBloc.add(SelectSceneEvent(unitId: scene.id)); + sensorBloc.add(SelectSceneEvent( + selectedSceneId: scene.id, isSelected: isSelected)); }, icon: scene.iconInBytes, title: scene.name, diff --git a/lib/features/devices/view/widgets/6_scene_switch/six_scene_screen.dart b/lib/features/devices/view/widgets/6_scene_switch/six_scene_screen.dart index f1fcf5d..908f5f8 100644 --- a/lib/features/devices/view/widgets/6_scene_switch/six_scene_screen.dart +++ b/lib/features/devices/view/widgets/6_scene_switch/six_scene_screen.dart @@ -196,12 +196,14 @@ class SixSceneScreen extends StatelessWidget { ); }, ); + if (value == true) { - _bloc.add(const SixSceneInitial()); - _bloc.add( - const SixSceneInitialInfo()); - _bloc.add( - const SexSceneSwitchInitial()); + Future.delayed( + const Duration( + milliseconds: 250), () { + _bloc.add( + const SexSceneSwitchInitial()); + }); } }, child: Column( diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_screen.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_screen.dart index 238c737..6426e64 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_screen.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_screen.dart @@ -175,12 +175,14 @@ class FourSceneScreen extends StatelessWidget { ); }, ); + if (value == true) { - _bloc.add(const FourSceneInitial()); - _bloc.add( - const FourSceneInitialInfo()); - _bloc.add( - const FourSceneSwitchInitial()); + Future.delayed( + const Duration( + milliseconds: 250), () { + _bloc.add( + const FourSceneSwitchInitial()); + }); } }, child: Column( diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_select_scene_page.dart b/lib/features/devices/view/widgets/four_scene_switch/four_select_scene_page.dart index f139fb6..4ffdd3a 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_select_scene_page.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_select_scene_page.dart @@ -37,8 +37,10 @@ class FourSelectSceneFourPage extends StatelessWidget { builder: (context, state) { final sensorBloc = BlocProvider.of(context); if (state is SaveSelectionSuccessState) { - Navigator.of(context).pop(true); - Navigator.of(context).pop(true); + Future.delayed(const Duration(milliseconds: 250), () { + Navigator.of(context).pop(true); + Navigator.of(context).pop(true); + }); } return DefaultScaffold( title: 'Select Scene', @@ -153,55 +155,25 @@ class FourSelectSceneFourPage extends StatelessWidget { ), itemBuilder: (context, index) { final scene = scenes[index]; + + // Check if this scene is currently selected bool isSelected = scene.id == (state is SceneSelectionUpdatedState ? state.selectedSceneId : sensorBloc.selectedFormApiSceneId); + return SceneItem( id: scene.id, - value: isSelected, + value: isSelected, // Pass isSelected to the SceneItem disablePlayButton: false, - onChanged: (isSelected) { + onChanged: (newSelection) { + // If selected, assign the scene sensorBloc.add(SelectOptionEvent(selectedOption: scene.id)); - - sensorBloc.add(SelectSceneEvent(selectedSceneId: scene.id)); + sensorBloc.add(SelectSceneEvent(selectedSceneId: scene.id,isSelected:newSelection)); }, icon: scene.iconInBytes, title: scene.name, ); - - // if (index == scenes.length) { - // return InkWell( - // onTap: () => Navigator.pushNamed( - // NavigationService.navigatorKey.currentContext!, - // Routes.sceneTasksRoute, - // arguments: SceneSettingsRouteArguments( - // sceneType: '', - // sceneId: '', - // sceneName: '', - // ), - // ), - // child: CreateSceneItem(), - // ); - // } else { - // final scene = scenes[index]; - // bool isSelected = scene.id == - // (state is SceneSelectionUpdatedState - // ? state.selectedSceneId - // : sensorBloc.selectedFormApiSceneId); - // return SceneItem( - // id: scene.id, - // value: isSelected, - // disablePlayButton: false, - // onChanged: (isSelected) { - // sensorBloc.add(SelectOptionEvent(selectedOption: scene.id)); - - // sensorBloc.add(SelectSceneEvent(selectedSceneId: scene.id)); - // }, - // icon: scene.iconInBytes, - // title: scene.name, - // ); - // } }, ); } @@ -317,3 +289,37 @@ class CreateSceneItem extends StatelessWidget { ); } } + + + // if (index == scenes.length) { + // return InkWell( + // onTap: () => Navigator.pushNamed( + // NavigationService.navigatorKey.currentContext!, + // Routes.sceneTasksRoute, + // arguments: SceneSettingsRouteArguments( + // sceneType: '', + // sceneId: '', + // sceneName: '', + // ), + // ), + // child: CreateSceneItem(), + // ); + // } else { + // final scene = scenes[index]; + // bool isSelected = scene.id == + // (state is SceneSelectionUpdatedState + // ? state.selectedSceneId + // : sensorBloc.selectedFormApiSceneId); + // return SceneItem( + // id: scene.id, + // value: isSelected, + // disablePlayButton: false, + // onChanged: (isSelected) { + // sensorBloc.add(SelectOptionEvent(selectedOption: scene.id)); + + // sensorBloc.add(SelectSceneEvent(selectedSceneId: scene.id)); + // }, + // icon: scene.iconInBytes, + // title: scene.name, + // ); + // } \ No newline at end of file diff --git a/lib/services/api/api_links_endpoints.dart b/lib/services/api/api_links_endpoints.dart index ec41710..c4fff35 100644 --- a/lib/services/api/api_links_endpoints.dart +++ b/lib/services/api/api_links_endpoints.dart @@ -213,11 +213,12 @@ abstract class ApiEndpoints { '/device/report-logs/{deviceUuid}?code={code}&startTime={startTime}&endTime={endTime}'; static const String controlBatch = '/device/control/batch'; static const String statusBatch = '/device/status/batch'; - static const String fourScene = '/device/{deviceUuid}/scenes'; + static const String deviceScene = '/device/{deviceUuid}/scenes'; static const String fourSceneByName = '/device/{deviceUuid}/scenes?switchName={switchName}'; static const String resetDevice = '/factory/reset/{deviceUuid}'; - static const String unAssignScenesDevice = '/factory/reset/{deviceUuid}'; + static const String unAssignScenesDevice = + '/device/{deviceUuid}/scenes?switchName={switchName}'; } diff --git a/lib/services/api/devices_api.dart b/lib/services/api/devices_api.dart index bcb87d2..1a2a366 100644 --- a/lib/services/api/devices_api.dart +++ b/lib/services/api/devices_api.dart @@ -91,7 +91,6 @@ class DevicesAPI { .replaceAll('{deviceUuid}', deviceId), showServerMessage: false, expectedResponseModel: (json) { - print('json==#$json'); return json; }, ); @@ -138,11 +137,12 @@ class DevicesAPI { return response; } - static Future getFourSceneInfo(String deviceId) async { + static Future getDeviceSceneInfo(String deviceId) async { final response = await _httpService.get( - path: ApiEndpoints.fourScene.replaceAll('{deviceUuid}', deviceId), + path: ApiEndpoints.deviceScene.replaceAll('{deviceUuid}', deviceId), showServerMessage: false, expectedResponseModel: (json) { + print(json); return json; }); return response; @@ -161,14 +161,14 @@ class DevicesAPI { return response; } - static Future postFourSceneInfo({ + static Future postDeviceSceneInfo({ String? switchName, String? sceneUuid, String? deviceId, String? spaceUuid, }) async { final response = await _httpService.post( - path: ApiEndpoints.fourScene.replaceAll('{deviceUuid}', deviceId!), + path: ApiEndpoints.deviceScene.replaceAll('{deviceUuid}', deviceId!), body: jsonEncode( { "switchName": switchName, @@ -178,7 +178,6 @@ class DevicesAPI { ), showServerMessage: false, expectedResponseModel: (json) { - print('postFourSceneInfo=$json'); return json; }); return response; @@ -189,7 +188,7 @@ class DevicesAPI { path: ApiEndpoints.deviceByUuid.replaceAll('{deviceUuid}', deviceId), showServerMessage: false, expectedResponseModel: (json) { - print('json==$json'); + print('object-*-*-*${json}'); return json; }); return response; @@ -529,4 +528,20 @@ class DevicesAPI { ); return response; } + + static Future unAssignScenesDevice({ + String? deviceUuid, + String? switchName, + }) async { + final response = await _httpService.delete( + path: ApiEndpoints.unAssignScenesDevice + .replaceAll('{deviceUuid}', deviceUuid!) + .replaceAll('{switchName}', switchName!), + showServerMessage: false, + expectedResponseModel: (json) { + return json; + }, + ); + return response; + } } From 4e506652f8eb143a67b8869388777cc72c7b2bf5 Mon Sep 17 00:00:00 2001 From: mohammad Date: Wed, 27 Nov 2024 15:04:40 +0300 Subject: [PATCH 27/29] 4scene&6scene&sos --- assets/icons/edit_name_setting.svg | 10 ++++++ .../view/device_settings/profile_page.dart | 22 +++++++------ .../view/device_settings/settings_page.dart | 31 ++++++++++++++----- .../6_scene_switch/select_scene_page.dart | 2 +- .../6_scene_switch/six_scene_screen.dart | 14 ++++----- .../four_scene_switch/four_scene_screen.dart | 9 ++++-- .../four_select_scene_page.dart | 5 +-- lib/generated/assets.dart | 4 +-- 8 files changed, 65 insertions(+), 32 deletions(-) create mode 100644 assets/icons/edit_name_setting.svg diff --git a/assets/icons/edit_name_setting.svg b/assets/icons/edit_name_setting.svg new file mode 100644 index 0000000..9011e82 --- /dev/null +++ b/assets/icons/edit_name_setting.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/lib/features/devices/view/device_settings/profile_page.dart b/lib/features/devices/view/device_settings/profile_page.dart index 216ab12..83b53cf 100644 --- a/lib/features/devices/view/device_settings/profile_page.dart +++ b/lib/features/devices/view/device_settings/profile_page.dart @@ -57,7 +57,8 @@ class SettingProfilePage extends StatelessWidget { child: SvgPicture.asset( Assets.sosHomeIcon, fit: BoxFit.fitHeight, - height: 100, + height: + MediaQuery.of(context).size.height * 0.13, )) : CircleAvatar( radius: 55, @@ -69,15 +70,16 @@ class SettingProfilePage extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, children: [ - const SizedBox( - height: 10, - ), Center( child: SvgPicture.asset( device!.type == "4S" ? Assets.fourSceneIcon : Assets.sixSceneIcon, fit: BoxFit.contain, + height: MediaQuery.of(context) + .size + .height * + 0.08, ), ), ], @@ -123,12 +125,14 @@ class SettingProfilePage extends StatelessWidget { onTap: () { _bloc.add(const ChangeNameEvent(value: true)); }, - child: const Padding( + child: Padding( padding: EdgeInsets.symmetric(horizontal: 10), - child: Icon( - Icons.edit_outlined, - size: 20, - color: ColorsManager.textPrimaryColor, + child: SvgPicture.asset( + Assets.sosEditProfile, + color: Colors.grey, + fit: BoxFit.contain, + height: MediaQuery.of(context).size.height * + 0.02, ), ), ), diff --git a/lib/features/devices/view/device_settings/settings_page.dart b/lib/features/devices/view/device_settings/settings_page.dart index 43c220c..e6e0573 100644 --- a/lib/features/devices/view/device_settings/settings_page.dart +++ b/lib/features/devices/view/device_settings/settings_page.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_bloc.dart'; @@ -97,7 +98,11 @@ class SettingsPage extends StatelessWidget { .subspace.subspaceName), ], ), - const Icon(Icons.edit_sharp) + SvgPicture.asset( + Assets.editNameSetting, + fit: BoxFit.contain, + height: 30, + ), ], ), ), @@ -132,13 +137,23 @@ class SettingsPage extends StatelessWidget { height: 70, ), ) - : SizedBox( - height: 70, - child: SvgPicture.asset( - device!.type == "4S" - ? Assets.fourSceneIcon - : Assets.sixSceneIcon, - fit: BoxFit.contain, + : Padding( + padding: device!.type == + "4S" + ? const EdgeInsets.only( + top: 5) + : const EdgeInsets.only( + top: 0), + child: SizedBox( + height: 70, + child: SvgPicture.asset( + device!.type == "4S" + ? Assets + .fourSceneIcon + : Assets + .sixSceneIcon, + fit: BoxFit.contain, + ), ), ), ], diff --git a/lib/features/devices/view/widgets/6_scene_switch/select_scene_page.dart b/lib/features/devices/view/widgets/6_scene_switch/select_scene_page.dart index 1257133..cb1ee63 100644 --- a/lib/features/devices/view/widgets/6_scene_switch/select_scene_page.dart +++ b/lib/features/devices/view/widgets/6_scene_switch/select_scene_page.dart @@ -67,7 +67,7 @@ class SixSelectSceneFourPage extends StatelessWidget { } : null, child: Padding( - padding: const EdgeInsets.all(8.0), + padding: const EdgeInsets.only(left: 10, right: 10), child: BodyMedium( text: 'Save', fontWeight: FontWeight.w700, diff --git a/lib/features/devices/view/widgets/6_scene_switch/six_scene_screen.dart b/lib/features/devices/view/widgets/6_scene_switch/six_scene_screen.dart index 908f5f8..4b4a369 100644 --- a/lib/features/devices/view/widgets/6_scene_switch/six_scene_screen.dart +++ b/lib/features/devices/view/widgets/6_scene_switch/six_scene_screen.dart @@ -32,7 +32,6 @@ class SixSceneScreen extends StatelessWidget { child: BlocBuilder( builder: (context, state) { final _bloc = BlocProvider.of(context); - SixSceneModel model = SixSceneModel( scene_1: '', scene_2: '', @@ -43,25 +42,25 @@ class SixSceneScreen extends StatelessWidget { scene_id_group_id: '', switch_backlight: '', ); - if (state is LoadingNewSate) { model = state.device; } else if (state is UpdateState) { model = state.device; } - return DefaultScaffold( - title: _bloc.deviceInfo.subspace.subspaceName, + title: _bloc.deviceInfo.name, actions: [ InkWell( onTap: () async { - bool val = await Navigator.of(context).push( + var val = await Navigator.of(context).push( MaterialPageRoute( builder: (context) => SettingsPage(device: device!), ), ); - if (val == true) { + if (val == null) { _bloc.add(const SixSceneInitialInfo()); + _bloc.add(const SixSceneInitial()); + _bloc.add(const SexSceneSwitchInitial()); } }, child: SvgPicture.asset(Assets.assetsIconsSettings), @@ -196,11 +195,10 @@ class SixSceneScreen extends StatelessWidget { ); }, ); - if (value == true) { Future.delayed( const Duration( - milliseconds: 250), () { + milliseconds: 200), () { _bloc.add( const SexSceneSwitchInitial()); }); diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_scene_screen.dart b/lib/features/devices/view/widgets/four_scene_switch/four_scene_screen.dart index 6426e64..9e63b16 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_scene_screen.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_scene_screen.dart @@ -50,12 +50,17 @@ class FourSceneScreen extends StatelessWidget { title: _bloc.deviceInfo.name, actions: [ InkWell( - onTap: () { - Navigator.of(context).push( + onTap: () async { + var val = await Navigator.of(context).push( MaterialPageRoute( builder: (context) => SettingsPage(device: device!), ), ); + if (val == null) { + _bloc.add(const FourSceneInitial()); + _bloc.add(const FourSceneInitialInfo()); + _bloc.add(const FourSceneSwitchInitial()); + } }, child: SvgPicture.asset(Assets.assetsIconsSettings), ), diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_select_scene_page.dart b/lib/features/devices/view/widgets/four_scene_switch/four_select_scene_page.dart index 4ffdd3a..bf18442 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_select_scene_page.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_select_scene_page.dart @@ -67,7 +67,7 @@ class FourSelectSceneFourPage extends StatelessWidget { } : null, child: Padding( - padding: const EdgeInsets.all(8.0), + padding: const EdgeInsets.only(left: 10, right: 15), child: BodyMedium( text: 'Save', fontWeight: FontWeight.w700, @@ -169,7 +169,8 @@ class FourSelectSceneFourPage extends StatelessWidget { onChanged: (newSelection) { // If selected, assign the scene sensorBloc.add(SelectOptionEvent(selectedOption: scene.id)); - sensorBloc.add(SelectSceneEvent(selectedSceneId: scene.id,isSelected:newSelection)); + sensorBloc.add(SelectSceneEvent( + selectedSceneId: scene.id, isSelected: newSelection)); }, icon: scene.iconInBytes, title: scene.name, diff --git a/lib/generated/assets.dart b/lib/generated/assets.dart index 859ae1c..7ff3fa0 100644 --- a/lib/generated/assets.dart +++ b/lib/generated/assets.dart @@ -1123,6 +1123,6 @@ class Assets { static const String sixSceneHomeIcon = "assets/icons/six_scene_home_icon.svg"; static const String editDeviceNameIcon = "assets/icons/edit_device_name_icon.svg"; - static const String sosHomeIcon = - "assets/icons/sos_home_icon.svg"; + static const String sosHomeIcon = "assets/icons/sos_home_icon.svg"; + static const String editNameSetting = "assets/icons/edit_name_setting.svg"; } From d9ef6de71ab0677111829ca1e5ce8f67ddb5407d Mon Sep 17 00:00:00 2001 From: mohammad Date: Thu, 28 Nov 2024 11:14:14 +0300 Subject: [PATCH 28/29] fixes issue --- .../6_scene_switch/select_scene_page.dart | 70 ++++++++----------- .../four_select_scene_page.dart | 54 +++++++------- pubspec.yaml | 2 +- 3 files changed, 62 insertions(+), 64 deletions(-) diff --git a/lib/features/devices/view/widgets/6_scene_switch/select_scene_page.dart b/lib/features/devices/view/widgets/6_scene_switch/select_scene_page.dart index cb1ee63..ab6fb36 100644 --- a/lib/features/devices/view/widgets/6_scene_switch/select_scene_page.dart +++ b/lib/features/devices/view/widgets/6_scene_switch/select_scene_page.dart @@ -242,53 +242,45 @@ class SceneItem extends StatelessWidget { ], ), padding: const EdgeInsets.all(16), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, + child: Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Column( + Row( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - if (!disablePlayButton) - Expanded( - child: Image.memory( - icon, - height: 32, - width: 32, - fit: BoxFit.fill, - errorBuilder: (context, error, stackTrace) => Image.asset( - Assets.assetsIconsLogo, - height: 32, - width: 32, - fit: BoxFit.fill), - ), - ), - Spacer(), - Expanded( - child: Container( - width: MediaQuery.of(context).size.width * 0.3, - child: Row( - children: [ - BodyMedium( - text: title, - style: const TextStyle( - fontSize: 17, - fontWeight: FontWeight.w700, - color: ColorsManager.secondaryTextColor), - textAlign: TextAlign.center, - ), - ], - ), - ), + Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + if (!disablePlayButton) + Image.memory( + icon, + height: 32, + width: 32, + fit: BoxFit.fill, + errorBuilder: (context, error, stackTrace) => Image.asset( + Assets.assetsIconsLogo, + height: 32, + width: 32, + fit: BoxFit.fill), + ), + ], + ), + CircularCheckbox( + value: value, + onChanged: (isSelected) => onChanged(isSelected!), ), ], ), - Expanded( - child: CircularCheckbox( - value: value, - onChanged: (isSelected) => onChanged(isSelected!), - ), + BodyMedium( + text: title, + style: const TextStyle( + fontSize: 17, + fontWeight: FontWeight.w700, + color: ColorsManager.secondaryTextColor), + textAlign: TextAlign.center, ), ], ), diff --git a/lib/features/devices/view/widgets/four_scene_switch/four_select_scene_page.dart b/lib/features/devices/view/widgets/four_scene_switch/four_select_scene_page.dart index bf18442..9346f58 100644 --- a/lib/features/devices/view/widgets/four_scene_switch/four_select_scene_page.dart +++ b/lib/features/devices/view/widgets/four_scene_switch/four_select_scene_page.dart @@ -213,39 +213,45 @@ class SceneItem extends StatelessWidget { ], ), padding: const EdgeInsets.all(16), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, + child: Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.center, + Row( + crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - if (!disablePlayButton) - Image.memory( - icon, - height: 32, - width: 32, - fit: BoxFit.fill, - errorBuilder: (context, error, stackTrace) => Image.asset( - Assets.assetsIconsLogo, + Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + if (!disablePlayButton) + Image.memory( + icon, height: 32, width: 32, - fit: BoxFit.fill), - ), - BodyMedium( - text: title, - style: const TextStyle( - fontSize: 17, - fontWeight: FontWeight.w700, - color: ColorsManager.secondaryTextColor), - textAlign: TextAlign.center, + fit: BoxFit.fill, + errorBuilder: (context, error, stackTrace) => Image.asset( + Assets.assetsIconsLogo, + height: 32, + width: 32, + fit: BoxFit.fill), + ), + ], + ), + CircularCheckbox( + value: value, + onChanged: (isSelected) => onChanged(isSelected!), ), ], ), - CircularCheckbox( - value: value, - onChanged: (isSelected) => onChanged(isSelected!), + BodyMedium( + text: title, + style: const TextStyle( + fontSize: 17, + fontWeight: FontWeight.w700, + color: ColorsManager.secondaryTextColor), + textAlign: TextAlign.center, ), ], ), diff --git a/pubspec.yaml b/pubspec.yaml index 42bd7df..27b05f4 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.9+42 +version: 1.0.9+44 environment: sdk: ">=3.0.6 <4.0.0" From 6f02459ad8a2e4941db73c2b3123f063c403ae37 Mon Sep 17 00:00:00 2001 From: mohammad Date: Sun, 1 Dec 2024 09:41:59 +0300 Subject: [PATCH 29/29] fixes issues --- .../bloc/four_scene_bloc/four_scene_bloc.dart | 3 -- .../view/device_settings/settings_page.dart | 45 ++++++++++++------- .../devices/view/widgets/room_page.dart | 6 ++- lib/services/api/devices_api.dart | 1 - lib/services/api/scene_api.dart | 1 - pubspec.yaml | 2 +- 6 files changed, 35 insertions(+), 23 deletions(-) diff --git a/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart b/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart index d58621b..d3069f7 100644 --- a/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart +++ b/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart @@ -99,8 +99,6 @@ class FourSceneBloc extends Bloc { _selectScene(SelectSceneEvent event, Emitter emit) { emit(FourSceneLoadingState()); - print('-------${event.selectedSceneId}------'); - print('-------${event.isSelected}------'); if (event.isSelected == false) { selectedSceneId = ''; selectedFormApiSceneId = ''; @@ -187,7 +185,6 @@ class FourSceneBloc extends Bloc { } } - void _fetchDeviceScene( FetchDeviceScene event, Emitter emit) async { emit(FourSceneLoadingState()); diff --git a/lib/features/devices/view/device_settings/settings_page.dart b/lib/features/devices/view/device_settings/settings_page.dart index e6e0573..fdfed4d 100644 --- a/lib/features/devices/view/device_settings/settings_page.dart +++ b/lib/features/devices/view/device_settings/settings_page.dart @@ -82,21 +82,36 @@ class SettingsPage extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - BodyMedium( - text: _bloc.deviceInfo.name, - fontWeight: FontWeight.bold, - ), - const SizedBox( - height: 5, - ), - BodySmall( - text: _bloc.deviceInfo - .subspace.subspaceName), - ], + Expanded( + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + SizedBox( + child: Text( + _bloc.deviceInfo.name, + style: const TextStyle( + fontSize: 16, + fontWeight: + FontWeight.w700, + color: ColorsManager + .grayColor, + ), + overflow: TextOverflow + .ellipsis, // Adds ellipsis (...) when the text overflows. + maxLines: + 1, // Restricts the text to a single line. + )), + const SizedBox( + height: 5, + ), + BodySmall( + text: _bloc + .deviceInfo + .subspace + .subspaceName), + ], + ), ), SvgPicture.asset( Assets.editNameSetting, diff --git a/lib/features/devices/view/widgets/room_page.dart b/lib/features/devices/view/widgets/room_page.dart index 3a30ba4..f76210f 100644 --- a/lib/features/devices/view/widgets/room_page.dart +++ b/lib/features/devices/view/widgets/room_page.dart @@ -36,7 +36,7 @@ class _RoomPageState extends State { final query = _searchController.text.toLowerCase(); setState(() { _filteredDevices = widget.room.devices! - .where((device) => device.type!.toLowerCase().contains(query)) + .where((device) => device.name!.toLowerCase().contains(query)) .toList(); }); } @@ -51,7 +51,9 @@ class _RoomPageState extends State { decoration: InputDecoration( hintText: 'Search', hintStyle: const TextStyle( - color: ColorsManager.textGray, fontSize: 16, fontWeight: FontWeight.w400), + color: ColorsManager.textGray, + fontSize: 16, + fontWeight: FontWeight.w400), prefixIcon: Container( padding: const EdgeInsets.all(5.0), margin: const EdgeInsets.all(10.0), diff --git a/lib/services/api/devices_api.dart b/lib/services/api/devices_api.dart index 1a2a366..3990a65 100644 --- a/lib/services/api/devices_api.dart +++ b/lib/services/api/devices_api.dart @@ -142,7 +142,6 @@ class DevicesAPI { path: ApiEndpoints.deviceScene.replaceAll('{deviceUuid}', deviceId), showServerMessage: false, expectedResponseModel: (json) { - print(json); return json; }); return response; diff --git a/lib/services/api/scene_api.dart b/lib/services/api/scene_api.dart index e2040e9..fe4c1ae 100644 --- a/lib/services/api/scene_api.dart +++ b/lib/services/api/scene_api.dart @@ -1,4 +1,3 @@ -import 'dart:convert'; import 'package:syncrow_app/features/scene/model/create_automation_model.dart'; import 'package:syncrow_app/features/scene/model/create_scene_model.dart'; diff --git a/pubspec.yaml b/pubspec.yaml index 27b05f4..bc5d09f 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.9+44 +version: 1.0.9+45 environment: sdk: ">=3.0.6 <4.0.0"