fixes issues

This commit is contained in:
mohammad
2024-11-27 14:23:00 +03:00
parent 80d92de625
commit 51b1438d0e
15 changed files with 405 additions and 810 deletions

View File

@ -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_control_model.dart';
import 'package:syncrow_app/features/devices/model/device_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/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/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/six_scene_model.dart';
import 'package:syncrow_app/features/devices/model/status_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/devices/model/subspace_model.dart';
import 'package:syncrow_app/features/scene/model/scenes_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/devices_api.dart';
import 'package:syncrow_app/services/api/home_management_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/scene_api.dart';
@ -27,29 +24,21 @@ class SixSceneBloc extends Bloc<SixSceneEvent, SixSceneState> {
required this.sixSceneId, required this.sixSceneId,
}) : super(const SixSceneState()) { }) : super(const SixSceneState()) {
on<SixSceneInitial>(_fetchDeviceStatus); on<SixSceneInitial>(_fetchDeviceStatus);
on<ToggleNotificationEvent>(_toggleNotification);
on<ChangeNameEvent>(_changeName);
on<SearchFaqEvent>(_onSearchFaq);
on<ChangeSwitchStatusEvent>(changeSwitchStatus); on<ChangeSwitchStatusEvent>(changeSwitchStatus);
on<LoadScenes>(_onLoadScenes); on<LoadScenes>(_onLoadScenes);
on<SearchScenesEvent>(searchScene); on<SearchScenesEvent>(searchScene);
on<SaveSelectionEvent>(_onSaveSelection); on<SaveSelectionEvent>(_onSaveSelection);
on<SelectOptionEvent>(_onOptionSelected); on<SelectOptionEvent>(_onOptionSelected);
on<AddDeviceToGroup>(_addDeviceToGroup);
on<RemoveDeviceFromGroup>(_removeDeviceFromGroup);
on<SexSceneSwitchInitial>(_fetchFourSceneSwitches); on<SexSceneSwitchInitial>(_fetchFourSceneSwitches);
on<AssignDeviceScene>(assignScene); on<AssignDeviceScene>(assignScene);
on<GetSceneBySwitchName>(getSceneByName); on<GetSceneBySwitchName>(getSceneByName);
on<SelectSceneEvent>(_selectScene); on<SelectSceneEvent>(_selectScene);
on<SixSceneInitialInfo>(fetchDeviceInfo); on<SixSceneInitialInfo>(fetchDeviceInfo);
on<SaveNameEvent>(saveName);
on<AssignRoomEvent>(_assignDevice); on<AssignRoomEvent>(_assignDevice);
on<FetchRoomsEvent>(_fetchRoomsAndDevices); on<FetchRoomsEvent>(_fetchRoomsAndDevices);
on<SixSceneInitialQuestion>(_onSixSceneInitial);
on<DeleteDeviceEvent>(deleteDevice); on<DeleteDeviceEvent>(deleteDevice);
on<ToggleEnableAlarmEvent>(_toggleLowBattery); on<ToggleEnableAlarmEvent>(_toggleLowBattery);
on<ToggleUpdateEvent>(_toggleUpdate); on<UnAssignSceneEvent>(_unAssignScene);
on<ToggleHelpfulEvent>(_toggleHelpful);
} }
final TextEditingController nameController = final TextEditingController nameController =
@ -156,6 +145,22 @@ class SixSceneBloc extends Bloc<SixSceneEvent, SixSceneState> {
} }
} }
void _unAssignScene(
UnAssignSceneEvent event, Emitter<SixSceneState> 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<SixSceneState> emit) async { deleteDevice(DeleteDeviceEvent event, Emitter<SixSceneState> emit) async {
try { try {
emit(SixSceneLoadingState()); emit(SixSceneLoadingState());
@ -226,9 +231,16 @@ class SixSceneBloc extends Bloc<SixSceneEvent, SixSceneState> {
String selectedSceneId = ''; String selectedSceneId = '';
_selectScene(SelectSceneEvent event, Emitter<SixSceneState> emit) {
_selectScene(SelectSceneEvent event, Emitter<SixSceneState> emit) {
emit(SixSceneLoadingState()); emit(SixSceneLoadingState());
selectedSceneId = event.unitId; if (event.isSelected == false) {
selectedSceneId = '';
selectedFormApiSceneId = '';
emit(SceneSelectionUpdatedState(selectedSceneId: selectedSceneId));
} else {
selectedSceneId = event.selectedSceneId;
}
emit(SceneSelectionUpdatedState(selectedSceneId: selectedSceneId)); emit(SceneSelectionUpdatedState(selectedSceneId: selectedSceneId));
} }
@ -238,7 +250,8 @@ class SixSceneBloc extends Bloc<SixSceneEvent, SixSceneState> {
SexSceneSwitchInitial event, Emitter<SixSceneState> emit) async { SexSceneSwitchInitial event, Emitter<SixSceneState> emit) async {
emit(SixSceneLoadingState()); emit(SixSceneLoadingState());
try { try {
var response = await DevicesAPI.getFourSceneInfo(sixSceneId); var response = await DevicesAPI.getDeviceSceneInfo(sixSceneId);
Map<String, String> sceneTitles = { Map<String, String> sceneTitles = {
"scene_1": '', "scene_1": '',
"scene_2": '', "scene_2": '',
@ -272,11 +285,16 @@ class SixSceneBloc extends Bloc<SixSceneEvent, SixSceneState> {
void assignScene(AssignDeviceScene event, Emitter<SixSceneState> emit) async { void assignScene(AssignDeviceScene event, Emitter<SixSceneState> emit) async {
emit(SixSceneLoadingState()); emit(SixSceneLoadingState());
try { try {
final response = await DevicesAPI.postFourSceneInfo( if (event.sceneUuid == '') {
deviceId: sixSceneId, final response = await DevicesAPI.unAssignScenesDevice(
sceneUuid: event.sceneUuid, deviceUuid: sixSceneId, switchName: event.switchName);
spaceUuid: event.unit!.id, } else {
switchName: event.switchName); final response = await DevicesAPI.postDeviceSceneInfo(
deviceId: sixSceneId,
sceneUuid: event.sceneUuid,
spaceUuid: event.unit!.id,
switchName: event.switchName);
}
emit(SaveSelectionSuccessState()); emit(SaveSelectionSuccessState());
CustomSnackBar.displaySnackBar('Save Successfully'); CustomSnackBar.displaySnackBar('Save Successfully');
@ -285,27 +303,6 @@ class SixSceneBloc extends Bloc<SixSceneEvent, SixSceneState> {
} }
} }
void _onSearchFaq(SearchFaqEvent event, Emitter<SixSceneState> emit) {
emit(SixSceneLoadingState());
List<SixSceneQuestionModel> _faqQuestions = faqQuestions.where((question) {
return question.question
.toLowerCase()
.contains(event.query.toLowerCase());
}).toList();
emit(FaqSearchState(filteredFaqQuestions: _faqQuestions));
}
void _toggleNotification(
ToggleNotificationEvent event, Emitter<SixSceneState> emit) async {
emit(LoadingNewSate(device: deviceStatus));
try {
closingReminder = event.isClosingEnabled;
emit(UpdateState(device: deviceStatus));
} catch (e) {
emit(SixSceneFailedState(errorMessage: e.toString()));
}
}
DeviceReport recordGroups = DeviceReport recordGroups =
DeviceReport(startTime: '0', endTime: '0', data: []); DeviceReport(startTime: '0', endTime: '0', data: []);
@ -355,6 +352,7 @@ class SixSceneBloc extends Bloc<SixSceneEvent, SixSceneState> {
} catch (e) { } catch (e) {
emit(const SixSceneFailedState(errorMessage: 'Something went wrong')); emit(const SixSceneFailedState(errorMessage: 'Something went wrong'));
} }
emit(SuccessState()); emit(SuccessState());
} }
@ -368,7 +366,7 @@ class SixSceneBloc extends Bloc<SixSceneEvent, SixSceneState> {
filteredScenes = event.query.isEmpty filteredScenes = event.query.isEmpty
? allScenes ? allScenes
: allScenes.where((scene) { : allScenes.where((scene) {
final sceneName = scene.name.toLowerCase() ?? ''; final sceneName = scene.name.toLowerCase();
return sceneName.contains(event.query.toLowerCase()); return sceneName.contains(event.query.toLowerCase());
}).toList(); }).toList();
emit(SearchResultsState()); emit(SearchResultsState());
@ -393,162 +391,4 @@ class SixSceneBloc extends Bloc<SixSceneEvent, SixSceneState> {
emit(SaveSelectionSuccessState()); emit(SaveSelectionSuccessState());
} }
} }
//============================= group settings =================================
//addDevicesIcon
List<GroupDevicesModel> groupDevices = [
GroupDevicesModel(
dec: 'Syncroom', icon: Assets.minusIcon, name: '6 Scene Switch')
];
List<GroupDevicesModel> devices = [
GroupDevicesModel(
dec: 'Syncroom', icon: Assets.addDevicesIcon, name: '6 Scene Switch')
];
// Handler for AddDeviceToGroup
void _addDeviceToGroup(AddDeviceToGroup event, Emitter<SixSceneState> 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<SixSceneState> 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<SixSceneState> 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<SixSceneState> emit) async {
try {
emit(SixSceneLoadingState());
isHelpful = event.isHelpful!;
emit(SaveState());
} catch (e) {
emit(const SixSceneFailedState(errorMessage: 'Something went wrong'));
}
}
final List<SixSceneQuestionModel> 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<void> _onSixSceneInitial(
SixSceneInitialQuestion event, Emitter<SixSceneState> emit) async {
emit(SixSceneLoadingState());
emit(FaqLoadedState(filteredFaqQuestions: faqQuestions));
}
//=========================== name setting ===================================
////////////////////////////////////////////////////////////////////////////////
void _changeName(ChangeNameEvent event, Emitter<SixSceneState> emit) {
emit(SixSceneLoadingState());
editName = event.value!;
if (editName) {
Future.delayed(const Duration(milliseconds: 500), () {
focusNode.requestFocus();
});
} else {
focusNode.unfocus();
}
emit(NameEditingState(editName: editName));
}
Future<void> saveName(
SaveNameEvent event, Emitter<SixSceneState> 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;
}
} }

View File

@ -24,6 +24,11 @@ class SaveNameEvent extends SixSceneEvent {
const SaveNameEvent(); const SaveNameEvent();
} }
class UnAssignSceneEvent extends SixSceneEvent {
final String switchSceneUuid;
const UnAssignSceneEvent({required this.switchSceneUuid});
}
class SixSceneInitialInfo extends SixSceneEvent { class SixSceneInitialInfo extends SixSceneEvent {
const SixSceneInitialInfo(); const SixSceneInitialInfo();
} }
@ -91,12 +96,17 @@ class LoadScenes extends SixSceneEvent {
} }
class SelectSceneEvent extends SixSceneEvent { class SelectSceneEvent extends SixSceneEvent {
final String unitId; final String selectedSceneId;
final bool isSelected;
// final String unitId;
const SelectSceneEvent({ const SelectSceneEvent({
required this.unitId, // required this.unitId,
required this.selectedSceneId,
required this.isSelected,
}); });
} }
class SearchScenesEvent extends SixSceneEvent { class SearchScenesEvent extends SixSceneEvent {
final String query; final String query;
const SearchScenesEvent({ const SearchScenesEvent({

View File

@ -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/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_event.dart';
import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_scene_state.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_model.dart';
import 'package:syncrow_app/features/devices/model/device_report_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_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/generated/assets.dart';
import 'package:syncrow_app/services/api/devices_api.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/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/services/api/spaces_api.dart';
import 'package:syncrow_app/utils/helpers/snack_bar.dart'; import 'package:syncrow_app/utils/helpers/snack_bar.dart';
@ -34,23 +32,20 @@ class DeviceSettingBloc extends Bloc<DeviceSettingEvent, DeviceSettingState> {
on<ChangeNameEvent>(_changeName); on<ChangeNameEvent>(_changeName);
on<SearchFaqEvent>(_onSearchFaq); on<SearchFaqEvent>(_onSearchFaq);
on<FetchRoomsEvent>(_fetchRoomsAndDevices); on<FetchRoomsEvent>(_fetchRoomsAndDevices);
on<ChangeSwitchStatusEvent>(changeSwitchStatus);
on<LoadSettings>(_onLoadSettings); on<LoadSettings>(_onLoadSettings);
on<SearchSettingsEvent>(searchSetting); on<SearchSettingsEvent>(searchSetting);
on<AssignRoomEvent>(_assignDevice); on<AssignRoomEvent>(_assignDevice);
on<SelectOptionEvent>(_onOptionSelected);
on<AddDeviceToGroup>(_addDeviceToGroup); on<AddDeviceToGroup>(_addDeviceToGroup);
on<RemoveDeviceFromGroup>(_removeDeviceFromGroup); on<RemoveDeviceFromGroup>(_removeDeviceFromGroup);
on<DeviceSettingInitialQuestion>(_onDeviceSettingInitial); on<DeviceSettingInitialQuestion>(_onDeviceSettingInitial);
on<FetchDeviceSetting>(_fetchDeviceSetting); on<FetchDeviceSetting>(_fetchDeviceSetting);
on<DeviceSettingSwitchInitial>(_fetchDeviceSettingSwitches);
on<AssignDeviceSetting>(assignSetting);
on<GetSettingBySwitchName>(getSettingByName); on<GetSettingBySwitchName>(getSettingByName);
on<SelectSettingEvent>(_selectSetting); on<SelectSettingEvent>(_selectSetting);
on<DeleteDeviceEvent>(deleteDevice); on<DeleteDeviceEvent>(deleteDevice);
on<ToggleEnableAlarmEvent>(_toggleLowBattery); on<ToggleEnableAlarmEvent>(_toggleLowBattery);
on<ToggleUpdateEvent>(_toggleUpdate); on<ToggleUpdateEvent>(_toggleUpdate);
on<ToggleHelpfulEvent>(_toggleHelpful); on<ToggleHelpfulEvent>(_toggleHelpful);
on<SelectOptionEvent>(_onOptionSelected);
} }
final TextEditingController nameController = final TextEditingController nameController =
@ -133,64 +128,6 @@ class DeviceSettingBloc extends Bloc<DeviceSettingEvent, DeviceSettingState> {
} }
} }
void _onOptionSelected(
SelectOptionEvent event, Emitter<DeviceSettingState> emit) {
emit(DeviceSettingLoadingState());
_selectedOption = event.selectedOption;
_hasSelectionChanged = true;
emit(OptionSelectedState(
selectedOption: _selectedOption,
hasSelectionChanged: _hasSelectionChanged));
}
void _fetchDeviceSettingSwitches(DeviceSettingSwitchInitial event,
Emitter<DeviceSettingState> emit) async {
emit(DeviceSettingLoadingState());
try {
var response = await DevicesAPI.getFourSceneInfo(deviceId);
Map<String, String> 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<DeviceSettingState> 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( void _fetchDeviceSetting(
FetchDeviceSetting event, Emitter<DeviceSettingState> emit) async { FetchDeviceSetting event, Emitter<DeviceSettingState> emit) async {
emit(DeviceSettingLoadingState()); emit(DeviceSettingLoadingState());
@ -315,7 +252,7 @@ class DeviceSettingBloc extends Bloc<DeviceSettingEvent, DeviceSettingState> {
), ),
]; ];
bool isHelpful = false; bool? isHelpful;
void _toggleHelpful( void _toggleHelpful(
ToggleHelpfulEvent event, Emitter<DeviceSettingState> emit) async { ToggleHelpfulEvent event, Emitter<DeviceSettingState> emit) async {
@ -338,30 +275,6 @@ class DeviceSettingBloc extends Bloc<DeviceSettingEvent, DeviceSettingState> {
List<DeviceModel> allDevices = []; List<DeviceModel> allDevices = [];
List<SubSpaceModel> roomsList = []; List<SubSpaceModel> roomsList = [];
bool switchStatus = true; bool switchStatus = true;
Future<void> changeSwitchStatus(
ChangeSwitchStatusEvent event, Emitter<DeviceSettingState> 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<void> _onLoadSettings( Future<void> _onLoadSettings(
LoadSettings event, Emitter<DeviceSettingState> emit) async { LoadSettings event, Emitter<DeviceSettingState> emit) async {
@ -519,6 +432,7 @@ class DeviceSettingBloc extends Bloc<DeviceSettingEvent, DeviceSettingState> {
var response = await DevicesAPI.putDeviceName( var response = await DevicesAPI.putDeviceName(
deviceId: deviceId, deviceName: nameController.text); deviceId: deviceId, deviceName: nameController.text);
add(const DeviceSettingInitialInfo()); add(const DeviceSettingInitialInfo());
await HomeCubit.getInstance().fetchUnitsByUserId();
CustomSnackBar.displaySnackBar('Save Successfully'); CustomSnackBar.displaySnackBar('Save Successfully');
emit(SaveState()); emit(SaveState());
} catch (e) { } catch (e) {
@ -556,4 +470,14 @@ class DeviceSettingBloc extends Bloc<DeviceSettingEvent, DeviceSettingState> {
return; return;
} }
} }
void _onOptionSelected(
SelectOptionEvent event, Emitter<DeviceSettingState> emit) {
emit(DeviceSettingLoadingState());
_selectedOption = event.selectedOption;
_hasSelectionChanged = true;
emit(OptionSelectedState(
selectedOption: _selectedOption,
hasSelectionChanged: _hasSelectionChanged));
}
} }

View File

@ -59,7 +59,7 @@ class DeviceSettingInitialQuestion extends DeviceSettingEvent {
const DeviceSettingInitialQuestion(); const DeviceSettingInitialQuestion();
} }
class ChangeSwitchStatusEvent extends DeviceSettingEvent {} // class ChangeSwitchStatusEvent extends DeviceSettingEvent {}
class FetchRoomsEvent extends DeviceSettingEvent { class FetchRoomsEvent extends DeviceSettingEvent {
final SpaceModel unit; final SpaceModel unit;
@ -139,9 +139,9 @@ class AssignRoomEvent extends DeviceSettingEvent {
class FetchDeviceSetting extends DeviceSettingEvent {} class FetchDeviceSetting extends DeviceSettingEvent {}
class DeviceSettingSwitchInitial extends DeviceSettingEvent { // class DeviceSettingSwitchInitial extends DeviceSettingEvent {
const DeviceSettingSwitchInitial(); // const DeviceSettingSwitchInitial();
} // }
class AssignDeviceSetting extends DeviceSettingEvent { class AssignDeviceSetting extends DeviceSettingEvent {
final String? sceneUuid; final String? sceneUuid;

View File

@ -1,25 +1,19 @@
import 'dart:async'; import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.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_event.dart';
import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_state.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_control_model.dart';
import 'package:syncrow_app/features/devices/model/device_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/device_report_model.dart';
import 'package:syncrow_app/features/devices/model/four_scene_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/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/device_info_model.dart';
import 'package:syncrow_app/features/devices/model/status_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/devices/model/subspace_model.dart';
import 'package:syncrow_app/features/scene/model/scenes_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/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/scene_api.dart';
import 'package:syncrow_app/services/api/spaces_api.dart';
import 'package:syncrow_app/utils/helpers/snack_bar.dart'; import 'package:syncrow_app/utils/helpers/snack_bar.dart';
class FourSceneBloc extends Bloc<FourSceneEvent, FourSceneState> { class FourSceneBloc extends Bloc<FourSceneEvent, FourSceneState> {
@ -29,28 +23,17 @@ class FourSceneBloc extends Bloc<FourSceneEvent, FourSceneState> {
}) : super(const FourSceneState()) { }) : super(const FourSceneState()) {
on<FourSceneInitial>(_fetchDeviceStatus); on<FourSceneInitial>(_fetchDeviceStatus);
on<FourSceneInitialInfo>(fetchDeviceInfo); on<FourSceneInitialInfo>(fetchDeviceInfo);
on<SaveNameEvent>(saveName);
on<ToggleNotificationEvent>(_toggleNotification); on<ToggleNotificationEvent>(_toggleNotification);
on<ChangeNameEvent>(_changeName);
on<SearchFaqEvent>(_onSearchFaq);
on<FetchRoomsEvent>(_fetchRoomsAndDevices);
on<ChangeSwitchStatusEvent>(changeSwitchStatus); on<ChangeSwitchStatusEvent>(changeSwitchStatus);
on<LoadScenes>(_onLoadScenes); on<LoadScenes>(_onLoadScenes);
on<SearchScenesEvent>(searchScene); on<SearchScenesEvent>(searchScene);
on<AssignRoomEvent>(_assignDevice);
on<SelectOptionEvent>(_onOptionSelected); on<SelectOptionEvent>(_onOptionSelected);
on<AddDeviceToGroup>(_addDeviceToGroup);
on<RemoveDeviceFromGroup>(_removeDeviceFromGroup);
on<FourSceneInitialQuestion>(_onFourSceneInitial);
on<FetchDeviceScene>(_fetchDeviceScene); on<FetchDeviceScene>(_fetchDeviceScene);
on<FourSceneSwitchInitial>(_fetchFourSceneSwitches); on<FourSceneSwitchInitial>(_fetchFourSceneSwitches);
on<AssignDeviceScene>(assignScene); on<AssignDeviceScene>(assignScene);
on<GetSceneBySwitchName>(getSceneByName); on<GetSceneBySwitchName>(getSceneByName);
on<SelectSceneEvent>(_selectScene); on<SelectSceneEvent>(_selectScene);
on<DeleteDeviceEvent>(deleteDevice);
on<ToggleEnableAlarmEvent>(_toggleLowBattery); on<ToggleEnableAlarmEvent>(_toggleLowBattery);
on<ToggleUpdateEvent>(_toggleUpdate);
on<ToggleHelpfulEvent>(_toggleHelpful);
} }
final TextEditingController nameController = final TextEditingController nameController =
@ -116,7 +99,15 @@ class FourSceneBloc extends Bloc<FourSceneEvent, FourSceneState> {
_selectScene(SelectSceneEvent event, Emitter<FourSceneState> emit) { _selectScene(SelectSceneEvent event, Emitter<FourSceneState> emit) {
emit(FourSceneLoadingState()); 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)); emit(SceneSelectionUpdatedState(selectedSceneId: selectedSceneId));
} }
@ -147,7 +138,7 @@ class FourSceneBloc extends Bloc<FourSceneEvent, FourSceneState> {
FourSceneSwitchInitial event, Emitter<FourSceneState> emit) async { FourSceneSwitchInitial event, Emitter<FourSceneState> emit) async {
emit(FourSceneLoadingState()); emit(FourSceneLoadingState());
try { try {
var response = await DevicesAPI.getFourSceneInfo(fourSceneId); var response = await DevicesAPI.getDeviceSceneInfo(fourSceneId);
Map<String, String> sceneTitles = { Map<String, String> sceneTitles = {
"scene_1": '', "scene_1": '',
"scene_2": '', "scene_2": '',
@ -178,11 +169,16 @@ class FourSceneBloc extends Bloc<FourSceneEvent, FourSceneState> {
AssignDeviceScene event, Emitter<FourSceneState> emit) async { AssignDeviceScene event, Emitter<FourSceneState> emit) async {
emit(FourSceneLoadingState()); emit(FourSceneLoadingState());
try { try {
final response = await DevicesAPI.postFourSceneInfo( if (event.sceneUuid == '') {
deviceId: fourSceneId, final response = await DevicesAPI.unAssignScenesDevice(
sceneUuid: event.sceneUuid, deviceUuid: fourSceneId, switchName: event.switchName);
spaceUuid: event.unit!.id, } else {
switchName: event.switchName); final response = await DevicesAPI.postDeviceSceneInfo(
deviceId: fourSceneId,
sceneUuid: event.sceneUuid,
spaceUuid: event.unit!.id,
switchName: event.switchName);
}
emit(SaveSelectionSuccessState()); emit(SaveSelectionSuccessState());
CustomSnackBar.displaySnackBar('Save Successfully'); CustomSnackBar.displaySnackBar('Save Successfully');
@ -191,6 +187,7 @@ class FourSceneBloc extends Bloc<FourSceneEvent, FourSceneState> {
} }
} }
void _fetchDeviceScene( void _fetchDeviceScene(
FetchDeviceScene event, Emitter<FourSceneState> emit) async { FetchDeviceScene event, Emitter<FourSceneState> emit) async {
emit(FourSceneLoadingState()); emit(FourSceneLoadingState());
@ -256,16 +253,6 @@ class FourSceneBloc extends Bloc<FourSceneEvent, FourSceneState> {
} }
} }
void _onSearchFaq(SearchFaqEvent event, Emitter<FourSceneState> emit) {
emit(FourSceneLoadingState());
List<QuestionModel> _faqQuestions = faqQuestions.where((question) {
return question.question
.toLowerCase()
.contains(event.query.toLowerCase());
}).toList();
emit(FaqSearchState(filteredFaqQuestions: _faqQuestions));
}
//============================ assign Device ================================== //============================ assign Device ==================================
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@ -283,56 +270,6 @@ class FourSceneBloc extends Bloc<FourSceneEvent, FourSceneState> {
DeviceReport recordGroups = DeviceReport recordGroups =
DeviceReport(startTime: '0', endTime: '0', data: []); DeviceReport(startTime: '0', endTime: '0', data: []);
//========================= Question and faq ================================
final List<QuestionModel> 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<FourSceneState> emit) async {
try {
emit(FourSceneLoadingState());
isHelpful = event.isHelpful!;
emit(SaveState());
} catch (e) {
emit(const FourSceneFailedState(errorMessage: 'Something went wrong'));
}
}
Future<void> _onFourSceneInitial(
FourSceneInitialQuestion event, Emitter<FourSceneState> emit) async {
emit(FourSceneLoadingState());
emit(FaqLoadedState(filteredFaqQuestions: faqQuestions));
}
List<DeviceModel> allDevices = []; List<DeviceModel> allDevices = [];
List<SubSpaceModel> roomsList = []; List<SubSpaceModel> roomsList = [];
bool switchStatus = true; bool switchStatus = true;
@ -393,159 +330,4 @@ class FourSceneBloc extends Bloc<FourSceneEvent, FourSceneState> {
}).toList(); }).toList();
emit(SearchResultsState()); emit(SearchResultsState());
} }
List<GroupDevicesModel> groupDevices = [
GroupDevicesModel(
dec: 'Syncroom', icon: Assets.minusIcon, name: '6 Scene Switch')
];
List<GroupDevicesModel> devices = [
GroupDevicesModel(
dec: 'Syncroom', icon: Assets.addDevicesIcon, name: '6 Scene Switch')
];
// Handler for AddDeviceToGroup
void _addDeviceToGroup(AddDeviceToGroup event, Emitter<FourSceneState> 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<FourSceneState> 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<FourSceneState> 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<String> 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<FourSceneState> 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<FourSceneState> 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<void> saveName(
SaveNameEvent event, Emitter<FourSceneState> 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<FourSceneState> emit) async {
try {
emit(FourSceneLoadingState());
enableUpdate = event.isUpdateEnabled!;
emit(SaveState());
} catch (e) {
emit(const FourSceneFailedState(errorMessage: 'Something went wrong'));
}
}
deleteDevice(DeleteDeviceEvent event, Emitter<FourSceneState> 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;
}
}
} }

View File

@ -84,10 +84,12 @@ class LoadScenes extends FourSceneEvent {
class SelectSceneEvent extends FourSceneEvent { class SelectSceneEvent extends FourSceneEvent {
final String selectedSceneId; final String selectedSceneId;
final bool isSelected;
// final String unitId; // final String unitId;
const SelectSceneEvent({ const SelectSceneEvent({
// required this.unitId, // required this.unitId,
required this.selectedSceneId, required this.selectedSceneId,
required this.isSelected,
}); });
} }
@ -143,6 +145,13 @@ class FourSceneSwitchInitial extends FourSceneEvent {
const FourSceneSwitchInitial(); const FourSceneSwitchInitial();
} }
class UnAssignSceneEvent extends FourSceneEvent {
final String deviceUuid;
final String switchName;
const UnAssignSceneEvent(
{required this.deviceUuid, required this.switchName});
}
class AssignDeviceScene extends FourSceneEvent { class AssignDeviceScene extends FourSceneEvent {
final String? sceneUuid; final String? sceneUuid;
final String? switchName; final String? switchName;

View File

@ -1,200 +1,200 @@
import 'package:flutter/material.dart'; // import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; // import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/svg.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_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_event.dart';
import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_state.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_model.dart';
import 'package:syncrow_app/features/shared_widgets/default_container.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/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_large.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.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/features/shared_widgets/text_widgets/body_small.dart';
import 'package:syncrow_app/generated/assets.dart'; // import 'package:syncrow_app/generated/assets.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; // import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
class FourSceneCreateGroup extends StatelessWidget { // class FourSceneCreateGroup extends StatelessWidget {
final DeviceModel? device; // final DeviceModel? device;
const FourSceneCreateGroup({super.key, this.device}); // const FourSceneCreateGroup({super.key, this.device});
@override // @override
Widget build(BuildContext context) { // Widget build(BuildContext context) {
return DefaultScaffold( // return DefaultScaffold(
title: 'Create Group', // title: 'Create Group',
child: BlocProvider( // child: BlocProvider(
create: (context) => FourSceneBloc(fourSceneId: device?.uuid ?? '') // create: (context) => FourSceneBloc(fourSceneId: device?.uuid ?? '')
..add(const FourSceneInitial()), // ..add(const FourSceneInitial()),
child: BlocBuilder<FourSceneBloc, FourSceneState>( // child: BlocBuilder<FourSceneBloc, FourSceneState>(
builder: (context, state) { // builder: (context, state) {
final sensor = BlocProvider.of<FourSceneBloc>(context); // final sensor = BlocProvider.of<FourSceneBloc>(context);
return state is LoadingNewSate // return state is LoadingNewSate
? const Center( // ? const Center(
child: DefaultContainer( // child: DefaultContainer(
width: 50, // width: 50,
height: 50, // height: 50,
child: CircularProgressIndicator()), // child: CircularProgressIndicator()),
) // )
: Padding( // : Padding(
padding: const EdgeInsets.all(8.0), // padding: const EdgeInsets.all(8.0),
child: Column( // child: Column(
children: [ // children: [
const Padding( // const Padding(
padding: EdgeInsets.only(left: 25, right: 25), // padding: EdgeInsets.only(left: 25, right: 25),
child: BodySmall( // child: BodySmall(
text: // text:
'Devices in the same group can be controlled together', // 'Devices in the same group can be controlled together',
fontColor: ColorsManager.primaryTextColor, // fontColor: ColorsManager.primaryTextColor,
textAlign: TextAlign.center, // textAlign: TextAlign.center,
), // ),
), // ),
Flexible( // Flexible(
child: ListView.builder( // child: ListView.builder(
itemCount: sensor.groupDevices.length, // itemCount: sensor.groupDevices.length,
itemBuilder: (context, index) { // itemBuilder: (context, index) {
return InkWell( // return InkWell(
onTap: () { // onTap: () {
BlocProvider.of<FourSceneBloc>(context).add( // BlocProvider.of<FourSceneBloc>(context).add(
RemoveDeviceFromGroup( // RemoveDeviceFromGroup(
sensor.groupDevices[index], // sensor.groupDevices[index],
Assets.addDevicesIcon)); // Assets.addDevicesIcon));
}, // },
child: DefaultContainer( // child: DefaultContainer(
child: Padding( // child: Padding(
padding: const EdgeInsets.all(5.0), // padding: const EdgeInsets.all(5.0),
child: Row( // child: Row(
crossAxisAlignment: // crossAxisAlignment:
CrossAxisAlignment.start, // CrossAxisAlignment.start,
mainAxisAlignment: // mainAxisAlignment:
MainAxisAlignment.spaceBetween, // MainAxisAlignment.spaceBetween,
children: [ // children: [
Row( // Row(
children: [ // children: [
SvgPicture.asset( // SvgPicture.asset(
sensor.groupDevices[index].icon!, // sensor.groupDevices[index].icon!,
fit: BoxFit.contain, // fit: BoxFit.contain,
), // ),
const SizedBox( // const SizedBox(
width: 15, // width: 15,
), // ),
BodyMedium( // BodyMedium(
text: sensor // text: sensor
.groupDevices[index].name!, // .groupDevices[index].name!,
fontColor: // fontColor:
ColorsManager.primaryTextColor, // ColorsManager.primaryTextColor,
textAlign: TextAlign.center, // textAlign: TextAlign.center,
fontSize: 15, // fontSize: 15,
), // ),
], // ],
), // ),
BodyMedium( // BodyMedium(
text: sensor.groupDevices[index].dec!, // text: sensor.groupDevices[index].dec!,
fontColor: ColorsManager.grayColor, // fontColor: ColorsManager.grayColor,
textAlign: TextAlign.center, // textAlign: TextAlign.center,
fontSize: 15, // fontSize: 15,
), // ),
], // ],
), // ),
)), // )),
); // );
}, // },
), // ),
), // ),
Flexible( // Flexible(
child: Column( // child: Column(
crossAxisAlignment: CrossAxisAlignment.start, // crossAxisAlignment: CrossAxisAlignment.start,
children: [ // children: [
const BodyLarge( // const BodyLarge(
text: 'Devices to be added', // text: 'Devices to be added',
fontColor: ColorsManager.grayColor, // fontColor: ColorsManager.grayColor,
textAlign: TextAlign.center, // textAlign: TextAlign.center,
fontSize: 12, // fontSize: 12,
fontWeight: FontWeight.w700, // fontWeight: FontWeight.w700,
), // ),
const SizedBox( // const SizedBox(
height: 5, // height: 5,
), // ),
sensor.devices.isNotEmpty // sensor.devices.isNotEmpty
? Expanded( // ? Expanded(
child: ListView.builder( // child: ListView.builder(
itemCount: sensor.devices.length, // itemCount: sensor.devices.length,
itemBuilder: (context, index) { // itemBuilder: (context, index) {
final device = sensor.devices[index]; // final device = sensor.devices[index];
return GestureDetector( // return GestureDetector(
onTap: () { // onTap: () {
BlocProvider.of<FourSceneBloc>( // BlocProvider.of<FourSceneBloc>(
context) // context)
.add(AddDeviceToGroup(device, // .add(AddDeviceToGroup(device,
Assets.minusIcon)); // Assets.minusIcon));
}, // },
child: DefaultContainer( // child: DefaultContainer(
child: Padding( // child: Padding(
padding: // padding:
const EdgeInsets.all(5.0), // const EdgeInsets.all(5.0),
child: Row( // child: Row(
crossAxisAlignment: // crossAxisAlignment:
CrossAxisAlignment.start, // CrossAxisAlignment.start,
mainAxisAlignment: // mainAxisAlignment:
MainAxisAlignment // MainAxisAlignment
.spaceBetween, // .spaceBetween,
children: [ // children: [
Row( // Row(
children: [ // children: [
SvgPicture.asset( // SvgPicture.asset(
device.icon!, // device.icon!,
fit: BoxFit.contain, // fit: BoxFit.contain,
), // ),
const SizedBox( // const SizedBox(
width: 15, // width: 15,
), // ),
BodyMedium( // BodyMedium(
text: device.name!, // text: device.name!,
fontColor: ColorsManager // fontColor: ColorsManager
.primaryTextColor, // .primaryTextColor,
textAlign: // textAlign:
TextAlign.center, // TextAlign.center,
fontSize: 15, // fontSize: 15,
), // ),
], // ],
), // ),
BodyMedium( // BodyMedium(
text: device.dec!, // text: device.dec!,
fontColor: ColorsManager // fontColor: ColorsManager
.grayColor, // .grayColor,
textAlign: // textAlign:
TextAlign.center, // TextAlign.center,
fontSize: 15, // fontSize: 15,
), // ),
], // ],
), // ),
), // ),
), // ),
); // );
}, // },
), // ),
) // )
: const Column( // : const Column(
children: [ // children: [
BodySmall( // BodySmall(
text: // text:
'Currently no devices available to create group', // 'Currently no devices available to create group',
fontColor: ColorsManager.grayColor, // fontColor: ColorsManager.grayColor,
textAlign: TextAlign.center, // textAlign: TextAlign.center,
fontSize: 12, // fontSize: 12,
fontWeight: FontWeight.w400, // fontWeight: FontWeight.w400,
), // ),
], // ],
), // ),
], // ],
), // ),
), // ),
const Spacer() // const Spacer()
], // ],
), // ),
); // );
}, // },
), // ),
), // ),
); // );
} // }
} // }

View File

@ -1,9 +1,9 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.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/device_settings_bloc/device_scene_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_event.dart'; import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_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_state.dart';
import 'package:syncrow_app/features/devices/model/device_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/question_model.dart';
import 'package:syncrow_app/features/devices/view/device_settings/question_page.dart'; import 'package:syncrow_app/features/devices/view/device_settings/question_page.dart';
@ -24,19 +24,18 @@ class FaqSettingPage extends StatelessWidget {
return DefaultScaffold( return DefaultScaffold(
title: 'FAQ', title: 'FAQ',
child: BlocProvider( child: BlocProvider(
create: (context) => FourSceneBloc(fourSceneId: device?.uuid ?? '') create: (context) => DeviceSettingBloc(deviceId: device?.uuid ?? '')
..add(const FourSceneInitialQuestion()), ..add(const DeviceSettingInitialQuestion()),
child: BlocBuilder<FourSceneBloc, FourSceneState>( child: BlocBuilder<DeviceSettingBloc, DeviceSettingState>(
builder: (context, state) { builder: (context, state) {
final sensor = BlocProvider.of<FourSceneBloc>(context); final sensor = BlocProvider.of<DeviceSettingBloc>(context);
List<QuestionModel> displayedQuestions = []; List<QuestionModel> displayedQuestions = [];
if (state is FaqSearchState) { if (state is FaqSearchState) {
displayedQuestions = state.filteredFaqQuestions; displayedQuestions = state.filteredFaqQuestions;
} else if (state is FaqLoadedState) { } else if (state is FaqLoadedState) {
displayedQuestions = state.filteredFaqQuestions; displayedQuestions = state.filteredFaqQuestions;
} }
return state is FourSceneLoadingState return state is DeviceSettingLoadingState
? const Center( ? const Center(
child: DefaultContainer( child: DefaultContainer(
width: 50, width: 50,

View File

@ -3,9 +3,9 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:percent_indicator/linear_percent_indicator.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/device_settings_bloc/device_scene_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/four_scene_bloc/four_scene_event.dart'; import 'package:syncrow_app/features/devices/bloc/device_settings_bloc/device_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_state.dart';
import 'package:syncrow_app/features/devices/view/device_settings/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_button.dart';
import 'package:syncrow_app/features/shared_widgets/default_container.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'; import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
class UpdatePageSetting extends StatelessWidget { class UpdatePageSetting extends StatelessWidget {
const UpdatePageSetting({super.key}); final String? deviceId;
const UpdatePageSetting({super.key, this.deviceId});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return DefaultScaffold( return DefaultScaffold(
title: 'Device Update', title: 'Device Update',
child: BlocProvider( child: BlocProvider(
create: (context) => create: (context) => DeviceSettingBloc(deviceId: deviceId ?? '')
FourSceneBloc(fourSceneId: '')..add(const FourSceneInitial()), ..add(const DeviceSettingInitial())
child: BlocBuilder<FourSceneBloc, FourSceneState>( ..add(const DeviceSettingInitialInfo()),
child: BlocBuilder<DeviceSettingBloc, DeviceSettingState>(
builder: (context, state) { builder: (context, state) {
final _bloc = BlocProvider.of<FourSceneBloc>(context); final _bloc = BlocProvider.of<DeviceSettingBloc>(context);
return state is FourSceneLoadingState return state is DeviceSettingLoadingState
? const Center( ? const Center(
child: DefaultContainer( child: DefaultContainer(
width: 50, width: 50,

View File

@ -37,8 +37,10 @@ class SixSelectSceneFourPage extends StatelessWidget {
builder: (context, state) { builder: (context, state) {
final sensorBloc = BlocProvider.of<SixSceneBloc>(context); final sensorBloc = BlocProvider.of<SixSceneBloc>(context);
if (state is SaveSelectionSuccessState) { if (state is SaveSelectionSuccessState) {
Navigator.of(context).pop(true); Future.delayed(const Duration(milliseconds: 250), () {
Navigator.of(context).pop(true); Navigator.of(context).pop(true);
Navigator.of(context).pop(true);
});
} }
return DefaultScaffold( return DefaultScaffold(
title: 'Select Scene', title: 'Select Scene',
@ -163,7 +165,8 @@ class SixSelectSceneFourPage extends StatelessWidget {
disablePlayButton: false, disablePlayButton: false,
onChanged: (isSelected) { onChanged: (isSelected) {
sensorBloc.add(SelectOptionEvent(selectedOption: scene.id)); sensorBloc.add(SelectOptionEvent(selectedOption: scene.id));
sensorBloc.add(SelectSceneEvent(unitId: scene.id)); sensorBloc.add(SelectSceneEvent(
selectedSceneId: scene.id, isSelected: isSelected));
}, },
icon: scene.iconInBytes, icon: scene.iconInBytes,
title: scene.name, title: scene.name,

View File

@ -196,12 +196,14 @@ class SixSceneScreen extends StatelessWidget {
); );
}, },
); );
if (value == true) { if (value == true) {
_bloc.add(const SixSceneInitial()); Future.delayed(
_bloc.add( const Duration(
const SixSceneInitialInfo()); milliseconds: 250), () {
_bloc.add( _bloc.add(
const SexSceneSwitchInitial()); const SexSceneSwitchInitial());
});
} }
}, },
child: Column( child: Column(

View File

@ -175,12 +175,14 @@ class FourSceneScreen extends StatelessWidget {
); );
}, },
); );
if (value == true) { if (value == true) {
_bloc.add(const FourSceneInitial()); Future.delayed(
_bloc.add( const Duration(
const FourSceneInitialInfo()); milliseconds: 250), () {
_bloc.add( _bloc.add(
const FourSceneSwitchInitial()); const FourSceneSwitchInitial());
});
} }
}, },
child: Column( child: Column(

View File

@ -37,8 +37,10 @@ class FourSelectSceneFourPage extends StatelessWidget {
builder: (context, state) { builder: (context, state) {
final sensorBloc = BlocProvider.of<FourSceneBloc>(context); final sensorBloc = BlocProvider.of<FourSceneBloc>(context);
if (state is SaveSelectionSuccessState) { if (state is SaveSelectionSuccessState) {
Navigator.of(context).pop(true); Future.delayed(const Duration(milliseconds: 250), () {
Navigator.of(context).pop(true); Navigator.of(context).pop(true);
Navigator.of(context).pop(true);
});
} }
return DefaultScaffold( return DefaultScaffold(
title: 'Select Scene', title: 'Select Scene',
@ -153,55 +155,25 @@ class FourSelectSceneFourPage extends StatelessWidget {
), ),
itemBuilder: (context, index) { itemBuilder: (context, index) {
final scene = scenes[index]; final scene = scenes[index];
// Check if this scene is currently selected
bool isSelected = scene.id == bool isSelected = scene.id ==
(state is SceneSelectionUpdatedState (state is SceneSelectionUpdatedState
? state.selectedSceneId ? state.selectedSceneId
: sensorBloc.selectedFormApiSceneId); : sensorBloc.selectedFormApiSceneId);
return SceneItem( return SceneItem(
id: scene.id, id: scene.id,
value: isSelected, value: isSelected, // Pass isSelected to the SceneItem
disablePlayButton: false, disablePlayButton: false,
onChanged: (isSelected) { onChanged: (newSelection) {
// If selected, assign the scene
sensorBloc.add(SelectOptionEvent(selectedOption: scene.id)); sensorBloc.add(SelectOptionEvent(selectedOption: scene.id));
sensorBloc.add(SelectSceneEvent(selectedSceneId: scene.id,isSelected:newSelection));
sensorBloc.add(SelectSceneEvent(selectedSceneId: scene.id));
}, },
icon: scene.iconInBytes, icon: scene.iconInBytes,
title: scene.name, 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,
// );
// }

View File

@ -213,11 +213,12 @@ abstract class ApiEndpoints {
'/device/report-logs/{deviceUuid}?code={code}&startTime={startTime}&endTime={endTime}'; '/device/report-logs/{deviceUuid}?code={code}&startTime={startTime}&endTime={endTime}';
static const String controlBatch = '/device/control/batch'; static const String controlBatch = '/device/control/batch';
static const String statusBatch = '/device/status/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 = static const String fourSceneByName =
'/device/{deviceUuid}/scenes?switchName={switchName}'; '/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}'; static const String unAssignScenesDevice =
'/device/{deviceUuid}/scenes?switchName={switchName}';
} }

View File

@ -91,7 +91,6 @@ class DevicesAPI {
.replaceAll('{deviceUuid}', deviceId), .replaceAll('{deviceUuid}', deviceId),
showServerMessage: false, showServerMessage: false,
expectedResponseModel: (json) { expectedResponseModel: (json) {
print('json==#$json');
return json; return json;
}, },
); );
@ -138,11 +137,12 @@ class DevicesAPI {
return response; return response;
} }
static Future getFourSceneInfo(String deviceId) async { static Future getDeviceSceneInfo(String deviceId) async {
final response = await _httpService.get( final response = await _httpService.get(
path: ApiEndpoints.fourScene.replaceAll('{deviceUuid}', deviceId), path: ApiEndpoints.deviceScene.replaceAll('{deviceUuid}', deviceId),
showServerMessage: false, showServerMessage: false,
expectedResponseModel: (json) { expectedResponseModel: (json) {
print(json);
return json; return json;
}); });
return response; return response;
@ -161,14 +161,14 @@ class DevicesAPI {
return response; return response;
} }
static Future postFourSceneInfo({ static Future postDeviceSceneInfo({
String? switchName, String? switchName,
String? sceneUuid, String? sceneUuid,
String? deviceId, String? deviceId,
String? spaceUuid, String? spaceUuid,
}) async { }) async {
final response = await _httpService.post( final response = await _httpService.post(
path: ApiEndpoints.fourScene.replaceAll('{deviceUuid}', deviceId!), path: ApiEndpoints.deviceScene.replaceAll('{deviceUuid}', deviceId!),
body: jsonEncode( body: jsonEncode(
{ {
"switchName": switchName, "switchName": switchName,
@ -178,7 +178,6 @@ class DevicesAPI {
), ),
showServerMessage: false, showServerMessage: false,
expectedResponseModel: (json) { expectedResponseModel: (json) {
print('postFourSceneInfo=$json');
return json; return json;
}); });
return response; return response;
@ -189,7 +188,7 @@ class DevicesAPI {
path: ApiEndpoints.deviceByUuid.replaceAll('{deviceUuid}', deviceId), path: ApiEndpoints.deviceByUuid.replaceAll('{deviceUuid}', deviceId),
showServerMessage: false, showServerMessage: false,
expectedResponseModel: (json) { expectedResponseModel: (json) {
print('json==$json'); print('object-*-*-*${json}');
return json; return json;
}); });
return response; return response;
@ -529,4 +528,20 @@ class DevicesAPI {
); );
return response; 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;
}
} }