mirror of
https://github.com/SyncrowIOT/syncrow-app.git
synced 2025-07-15 09:45:22 +00:00
all_devices and Restrict_user
This commit is contained in:
18
assets/icons/offToggleSwitchSmall.svg
Normal file
18
assets/icons/offToggleSwitchSmall.svg
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<svg width="47" height="37" viewBox="0 0 47 37" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect x="6" y="1" width="41" height="25" rx="12.5" fill="#E9E9E9"/>
|
||||||
|
<g filter="url(#filter0_d_6419_4507)">
|
||||||
|
<circle cx="18.5" cy="13.5" r="10.5" fill="white"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<filter id="filter0_d_6419_4507" x="0" y="0" width="37" height="37" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||||
|
<feOffset dy="5"/>
|
||||||
|
<feGaussianBlur stdDeviation="4"/>
|
||||||
|
<feComposite in2="hardAlpha" operator="out"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0"/>
|
||||||
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_6419_4507"/>
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_6419_4507" result="shape"/>
|
||||||
|
</filter>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 965 B |
18
assets/icons/toggleSwitchSmall.svg
Normal file
18
assets/icons/toggleSwitchSmall.svg
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<svg width="47" height="37" viewBox="0 0 47 37" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect y="1" width="41" height="25" rx="12.5" fill="#023DFE" fill-opacity="0.7"/>
|
||||||
|
<g filter="url(#filter0_d_6689_981)">
|
||||||
|
<circle cx="28.5" cy="13.5" r="10.5" fill="white"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<filter id="filter0_d_6689_981" x="10" y="0" width="37" height="37" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||||
|
<feOffset dy="5"/>
|
||||||
|
<feGaussianBlur stdDeviation="4"/>
|
||||||
|
<feComposite in2="hardAlpha" operator="out"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0"/>
|
||||||
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_6689_981"/>
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_6689_981" result="shape"/>
|
||||||
|
</filter>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 975 B |
@ -168,7 +168,7 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
|
|
||||||
static HomeCubit get(context) => BlocProvider.of(context);
|
static HomeCubit get(context) => BlocProvider.of(context);
|
||||||
|
|
||||||
List<SpaceModel>? spaces = [];
|
List<SpaceModel> spaces = [];
|
||||||
|
|
||||||
SpaceModel? selectedSpace;
|
SpaceModel? selectedSpace;
|
||||||
|
|
||||||
@ -261,8 +261,10 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
|
|
||||||
if (index == 0) {
|
if (index == 0) {
|
||||||
unselectRoom();
|
unselectRoom();
|
||||||
|
} else if (index == 1) {
|
||||||
|
unselectRoom1();
|
||||||
} else {
|
} else {
|
||||||
selectedRoom = selectedSpace!.subspaces[index - 1];
|
selectedRoom = selectedSpace!.subspaces[index - 2];
|
||||||
emitSafe(RoomSelected(selectedRoom!));
|
emitSafe(RoomSelected(selectedRoom!));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -276,8 +278,10 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
|
|
||||||
if (index <= 0) {
|
if (index <= 0) {
|
||||||
unselectRoom();
|
unselectRoom();
|
||||||
|
} else if (index == 1) {
|
||||||
|
unselectRoom1();
|
||||||
} else {
|
} else {
|
||||||
selectedRoom = selectedSpace!.subspaces[index - 1];
|
selectedRoom = selectedSpace!.subspaces[index - 2];
|
||||||
emitSafe(RoomSelected(selectedRoom!));
|
emitSafe(RoomSelected(selectedRoom!));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -299,6 +303,23 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
emitSafe(RoomUnSelected());
|
emitSafe(RoomUnSelected());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unselectRoom1() {
|
||||||
|
// selectedRoom = null;
|
||||||
|
devicesPageController.animateToPage(
|
||||||
|
1,
|
||||||
|
duration: duration,
|
||||||
|
curve: Curves.linear,
|
||||||
|
);
|
||||||
|
|
||||||
|
roomsPageController.animateToPage(
|
||||||
|
1,
|
||||||
|
duration: duration,
|
||||||
|
curve: Curves.linear,
|
||||||
|
);
|
||||||
|
|
||||||
|
emitSafe(RoomUnSelected());
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////// API ////////////////////////////////////////
|
//////////////////////////////////////// API ////////////////////////////////////////
|
||||||
generateInvitation(SpaceModel unit) async {
|
generateInvitation(SpaceModel unit) async {
|
||||||
try {
|
try {
|
||||||
@ -340,16 +361,16 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
emitSafe(GetSpacesLoading());
|
emitSafe(GetSpacesLoading());
|
||||||
try {
|
try {
|
||||||
spaces = await SpacesAPI.getSpacesByUserId();
|
spaces = await SpacesAPI.getSpacesByUserId();
|
||||||
emitSafe(GetSpacesSuccess(spaces!));
|
emitSafe(GetSpacesSuccess(spaces));
|
||||||
} catch (failure) {
|
} catch (failure) {
|
||||||
emitSafe(GetSpacesError("No units found"));
|
emitSafe(GetSpacesError("No units found"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spaces != null && spaces!.isNotEmpty) {
|
if (spaces.isNotEmpty) {
|
||||||
selectedSpace = spaces!.first;
|
selectedSpace = spaces.first;
|
||||||
await fetchRoomsByUnitId(selectedSpace!);
|
await fetchRoomsByUnitId(selectedSpace!);
|
||||||
emitSafe(GetSpacesSuccess(spaces!));
|
emitSafe(GetSpacesSuccess(spaces));
|
||||||
} else {
|
} else {
|
||||||
emitSafe(GetSpacesError("No spaces found"));
|
emitSafe(GetSpacesError("No spaces found"));
|
||||||
}
|
}
|
||||||
@ -460,7 +481,8 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
// ),
|
// ),
|
||||||
// onPressed: () {},
|
// onPressed: () {},
|
||||||
// ),
|
// ),
|
||||||
manageScene? IconButton(
|
manageScene
|
||||||
|
? IconButton(
|
||||||
icon: const Icon(
|
icon: const Icon(
|
||||||
Icons.add,
|
Icons.add,
|
||||||
size: 32,
|
size: 32,
|
||||||
|
@ -4,6 +4,7 @@ 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/acs_bloc/acs_event.dart';
|
import 'package:syncrow_app/features/devices/bloc/acs_bloc/acs_event.dart';
|
||||||
import 'package:syncrow_app/features/devices/bloc/acs_bloc/acs_state.dart';
|
import 'package:syncrow_app/features/devices/bloc/acs_bloc/acs_state.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/ac_model.dart';
|
import 'package:syncrow_app/features/devices/model/ac_model.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';
|
||||||
@ -135,6 +136,8 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
|
|||||||
ac.acSwitch = acSwitchValue;
|
ac.acSwitch = acSwitchValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
_setAllAcsTempsAndSwitches();
|
_setAllAcsTempsAndSwitches();
|
||||||
_emitAcsStatus(emit);
|
_emitAcsStatus(emit);
|
||||||
} else {
|
} else {
|
||||||
@ -433,9 +436,7 @@ class ACsBloc extends Bloc<AcsEvent, AcsState> {
|
|||||||
seconds = event.seconds;
|
seconds = event.seconds;
|
||||||
final response = await DevicesAPI.controlDevice(
|
final response = await DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(
|
DeviceControlModel(
|
||||||
deviceId: acId,
|
deviceId: acId, code: 'countdown_time', value: event.duration),
|
||||||
code: 'countdown_time',
|
|
||||||
value: event.duration),
|
|
||||||
acId);
|
acId);
|
||||||
|
|
||||||
if (response['success'] ?? false) {
|
if (response['success'] ?? false) {
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
import 'package:firebase_database/firebase_database.dart';
|
import 'package:firebase_database/firebase_database.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
@ -112,7 +114,7 @@ class CeilingSensorBloc extends Bloc<CeilingSensorEvent, CeilingSensorState> {
|
|||||||
code: 'presence_state',
|
code: 'presence_state',
|
||||||
);
|
);
|
||||||
recordGroups = response;
|
recordGroups = response;
|
||||||
// print('---${recordGroups.data!.first.eventTime}');
|
// print('---${jsonEncode(recordGroups.data.first.)}');
|
||||||
emit(FitchData());
|
emit(FitchData());
|
||||||
} on DioException catch (e) {
|
} on DioException catch (e) {
|
||||||
final errorData = e.response!.data;
|
final errorData = e.response!.data;
|
||||||
|
@ -31,6 +31,7 @@ class DevicesCubit extends Cubit<DevicesState> {
|
|||||||
|
|
||||||
// Fetch groups based on the selected space ID
|
// Fetch groups based on the selected space ID
|
||||||
await fetchGroups(selectedSpace.id);
|
await fetchGroups(selectedSpace.id);
|
||||||
|
await fetchAllDevices(selectedSpace);
|
||||||
}
|
}
|
||||||
|
|
||||||
DevicesCubit._() : super(DevicesInitial()) {
|
DevicesCubit._() : super(DevicesInitial()) {
|
||||||
@ -109,17 +110,6 @@ class DevicesCubit extends Cubit<DevicesState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Getter to retrieve all devices from HomeCubit
|
// Getter to retrieve all devices from HomeCubit
|
||||||
List<DeviceModel> get allDevices {
|
|
||||||
List<DeviceModel> devices = [];
|
|
||||||
if (HomeCubit.getInstance().selectedSpace != null) {
|
|
||||||
for (var room in HomeCubit.getInstance().selectedSpace!.subspaces) {
|
|
||||||
if (room.devices != null) {
|
|
||||||
devices.addAll(room.devices!);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return devices;
|
|
||||||
}
|
|
||||||
|
|
||||||
// DevicesCategoryModel? get chosenCategory {
|
// DevicesCategoryModel? get chosenCategory {
|
||||||
// for (var category in allCategories!) {
|
// for (var category in allCategories!) {
|
||||||
@ -267,36 +257,36 @@ class DevicesCubit extends Cubit<DevicesState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////// API CALLS //////////////////////////
|
///////////////////////// API CALLS //////////////////////////
|
||||||
deviceControl(DeviceControlModel control, String deviceId) async {
|
// deviceControl(DeviceControlModel control, String deviceId) async {
|
||||||
emitSafe(DeviceControlLoading(
|
// emitSafe(DeviceControlLoading(
|
||||||
code: control.code,
|
// code: control.code,
|
||||||
));
|
// ));
|
||||||
try {
|
// try {
|
||||||
var response = await DevicesAPI.controlDevice(control, deviceId);
|
// var response = await DevicesAPI.controlDevice(control, deviceId);
|
||||||
|
|
||||||
if (response['success'] ?? false) {
|
// if (response['success'] ?? false) {
|
||||||
emitSafe(DeviceControlSuccess(code: control.code));
|
// emitSafe(DeviceControlSuccess(code: control.code));
|
||||||
//this delay is to give tuya server time to update the status
|
// //this delay is to give tuya server time to update the status
|
||||||
// Future.delayed(const Duration(milliseconds: 400), () {
|
// // Future.delayed(const Duration(milliseconds: 400), () {
|
||||||
fetchDevicesStatues(
|
// fetchDevicesStatues(
|
||||||
deviceId,
|
// deviceId,
|
||||||
HomeCubit.getInstance()
|
// HomeCubit.getInstance()
|
||||||
.selectedSpace!
|
// .selectedSpace!
|
||||||
.subspaces
|
// .subspaces
|
||||||
.indexOf(HomeCubit.getInstance().selectedRoom!),
|
// .indexOf(HomeCubit.getInstance().selectedRoom!),
|
||||||
code: control.code);
|
// code: control.code);
|
||||||
// });
|
// // });
|
||||||
} else {
|
// } else {
|
||||||
emitSafe(DeviceControlError('Failed to control the device'));
|
// emitSafe(DeviceControlError('Failed to control the device'));
|
||||||
}
|
// }
|
||||||
} catch (failure) {
|
// } catch (failure) {
|
||||||
emitSafe(DeviceControlError(failure.toString()));
|
// emitSafe(DeviceControlError(failure.toString()));
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
fetchGroups(String spaceId) async {
|
fetchGroups(String spaceId) async {
|
||||||
emitSafe(DevicesCategoriesLoading());
|
emitSafe(GetDevicesLoading());
|
||||||
try {
|
try {
|
||||||
allCategories = await DevicesAPI.fetchGroups(spaceId);
|
allCategories = await DevicesAPI.fetchGroups(spaceId);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -321,12 +311,15 @@ class DevicesCubit extends Cubit<DevicesState> {
|
|||||||
try {
|
try {
|
||||||
HomeCubit.getInstance().selectedSpace!.subspaces[roomIndex].devices =
|
HomeCubit.getInstance().selectedSpace!.subspaces[roomIndex].devices =
|
||||||
await DevicesAPI.getDevicesByRoomId(
|
await DevicesAPI.getDevicesByRoomId(
|
||||||
communityUuid: unit!.community.uuid, spaceUuid: unit.id, roomId: roomId);
|
communityUuid: unit!.community.uuid,
|
||||||
|
spaceUuid: unit.id,
|
||||||
|
roomId: roomId);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emitSafe(GetDevicesError(e.toString()));
|
emitSafe(GetDevicesError(e.toString()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final devices = HomeCubit.getInstance().selectedSpace!.subspaces[roomIndex].devices;
|
final devices =
|
||||||
|
HomeCubit.getInstance().selectedSpace!.subspaces[roomIndex].devices;
|
||||||
emitSafe(GetDevicesSuccess(devices));
|
emitSafe(GetDevicesSuccess(devices));
|
||||||
|
|
||||||
//get status for each device
|
//get status for each device
|
||||||
@ -356,8 +349,11 @@ class DevicesCubit extends Cubit<DevicesState> {
|
|||||||
emitSafe(GetDeviceStatusError(e.toString()));
|
emitSafe(GetDeviceStatusError(e.toString()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
HomeCubit.getInstance().selectedSpace!.subspaces[roomIndex].devices![deviceIndex].status =
|
HomeCubit.getInstance()
|
||||||
statuses;
|
.selectedSpace!
|
||||||
|
.subspaces[roomIndex]
|
||||||
|
.devices![deviceIndex]
|
||||||
|
.status = statuses;
|
||||||
emitSafe(GetDeviceStatusSuccess(code: code));
|
emitSafe(GetDeviceStatusSuccess(code: code));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -406,6 +402,346 @@ class DevicesCubit extends Cubit<DevicesState> {
|
|||||||
// emitSafe(LightBrightnessChanged(value));
|
// emitSafe(LightBrightnessChanged(value));
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
// List<DeviceModel> _fetchedDevices = [];
|
||||||
|
|
||||||
|
// List<DeviceModel> get allDevices => _fetchedDevices;
|
||||||
|
List<DeviceModel> allDevices = [];
|
||||||
|
|
||||||
|
Future<void> fetchAllDevices(SpaceModel? unit) async {
|
||||||
|
emitSafe(GetDevicesLoading());
|
||||||
|
try {
|
||||||
|
final devices = await DevicesAPI.getAllDevices(
|
||||||
|
communityUuid: unit!.community.uuid,
|
||||||
|
spaceUuid: unit.id,
|
||||||
|
);
|
||||||
|
allDevices = devices;
|
||||||
|
emitSafe(GetDevicesSuccess(allDevices));
|
||||||
|
} catch (e) {
|
||||||
|
emitSafe(GetDevicesError(e.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isDeviceOn(DeviceModel device) {
|
||||||
|
final switchStatuses = device.status.where(
|
||||||
|
(s) => (s.code?.startsWith('switch') ?? false),
|
||||||
|
);
|
||||||
|
final anySwitchFalse = switchStatuses.any((s) => s.value == false);
|
||||||
|
return !anySwitchFalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateDeviceStatus(String deviceId, bool newToggleStatus) {
|
||||||
|
emitSafe(GetDevicesLoading());
|
||||||
|
|
||||||
|
// Create a fresh copy of the device list.
|
||||||
|
final updatedDevices = List<DeviceModel>.from(allDevices);
|
||||||
|
|
||||||
|
for (int i = 0; i < updatedDevices.length; i++) {
|
||||||
|
final device = updatedDevices[i];
|
||||||
|
if (device.uuid == deviceId) {
|
||||||
|
updatedDevices[i] = DeviceModel(
|
||||||
|
activeTime: device.activeTime,
|
||||||
|
localKey: device.localKey,
|
||||||
|
model: device.model,
|
||||||
|
name: device.name,
|
||||||
|
icon: device.icon,
|
||||||
|
categoryName: device.categoryName,
|
||||||
|
type: device.type,
|
||||||
|
isOnline: device.isOnline,
|
||||||
|
status: device.status, // Make sure to keep the same status list
|
||||||
|
productName: device.productName,
|
||||||
|
timeZone: device.timeZone,
|
||||||
|
updateTime: device.updateTime,
|
||||||
|
uuid: device.uuid,
|
||||||
|
productUuid: device.productUuid,
|
||||||
|
productType: device.productType,
|
||||||
|
subspace: device.subspace,
|
||||||
|
toggleStatus: newToggleStatus,
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
emit(GetDevicesSuccess(updatedDevices));
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> threeGangToggle(
|
||||||
|
DeviceControlModel control, String deviceUuid) async {
|
||||||
|
emit(SwitchControlLoading(code: control.code));
|
||||||
|
try {
|
||||||
|
final deviceIndex = allDevices.indexWhere((d) => d.uuid == deviceUuid);
|
||||||
|
if (deviceIndex == -1) {
|
||||||
|
throw Exception('Device not found');
|
||||||
|
}
|
||||||
|
final device = allDevices[deviceIndex];
|
||||||
|
final switches = ['switch_1', 'switch_2', 'switch_3'];
|
||||||
|
for (final switchCode in switches) {
|
||||||
|
final statusIndex =
|
||||||
|
device.status.indexWhere((s) => s.code == switchCode);
|
||||||
|
if (statusIndex != -1) {
|
||||||
|
final currentValue = device.status[statusIndex].value ?? false;
|
||||||
|
final toggledValue = !currentValue;
|
||||||
|
final controlRequest = DeviceControlModel(
|
||||||
|
code: switchCode, value: toggledValue, deviceId: deviceUuid);
|
||||||
|
final response =
|
||||||
|
await DevicesAPI.controlDevice(controlRequest, deviceUuid);
|
||||||
|
if (response['success'] != true) {
|
||||||
|
throw Exception('Failed to toggle $switchCode');
|
||||||
|
}
|
||||||
|
device.status[statusIndex].value = toggledValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
final anySwitchOff = device.status.any(
|
||||||
|
(s) => (s.code?.startsWith('switch_') ?? false) && (s.value == false),
|
||||||
|
);
|
||||||
|
device.toggleStatus = !anySwitchOff;
|
||||||
|
allDevices[deviceIndex] = device;
|
||||||
|
emit(DeviceControlSuccess(code: control.code));
|
||||||
|
} catch (failure) {
|
||||||
|
emit(DeviceControlError(failure.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> towGangToggle(
|
||||||
|
DeviceControlModel control, String deviceUuid) async {
|
||||||
|
emit(SwitchControlLoading(code: control.code));
|
||||||
|
try {
|
||||||
|
final deviceIndex = allDevices.indexWhere((d) => d.uuid == deviceUuid);
|
||||||
|
if (deviceIndex == -1) {
|
||||||
|
throw Exception('Device not found');
|
||||||
|
}
|
||||||
|
final device = allDevices[deviceIndex];
|
||||||
|
final switches = [
|
||||||
|
'switch_1',
|
||||||
|
'switch_2',
|
||||||
|
];
|
||||||
|
for (final switchCode in switches) {
|
||||||
|
final statusIndex =
|
||||||
|
device.status.indexWhere((s) => s.code == switchCode);
|
||||||
|
if (statusIndex != -1) {
|
||||||
|
final currentValue = device.status[statusIndex].value ?? false;
|
||||||
|
final toggledValue = !currentValue;
|
||||||
|
final controlRequest = DeviceControlModel(
|
||||||
|
code: switchCode, value: toggledValue, deviceId: deviceUuid);
|
||||||
|
final response =
|
||||||
|
await DevicesAPI.controlDevice(controlRequest, deviceUuid);
|
||||||
|
|
||||||
|
device.status[statusIndex].value = response['result'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
final anySwitchOff = device.status.any(
|
||||||
|
(s) => (s.code?.startsWith('switch_') ?? false) && (s.value == false),
|
||||||
|
);
|
||||||
|
device.toggleStatus = !anySwitchOff;
|
||||||
|
allDevices[deviceIndex] = device;
|
||||||
|
emit(DeviceControlSuccess(code: control.code));
|
||||||
|
} catch (failure) {
|
||||||
|
emit(DeviceControlError(failure.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> towGTGangToggle(
|
||||||
|
DeviceControlModel control, String deviceUuid) async {
|
||||||
|
emit(SwitchControlLoading(code: control.code));
|
||||||
|
try {
|
||||||
|
final deviceIndex = allDevices.indexWhere((d) => d.uuid == deviceUuid);
|
||||||
|
if (deviceIndex == -1) {
|
||||||
|
throw Exception('Device not found');
|
||||||
|
}
|
||||||
|
final device = allDevices[deviceIndex];
|
||||||
|
final switches = [
|
||||||
|
'switch_1',
|
||||||
|
'switch_2',
|
||||||
|
];
|
||||||
|
for (final switchCode in switches) {
|
||||||
|
final statusIndex =
|
||||||
|
device.status.indexWhere((s) => s.code == switchCode);
|
||||||
|
if (statusIndex != -1) {
|
||||||
|
final currentValue = device.status[statusIndex].value ?? false;
|
||||||
|
final toggledValue = !currentValue;
|
||||||
|
final controlRequest = DeviceControlModel(
|
||||||
|
code: switchCode, value: toggledValue, deviceId: deviceUuid);
|
||||||
|
final response =
|
||||||
|
await DevicesAPI.controlDevice(controlRequest, deviceUuid);
|
||||||
|
|
||||||
|
device.status[statusIndex].value = response['result'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
final anySwitchOff = device.status.any(
|
||||||
|
(s) => (s.code?.startsWith('switch_') ?? false) && (s.value == false),
|
||||||
|
);
|
||||||
|
device.toggleStatus = !anySwitchOff;
|
||||||
|
allDevices[deviceIndex] = device;
|
||||||
|
emit(DeviceControlSuccess(code: control.code));
|
||||||
|
} catch (failure) {
|
||||||
|
emit(DeviceControlError(failure.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> oneGangToggle(
|
||||||
|
DeviceControlModel control, String deviceUuid) async {
|
||||||
|
emit(SwitchControlLoading(code: control.code));
|
||||||
|
try {
|
||||||
|
final deviceIndex = allDevices.indexWhere((d) => d.uuid == deviceUuid);
|
||||||
|
if (deviceIndex == -1) {
|
||||||
|
throw Exception('Device not found');
|
||||||
|
}
|
||||||
|
final device = allDevices[deviceIndex];
|
||||||
|
|
||||||
|
final statusIndex = device.status.indexWhere((s) => s.code == 'switch_1');
|
||||||
|
if (statusIndex != -1) {
|
||||||
|
final currentValue = device.status[statusIndex].value ?? false;
|
||||||
|
final toggledValue = !currentValue;
|
||||||
|
final controlRequest = DeviceControlModel(
|
||||||
|
code: 'switch_1', value: toggledValue, deviceId: deviceUuid);
|
||||||
|
final response =
|
||||||
|
await DevicesAPI.controlDevice(controlRequest, deviceUuid);
|
||||||
|
print(response);
|
||||||
|
if (response['result'] != true) {
|
||||||
|
throw Exception('Failed to toggle switch_1');
|
||||||
|
}
|
||||||
|
device.status[statusIndex].value = response['result'];
|
||||||
|
}
|
||||||
|
|
||||||
|
final anySwitchOff = device.status.any(
|
||||||
|
(s) => (s.code?.startsWith('switch_') ?? false) && (s.value == false),
|
||||||
|
);
|
||||||
|
device.toggleStatus = !anySwitchOff;
|
||||||
|
allDevices[deviceIndex] = device;
|
||||||
|
emit(DeviceControlSuccess(code: control.code));
|
||||||
|
} catch (failure) {
|
||||||
|
emit(DeviceControlError(failure.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> oneGTGangToggle(
|
||||||
|
DeviceControlModel control, String deviceUuid) async {
|
||||||
|
emit(SwitchControlLoading(code: control.code));
|
||||||
|
try {
|
||||||
|
final deviceIndex = allDevices.indexWhere((d) => d.uuid == deviceUuid);
|
||||||
|
if (deviceIndex == -1) {
|
||||||
|
throw Exception('Device not found');
|
||||||
|
}
|
||||||
|
final device = allDevices[deviceIndex];
|
||||||
|
|
||||||
|
final statusIndex = device.status.indexWhere((s) => s.code == 'switch_1');
|
||||||
|
if (statusIndex != -1) {
|
||||||
|
final currentValue = device.status[statusIndex].value ?? false;
|
||||||
|
final toggledValue = !currentValue;
|
||||||
|
final controlRequest = DeviceControlModel(
|
||||||
|
code: 'switch_1', value: toggledValue, deviceId: deviceUuid);
|
||||||
|
final response =
|
||||||
|
await DevicesAPI.controlDevice(controlRequest, deviceUuid);
|
||||||
|
if (response['result'] != true) {
|
||||||
|
throw Exception('Failed to toggle switch_1');
|
||||||
|
}
|
||||||
|
device.status[statusIndex].value = response['result'];
|
||||||
|
}
|
||||||
|
|
||||||
|
final anySwitchOff = device.status.any(
|
||||||
|
(s) => (s.code?.startsWith('switch_') ?? false) && (s.value == false),
|
||||||
|
);
|
||||||
|
device.toggleStatus = !anySwitchOff;
|
||||||
|
allDevices[deviceIndex] = device;
|
||||||
|
emit(DeviceControlSuccess(code: control.code));
|
||||||
|
} catch (failure) {
|
||||||
|
emit(DeviceControlError(failure.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> deviceControl(
|
||||||
|
DeviceControlModel control, String deviceUuid) async {
|
||||||
|
emit(SwitchControlLoading(code: control.code));
|
||||||
|
try {
|
||||||
|
final response = await DevicesAPI.controlDevice(control, deviceUuid);
|
||||||
|
if (response['success'] == true) {
|
||||||
|
final deviceIndex = allDevices.indexWhere((d) => d.uuid == deviceUuid);
|
||||||
|
if (deviceIndex != -1) {
|
||||||
|
final device = allDevices[deviceIndex];
|
||||||
|
final statusIndex =
|
||||||
|
device.status.indexWhere((s) => s.code == control.code);
|
||||||
|
if (statusIndex != -1) {
|
||||||
|
device.status[statusIndex].value = control.value;
|
||||||
|
}
|
||||||
|
final anySwitchOff = device.status.any(
|
||||||
|
(s) =>
|
||||||
|
(s.code?.startsWith('switch_') ?? false) && (s.value == false),
|
||||||
|
);
|
||||||
|
device.toggleStatus = !anySwitchOff;
|
||||||
|
allDevices[deviceIndex] = device;
|
||||||
|
}
|
||||||
|
emit(DeviceControlSuccess(code: control.code));
|
||||||
|
} else {
|
||||||
|
emit(DeviceControlError('Failed to control the device'));
|
||||||
|
}
|
||||||
|
} catch (failure) {
|
||||||
|
emit(DeviceControlError(failure.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> changeCurtainSwitch(
|
||||||
|
DeviceControlModel control, String deviceUuid) async {
|
||||||
|
emit(SwitchControlLoading(code: control.code));
|
||||||
|
try {
|
||||||
|
final deviceIndex = allDevices.indexWhere((d) => d.uuid == deviceUuid);
|
||||||
|
if (deviceIndex == -1) {
|
||||||
|
throw Exception('Device not found');
|
||||||
|
}
|
||||||
|
final device = allDevices[deviceIndex];
|
||||||
|
final isOpen = control.value == "open";
|
||||||
|
final newValue = isOpen ? 0 : 100;
|
||||||
|
final response = await DevicesAPI.deviceBatchController(
|
||||||
|
code: 'percent_control',
|
||||||
|
devicesUuid: [deviceUuid],
|
||||||
|
value: newValue,
|
||||||
|
);
|
||||||
|
if (response['success'] == true) {
|
||||||
|
final statusIndex =
|
||||||
|
device.status.indexWhere((s) => s.code == 'percent_control');
|
||||||
|
if (statusIndex != -1) {
|
||||||
|
device.status[statusIndex].value = newValue;
|
||||||
|
}
|
||||||
|
allDevices[deviceIndex] = device;
|
||||||
|
|
||||||
|
emit(DeviceControlSuccess(code: control.code));
|
||||||
|
} else {
|
||||||
|
emit(DeviceControlError('Failed to toggle curtain.'));
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
emit(DeviceControlError(error.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Future<void> changeGarageSwitch(
|
||||||
|
DeviceControlModel control, String deviceUuid) async {
|
||||||
|
emit(SwitchControlLoading(code: control.code));
|
||||||
|
try {
|
||||||
|
final deviceIndex = allDevices.indexWhere((d) => d.uuid == deviceUuid);
|
||||||
|
if (deviceIndex == -1) {
|
||||||
|
throw Exception('Device not found');
|
||||||
|
}
|
||||||
|
final device = allDevices[deviceIndex];
|
||||||
|
final isOpen = control.value == "open";
|
||||||
|
final newValue = isOpen ? 0 : 100;
|
||||||
|
final response = await DevicesAPI.deviceBatchController(
|
||||||
|
code: 'percent_control',
|
||||||
|
devicesUuid: [deviceUuid],
|
||||||
|
value: newValue,
|
||||||
|
);
|
||||||
|
if (response['success'] == true) {
|
||||||
|
final statusIndex =
|
||||||
|
device.status.indexWhere((s) => s.code == 'percent_control');
|
||||||
|
if (statusIndex != -1) {
|
||||||
|
device.status[statusIndex].value = newValue;
|
||||||
|
}
|
||||||
|
allDevices[deviceIndex] = device;
|
||||||
|
emit(DeviceControlSuccess(code: control.code));
|
||||||
|
} else {
|
||||||
|
emit(DeviceControlError('Failed to toggle curtain.'));
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
emit(DeviceControlError(error.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum LightMode {
|
enum LightMode {
|
||||||
|
@ -34,6 +34,7 @@ class GetDeviceStatusError extends DevicesState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class GetDevicesLoading extends DevicesState {}
|
class GetDevicesLoading extends DevicesState {}
|
||||||
|
class RoomLoading extends DevicesState {}
|
||||||
|
|
||||||
class GetDevicesSuccess extends DevicesState {
|
class GetDevicesSuccess extends DevicesState {
|
||||||
GetDevicesSuccess(this.devices);
|
GetDevicesSuccess(this.devices);
|
||||||
@ -55,10 +56,16 @@ class DeviceSwitchChanged extends DevicesState {}
|
|||||||
class DeviceSelected extends DevicesState {}
|
class DeviceSelected extends DevicesState {}
|
||||||
|
|
||||||
// Device Control
|
// Device Control
|
||||||
class DeviceControlLoading extends DevicesState {
|
// class DeviceControlLoading extends DevicesState {
|
||||||
final String? code;
|
// final String? code;
|
||||||
|
|
||||||
DeviceControlLoading({this.code});
|
// DeviceControlLoading({this.code});
|
||||||
|
// }
|
||||||
|
class SwitchControlLoading extends DevicesState {
|
||||||
|
final String? code;
|
||||||
|
final String? deviceId;
|
||||||
|
|
||||||
|
SwitchControlLoading({this.deviceId, this.code});
|
||||||
}
|
}
|
||||||
|
|
||||||
class DeviceControlSuccess extends DevicesState {
|
class DeviceControlSuccess extends DevicesState {
|
||||||
|
@ -40,7 +40,8 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
|
|||||||
bool createSchedule = false;
|
bool createSchedule = false;
|
||||||
List<ScheduleModel> listSchedule = [];
|
List<ScheduleModel> listSchedule = [];
|
||||||
|
|
||||||
TwoTouchBloc({required this.twoTouchId, required this.switchCode}) : super(InitialState()) {
|
TwoTouchBloc({required this.twoTouchId, required this.switchCode})
|
||||||
|
: super(InitialState()) {
|
||||||
on<InitialEvent>(_fetchTwoTouchStatus);
|
on<InitialEvent>(_fetchTwoTouchStatus);
|
||||||
on<TwoTouchUpdated>(_twoTouchUpdated);
|
on<TwoTouchUpdated>(_twoTouchUpdated);
|
||||||
on<ChangeFirstSwitchStatusEvent>(_changeFirstSwitch);
|
on<ChangeFirstSwitchStatusEvent>(_changeFirstSwitch);
|
||||||
@ -71,13 +72,15 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
|
|||||||
|
|
||||||
int selectedTabIndex = 0;
|
int selectedTabIndex = 0;
|
||||||
|
|
||||||
void toggleSelectedIndex(ToggleSelectedEvent event, Emitter<TwoTouchState> emit) {
|
void toggleSelectedIndex(
|
||||||
|
ToggleSelectedEvent event, Emitter<TwoTouchState> emit) {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
selectedTabIndex = event.index;
|
selectedTabIndex = event.index;
|
||||||
emit(ChangeSlidingSegmentState(value: selectedTabIndex));
|
emit(ChangeSlidingSegmentState(value: selectedTabIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
void toggleCreateSchedule(ToggleCreateScheduleEvent event, Emitter<TwoTouchState> emit) {
|
void toggleCreateSchedule(
|
||||||
|
ToggleCreateScheduleEvent event, Emitter<TwoTouchState> emit) {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
createSchedule = !createSchedule;
|
createSchedule = !createSchedule;
|
||||||
selectedDays.clear();
|
selectedDays.clear();
|
||||||
@ -85,7 +88,8 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
|
|||||||
emit(UpdateCreateScheduleState(createSchedule));
|
emit(UpdateCreateScheduleState(createSchedule));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _fetchTwoTouchStatus(InitialEvent event, Emitter<TwoTouchState> emit) async {
|
void _fetchTwoTouchStatus(
|
||||||
|
InitialEvent event, Emitter<TwoTouchState> emit) async {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
try {
|
try {
|
||||||
var response = await DevicesAPI.getDeviceStatus(twoTouchId);
|
var response = await DevicesAPI.getDeviceStatus(twoTouchId);
|
||||||
@ -104,18 +108,21 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
|
|||||||
|
|
||||||
_listenToChanges() {
|
_listenToChanges() {
|
||||||
try {
|
try {
|
||||||
DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$twoTouchId');
|
DatabaseReference ref =
|
||||||
|
FirebaseDatabase.instance.ref('device-status/$twoTouchId');
|
||||||
Stream<DatabaseEvent> stream = ref.onValue;
|
Stream<DatabaseEvent> stream = ref.onValue;
|
||||||
|
|
||||||
stream.listen((DatabaseEvent event) async {
|
stream.listen((DatabaseEvent event) async {
|
||||||
if (_timer != null) {
|
if (_timer != null) {
|
||||||
await Future.delayed(const Duration(seconds: 2));
|
await Future.delayed(const Duration(seconds: 2));
|
||||||
}
|
}
|
||||||
Map<dynamic, dynamic> usersMap = event.snapshot.value as Map<dynamic, dynamic>;
|
Map<dynamic, dynamic> usersMap =
|
||||||
|
event.snapshot.value as Map<dynamic, dynamic>;
|
||||||
List<StatusModel> statusList = [];
|
List<StatusModel> statusList = [];
|
||||||
|
|
||||||
usersMap['status'].forEach((element) {
|
usersMap['status'].forEach((element) {
|
||||||
statusList.add(StatusModel(code: element['code'], value: element['value']));
|
statusList
|
||||||
|
.add(StatusModel(code: element['code'], value: element['value']));
|
||||||
});
|
});
|
||||||
|
|
||||||
deviceStatus = TwoTouchModel.fromJson(statusList);
|
deviceStatus = TwoTouchModel.fromJson(statusList);
|
||||||
@ -130,7 +137,8 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
|
|||||||
emit(UpdateState(twoTouchModel: deviceStatus));
|
emit(UpdateState(twoTouchModel: deviceStatus));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _changeFirstSwitch(ChangeFirstSwitchStatusEvent event, Emitter<TwoTouchState> emit) async {
|
void _changeFirstSwitch(
|
||||||
|
ChangeFirstSwitchStatusEvent event, Emitter<TwoTouchState> emit) async {
|
||||||
emit(LoadingNewSate(twoTouchModel: deviceStatus));
|
emit(LoadingNewSate(twoTouchModel: deviceStatus));
|
||||||
try {
|
try {
|
||||||
deviceStatus.firstSwitch = !event.value;
|
deviceStatus.firstSwitch = !event.value;
|
||||||
@ -141,7 +149,8 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
|
|||||||
|
|
||||||
_timer = Timer(const Duration(milliseconds: 100), () async {
|
_timer = Timer(const Duration(milliseconds: 100), () async {
|
||||||
final response = await DevicesAPI.controlDevice(
|
final response = await DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(deviceId: twoTouchId, code: 'switch_1', value: !event.value),
|
DeviceControlModel(
|
||||||
|
deviceId: twoTouchId, code: 'switch_1', value: !event.value),
|
||||||
twoTouchId);
|
twoTouchId);
|
||||||
|
|
||||||
if (!response['success']) {
|
if (!response['success']) {
|
||||||
@ -153,7 +162,8 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _changeSecondSwitch(ChangeSecondSwitchStatusEvent event, Emitter<TwoTouchState> emit) async {
|
void _changeSecondSwitch(
|
||||||
|
ChangeSecondSwitchStatusEvent event, Emitter<TwoTouchState> emit) async {
|
||||||
emit(LoadingNewSate(twoTouchModel: deviceStatus));
|
emit(LoadingNewSate(twoTouchModel: deviceStatus));
|
||||||
try {
|
try {
|
||||||
deviceStatus.secondSwitch = !event.value;
|
deviceStatus.secondSwitch = !event.value;
|
||||||
@ -163,7 +173,8 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
|
|||||||
}
|
}
|
||||||
_timer = Timer(const Duration(milliseconds: 100), () async {
|
_timer = Timer(const Duration(milliseconds: 100), () async {
|
||||||
final response = await DevicesAPI.controlDevice(
|
final response = await DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(deviceId: twoTouchId, code: 'switch_2', value: !event.value),
|
DeviceControlModel(
|
||||||
|
deviceId: twoTouchId, code: 'switch_2', value: !event.value),
|
||||||
twoTouchId);
|
twoTouchId);
|
||||||
|
|
||||||
if (!response['success']) {
|
if (!response['success']) {
|
||||||
@ -186,11 +197,15 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
|
|||||||
final response = await Future.wait([
|
final response = await Future.wait([
|
||||||
DevicesAPI.controlDevice(
|
DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(
|
DeviceControlModel(
|
||||||
deviceId: twoTouchId, code: 'switch_1', value: deviceStatus.firstSwitch),
|
deviceId: twoTouchId,
|
||||||
|
code: 'switch_1',
|
||||||
|
value: deviceStatus.firstSwitch),
|
||||||
twoTouchId),
|
twoTouchId),
|
||||||
DevicesAPI.controlDevice(
|
DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(
|
DeviceControlModel(
|
||||||
deviceId: twoTouchId, code: 'switch_2', value: deviceStatus.secondSwitch),
|
deviceId: twoTouchId,
|
||||||
|
code: 'switch_2',
|
||||||
|
value: deviceStatus.secondSwitch),
|
||||||
twoTouchId),
|
twoTouchId),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -213,11 +228,15 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
|
|||||||
final response = await Future.wait([
|
final response = await Future.wait([
|
||||||
DevicesAPI.controlDevice(
|
DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(
|
DeviceControlModel(
|
||||||
deviceId: twoTouchId, code: 'switch_1', value: deviceStatus.firstSwitch),
|
deviceId: twoTouchId,
|
||||||
|
code: 'switch_1',
|
||||||
|
value: deviceStatus.firstSwitch),
|
||||||
twoTouchId),
|
twoTouchId),
|
||||||
DevicesAPI.controlDevice(
|
DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(
|
DeviceControlModel(
|
||||||
deviceId: twoTouchId, code: 'switch_2', value: deviceStatus.secondSwitch),
|
deviceId: twoTouchId,
|
||||||
|
code: 'switch_2',
|
||||||
|
value: deviceStatus.secondSwitch),
|
||||||
twoTouchId),
|
twoTouchId),
|
||||||
]);
|
]);
|
||||||
if (response.every((element) => !element['success'])) {
|
if (response.every((element) => !element['success'])) {
|
||||||
@ -237,8 +256,10 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
|
|||||||
groupTwoTouchList[i].firstSwitch = true;
|
groupTwoTouchList[i].firstSwitch = true;
|
||||||
groupTwoTouchList[i].secondSwitch = true;
|
groupTwoTouchList[i].secondSwitch = true;
|
||||||
}
|
}
|
||||||
emit(UpdateGroupState(twoTouchList: groupTwoTouchList, allSwitches: true));
|
emit(
|
||||||
List<String> allDeviceIds = groupTwoTouchList.map((device) => device.deviceId).toList();
|
UpdateGroupState(twoTouchList: groupTwoTouchList, allSwitches: true));
|
||||||
|
List<String> allDeviceIds =
|
||||||
|
groupTwoTouchList.map((device) => device.deviceId).toList();
|
||||||
|
|
||||||
final response1 = await DevicesAPI.deviceBatchController(
|
final response1 = await DevicesAPI.deviceBatchController(
|
||||||
code: 'switch_1',
|
code: 'switch_1',
|
||||||
@ -271,9 +292,11 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
|
|||||||
groupTwoTouchList[i].secondSwitch = false;
|
groupTwoTouchList[i].secondSwitch = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
emit(UpdateGroupState(twoTouchList: groupTwoTouchList, allSwitches: false));
|
emit(UpdateGroupState(
|
||||||
|
twoTouchList: groupTwoTouchList, allSwitches: false));
|
||||||
|
|
||||||
List<String> allDeviceIds = groupTwoTouchList.map((device) => device.deviceId).toList();
|
List<String> allDeviceIds =
|
||||||
|
groupTwoTouchList.map((device) => device.deviceId).toList();
|
||||||
|
|
||||||
final response1 = await DevicesAPI.deviceBatchController(
|
final response1 = await DevicesAPI.deviceBatchController(
|
||||||
code: 'switch_1',
|
code: 'switch_1',
|
||||||
@ -298,17 +321,20 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _changeSliding(ChangeSlidingSegment event, Emitter<TwoTouchState> emit) async {
|
void _changeSliding(
|
||||||
|
ChangeSlidingSegment event, Emitter<TwoTouchState> emit) async {
|
||||||
emit(ChangeSlidingSegmentState(value: event.value));
|
emit(ChangeSlidingSegmentState(value: event.value));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _setCounterValue(SetCounterValue event, Emitter<TwoTouchState> emit) async {
|
void _setCounterValue(
|
||||||
|
SetCounterValue event, Emitter<TwoTouchState> emit) async {
|
||||||
emit(LoadingNewSate(twoTouchModel: deviceStatus));
|
emit(LoadingNewSate(twoTouchModel: deviceStatus));
|
||||||
int seconds = 0;
|
int seconds = 0;
|
||||||
try {
|
try {
|
||||||
seconds = event.duration.inSeconds;
|
seconds = event.duration.inSeconds;
|
||||||
final response = await DevicesAPI.controlDevice(
|
final response = await DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(deviceId: twoTouchId, code: event.deviceCode, value: seconds),
|
DeviceControlModel(
|
||||||
|
deviceId: twoTouchId, code: event.deviceCode, value: seconds),
|
||||||
twoTouchId);
|
twoTouchId);
|
||||||
|
|
||||||
if (response['success'] ?? false) {
|
if (response['success'] ?? false) {
|
||||||
@ -333,7 +359,8 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _getCounterValue(GetCounterEvent event, Emitter<TwoTouchState> emit) async {
|
void _getCounterValue(
|
||||||
|
GetCounterEvent event, Emitter<TwoTouchState> emit) async {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
try {
|
try {
|
||||||
add(GetScheduleEvent());
|
add(GetScheduleEvent());
|
||||||
@ -441,7 +468,8 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
|
|||||||
deviceId: twoTouchId,
|
deviceId: twoTouchId,
|
||||||
);
|
);
|
||||||
List<dynamic> jsonData = response;
|
List<dynamic> jsonData = response;
|
||||||
listSchedule = jsonData.map((item) => ScheduleModel.fromJson(item)).toList();
|
listSchedule =
|
||||||
|
jsonData.map((item) => ScheduleModel.fromJson(item)).toList();
|
||||||
emit(InitialState());
|
emit(InitialState());
|
||||||
} on DioException catch (e) {
|
} on DioException catch (e) {
|
||||||
final errorData = e.response!.data;
|
final errorData = e.response!.data;
|
||||||
@ -452,12 +480,13 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
|
|||||||
|
|
||||||
int? getTimeStampWithoutSeconds(DateTime? dateTime) {
|
int? getTimeStampWithoutSeconds(DateTime? dateTime) {
|
||||||
if (dateTime == null) return null;
|
if (dateTime == null) return null;
|
||||||
DateTime dateTimeWithoutSeconds =
|
DateTime dateTimeWithoutSeconds = DateTime(dateTime.year, dateTime.month,
|
||||||
DateTime(dateTime.year, dateTime.month, dateTime.day, dateTime.hour, dateTime.minute);
|
dateTime.day, dateTime.hour, dateTime.minute);
|
||||||
return dateTimeWithoutSeconds.millisecondsSinceEpoch ~/ 1000;
|
return dateTimeWithoutSeconds.millisecondsSinceEpoch ~/ 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future toggleRepeat(ToggleScheduleEvent event, Emitter<TwoTouchState> emit) async {
|
Future toggleRepeat(
|
||||||
|
ToggleScheduleEvent event, Emitter<TwoTouchState> emit) async {
|
||||||
try {
|
try {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
final response = await DevicesAPI.changeSchedule(
|
final response = await DevicesAPI.changeSchedule(
|
||||||
@ -476,7 +505,8 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future deleteSchedule(DeleteScheduleEvent event, Emitter<TwoTouchState> emit) async {
|
Future deleteSchedule(
|
||||||
|
DeleteScheduleEvent event, Emitter<TwoTouchState> emit) async {
|
||||||
try {
|
try {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
final response = await DevicesAPI.deleteSchedule(
|
final response = await DevicesAPI.deleteSchedule(
|
||||||
@ -496,7 +526,8 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _fetchTwoTouchWizardStatus(InitialWizardEvent event, Emitter<TwoTouchState> emit) async {
|
void _fetchTwoTouchWizardStatus(
|
||||||
|
InitialWizardEvent event, Emitter<TwoTouchState> emit) async {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
try {
|
try {
|
||||||
devicesList = [];
|
devicesList = [];
|
||||||
@ -506,7 +537,8 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
|
|||||||
HomeCubit.getInstance().selectedSpace?.id ?? '', '2GT');
|
HomeCubit.getInstance().selectedSpace?.id ?? '', '2GT');
|
||||||
|
|
||||||
for (int i = 0; i < devicesList.length; i++) {
|
for (int i = 0; i < devicesList.length; i++) {
|
||||||
var response = await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? '');
|
var response =
|
||||||
|
await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? '');
|
||||||
List<StatusModel> statusModelList = [];
|
List<StatusModel> statusModelList = [];
|
||||||
for (var status in response['status']) {
|
for (var status in response['status']) {
|
||||||
statusModelList.add(StatusModel.fromJson(status));
|
statusModelList.add(StatusModel.fromJson(status));
|
||||||
@ -529,15 +561,16 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
|
|||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
emit(UpdateGroupState(twoTouchList: groupTwoTouchList, allSwitches: allSwitchesOn));
|
emit(UpdateGroupState(
|
||||||
|
twoTouchList: groupTwoTouchList, allSwitches: allSwitchesOn));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(FailedState(error: e.toString()));
|
emit(FailedState(error: e.toString()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _changeFirstWizardSwitch(
|
void _changeFirstWizardSwitch(ChangeFirstWizardSwitchStatusEvent event,
|
||||||
ChangeFirstWizardSwitchStatusEvent event, Emitter<TwoTouchState> emit) async {
|
Emitter<TwoTouchState> emit) async {
|
||||||
emit(LoadingNewSate(twoTouchModel: deviceStatus));
|
emit(LoadingNewSate(twoTouchModel: deviceStatus));
|
||||||
try {
|
try {
|
||||||
bool allSwitchesValue = true;
|
bool allSwitchesValue = true;
|
||||||
@ -550,7 +583,8 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
emit(UpdateGroupState(twoTouchList: groupTwoTouchList, allSwitches: allSwitchesValue));
|
emit(UpdateGroupState(
|
||||||
|
twoTouchList: groupTwoTouchList, allSwitches: allSwitchesValue));
|
||||||
final response = await DevicesAPI.deviceBatchController(
|
final response = await DevicesAPI.deviceBatchController(
|
||||||
code: 'switch_1',
|
code: 'switch_1',
|
||||||
devicesUuid: [event.deviceId],
|
devicesUuid: [event.deviceId],
|
||||||
@ -565,8 +599,8 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _changeSecondWizardSwitch(
|
void _changeSecondWizardSwitch(ChangeSecondWizardSwitchStatusEvent event,
|
||||||
ChangeSecondWizardSwitchStatusEvent event, Emitter<TwoTouchState> emit) async {
|
Emitter<TwoTouchState> emit) async {
|
||||||
emit(LoadingNewSate(twoTouchModel: deviceStatus));
|
emit(LoadingNewSate(twoTouchModel: deviceStatus));
|
||||||
try {
|
try {
|
||||||
bool allSwitchesValue = true;
|
bool allSwitchesValue = true;
|
||||||
@ -579,7 +613,8 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
emit(UpdateGroupState(twoTouchList: groupTwoTouchList, allSwitches: allSwitchesValue));
|
emit(UpdateGroupState(
|
||||||
|
twoTouchList: groupTwoTouchList, allSwitches: allSwitchesValue));
|
||||||
|
|
||||||
final response = await DevicesAPI.deviceBatchController(
|
final response = await DevicesAPI.deviceBatchController(
|
||||||
code: 'switch_2',
|
code: 'switch_2',
|
||||||
@ -598,7 +633,8 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
|
|||||||
String statusSelected = '';
|
String statusSelected = '';
|
||||||
String optionSelected = '';
|
String optionSelected = '';
|
||||||
|
|
||||||
Future<void> _changeStatus(ChangeStatusEvent event, Emitter<TwoTouchState> emit) async {
|
Future<void> _changeStatus(
|
||||||
|
ChangeStatusEvent event, Emitter<TwoTouchState> emit) async {
|
||||||
try {
|
try {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
final Map<String, Map<String, String>> controlMap = {
|
final Map<String, Map<String, String>> controlMap = {
|
||||||
@ -627,11 +663,15 @@ class TwoTouchBloc extends Bloc<TwoTouchEvent, TwoTouchState> {
|
|||||||
final selectedControl = controlMap[optionSelected]?[statusSelected];
|
final selectedControl = controlMap[optionSelected]?[statusSelected];
|
||||||
if (selectedControl != null) {
|
if (selectedControl != null) {
|
||||||
await DevicesAPI.controlDevice(
|
await DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(deviceId: twoTouchId, code: optionSelected, value: selectedControl),
|
DeviceControlModel(
|
||||||
|
deviceId: twoTouchId,
|
||||||
|
code: optionSelected,
|
||||||
|
value: selectedControl),
|
||||||
twoTouchId,
|
twoTouchId,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
emit(const FailedState(error: 'Invalid statusSelected or optionSelected'));
|
emit(const FailedState(
|
||||||
|
error: 'Invalid statusSelected or optionSelected'));
|
||||||
}
|
}
|
||||||
} on DioException catch (e) {
|
} on DioException catch (e) {
|
||||||
final errorData = e.response!.data;
|
final errorData = e.response!.data;
|
||||||
|
@ -10,6 +10,9 @@ class DeviceModel {
|
|||||||
String? model;
|
String? model;
|
||||||
String? name;
|
String? name;
|
||||||
String? icon;
|
String? icon;
|
||||||
|
String? categoryName;
|
||||||
|
bool? toggleStatus = false;
|
||||||
|
|
||||||
String? type;
|
String? type;
|
||||||
bool? isOnline;
|
bool? isOnline;
|
||||||
List<StatusModel> status = [];
|
List<StatusModel> status = [];
|
||||||
@ -21,6 +24,8 @@ class DeviceModel {
|
|||||||
DeviceType? productType;
|
DeviceType? productType;
|
||||||
bool isSelected = false;
|
bool isSelected = false;
|
||||||
late List<FunctionModel> functions;
|
late List<FunctionModel> functions;
|
||||||
|
DeviceSubspace? subspace;
|
||||||
|
|
||||||
DeviceModel(
|
DeviceModel(
|
||||||
{this.activeTime,
|
{this.activeTime,
|
||||||
this.productUuid,
|
this.productUuid,
|
||||||
@ -34,6 +39,9 @@ class DeviceModel {
|
|||||||
this.updateTime,
|
this.updateTime,
|
||||||
this.uuid,
|
this.uuid,
|
||||||
this.productType,
|
this.productType,
|
||||||
|
this.categoryName,
|
||||||
|
this.subspace,
|
||||||
|
this.toggleStatus,
|
||||||
this.icon,
|
this.icon,
|
||||||
this.type}) {
|
this.type}) {
|
||||||
functions = getFunctions(productType!);
|
functions = getFunctions(productType!);
|
||||||
@ -87,23 +95,74 @@ class DeviceModel {
|
|||||||
} else {
|
} else {
|
||||||
tempIcon = Assets.assetsIconsLogo;
|
tempIcon = Assets.assetsIconsLogo;
|
||||||
}
|
}
|
||||||
|
// Step 1: Parse `status` as before
|
||||||
|
final statusList = (json['status'] as List<dynamic>?)
|
||||||
|
?.map((st) => StatusModel.fromJson(st as Map<String, dynamic>))
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
// Step 2: Check whether ANY status means "off"
|
||||||
|
final anyOff = statusList?.any((s) {
|
||||||
|
final code = s.code;
|
||||||
|
if (code == null) return false;
|
||||||
|
|
||||||
|
// 1) Handle "switch" or "switch_x"
|
||||||
|
if (code == 'switch' || code.startsWith('switch_')) {
|
||||||
|
// If it's false, we consider that "off"
|
||||||
|
return s.value == false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2) If code == "control" and value == "stop", consider "off"
|
||||||
|
if (s.value == 'open') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3) If code == "percent_control" and value == 0, maybe "off"
|
||||||
|
if (code == 'percent_control' && s.value == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add more conditions for other codes as needed
|
||||||
|
|
||||||
|
// Default: if none of the above apply, it's not "off"
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Step 3: Decide final toggleStatus (true = fully "on", false = partially/fully "off")
|
||||||
|
bool computedToggleStatus = !(anyOff ?? false);
|
||||||
|
|
||||||
return DeviceModel(
|
return DeviceModel(
|
||||||
icon: tempIcon,
|
icon: tempIcon,
|
||||||
activeTime: json['activeTime'],
|
activeTime: json['activeTime'],
|
||||||
// id: json['id'],
|
categoryName: json['categoryName'],
|
||||||
localKey: json['localKey'],
|
localKey: json['localKey'],
|
||||||
model: json['model'],
|
model: json['model'],
|
||||||
name: json['name'],
|
name: json['name'],
|
||||||
isOnline: json['online'],
|
isOnline: json['online'],
|
||||||
productName: json['productName'],
|
productName: json['productName'],
|
||||||
timeZone: json['timeZone'],
|
timeZone: json['timeZone'],
|
||||||
updateTime: json['updateTime'],
|
updateTime: json['updateTime'],
|
||||||
uuid: json['uuid'],
|
uuid: json['uuid'],
|
||||||
productType: type,
|
productType: type,
|
||||||
type: json['productType'],
|
type: json['productType'],
|
||||||
status: [],
|
|
||||||
productUuid: json['productUuid']);
|
// Use the newly computed toggleStatus:
|
||||||
|
toggleStatus: computedToggleStatus,
|
||||||
|
|
||||||
|
// Or if you prefer to use the value returned by the backend when available:
|
||||||
|
// toggleStatus: json['toggleStatus'] ?? computedToggleStatus,
|
||||||
|
|
||||||
|
status: statusList ?? [],
|
||||||
|
subspace: json['subspace'] != null
|
||||||
|
? DeviceSubspace.fromJson(json['subspace'])
|
||||||
|
: DeviceSubspace(
|
||||||
|
createdAt: null,
|
||||||
|
disabled: false,
|
||||||
|
subspaceName: '',
|
||||||
|
updatedAt: null,
|
||||||
|
uuid: '',
|
||||||
|
),
|
||||||
|
productUuid: json['productUuid'],
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
@ -118,9 +177,50 @@ class DeviceModel {
|
|||||||
'updateTime': updateTime,
|
'updateTime': updateTime,
|
||||||
'uuid': uuid,
|
'uuid': uuid,
|
||||||
'productType': productType,
|
'productType': productType,
|
||||||
|
'subspace': subspace?.toJson(), // serialize subspace
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
List<FunctionModel> getFunctions(DeviceType type) =>
|
List<FunctionModel> getFunctions(DeviceType type) =>
|
||||||
devicesFunctionsMap[productType] ?? [];
|
devicesFunctionsMap[productType] ?? [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class DeviceSubspace {
|
||||||
|
String? uuid;
|
||||||
|
DateTime? createdAt;
|
||||||
|
DateTime? updatedAt;
|
||||||
|
String? subspaceName;
|
||||||
|
bool? disabled;
|
||||||
|
|
||||||
|
DeviceSubspace({
|
||||||
|
this.uuid,
|
||||||
|
this.createdAt,
|
||||||
|
this.updatedAt,
|
||||||
|
this.subspaceName,
|
||||||
|
this.disabled,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory DeviceSubspace.fromJson(Map<String, dynamic> json) {
|
||||||
|
return DeviceSubspace(
|
||||||
|
uuid: json['uuid'],
|
||||||
|
createdAt: json['createdAt'] != null
|
||||||
|
? DateTime.tryParse(json['createdAt'])
|
||||||
|
: null,
|
||||||
|
updatedAt: json['updatedAt'] != null
|
||||||
|
? DateTime.tryParse(json['updatedAt'])
|
||||||
|
: null,
|
||||||
|
subspaceName: json['subspaceName'],
|
||||||
|
disabled: json['disabled'],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return {
|
||||||
|
'uuid': uuid,
|
||||||
|
'createdAt': createdAt?.toIso8601String(),
|
||||||
|
'updatedAt': updatedAt?.toIso8601String(),
|
||||||
|
'subspaceName': subspaceName,
|
||||||
|
'disabled': disabled,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
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/app_layout/bloc/home_cubit.dart';
|
||||||
import 'package:syncrow_app/features/devices/bloc/acs_bloc/acs_bloc.dart';
|
import 'package:syncrow_app/features/devices/bloc/acs_bloc/acs_bloc.dart';
|
||||||
import 'package:syncrow_app/features/devices/bloc/acs_bloc/acs_event.dart';
|
import 'package:syncrow_app/features/devices/bloc/acs_bloc/acs_event.dart';
|
||||||
import 'package:syncrow_app/features/devices/bloc/acs_bloc/acs_state.dart';
|
import 'package:syncrow_app/features/devices/bloc/acs_bloc/acs_state.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/ac_model.dart';
|
import 'package:syncrow_app/features/devices/model/ac_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/view/widgets/ACs/ac_interface_controls.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/ACs/ac_interface_controls.dart';
|
||||||
@ -71,6 +73,7 @@ class AcInterface extends StatelessWidget {
|
|||||||
onTap: () {
|
onTap: () {
|
||||||
BlocProvider.of<ACsBloc>(context)
|
BlocProvider.of<ACsBloc>(context)
|
||||||
.add(AcSwitch(acSwitch: statusModel.acSwitch));
|
.add(AcSwitch(acSwitch: statusModel.acSwitch));
|
||||||
|
|
||||||
},
|
},
|
||||||
child: SvgPicture.asset(Assets.acSwitchIcon))
|
child: SvgPicture.asset(Assets.acSwitchIcon))
|
||||||
],
|
],
|
||||||
|
@ -4,6 +4,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
|||||||
import 'package:syncrow_app/features/devices/bloc/acs_bloc/acs_bloc.dart';
|
import 'package:syncrow_app/features/devices/bloc/acs_bloc/acs_bloc.dart';
|
||||||
import 'package:syncrow_app/features/devices/bloc/acs_bloc/acs_event.dart';
|
import 'package:syncrow_app/features/devices/bloc/acs_bloc/acs_event.dart';
|
||||||
import 'package:syncrow_app/features/devices/bloc/acs_bloc/acs_state.dart';
|
import 'package:syncrow_app/features/devices/bloc/acs_bloc/acs_state.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/model/ac_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/view/widgets/ACs/ac_interface.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/ACs/ac_interface.dart';
|
||||||
import 'package:syncrow_app/features/devices/view/widgets/ACs/acs_list.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/ACs/acs_list.dart';
|
||||||
@ -40,6 +41,8 @@ class ACsView extends StatelessWidget {
|
|||||||
extendBody: true,
|
extendBody: true,
|
||||||
appBar: deviceModel != null
|
appBar: deviceModel != null
|
||||||
? DeviceAppbar(
|
? DeviceAppbar(
|
||||||
|
//BlocProvider.of<ACsBloc>(context).deviceStatus.acSwitch.toString()
|
||||||
|
value: true,
|
||||||
deviceName: deviceModel!.name!,
|
deviceName: deviceModel!.name!,
|
||||||
deviceUuid: deviceModel!.uuid!,
|
deviceUuid: deviceModel!.uuid!,
|
||||||
)
|
)
|
||||||
|
110
lib/features/devices/view/widgets/all_devices.dart
Normal file
110
lib/features/devices/view/widgets/all_devices.dart
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||||
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/view/widgets/room_page_switch.dart';
|
||||||
|
import 'package:syncrow_app/generated/assets.dart';
|
||||||
|
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||||
|
|
||||||
|
class AllDevices extends StatefulWidget {
|
||||||
|
const AllDevices({super.key, required this.allDevices});
|
||||||
|
|
||||||
|
final List<DeviceModel> allDevices;
|
||||||
|
|
||||||
|
@override
|
||||||
|
_AllDevicesState createState() => _AllDevicesState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AllDevicesState extends State<AllDevices> {
|
||||||
|
final TextEditingController _searchController = TextEditingController();
|
||||||
|
List<DeviceModel> _filteredDevices = [];
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_filteredDevices = widget.allDevices ?? [];
|
||||||
|
_searchController.addListener(_filterDevices);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_searchController.removeListener(_filterDevices);
|
||||||
|
_searchController.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _filterDevices() {
|
||||||
|
final query = _searchController.text.toLowerCase();
|
||||||
|
setState(() {
|
||||||
|
_filteredDevices = widget.allDevices!
|
||||||
|
.where((device) => device.name!.toLowerCase().contains(query))
|
||||||
|
.toList();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
if (widget.allDevices.isNotEmpty)
|
||||||
|
TextFormField(
|
||||||
|
controller: _searchController,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
hintText: 'Search',
|
||||||
|
hintStyle: const TextStyle(
|
||||||
|
color: ColorsManager.textGray,
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w400),
|
||||||
|
prefixIcon: 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),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
_filteredDevices.isNotEmpty
|
||||||
|
? Expanded(
|
||||||
|
child: GridView.builder(
|
||||||
|
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
|
crossAxisCount: 2,
|
||||||
|
crossAxisSpacing: 10,
|
||||||
|
mainAxisSpacing: 10,
|
||||||
|
childAspectRatio: 1.5,
|
||||||
|
),
|
||||||
|
padding: const EdgeInsets.only(top: 10),
|
||||||
|
itemCount: _filteredDevices.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
return RoomPageSwitch(
|
||||||
|
allDevices: _filteredDevices,
|
||||||
|
isAllDevices: true,
|
||||||
|
device: _filteredDevices[index]);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: widget.allDevices.isNotEmpty
|
||||||
|
? const Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Center(
|
||||||
|
child: Text(
|
||||||
|
'No Results Found',
|
||||||
|
style: TextStyle(
|
||||||
|
color: ColorsManager.grayColor,
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: FontWeight.w400),
|
||||||
|
)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: const SizedBox(),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -250,7 +250,9 @@ class CeilingSensorInterface extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
] else if (button['title'] == 'Space Type') ...[
|
] else if (button['title'] == 'Space Type') ...[
|
||||||
Text(
|
Text(
|
||||||
model.spaceType.name.toString(),
|
model.spaceType.name.toString() == "none"
|
||||||
|
? "Office"
|
||||||
|
: model.spaceType.name.toString(),
|
||||||
style: const TextStyle(color: Colors.black),
|
style: const TextStyle(color: Colors.black),
|
||||||
),
|
),
|
||||||
] else ...[
|
] else ...[
|
||||||
@ -299,7 +301,13 @@ class CeilingSensorInterface extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
bloc.add(ChangeValueEvent(
|
bloc.add(ChangeValueEvent(
|
||||||
type: title.toString(), value: result, code: 'nobody_time'));
|
type: title.toString(),
|
||||||
|
value: result
|
||||||
|
.toString()
|
||||||
|
.toLowerCase()
|
||||||
|
.replaceAll('sec', 's')
|
||||||
|
.replaceAll('1hr', '1hour'), // Replacing "sec" with "s"
|
||||||
|
code: 'nobody_time'));
|
||||||
}
|
}
|
||||||
} else if (title == 'Maximum Distance') {
|
} else if (title == 'Maximum Distance') {
|
||||||
final result = await _showDialog(
|
final result = await _showDialog(
|
||||||
|
@ -90,9 +90,7 @@ class PresenceRecord extends StatelessWidget {
|
|||||||
: Colors.grey,
|
: Colors.grey,
|
||||||
),
|
),
|
||||||
title: Text(
|
title: Text(
|
||||||
record.value == 'true'
|
record.value.toString(),
|
||||||
? "Opened"
|
|
||||||
: "Closed",
|
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
fontSize: 18,
|
fontSize: 18,
|
||||||
|
@ -106,12 +106,11 @@ class _PresenceSpaceTypeDialogState extends State<PresenceSpaceTypeDialog> {
|
|||||||
padding: const EdgeInsets.all(10),
|
padding: const EdgeInsets.all(10),
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.asset(
|
||||||
icon,
|
icon,
|
||||||
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 4),
|
const SizedBox(height: 4),
|
||||||
Text(
|
Text(
|
||||||
title,
|
title == "None" ? "Office" : title,
|
||||||
style: Theme.of(context)
|
style: Theme.of(context)
|
||||||
.textTheme
|
.textTheme
|
||||||
.bodySmall
|
.bodySmall
|
||||||
|
@ -6,6 +6,7 @@ import 'package:syncrow_app/features/devices/bloc/curtain_bloc/curtain_event.dar
|
|||||||
import 'package:syncrow_app/features/devices/bloc/curtain_bloc/curtain_state.dart';
|
import 'package:syncrow_app/features/devices/bloc/curtain_bloc/curtain_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/view/widgets/curtains/curtain_buttons.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/curtains/curtain_buttons.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/view/widgets/device_appbar.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/generated/assets.dart';
|
import 'package:syncrow_app/generated/assets.dart';
|
||||||
@ -33,11 +34,17 @@ class CurtainView extends StatelessWidget {
|
|||||||
// blindHeight = state.blindHeight;
|
// blindHeight = state.blindHeight;
|
||||||
}
|
}
|
||||||
return DefaultScaffold(
|
return DefaultScaffold(
|
||||||
|
appBar: DeviceAppbar(
|
||||||
|
deviceName: curtain!.name!,
|
||||||
|
deviceUuid: curtain!.uuid!,
|
||||||
|
),
|
||||||
title: curtain.name,
|
title: curtain.name,
|
||||||
child: state is CurtainLoadingState
|
child: state is CurtainLoadingState
|
||||||
? const Center(
|
? const Center(
|
||||||
child:
|
child: DefaultContainer(
|
||||||
DefaultContainer(width: 50, height: 50, child: CircularProgressIndicator()),
|
width: 50,
|
||||||
|
height: 50,
|
||||||
|
child: CircularProgressIndicator()),
|
||||||
)
|
)
|
||||||
: RefreshIndicator(
|
: RefreshIndicator(
|
||||||
onRefresh: () async {
|
onRefresh: () async {
|
||||||
@ -62,37 +69,56 @@ class CurtainView extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
SvgPicture.asset(
|
SvgPicture.asset(
|
||||||
Assets.assetsIconsCurtainsIconCurtainHolder,
|
Assets.assetsIconsCurtainsIconCurtainHolder,
|
||||||
width: MediaQuery.sizeOf(context).width * 0.75,
|
width:
|
||||||
|
MediaQuery.sizeOf(context).width * 0.75,
|
||||||
),
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: MediaQuery.sizeOf(context).width * 0.75,
|
width:
|
||||||
|
MediaQuery.sizeOf(context).width * 0.75,
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: MediaQuery.sizeOf(context).width * 0.025,
|
width:
|
||||||
|
MediaQuery.sizeOf(context).width *
|
||||||
|
0.025,
|
||||||
),
|
),
|
||||||
AnimatedContainer(
|
AnimatedContainer(
|
||||||
duration: const Duration(milliseconds: 200),
|
duration:
|
||||||
|
const Duration(milliseconds: 200),
|
||||||
curve: Curves.linear,
|
curve: Curves.linear,
|
||||||
height: MediaQuery.sizeOf(context).height * 0.35,
|
height: MediaQuery.sizeOf(context)
|
||||||
width: MediaQuery.sizeOf(context).width * 0.35,
|
.height *
|
||||||
|
0.35,
|
||||||
|
width:
|
||||||
|
MediaQuery.sizeOf(context).width *
|
||||||
|
0.35,
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: List.generate(
|
children: List.generate(
|
||||||
4,
|
4,
|
||||||
(index) {
|
(index) {
|
||||||
double spacing = curtainWidth / 7.5;
|
double spacing =
|
||||||
double leftMostPosition = index * spacing;
|
curtainWidth / 7.5;
|
||||||
|
double leftMostPosition =
|
||||||
|
index * spacing;
|
||||||
return AnimatedPositioned(
|
return AnimatedPositioned(
|
||||||
duration: const Duration(milliseconds: 200),
|
duration: const Duration(
|
||||||
|
milliseconds: 200),
|
||||||
curve: Curves.linear,
|
curve: Curves.linear,
|
||||||
left: leftMostPosition,
|
left: leftMostPosition,
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height:
|
height: MediaQuery.sizeOf(
|
||||||
MediaQuery.sizeOf(context).height * 0.35,
|
context)
|
||||||
width: MediaQuery.sizeOf(context).width * 0.08,
|
.height *
|
||||||
|
0.35,
|
||||||
|
width: MediaQuery.sizeOf(
|
||||||
|
context)
|
||||||
|
.width *
|
||||||
|
0.08,
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.asset(
|
||||||
Assets.assetsIconsCurtainsIconVerticalBlade,
|
Assets
|
||||||
|
.assetsIconsCurtainsIconVerticalBlade,
|
||||||
fit: BoxFit.fill,
|
fit: BoxFit.fill,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -102,23 +128,37 @@ class CurtainView extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
AnimatedContainer(
|
AnimatedContainer(
|
||||||
duration: const Duration(milliseconds: 200),
|
duration:
|
||||||
|
const Duration(milliseconds: 200),
|
||||||
curve: Curves.linear,
|
curve: Curves.linear,
|
||||||
height: MediaQuery.sizeOf(context).height * 0.35,
|
height: MediaQuery.sizeOf(context)
|
||||||
width: MediaQuery.sizeOf(context).width * 0.35,
|
.height *
|
||||||
|
0.35,
|
||||||
|
width:
|
||||||
|
MediaQuery.sizeOf(context).width *
|
||||||
|
0.35,
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: List.generate(
|
children: List.generate(
|
||||||
4,
|
4,
|
||||||
(index) {
|
(index) {
|
||||||
double spacing = curtainWidth / 7.5;
|
double spacing =
|
||||||
double rightMostPosition = index * spacing;
|
curtainWidth / 7.5;
|
||||||
|
double rightMostPosition =
|
||||||
|
index * spacing;
|
||||||
return AnimatedPositioned(
|
return AnimatedPositioned(
|
||||||
duration: const Duration(milliseconds: 200),
|
duration: const Duration(
|
||||||
|
milliseconds: 200),
|
||||||
curve: Curves.linear,
|
curve: Curves.linear,
|
||||||
right: rightMostPosition,
|
right: rightMostPosition,
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: MediaQuery.sizeOf(context).height * 0.35,
|
height: MediaQuery.sizeOf(
|
||||||
width: MediaQuery.sizeOf(context).width * 0.08,
|
context)
|
||||||
|
.height *
|
||||||
|
0.35,
|
||||||
|
width: MediaQuery.sizeOf(
|
||||||
|
context)
|
||||||
|
.width *
|
||||||
|
0.08,
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.asset(
|
||||||
Assets.rightVerticalBlade,
|
Assets.rightVerticalBlade,
|
||||||
fit: BoxFit.fill,
|
fit: BoxFit.fill,
|
||||||
@ -130,7 +170,9 @@ class CurtainView extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: MediaQuery.sizeOf(context).width * 0.025,
|
width:
|
||||||
|
MediaQuery.sizeOf(context).width *
|
||||||
|
0.025,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import 'dart:io';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
||||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||||
@ -6,14 +7,27 @@ import 'package:syncrow_app/utils/resource_manager/font_manager.dart';
|
|||||||
class DeviceAppbar extends StatelessWidget implements PreferredSizeWidget {
|
class DeviceAppbar extends StatelessWidget implements PreferredSizeWidget {
|
||||||
final String deviceName;
|
final String deviceName;
|
||||||
final String deviceUuid;
|
final String deviceUuid;
|
||||||
|
final bool? value;
|
||||||
|
|
||||||
final double appBarHeight = 56.0;
|
final double appBarHeight = 56.0;
|
||||||
final void Function()? onPressed;
|
final void Function()? onPressed;
|
||||||
const DeviceAppbar(
|
const DeviceAppbar(
|
||||||
{super.key, required this.deviceName, required this.deviceUuid, this.onPressed});
|
{super.key,
|
||||||
|
required this.deviceName,
|
||||||
|
this.value,
|
||||||
|
required this.deviceUuid,
|
||||||
|
this.onPressed});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return AppBar(
|
return AppBar(
|
||||||
|
leading: IconButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pop(value ?? true);
|
||||||
|
},
|
||||||
|
icon: Icon(
|
||||||
|
Platform.isIOS ? Icons.arrow_back_ios : Icons.arrow_back,
|
||||||
|
)),
|
||||||
backgroundColor: Colors.transparent,
|
backgroundColor: Colors.transparent,
|
||||||
centerTitle: true,
|
centerTitle: true,
|
||||||
title: BodyLarge(
|
title: BodyLarge(
|
||||||
|
@ -1,12 +1,147 @@
|
|||||||
|
// import 'package:flutter/material.dart';
|
||||||
|
// import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
// import 'package:smooth_page_indicator/smooth_page_indicator.dart';
|
||||||
|
// import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
|
||||||
|
// import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
|
||||||
|
// import 'package:syncrow_app/features/devices/view/widgets/all_devices.dart';
|
||||||
|
// import 'package:syncrow_app/features/devices/view/widgets/room_page.dart';
|
||||||
|
// import 'package:syncrow_app/features/devices/view/widgets/rooms_slider.dart';
|
||||||
|
// import 'package:syncrow_app/features/devices/view/widgets/wizard_page.dart';
|
||||||
|
// import 'package:syncrow_app/features/scene/bloc/scene_bloc/scene_bloc.dart';
|
||||||
|
// import 'package:syncrow_app/features/scene/view/scene_view.dart';
|
||||||
|
// import 'package:syncrow_app/features/shared_widgets/create_unit.dart';
|
||||||
|
// import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
||||||
|
// import 'package:syncrow_app/features/shared_widgets/text_widgets/title_medium.dart';
|
||||||
|
// import 'package:syncrow_app/utils/context_extension.dart';
|
||||||
|
// import 'package:syncrow_app/utils/resource_manager/strings_manager.dart';
|
||||||
|
|
||||||
|
// class DevicesViewPage extends StatelessWidget {
|
||||||
|
// const DevicesViewPage({super.key});
|
||||||
|
|
||||||
|
// @override
|
||||||
|
// Widget build(BuildContext context) {
|
||||||
|
// return BlocProvider(
|
||||||
|
// create: (context) => SceneBloc(), // Initialize your SceneBloc here
|
||||||
|
// child: DevicesViewBody(),
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// class DevicesViewBody extends StatelessWidget {
|
||||||
|
// const DevicesViewBody({
|
||||||
|
// super.key,
|
||||||
|
// });
|
||||||
|
|
||||||
|
// @override
|
||||||
|
// Widget build(BuildContext context) {
|
||||||
|
// return BlocBuilder<DevicesCubit, DevicesState>(
|
||||||
|
// builder: (context, state) {
|
||||||
|
// if (state is DevicesLoading ||
|
||||||
|
// state is GetDevicesLoading ||
|
||||||
|
// state is DevicesCategoriesLoading) {
|
||||||
|
// return const Center(child: CircularProgressIndicator());
|
||||||
|
// } else {
|
||||||
|
// return HomeCubit.getInstance().spaces?.isEmpty ?? true
|
||||||
|
// ? const CreateUnitWidget()
|
||||||
|
// : Column(
|
||||||
|
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
// crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
// children: [
|
||||||
|
// Row(
|
||||||
|
// children: [
|
||||||
|
// TitleMedium(
|
||||||
|
// text: StringsManager.devices,
|
||||||
|
// style: context.titleMedium.copyWith(
|
||||||
|
// fontSize: 25,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// SizedBox(
|
||||||
|
// height: MediaQuery.of(context).size.height * 0.1,
|
||||||
|
// child: const SceneView(
|
||||||
|
// pageType: true,
|
||||||
|
// )),
|
||||||
|
// const SizedBox(
|
||||||
|
// height: 20,
|
||||||
|
// ),
|
||||||
|
// const RoomsSlider(),
|
||||||
|
// const SizedBox(
|
||||||
|
// height: 10,
|
||||||
|
// ),
|
||||||
|
// Expanded(
|
||||||
|
// child: PageView(
|
||||||
|
// controller:
|
||||||
|
// HomeCubit.getInstance().devicesPageController,
|
||||||
|
// onPageChanged: (index) {
|
||||||
|
// HomeCubit.getInstance().devicesPageChanged(index);
|
||||||
|
// print(index);
|
||||||
|
// if (index == 0) {
|
||||||
|
// context.read<DevicesCubit>().fetchAllDevices(HomeCubit.getInstance().selectedSpace);
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// children: [
|
||||||
|
// AllDevices(
|
||||||
|
// allDevices: context.read<DevicesCubit>().allDevices,
|
||||||
|
// ),
|
||||||
|
// WizardPage(
|
||||||
|
// groupsList:
|
||||||
|
// DevicesCubit.getInstance().allCategories ?? [],
|
||||||
|
// ),
|
||||||
|
// if (HomeCubit.getInstance().selectedSpace != null)
|
||||||
|
// ...HomeCubit.getInstance()
|
||||||
|
// .selectedSpace!
|
||||||
|
// .subspaces
|
||||||
|
// .map(
|
||||||
|
// (room) {
|
||||||
|
// return RoomPage(
|
||||||
|
// room: room,
|
||||||
|
// );
|
||||||
|
// },
|
||||||
|
// )
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// HomeCubit.getInstance().selectedSpace != null
|
||||||
|
// ? Padding(
|
||||||
|
// padding: const EdgeInsets.symmetric(
|
||||||
|
// vertical: 7,
|
||||||
|
// ),
|
||||||
|
// child: SmoothPageIndicator(
|
||||||
|
// controller:
|
||||||
|
// HomeCubit.getInstance().devicesPageController,
|
||||||
|
// count: HomeCubit.getInstance()
|
||||||
|
// .selectedSpace!
|
||||||
|
// .subspaces
|
||||||
|
// .length +
|
||||||
|
// 2,
|
||||||
|
// effect: const WormEffect(
|
||||||
|
// paintStyle: PaintingStyle.stroke,
|
||||||
|
// dotHeight: 8,
|
||||||
|
// dotWidth: 8,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// )
|
||||||
|
// : const Center(
|
||||||
|
// child: BodyLarge(text: 'No Home Found'),
|
||||||
|
// ),
|
||||||
|
// ],
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
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:smooth_page_indicator/smooth_page_indicator.dart';
|
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
|
||||||
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
|
|
||||||
import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
|
import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
|
||||||
|
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/view/widgets/all_devices.dart';
|
||||||
import 'package:syncrow_app/features/devices/view/widgets/room_page.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/room_page.dart';
|
||||||
import 'package:syncrow_app/features/devices/view/widgets/rooms_slider.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/rooms_slider.dart';
|
||||||
import 'package:syncrow_app/features/devices/view/widgets/wizard_page.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/wizard_page.dart';
|
||||||
import 'package:syncrow_app/features/scene/bloc/scene_bloc/scene_bloc.dart';
|
|
||||||
import 'package:syncrow_app/features/scene/view/scene_view.dart';
|
import 'package:syncrow_app/features/scene/view/scene_view.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/create_unit.dart';
|
import 'package:syncrow_app/features/shared_widgets/create_unit.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';
|
||||||
@ -14,35 +149,53 @@ import 'package:syncrow_app/features/shared_widgets/text_widgets/title_medium.da
|
|||||||
import 'package:syncrow_app/utils/context_extension.dart';
|
import 'package:syncrow_app/utils/context_extension.dart';
|
||||||
import 'package:syncrow_app/utils/resource_manager/strings_manager.dart';
|
import 'package:syncrow_app/utils/resource_manager/strings_manager.dart';
|
||||||
|
|
||||||
class DevicesViewPage extends StatelessWidget {
|
|
||||||
const DevicesViewPage({super.key});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return BlocProvider(
|
|
||||||
create: (context) => SceneBloc(), // Initialize your SceneBloc here
|
|
||||||
child: DevicesViewBody(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class DevicesViewBody extends StatelessWidget {
|
class DevicesViewBody extends StatelessWidget {
|
||||||
const DevicesViewBody({
|
const DevicesViewBody({Key? key}) : super(key: key);
|
||||||
super.key,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocBuilder<DevicesCubit, DevicesState>(
|
return BlocBuilder<HomeCubit, HomeState>(
|
||||||
builder: (context, state) {
|
builder: (context, homeState) {
|
||||||
if (state is DevicesLoading ||
|
final homeCubit = HomeCubit.getInstance();
|
||||||
state is GetDevicesLoading ||
|
if (homeState is GetSpacesLoading || homeState is HomeLoading) {
|
||||||
state is DevicesCategoriesLoading) {
|
|
||||||
return const Center(child: CircularProgressIndicator());
|
return const Center(child: CircularProgressIndicator());
|
||||||
} else {
|
}
|
||||||
return HomeCubit.getInstance().spaces?.isEmpty ?? true
|
final spaces = homeCubit.spaces;
|
||||||
? const CreateUnitWidget()
|
return BlocBuilder<DevicesCubit, DevicesState>(
|
||||||
: Column(
|
builder: (context, devicesState) {
|
||||||
|
if (devicesState is DevicesLoading ||
|
||||||
|
devicesState is DevicesCategoriesLoading ||
|
||||||
|
devicesState is GetDevicesLoading) {
|
||||||
|
return const Center(child: CircularProgressIndicator());
|
||||||
|
} else if (spaces.isEmpty) {
|
||||||
|
return FutureBuilder(
|
||||||
|
future: Future.delayed(
|
||||||
|
const Duration(seconds: 1)),
|
||||||
|
builder: (context, snapshot) {
|
||||||
|
if (snapshot.connectionState == ConnectionState.waiting) {
|
||||||
|
return const Center(
|
||||||
|
child:
|
||||||
|
CircularProgressIndicator());
|
||||||
|
}
|
||||||
|
if (spaces.isEmpty) {
|
||||||
|
return const CreateUnitWidget();
|
||||||
|
}
|
||||||
|
return Container();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (devicesState is GetDevicesError) {
|
||||||
|
return const Center(child: Text('Error'));
|
||||||
|
}
|
||||||
|
if (devicesState is GetDevicesSuccess ||
|
||||||
|
devicesState is SwitchControlLoading ||
|
||||||
|
devicesState is DeviceControlSuccess ||
|
||||||
|
devicesState is DeviceControlError) {
|
||||||
|
if (spaces.isEmpty) {
|
||||||
|
return const CreateUnitWidget();
|
||||||
|
} else {
|
||||||
|
final devicesCubit = context.read<DevicesCubit>();
|
||||||
|
|
||||||
|
return Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
@ -50,53 +203,50 @@ class DevicesViewBody extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
TitleMedium(
|
TitleMedium(
|
||||||
text: StringsManager.devices,
|
text: StringsManager.devices,
|
||||||
style: context.titleMedium.copyWith(
|
style: context.titleMedium.copyWith(fontSize: 25),
|
||||||
fontSize: 25,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: MediaQuery.of(context).size.height * 0.1,
|
height: MediaQuery.of(context).size.height * 0.1,
|
||||||
child: const SceneView(
|
child: const SceneView(pageType: true),
|
||||||
pageType: true,
|
|
||||||
)),
|
|
||||||
const SizedBox(
|
|
||||||
height: 20,
|
|
||||||
),
|
),
|
||||||
|
const SizedBox(height: 20),
|
||||||
const RoomsSlider(),
|
const RoomsSlider(),
|
||||||
const SizedBox(
|
const SizedBox(height: 10),
|
||||||
height: 10,
|
|
||||||
),
|
|
||||||
Expanded(
|
Expanded(
|
||||||
child: PageView(
|
child: PageView(
|
||||||
controller: HomeCubit.getInstance().devicesPageController,
|
controller: homeCubit.devicesPageController,
|
||||||
onPageChanged: (index) {
|
onPageChanged: (index) {
|
||||||
HomeCubit.getInstance().devicesPageChanged(index);
|
homeCubit.devicesPageChanged(index);
|
||||||
|
if (index == 0) {
|
||||||
|
devicesCubit.fetchAllDevices(
|
||||||
|
homeCubit.selectedSpace,
|
||||||
|
);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
WizardPage(
|
AllDevices(
|
||||||
groupsList: DevicesCubit.getInstance().allCategories ?? [],
|
allDevices: DevicesCubit.getInstance().allDevices,
|
||||||
),
|
),
|
||||||
if (HomeCubit.getInstance().selectedSpace != null)
|
WizardPage(
|
||||||
...HomeCubit.getInstance().selectedSpace!.subspaces.map(
|
groupsList:
|
||||||
(room) {
|
DevicesCubit.getInstance().allCategories ?? [],
|
||||||
return RoomPage(
|
),
|
||||||
room: room,
|
if (homeCubit.selectedSpace != null)
|
||||||
);
|
...homeCubit.selectedSpace!.subspaces.map(
|
||||||
},
|
(room) => RoomPage(room: room),
|
||||||
)
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
HomeCubit.getInstance().selectedSpace != null
|
homeCubit.selectedSpace != null
|
||||||
? Padding(
|
? Padding(
|
||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.symmetric(vertical: 7),
|
||||||
vertical: 7,
|
|
||||||
),
|
|
||||||
child: SmoothPageIndicator(
|
child: SmoothPageIndicator(
|
||||||
controller: HomeCubit.getInstance().devicesPageController,
|
controller: homeCubit.devicesPageController,
|
||||||
count: HomeCubit.getInstance().selectedSpace!.subspaces.length + 1,
|
count:
|
||||||
|
homeCubit.selectedSpace!.subspaces.length + 2,
|
||||||
effect: const WormEffect(
|
effect: const WormEffect(
|
||||||
paintStyle: PaintingStyle.stroke,
|
paintStyle: PaintingStyle.stroke,
|
||||||
dotHeight: 8,
|
dotHeight: 8,
|
||||||
@ -109,7 +259,11 @@ class DevicesViewBody extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return const SizedBox.shrink();
|
||||||
|
},
|
||||||
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import 'package:syncrow_app/features/devices/bloc/garage_door_bloc/garage_door_b
|
|||||||
import 'package:syncrow_app/features/devices/bloc/garage_door_bloc/garage_door_event.dart';
|
import 'package:syncrow_app/features/devices/bloc/garage_door_bloc/garage_door_event.dart';
|
||||||
import 'package:syncrow_app/features/devices/bloc/garage_door_bloc/garage_door_state.dart';
|
import 'package:syncrow_app/features/devices/bloc/garage_door_bloc/garage_door_state.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/view/widgets/device_appbar.dart';
|
||||||
import 'package:syncrow_app/features/devices/view/widgets/garage_door/garage_preferences_settings.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/garage_door/garage_preferences_settings.dart';
|
||||||
import 'package:syncrow_app/features/devices/view/widgets/garage_door/garage_records_screen.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/garage_door/garage_records_screen.dart';
|
||||||
import 'package:syncrow_app/features/devices/view/widgets/garage_door/schedule_garage_screen.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/garage_door/schedule_garage_screen.dart';
|
||||||
@ -22,6 +23,10 @@ class GarageDoorScreen extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return DefaultScaffold(
|
return DefaultScaffold(
|
||||||
|
appBar: DeviceAppbar(
|
||||||
|
deviceName: device!.name!,
|
||||||
|
deviceUuid: device!.uuid!,
|
||||||
|
),
|
||||||
title: 'Garage Door Opener',
|
title: 'Garage Door Opener',
|
||||||
child: BlocProvider(
|
child: BlocProvider(
|
||||||
create: (context) => GarageDoorBloc(GDId: device?.uuid ?? '')
|
create: (context) => GarageDoorBloc(GDId: device?.uuid ?? '')
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
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/app_layout/bloc/home_cubit.dart';
|
||||||
import 'package:syncrow_app/features/devices/bloc/devices_cubit.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/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/6_scene_switch/six_scene_screen.dart';
|
||||||
@ -28,23 +29,31 @@ import 'package:syncrow_app/features/devices/view/widgets/smart_door/door_interf
|
|||||||
import 'package:syncrow_app/features/devices/view/widgets/three_gang/three_gang_interface.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/three_gang/three_gang_interface.dart';
|
||||||
import 'package:syncrow_app/features/devices/view/widgets/water_heater/water_heater_page.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/water_heater/water_heater_page.dart';
|
||||||
import 'package:syncrow_app/features/devices/view/widgets/water_leak/water_leak_screen.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/water_leak/water_leak_screen.dart';
|
||||||
|
import 'package:syncrow_app/features/shared_widgets/custom_switch.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/utils/context_extension.dart';
|
import 'package:syncrow_app/utils/context_extension.dart';
|
||||||
import 'package:syncrow_app/utils/helpers/custom_page_route.dart';
|
import 'package:syncrow_app/utils/helpers/custom_page_route.dart';
|
||||||
import 'package:syncrow_app/utils/resource_manager/constants.dart';
|
import 'package:syncrow_app/utils/resource_manager/constants.dart';
|
||||||
|
|
||||||
class RoomPageSwitch extends StatelessWidget {
|
class RoomPageSwitch extends StatelessWidget {
|
||||||
const RoomPageSwitch({
|
const RoomPageSwitch(
|
||||||
super.key,
|
{super.key,
|
||||||
required this.device,
|
required this.device,
|
||||||
});
|
this.isAllDevices = false,
|
||||||
|
this.allDevices});
|
||||||
|
|
||||||
final DeviceModel device;
|
final DeviceModel device;
|
||||||
|
final List<DeviceModel>? allDevices;
|
||||||
|
final bool isAllDevices;
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
showDeviceInterface(device, context);
|
showDeviceInterface(
|
||||||
|
device: device,
|
||||||
|
context: context,
|
||||||
|
isAllDevices: isAllDevices,
|
||||||
|
allDevices: allDevices);
|
||||||
},
|
},
|
||||||
child: DefaultContainer(
|
child: DefaultContainer(
|
||||||
padding: const EdgeInsets.all(15),
|
padding: const EdgeInsets.all(15),
|
||||||
@ -60,22 +69,38 @@ class RoomPageSwitch extends StatelessWidget {
|
|||||||
device.icon!,
|
device.icon!,
|
||||||
fit: BoxFit.contain,
|
fit: BoxFit.contain,
|
||||||
),
|
),
|
||||||
// CustomSwitch(
|
isAllDevices
|
||||||
// device: device,
|
? CustomSwitch(
|
||||||
// ),
|
device: device,
|
||||||
|
)
|
||||||
|
: const SizedBox(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
Flexible(
|
Flexible(
|
||||||
child: FittedBox(
|
child: FittedBox(
|
||||||
child: Text(
|
child: Column(
|
||||||
device.name ?? "",
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
overflow: TextOverflow.ellipsis,
|
children: [
|
||||||
maxLines: 2,
|
Text(
|
||||||
style: context.bodyLarge.copyWith(
|
device.name ?? "",
|
||||||
fontWeight: FontWeight.bold,
|
overflow: TextOverflow.ellipsis,
|
||||||
fontSize: 20,
|
maxLines: 2,
|
||||||
color: Colors.grey,
|
style: context.bodyLarge.copyWith(
|
||||||
),
|
fontWeight: FontWeight.bold,
|
||||||
|
fontSize: 20,
|
||||||
|
color: Colors.grey,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
device.subspace!.subspaceName ?? '',
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: context.bodySmall.copyWith(
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
fontSize: 10,
|
||||||
|
color: Colors.grey,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -89,14 +114,23 @@ class RoomPageSwitch extends StatelessWidget {
|
|||||||
/// Shows the device interface based on the product type of the device.
|
/// Shows the device interface based on the product type of the device.
|
||||||
///
|
///
|
||||||
/// The [device] parameter represents the device model.
|
/// The [device] parameter represents the device model.
|
||||||
void showDeviceInterface(DeviceModel device, BuildContext context) {
|
Future<void> showDeviceInterface(
|
||||||
|
{required DeviceModel device,
|
||||||
|
required BuildContext context,
|
||||||
|
required isAllDevices,
|
||||||
|
List<DeviceModel>? allDevices}) async {
|
||||||
|
final devicesCubit = context.read<DevicesCubit>();
|
||||||
|
|
||||||
switch (device.productType) {
|
switch (device.productType) {
|
||||||
case DeviceType.AC:
|
case DeviceType.AC:
|
||||||
Navigator.push(
|
var value = await Navigator.push(
|
||||||
context,
|
context,
|
||||||
PageRouteBuilder(
|
PageRouteBuilder(
|
||||||
pageBuilder: (context, animation1, animation2) =>
|
pageBuilder: (context, animation1, animation2) =>
|
||||||
ACsView(deviceModel: device)));
|
ACsView(deviceModel: device)));
|
||||||
|
if (value && isAllDevices) {
|
||||||
|
devicesCubit.fetchAllDevices(HomeCubit.getInstance().selectedSpace);
|
||||||
|
}
|
||||||
// navigateToInterface(ACsView(deviceModel: device), context);
|
// navigateToInterface(ACsView(deviceModel: device), context);
|
||||||
break;
|
break;
|
||||||
case DeviceType.WallSensor:
|
case DeviceType.WallSensor:
|
||||||
@ -116,12 +150,15 @@ void showDeviceInterface(DeviceModel device, BuildContext context) {
|
|||||||
// navigateToInterface(CeilingSensorInterface(ceilingSensor: device), context);
|
// navigateToInterface(CeilingSensorInterface(ceilingSensor: device), context);
|
||||||
break;
|
break;
|
||||||
case DeviceType.Curtain:
|
case DeviceType.Curtain:
|
||||||
Navigator.push(
|
var value = await Navigator.push(
|
||||||
context,
|
context,
|
||||||
PageRouteBuilder(
|
PageRouteBuilder(
|
||||||
pageBuilder: (context, animation1, animation2) => CurtainView(
|
pageBuilder: (context, animation1, animation2) => CurtainView(
|
||||||
curtain: device,
|
curtain: device,
|
||||||
)));
|
)));
|
||||||
|
if (value && isAllDevices) {
|
||||||
|
devicesCubit.fetchAllDevices(HomeCubit.getInstance().selectedSpace);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case DeviceType.Blind:
|
case DeviceType.Blind:
|
||||||
break;
|
break;
|
||||||
@ -143,30 +180,43 @@ void showDeviceInterface(DeviceModel device, BuildContext context) {
|
|||||||
case DeviceType.LightBulb:
|
case DeviceType.LightBulb:
|
||||||
navigateToInterface(LightInterface(light: device), context);
|
navigateToInterface(LightInterface(light: device), context);
|
||||||
case DeviceType.OneGang:
|
case DeviceType.OneGang:
|
||||||
Navigator.push(
|
var value = await Navigator.push(
|
||||||
context,
|
context,
|
||||||
PageRouteBuilder(
|
PageRouteBuilder(
|
||||||
pageBuilder: (context, animation1, animation2) =>
|
pageBuilder: (context, animation1, animation2) =>
|
||||||
OneGangInterface(gangSwitch: device)));
|
OneGangInterface(gangSwitch: device)));
|
||||||
|
|
||||||
|
if (value && isAllDevices) {
|
||||||
|
devicesCubit.fetchAllDevices(HomeCubit.getInstance().selectedSpace);
|
||||||
|
}
|
||||||
case DeviceType.TwoGang:
|
case DeviceType.TwoGang:
|
||||||
Navigator.push(
|
var value = await Navigator.push(
|
||||||
context,
|
context,
|
||||||
PageRouteBuilder(
|
PageRouteBuilder(
|
||||||
pageBuilder: (context, animation1, animation2) =>
|
pageBuilder: (context, animation1, animation2) =>
|
||||||
TwoGangInterface(gangSwitch: device)));
|
TwoGangInterface(gangSwitch: device)));
|
||||||
|
if (value && isAllDevices) {
|
||||||
|
devicesCubit.fetchAllDevices(HomeCubit.getInstance().selectedSpace);
|
||||||
|
}
|
||||||
case DeviceType.ThreeGang:
|
case DeviceType.ThreeGang:
|
||||||
Navigator.push(
|
var value = await Navigator.push(
|
||||||
context,
|
context,
|
||||||
PageRouteBuilder(
|
PageRouteBuilder(
|
||||||
pageBuilder: (context, animation1, animation2) =>
|
pageBuilder: (context, animation1, animation2) =>
|
||||||
ThreeGangInterface(gangSwitch: device)));
|
ThreeGangInterface(gangSwitch: device)));
|
||||||
|
if (value && isAllDevices) {
|
||||||
|
devicesCubit.fetchAllDevices(HomeCubit.getInstance().selectedSpace);
|
||||||
|
}
|
||||||
|
|
||||||
case DeviceType.WH:
|
case DeviceType.WH:
|
||||||
Navigator.push(
|
var value = await Navigator.push(
|
||||||
context,
|
context,
|
||||||
PageRouteBuilder(
|
PageRouteBuilder(
|
||||||
pageBuilder: (context, animation1, animation2) =>
|
pageBuilder: (context, animation1, animation2) =>
|
||||||
WaterHeaterPage(device: device)));
|
WaterHeaterPage(device: device)));
|
||||||
|
if (value && isAllDevices) {
|
||||||
|
devicesCubit.fetchAllDevices(HomeCubit.getInstance().selectedSpace);
|
||||||
|
}
|
||||||
case DeviceType.DS:
|
case DeviceType.DS:
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
@ -182,31 +232,43 @@ void showDeviceInterface(DeviceModel device, BuildContext context) {
|
|||||||
PowerClampPage(device: device)));
|
PowerClampPage(device: device)));
|
||||||
|
|
||||||
case DeviceType.OneTouch:
|
case DeviceType.OneTouch:
|
||||||
Navigator.push(
|
var value = await Navigator.push(
|
||||||
context,
|
context,
|
||||||
PageRouteBuilder(
|
PageRouteBuilder(
|
||||||
pageBuilder: (context, animation1, animation2) =>
|
pageBuilder: (context, animation1, animation2) =>
|
||||||
OneTouchScreen(device: device)));
|
OneTouchScreen(device: device)));
|
||||||
|
if (value && isAllDevices) {
|
||||||
|
devicesCubit.fetchAllDevices(HomeCubit.getInstance().selectedSpace);
|
||||||
|
}
|
||||||
|
|
||||||
case DeviceType.TowTouch:
|
case DeviceType.TowTouch:
|
||||||
Navigator.push(
|
var value = await Navigator.push(
|
||||||
context,
|
context,
|
||||||
PageRouteBuilder(
|
PageRouteBuilder(
|
||||||
pageBuilder: (context, animation1, animation2) =>
|
pageBuilder: (context, animation1, animation2) =>
|
||||||
TwoTouchInterface(touchSwitch: device)));
|
TwoTouchInterface(touchSwitch: device)));
|
||||||
|
if (value && isAllDevices) {
|
||||||
|
devicesCubit.fetchAllDevices(HomeCubit.getInstance().selectedSpace);
|
||||||
|
}
|
||||||
case DeviceType.ThreeTouch:
|
case DeviceType.ThreeTouch:
|
||||||
Navigator.push(
|
var value = await Navigator.push(
|
||||||
context,
|
context,
|
||||||
PageRouteBuilder(
|
PageRouteBuilder(
|
||||||
pageBuilder: (context, animation1, animation2) =>
|
pageBuilder: (context, animation1, animation2) =>
|
||||||
ThreeTouchInterface(touchSwitch: device)));
|
ThreeTouchInterface(touchSwitch: device)));
|
||||||
|
if (value && isAllDevices) {
|
||||||
|
devicesCubit.fetchAllDevices(HomeCubit.getInstance().selectedSpace);
|
||||||
|
}
|
||||||
|
|
||||||
case DeviceType.GarageDoor:
|
case DeviceType.GarageDoor:
|
||||||
Navigator.push(
|
var value = await Navigator.push(
|
||||||
context,
|
context,
|
||||||
PageRouteBuilder(
|
PageRouteBuilder(
|
||||||
pageBuilder: (context, animation1, animation2) =>
|
pageBuilder: (context, animation1, animation2) =>
|
||||||
GarageDoorScreen(device: device)));
|
GarageDoorScreen(device: device)));
|
||||||
|
if (value && isAllDevices) {
|
||||||
|
devicesCubit.fetchAllDevices(HomeCubit.getInstance().selectedSpace);
|
||||||
|
}
|
||||||
|
|
||||||
case DeviceType.WaterLeak:
|
case DeviceType.WaterLeak:
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
@ -216,18 +278,24 @@ void showDeviceInterface(DeviceModel device, BuildContext context) {
|
|||||||
WaterLeakScreen(device: device)));
|
WaterLeakScreen(device: device)));
|
||||||
|
|
||||||
case DeviceType.SixScene:
|
case DeviceType.SixScene:
|
||||||
Navigator.push(
|
var value = await Navigator.push(
|
||||||
context,
|
context,
|
||||||
PageRouteBuilder(
|
PageRouteBuilder(
|
||||||
pageBuilder: (context, animation1, animation2) =>
|
pageBuilder: (context, animation1, animation2) =>
|
||||||
SixSceneScreen(device: device)));
|
SixSceneScreen(device: device)));
|
||||||
|
if (value && isAllDevices) {
|
||||||
|
devicesCubit.fetchAllDevices(HomeCubit.getInstance().selectedSpace);
|
||||||
|
}
|
||||||
|
|
||||||
case DeviceType.FourScene:
|
case DeviceType.FourScene:
|
||||||
Navigator.push(
|
var value = await Navigator.push(
|
||||||
context,
|
context,
|
||||||
PageRouteBuilder(
|
PageRouteBuilder(
|
||||||
pageBuilder: (context, animation1, animation2) =>
|
pageBuilder: (context, animation1, animation2) =>
|
||||||
FourSceneScreen(device: device)));
|
FourSceneScreen(device: device)));
|
||||||
|
if (value && isAllDevices) {
|
||||||
|
devicesCubit.fetchAllDevices(HomeCubit.getInstance().selectedSpace);
|
||||||
|
}
|
||||||
|
|
||||||
case DeviceType.SOS:
|
case DeviceType.SOS:
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
|
@ -23,6 +23,21 @@ class RoomsSlider extends StatelessWidget {
|
|||||||
HomeCubit.getInstance().roomSliderPageChanged(index);
|
HomeCubit.getInstance().roomSliderPageChanged(index);
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 15),
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () {
|
||||||
|
HomeCubit.getInstance().unselectRoom();
|
||||||
|
},
|
||||||
|
child: TitleMedium(
|
||||||
|
text: 'All Devices',
|
||||||
|
style: context.titleMedium.copyWith(
|
||||||
|
fontSize: 25,
|
||||||
|
color: ColorsManager.textPrimaryColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 15),
|
padding: const EdgeInsets.symmetric(horizontal: 15),
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
@ -43,7 +58,10 @@ class RoomsSlider extends StatelessWidget {
|
|||||||
(room) => InkWell(
|
(room) => InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
HomeCubit.getInstance().roomSliderPageChanged(
|
HomeCubit.getInstance().roomSliderPageChanged(
|
||||||
HomeCubit.getInstance().selectedSpace!.subspaces.indexOf(room));
|
HomeCubit.getInstance()
|
||||||
|
.selectedSpace!
|
||||||
|
.subspaces
|
||||||
|
.indexOf(room));
|
||||||
},
|
},
|
||||||
child: TitleMedium(
|
child: TitleMedium(
|
||||||
text: room.name!,
|
text: room.name!,
|
||||||
@ -51,7 +69,8 @@ class RoomsSlider extends StatelessWidget {
|
|||||||
fontSize: 25,
|
fontSize: 25,
|
||||||
color: HomeCubit.getInstance().selectedRoom == room
|
color: HomeCubit.getInstance().selectedRoom == room
|
||||||
? ColorsManager.textPrimaryColor
|
? ColorsManager.textPrimaryColor
|
||||||
: ColorsManager.textPrimaryColor.withOpacity(.2),
|
: ColorsManager.textPrimaryColor
|
||||||
|
.withOpacity(.2),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/bloc/two_touch_bloc/two_touch_bloc.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/view/widgets/device_appbar.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/device_appbar.dart';
|
||||||
import 'package:syncrow_app/features/devices/view/widgets/two_touch/two_touch_screen.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/two_touch/two_touch_screen.dart';
|
||||||
@ -26,6 +28,7 @@ class TwoTouchInterface extends StatelessWidget {
|
|||||||
extendBody: true,
|
extendBody: true,
|
||||||
appBar: touchSwitch != null
|
appBar: touchSwitch != null
|
||||||
? DeviceAppbar(
|
? DeviceAppbar(
|
||||||
|
value: true,
|
||||||
deviceName: touchSwitch!.name!,
|
deviceName: touchSwitch!.name!,
|
||||||
deviceUuid: touchSwitch!.uuid!,
|
deviceUuid: touchSwitch!.uuid!,
|
||||||
)
|
)
|
||||||
|
@ -16,10 +16,12 @@ class SceneRoomsTabBarDevicesView extends StatefulWidget {
|
|||||||
const SceneRoomsTabBarDevicesView({super.key});
|
const SceneRoomsTabBarDevicesView({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<SceneRoomsTabBarDevicesView> createState() => _SceneRoomsTabBarDevicesViewState();
|
State<SceneRoomsTabBarDevicesView> createState() =>
|
||||||
|
_SceneRoomsTabBarDevicesViewState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _SceneRoomsTabBarDevicesViewState extends State<SceneRoomsTabBarDevicesView>
|
class _SceneRoomsTabBarDevicesViewState
|
||||||
|
extends State<SceneRoomsTabBarDevicesView>
|
||||||
with SingleTickerProviderStateMixin {
|
with SingleTickerProviderStateMixin {
|
||||||
late final TabController _tabController;
|
late final TabController _tabController;
|
||||||
List<SubSpaceModel>? rooms = [];
|
List<SubSpaceModel>? rooms = [];
|
||||||
@ -35,14 +37,15 @@ class _SceneRoomsTabBarDevicesViewState extends State<SceneRoomsTabBarDevicesVie
|
|||||||
0,
|
0,
|
||||||
SubSpaceModel(
|
SubSpaceModel(
|
||||||
name: 'All Devices',
|
name: 'All Devices',
|
||||||
devices: DevicesCubit.getInstance().allDevices,
|
devices: context.read<DevicesCubit>().allDevices,
|
||||||
id: '-1',
|
id: '-1',
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_tabController = TabController(length: rooms!.length, vsync: this, initialIndex: 0);
|
_tabController =
|
||||||
|
TabController(length: rooms!.length, vsync: this, initialIndex: 0);
|
||||||
_tabController.addListener(_handleTabSwitched);
|
_tabController.addListener(_handleTabSwitched);
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
@ -52,8 +55,10 @@ class _SceneRoomsTabBarDevicesViewState extends State<SceneRoomsTabBarDevicesVie
|
|||||||
final value = _tabController.index;
|
final value = _tabController.index;
|
||||||
|
|
||||||
/// select tab
|
/// select tab
|
||||||
context.read<TabBarBloc>().add(
|
context.read<TabBarBloc>().add(TabChanged(
|
||||||
TabChanged(selectedIndex: value, roomId: rooms?[value].id ?? '', unit: selectedSpace));
|
selectedIndex: value,
|
||||||
|
roomId: rooms?[value].id ?? '',
|
||||||
|
unit: selectedSpace));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,81 +1,146 @@
|
|||||||
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:syncrow_app/features/devices/bloc/devices_cubit.dart';
|
import 'package:syncrow_app/features/devices/bloc/devices_cubit.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/generated/assets.dart';
|
||||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||||
import 'package:collection/collection.dart';
|
|
||||||
|
|
||||||
class CustomSwitch extends StatelessWidget {
|
class CustomSwitch extends StatefulWidget {
|
||||||
const CustomSwitch({super.key, required this.device});
|
const CustomSwitch({Key? key, required this.device}) : super(key: key);
|
||||||
|
|
||||||
final DeviceModel device;
|
final DeviceModel device;
|
||||||
|
|
||||||
|
@override
|
||||||
|
_CustomSwitchState createState() => _CustomSwitchState();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isCurtainOpen(DeviceModel device) {
|
||||||
|
// Find the status with code == 'percent_control'
|
||||||
|
final curtainStatus = device.status.firstWhere(
|
||||||
|
(s) => s.code == 'percent_control',
|
||||||
|
// orElse: () => null,
|
||||||
|
);
|
||||||
|
|
||||||
|
// We consider it "on/open" if percent_control == 100
|
||||||
|
return curtainStatus.value >= 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CustomSwitchState extends State<CustomSwitch> {
|
||||||
|
bool _isLoading = false;
|
||||||
|
|
||||||
|
bool isDeviceOn(DeviceModel device) {
|
||||||
|
// If it's a curtain, check percent_control
|
||||||
|
if (device.type == "CUR") {
|
||||||
|
return isCurtainOpen(device);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, default to your existing switch logic
|
||||||
|
final switchStatuses = device.status.where(
|
||||||
|
(s) => (s.code?.startsWith('switch') ?? false),
|
||||||
|
);
|
||||||
|
final anySwitchFalse = switchStatuses.any((s) => s.value == false);
|
||||||
|
return !anySwitchFalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildLoadingIndicator() {
|
||||||
|
return const SizedBox(
|
||||||
|
width: 45,
|
||||||
|
height: 28,
|
||||||
|
child: Center(
|
||||||
|
child: SizedBox(
|
||||||
|
width: 22,
|
||||||
|
height: 22,
|
||||||
|
child: CircularProgressIndicator(
|
||||||
|
strokeWidth: 2,
|
||||||
|
color: ColorsManager.primaryColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocBuilder<DevicesCubit, DevicesState>(
|
final isSwitch = widget.device.categoryName == 'Switch';
|
||||||
builder: (context, state) {
|
if (!isSwitch &&
|
||||||
bool? status;
|
widget.device.type != "AC" &&
|
||||||
if (device.status.isNotEmpty) {
|
widget.device.type != "GD" &&
|
||||||
status = device.status
|
widget.device.type != "CUR") {
|
||||||
.firstWhereOrNull((status) => status.code == "switch")
|
return const SizedBox();
|
||||||
?.value;
|
}
|
||||||
|
final isOn = isDeviceOn(widget.device);
|
||||||
|
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: () async {
|
||||||
|
setState(() {
|
||||||
|
_isLoading = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
final newValue = !isOn;
|
||||||
|
String code;
|
||||||
|
dynamic controlValue;
|
||||||
|
|
||||||
|
if (widget.device.type == "AC") {
|
||||||
|
code = "switch";
|
||||||
|
controlValue = newValue;
|
||||||
|
} else if (widget.device.type == "CUR") {
|
||||||
|
code = "percent_control";
|
||||||
|
controlValue = newValue ? "close" : "open";
|
||||||
|
} else {
|
||||||
|
code = "switch_1";
|
||||||
|
controlValue = newValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
final control = DeviceControlModel(
|
||||||
|
code: code,
|
||||||
|
value: controlValue,
|
||||||
|
deviceId: widget.device.uuid!,
|
||||||
|
);
|
||||||
|
try {
|
||||||
|
if (widget.device.type == "CUR") {
|
||||||
|
await context
|
||||||
|
.read<DevicesCubit>()
|
||||||
|
.changeCurtainSwitch(control, widget.device.uuid!);
|
||||||
|
} else if (widget.device.type == "1GT") {
|
||||||
|
await context
|
||||||
|
.read<DevicesCubit>()
|
||||||
|
.oneGTGangToggle(control, widget.device.uuid!);
|
||||||
|
} else if (widget.device.type == "2GT") {
|
||||||
|
await context
|
||||||
|
.read<DevicesCubit>()
|
||||||
|
.towGTGangToggle(control, widget.device.uuid!);
|
||||||
|
} else if (widget.device.type == "3G") {
|
||||||
|
await context
|
||||||
|
.read<DevicesCubit>()
|
||||||
|
.threeGangToggle(control, widget.device.uuid!);
|
||||||
|
} else if (widget.device.type == "2G") {
|
||||||
|
await context
|
||||||
|
.read<DevicesCubit>()
|
||||||
|
.towGangToggle(control, widget.device.uuid!);
|
||||||
|
} else if (widget.device.type == "1G") {
|
||||||
|
await context
|
||||||
|
.read<DevicesCubit>()
|
||||||
|
.oneGangToggle(control, widget.device.uuid!);
|
||||||
|
} else {
|
||||||
|
await context
|
||||||
|
.read<DevicesCubit>()
|
||||||
|
.deviceControl(control, widget.device.uuid!);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
setState(() {
|
||||||
|
_isLoading = false;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
return status == null
|
|
||||||
? const SizedBox()
|
|
||||||
: GestureDetector(
|
|
||||||
onTap: () {
|
|
||||||
DevicesCubit.getInstance().deviceControl(
|
|
||||||
DeviceControlModel(
|
|
||||||
deviceId: device.uuid,
|
|
||||||
code: device.status
|
|
||||||
.firstWhere((status) => status.code == "switch")
|
|
||||||
.code,
|
|
||||||
value: !device.status
|
|
||||||
.firstWhere((status) => status.code == "switch")
|
|
||||||
.value!,
|
|
||||||
),
|
|
||||||
device.uuid!,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
child: Container(
|
|
||||||
width: 45.0,
|
|
||||||
height: 28.0,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
borderRadius: BorderRadius.circular(24.0),
|
|
||||||
color: status
|
|
||||||
? ColorsManager.primaryColor
|
|
||||||
: const Color(0xFFD9D9D9)),
|
|
||||||
child: Center(
|
|
||||||
child: Container(
|
|
||||||
width: 40.0,
|
|
||||||
height: 23.0,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
borderRadius: BorderRadius.circular(24.0),
|
|
||||||
color: Colors.white,
|
|
||||||
),
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.all(2.0),
|
|
||||||
child: Container(
|
|
||||||
alignment: status
|
|
||||||
? Alignment.centerRight
|
|
||||||
: Alignment.centerLeft,
|
|
||||||
child: Container(
|
|
||||||
width: 20.0,
|
|
||||||
height: 20.0,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
shape: BoxShape.circle,
|
|
||||||
color: status
|
|
||||||
? ColorsManager.primaryColor
|
|
||||||
: Colors.grey,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
|
child: _isLoading
|
||||||
|
? _buildLoadingIndicator()
|
||||||
|
: SizedBox(
|
||||||
|
child: SvgPicture.asset(
|
||||||
|
isOn ? Assets.toggleSwitchSmall : Assets.offToggleSwitchSmall,
|
||||||
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1139,4 +1139,8 @@ class Assets {
|
|||||||
static const String office = 'assets/icons/office.svg';
|
static const String office = 'assets/icons/office.svg';
|
||||||
static const String parlour = 'assets/icons/parlour.svg';
|
static const String parlour = 'assets/icons/parlour.svg';
|
||||||
static const String grid = 'assets/images/grid.svg';
|
static const String grid = 'assets/images/grid.svg';
|
||||||
|
|
||||||
|
static const String toggleSwitchSmall = 'assets/icons/toggleSwitchSmall.svg';
|
||||||
|
static const String offToggleSwitchSmall = 'assets/icons/offToggleSwitchSmall.svg';
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
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/auth/bloc/auth_cubit.dart';
|
import 'package:syncrow_app/features/auth/bloc/auth_cubit.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
|
||||||
import 'package:syncrow_app/features/menu/bloc/menu_cubit.dart';
|
import 'package:syncrow_app/features/menu/bloc/menu_cubit.dart';
|
||||||
import 'package:syncrow_app/features/menu/bloc/profile_bloc/profile_bloc.dart';
|
import 'package:syncrow_app/features/menu/bloc/profile_bloc/profile_bloc.dart';
|
||||||
import 'package:syncrow_app/features/scene/bloc/create_scene/create_scene_bloc.dart';
|
import 'package:syncrow_app/features/scene/bloc/create_scene/create_scene_bloc.dart';
|
||||||
@ -27,6 +28,9 @@ class MyApp extends StatelessWidget {
|
|||||||
Constants.bottomNavBarHeightPercentage;
|
Constants.bottomNavBarHeightPercentage;
|
||||||
return MultiBlocProvider(
|
return MultiBlocProvider(
|
||||||
providers: [
|
providers: [
|
||||||
|
BlocProvider<DevicesCubit>(
|
||||||
|
create: (context) => DevicesCubit.getInstance(),
|
||||||
|
),
|
||||||
BlocProvider(create: (context) => AuthCubit()),
|
BlocProvider(create: (context) => AuthCubit()),
|
||||||
BlocProvider(
|
BlocProvider(
|
||||||
create: (context) => EffectPeriodBloc(),
|
create: (context) => EffectPeriodBloc(),
|
||||||
@ -35,7 +39,7 @@ class MyApp extends StatelessWidget {
|
|||||||
BlocProvider(create: (context) => CreateSceneBloc()),
|
BlocProvider(create: (context) => CreateSceneBloc()),
|
||||||
BlocProvider(create: (context) => SceneBloc()),
|
BlocProvider(create: (context) => SceneBloc()),
|
||||||
BlocProvider(create: (context) => ProfileBloc()),
|
BlocProvider(create: (context) => ProfileBloc()),
|
||||||
BlocProvider(create: (context) => MenuCubit()),
|
BlocProvider(create: (context) => MenuCubit()), //DevicesCubit
|
||||||
],
|
],
|
||||||
child: MaterialApp(
|
child: MaterialApp(
|
||||||
navigatorKey: NavigationService.navigatorKey,
|
navigatorKey: NavigationService.navigatorKey,
|
||||||
|
@ -225,7 +225,7 @@ abstract class ApiEndpoints {
|
|||||||
static const String getDeviceLogs = '/device/report-logs/{uuid}?code={code}';
|
static const String getDeviceLogs = '/device/report-logs/{uuid}?code={code}';
|
||||||
static const String terms = '/terms';
|
static const String terms = '/terms';
|
||||||
static const String policy = '/policy';
|
static const String policy = '/policy';
|
||||||
static const String getPermission = '/permission/{roleUuid}';
|
static const String getPermission = '/permission/{roleUuid}';
|
||||||
|
static const String getAllDevices =
|
||||||
///permission/roleUuid
|
'/projects/{projectUuid}/communities/{communityUuid}/spaces/{spaceUuid}/devices';
|
||||||
}
|
}
|
||||||
|
@ -51,11 +51,14 @@ class DevicesAPI {
|
|||||||
static Future<Map<String, dynamic>> controlDevice(
|
static Future<Map<String, dynamic>> controlDevice(
|
||||||
DeviceControlModel controlModel, String deviceId) async {
|
DeviceControlModel controlModel, String deviceId) async {
|
||||||
try {
|
try {
|
||||||
|
print('object-*/-*/-*/${controlModel.toJson()}');
|
||||||
final response = await _httpService.post(
|
final response = await _httpService.post(
|
||||||
path: ApiEndpoints.controlDevice.replaceAll('{deviceUuid}', deviceId),
|
path: ApiEndpoints.controlDevice.replaceAll('{deviceUuid}', deviceId),
|
||||||
body: controlModel.toJson(),
|
body: controlModel.toJson(),
|
||||||
showServerMessage: true,
|
showServerMessage: true,
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
|
print('object-*/-*/-*/${json}');
|
||||||
|
|
||||||
return json;
|
return json;
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -561,4 +564,45 @@ class DevicesAPI {
|
|||||||
);
|
);
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Future<List<DeviceModel>> getAllDevices({
|
||||||
|
required String communityUuid,
|
||||||
|
required String spaceUuid,
|
||||||
|
}) async {
|
||||||
|
print('communityUuid=$communityUuid');
|
||||||
|
print('spaceUuid=$spaceUuid');
|
||||||
|
print('projectUuid=${TempConst.projectId}');
|
||||||
|
|
||||||
|
try {
|
||||||
|
final String path = ApiEndpoints.getAllDevices
|
||||||
|
.replaceAll('{communityUuid}', communityUuid)
|
||||||
|
.replaceAll('{spaceUuid}', spaceUuid)
|
||||||
|
.replaceAll('{projectUuid}', TempConst.projectId);
|
||||||
|
|
||||||
|
final response = await _httpService.get(
|
||||||
|
path: path,
|
||||||
|
showServerMessage: false,
|
||||||
|
expectedResponseModel: (json) {
|
||||||
|
print('response-*/-*/$json');
|
||||||
|
final data = json['data'];
|
||||||
|
|
||||||
|
if (data == null || data.isEmpty) {
|
||||||
|
return <DeviceModel>[];
|
||||||
|
}
|
||||||
|
if (json == null || json.isEmpty || json == []) {
|
||||||
|
return <DeviceModel>[];
|
||||||
|
}
|
||||||
|
return data
|
||||||
|
.map<DeviceModel>((device) => DeviceModel.fromJson(device))
|
||||||
|
.toList();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
return response;
|
||||||
|
} catch (e) {
|
||||||
|
// Log the error if needed
|
||||||
|
// Return an empty list in case of error
|
||||||
|
return <DeviceModel>[];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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.
|
# 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
|
publish_to: "none" # Remove this line if you wish to publish to pub.dev
|
||||||
|
|
||||||
version: 1.0.10+46
|
version: 1.0.18+55
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=3.0.6 <4.0.0"
|
sdk: ">=3.0.6 <4.0.0"
|
||||||
|
Reference in New Issue
Block a user