Merge pull request #23 from SyncrowIOT/Syncing_with_backend

Synced with the backend
This commit is contained in:
Mohammad Salameh
2024-04-30 12:14:10 +03:00
committed by GitHub
19 changed files with 255 additions and 181 deletions
+6 -6
View File
@@ -18,9 +18,9 @@ part 'home_state.dart';
class HomeCubit extends Cubit<HomeState> {
HomeCubit._() : super(HomeInitial()) {
if (selectedSpace == null) {
fetchSpaces().then((value) {
fetchUnitsByUserId().then((value) {
if (selectedSpace != null) {
fetchRooms(selectedSpace!);
fetchRoomsByUnitId(selectedSpace!);
}
});
}
@@ -120,10 +120,10 @@ class HomeCubit extends Cubit<HomeState> {
}
//////////////////////////////////////// API ////////////////////////////////////////
fetchSpaces() async {
fetchUnitsByUserId() async {
emitSafe(GetSpacesLoading());
try {
spaces = await SpacesAPI.getSpaces();
spaces = await SpacesAPI.getUnitsByUserId();
} catch (failure) {
emitSafe(GetSpacesError(failure.toString()));
return;
@@ -132,13 +132,13 @@ class HomeCubit extends Cubit<HomeState> {
if (spaces != null && spaces!.isNotEmpty) {
selectedSpace = spaces!.first;
emitSafe(GetSpacesSuccess(spaces!));
fetchRooms(selectedSpace!);
// fetchRoomsByUnitId(selectedSpace!);
} else {
emitSafe(GetSpacesError("No spaces found"));
}
}
fetchRooms(SpaceModel space) async {
fetchRoomsByUnitId(SpaceModel space) async {
emitSafe(GetSpaceRoomsLoading());
try {
space.rooms = await SpacesAPI.getRoomsBySpaceId(space.id!);
@@ -1,11 +1,14 @@
import 'package:syncrow_app/features/devices/model/room_model.dart';
import 'package:syncrow_app/utils/resource_manager/constants.dart';
class SpaceModel {
final int? id;
final String? id;
final String? name;
final SpaceType type;
late List<RoomModel>? rooms;
SpaceModel({
required this.type,
required this.id,
required this.name,
required this.rooms,
@@ -21,8 +24,9 @@ class SpaceModel {
factory SpaceModel.fromJson(Map<String, dynamic> json) {
return SpaceModel(
id: int.parse(json['homeId']),
name: json['homeName'],
id: json['uuid'],
name: json['name'],
type: spaceTypesMap[json['type']]!,
rooms: [],
);
}
+16 -13
View File
@@ -46,19 +46,19 @@ class AuthCubit extends Cubit<AuthState> {
String? passwordValidator(String? value) {
if (value != null) {
if (value.isNotEmpty) {
if (value.length >= 6) {
return null;
//TODO uncomment this code when the password validation is needed
// if (RegExp(
// r'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$')
// .hasMatch(value)) {
// return null;
// } else {
// return 'Password must contain at least one uppercase letter, one lowercase letter, one number and one special character';
// }
} else {
return 'Password must be at least 6 characters';
}
// if (value.length >= 6) {
return null;
//TODO uncomment this code when the password validation is needed
// if (RegExp(
// r'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$')
// .hasMatch(value)) {
// return null;
// } else {
// return 'Password must contain at least one uppercase letter, one lowercase letter, one number and one special character';
// }
// } else {
// return 'Password must be at least 6 characters';
// }
} else {
return 'Please enter your password';
}
@@ -106,12 +106,15 @@ class AuthCubit extends Cubit<AuthState> {
return;
}
if (token.accessTokenIsNotEmpty) {
debugPrint('token: ${token.accessToken}');
FlutterSecureStorage storage = const FlutterSecureStorage();
await storage.write(
key: Token.loginAccessTokenKey, value: token.accessToken);
const FlutterSecureStorage().write(
key: UserModel.userUuidKey,
value: Token.decodeToken(token.accessToken)['uuid'].toString());
user = UserModel.fromToken(token);
emailController.clear();
passwordController.clear();
+3 -2
View File
@@ -4,7 +4,7 @@ import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:syncrow_app/utils/helpers/decode_base64.dart';
class Token {
static const String loginAccessTokenKey = 'access_token';
static const String loginAccessTokenKey = 'accessToken';
static const String loginRefreshTokenKey = 'refreshToken';
final String accessToken;
@@ -56,7 +56,8 @@ class Token {
var storage = const FlutterSecureStorage();
storage.write(
key: loginAccessTokenKey, value: json[loginAccessTokenKey] ?? '');
storage.write(
key: loginRefreshTokenKey, value: json[loginRefreshTokenKey] ?? '');
//create token object ?
return Token(json[loginAccessTokenKey] ?? '',
json[loginRefreshTokenKey] ?? '', '', 0, 0);
+14 -11
View File
@@ -25,7 +25,7 @@ part 'devices_state.dart';
class DevicesCubit extends Cubit<DevicesState> {
DevicesCubit._() : super(DevicesInitial()) {
if (HomeCubit.getInstance().selectedSpace != null) {
fetchGroups(HomeCubit.getInstance().selectedSpace!.id!);
// fetchGroups(HomeCubit.getInstance().selectedSpace!.id!);
for (var room in HomeCubit.getInstance().selectedSpace!.rooms!) {
fetchDevicesByRoomId(room.id!);
}
@@ -257,7 +257,7 @@ class DevicesCubit extends Cubit<DevicesState> {
emitSafe(DeviceControlSuccess(code: control.code));
//this delay is to give tuya server time to update the status
Future.delayed(const Duration(milliseconds: 400), () {
getDevicesStatues(
fetchDevicesStatues(
deviceId,
HomeCubit.getInstance()
.selectedSpace!
@@ -274,7 +274,7 @@ class DevicesCubit extends Cubit<DevicesState> {
}
}
fetchGroups(int spaceId) async {
fetchGroups(String spaceId) async {
emitSafe(DevicesCategoriesLoading());
try {
allCategories = await DevicesAPI.fetchGroups(spaceId);
@@ -289,7 +289,7 @@ class DevicesCubit extends Cubit<DevicesState> {
}
}
fetchDevicesByRoomId(int? roomId) async {
fetchDevicesByRoomId(String? roomId) async {
if (roomId == null) return;
emitSafe(GetDevicesLoading());
@@ -308,23 +308,26 @@ class DevicesCubit extends Cubit<DevicesState> {
//get status for each device
//TODO get devices status per page via page controller instead of getting all devices status at once
for (var device
in HomeCubit.getInstance().selectedSpace!.rooms![roomIndex].devices!) {
getDevicesStatues(device.id!, roomIndex);
List<DeviceModel> devices =
HomeCubit.getInstance().selectedSpace!.rooms![roomIndex].devices!;
if (devices.isNotEmpty) {
for (var device in devices) {
fetchDevicesStatues(device.uuid!, roomIndex);
}
}
}
getDevicesStatues(String deviceId, int roomIndex, {String? code}) async {
fetchDevicesStatues(String deviceUuid, int roomIndex, {String? code}) async {
emitSafe(GetDeviceStatusLoading(code: code));
int deviceIndex = HomeCubit.getInstance()
.selectedSpace!
.rooms![roomIndex]
.devices!
.indexWhere((element) => element.id == deviceId);
.indexWhere((element) => element.uuid == deviceUuid);
List<StatusModel> statuses = [];
try {
var response = await DevicesAPI.getDeviceStatus(deviceId);
for (var status in response['result']['status']) {
var response = await DevicesAPI.getDeviceStatus(deviceUuid);
for (var status in response['status']) {
statuses.add(StatusModel.fromJson(status));
}
} catch (e) {
@@ -10,8 +10,9 @@ class DeviceControlModel {
});
factory DeviceControlModel.fromJson(Map<String, dynamic> json) {
print('json: $json');
return DeviceControlModel(
deviceId: json['deviceId'],
deviceId: json['deviceUuid'],
code: json['code'],
value: json['value'],
);
@@ -19,7 +20,7 @@ class DeviceControlModel {
Map<String, dynamic> toJson() {
return {
'deviceId': deviceId,
'deviceUuid': deviceId,
'code': code,
'value': value,
};
+17 -66
View File
@@ -5,25 +5,14 @@ import 'package:syncrow_app/utils/resource_manager/constants.dart';
class DeviceModel {
int? activeTime;
String? category; //unused
String? categoryName; //unused
int? createTime; //unused
String? gatewayId; //unused
String? icon; //unused
String? id;
String? ip; //unused
double? lat; //unused
// String? id;
String? localKey;
double? lon; //unused
String? model;
String? name;
String? nodeId; //remove
String? icon;
bool? isOnline;
List<StatusModel> status = [];
String? ownerId; //unused
String? productId; //unused
String? productName;
bool? isSub; //unused
String? timeZone;
int? updateTime;
String? uuid;
@@ -32,108 +21,70 @@ class DeviceModel {
late List<FunctionModel> functions;
DeviceModel({
this.activeTime,
this.category,
this.categoryName,
this.createTime,
this.gatewayId,
this.icon,
this.id,
this.ip,
this.lat,
// this.id,
this.localKey,
this.lon,
this.model,
this.name,
this.nodeId,
this.isOnline,
required this.status,
this.ownerId,
this.productId,
this.productName,
this.isSub,
this.timeZone,
this.updateTime,
this.uuid,
this.productType,
this.icon,
}) {
functions = getFunctions(productType!);
}
factory DeviceModel.fromJson(Map<String, dynamic> json) {
String icon = '';
DeviceType type = devicesTypesMap[json['productId']] ?? DeviceType.Other;
String tempIcon = '';
DeviceType type = devicesTypesMap[json['productType']] ?? DeviceType.Other;
if (type == DeviceType.LightBulb) {
icon = Assets.iconsLight;
tempIcon = Assets.iconsLight;
} else if (type == DeviceType.CeilingSensor ||
type == DeviceType.WallSensor) {
icon = Assets.iconsSensors;
tempIcon = Assets.iconsSensors;
} else if (type == DeviceType.AC) {
icon = Assets.iconsAC;
tempIcon = Assets.iconsAC;
} else if (type == DeviceType.DoorLock) {
icon = Assets.iconsDoorLock;
tempIcon = Assets.iconsDoorLock;
} else if (type == DeviceType.Curtain) {
icon = Assets.iconsCurtain;
tempIcon = Assets.iconsCurtain;
} else if (type == DeviceType.ThreeGang) {
icon = Assets.icons3GangSwitch;
tempIcon = Assets.icons3GangSwitch;
} else if (type == DeviceType.Gateway) {
icon = Assets.iconsGateway;
tempIcon = Assets.iconsGateway;
} else {
icon = Assets.iconsLogo;
tempIcon = Assets.iconsLogo;
}
return DeviceModel(
icon: tempIcon,
activeTime: json['activeTime'],
category: json['category'],
categoryName: json['categoryName'],
createTime: json['createTime'],
gatewayId: json['gatewayId'],
icon: icon,
id: json['id'],
ip: json['ip'],
lat: double.tryParse(json['lat']),
// id: json['id'],
localKey: json['localKey'],
lon: double.tryParse(json['lon']),
model: json['model'],
name: json['name'],
nodeId: json['nodeId'],
isOnline: json['online'],
ownerId: json['ownerId'],
productId: json['productId'],
productName: json['productName'],
isSub: json['sub'],
timeZone: json['timeZone'],
updateTime: json['updateTime'],
uuid: json['uuid'],
productType: type,
status: [],
// json['status']
// .map<StatusModel>((e) => StatusModel.fromJson(e))
// .toList(),
// devicesTypesMap[json['productName']] ?? DeviceType.Other,
);
}
Map<String, dynamic> toJson() {
return {
'activeTime': activeTime,
'category': category,
'categoryName': categoryName,
'createTime': createTime,
'gatewayId': gatewayId,
'icon': icon,
'id': id,
'ip': ip,
'lat': lat,
// 'id': id,
'localKey': localKey,
'lon': lon,
'model': model,
'name': name,
'nodeId': nodeId,
'online': isOnline,
'ownerId': ownerId,
'productId': productId,
'productName': productName,
'sub': isSub,
'timeZone': timeZone,
'updateTime': updateTime,
'uuid': uuid,
@@ -3,7 +3,7 @@ import 'package:syncrow_app/utils/resource_manager/constants.dart';
class FunctionModel {
String? code;
FunctionType? type;
ValueModel? values;
dynamic values;
FunctionModel({
required this.code,
+9 -5
View File
@@ -1,14 +1,16 @@
import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/utils/resource_manager/constants.dart';
class RoomModel {
final int? id;
final String? id;
final String? name;
final SpaceType type;
List<DeviceModel>? devices;
RoomModel({
required this.id,
required this.name,
required this.type,
required this.devices,
});
@@ -16,6 +18,7 @@ class RoomModel {
return {
'id': id,
'name': name,
'type': type,
'devices': devices,
};
}
@@ -28,9 +31,10 @@ class RoomModel {
}
}
return RoomModel(
id: json['roomId'],
name: json['roomName'],
devices: devices,
id: json['uuid'],
name: json['name'],
type: spaceTypesMap[json['type']]!,
devices: [],
);
}
}
@@ -91,10 +91,10 @@ class AcInterfaceTempUnit extends StatelessWidget {
value = double.parse(valueAsString);
DevicesCubit.getInstance().deviceControl(
DeviceControlModel(
deviceId: acDevice.id,
deviceId: acDevice.uuid,
code: 'temp_set',
value: value * 10),
acDevice.id!);
acDevice.uuid!);
}
},
),
@@ -121,10 +121,10 @@ class AcInterfaceTempUnit extends StatelessWidget {
if (setToTemp > 20) {
DevicesCubit.getInstance().deviceControl(
DeviceControlModel(
deviceId: acDevice.id,
deviceId: acDevice.uuid,
code: 'temp_set',
value: (setToTemp - 0.5) * 10),
acDevice.id!);
acDevice.uuid!);
}
},
child: SvgPicture.asset(
@@ -171,10 +171,10 @@ class AcInterfaceTempUnit extends StatelessWidget {
if (setToTemp < 30) {
DevicesCubit.getInstance().deviceControl(
DeviceControlModel(
deviceId: acDevice.id,
deviceId: acDevice.uuid,
code: 'temp_set',
value: (setToTemp + 0.5) * 10),
acDevice.id!);
acDevice.uuid!);
}
},
child: SvgPicture.asset(
@@ -42,10 +42,10 @@ class _ACModeControlUnitState extends State<ACModeControlUnit> {
DevicesCubit.getInstance().deviceControl(
DeviceControlModel(
deviceId: widget.acDevice.id,
deviceId: widget.acDevice.uuid,
code: 'level',
value: reversedFanSpeedsMap[fanSpeed]!),
widget.acDevice.id!);
widget.acDevice.uuid!);
},
child: DefaultContainer(
height: 55,
@@ -68,10 +68,10 @@ class _ACModeControlUnitState extends State<ACModeControlUnit> {
tempMode = tempModesMap[getNextItem(tempModesMap, tempMode)]!;
DevicesCubit.getInstance().deviceControl(
DeviceControlModel(
deviceId: widget.acDevice.id,
deviceId: widget.acDevice.uuid,
code: 'mode',
value: reversedTempModesMap[tempMode]!),
widget.acDevice.id!);
widget.acDevice.uuid!);
},
child: DefaultContainer(
height: 55,
@@ -149,10 +149,10 @@ class ParameterControlDialogState extends State<ParameterControlDialog> {
DevicesCubit.getInstance().deviceControl(
DeviceControlModel(
deviceId: widget.sensor.id,
deviceId: widget.sensor.uuid,
code: widget.controlCode,
value: widget.value),
widget.sensor.id ?? '');
widget.sensor.uuid ?? '');
},
child: Center(
child: BodyMedium(
@@ -313,11 +313,11 @@ Widget listItem(
if (wallSensor.isOnline ?? false) {
DevicesCubit.getInstance().deviceControl(
DeviceControlModel(
deviceId: wallSensor.id,
deviceId: wallSensor.uuid,
code: 'indicator',
value: value,
),
wallSensor.id ?? '');
wallSensor.uuid ?? '');
} else {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
@@ -34,7 +34,7 @@ class ThreeGangInterfaceBody extends StatelessWidget {
GangSwitch(
threeGangSwitch: device,
control: DeviceControlModel(
deviceId: device.id,
deviceId: device.uuid,
// code: 'switch_1',
code: device.status[0].code,
// value: true,
@@ -60,7 +60,7 @@ class ThreeGangInterfaceBody extends StatelessWidget {
// deviceId: 'bfe10693d4fd263206ocq9',
// code: 'switch_2',
// value: true,
deviceId: device.id,
deviceId: device.uuid,
code: device.status[1].code,
value: device.status[1].value,
),
@@ -84,7 +84,7 @@ class ThreeGangInterfaceBody extends StatelessWidget {
// deviceId: 'bfe10693d4fd263206ocq9',
// code: 'switch_3',
// value: true,
deviceId: device.id,
deviceId: device.uuid,
code: device.status[2].code,
value: device.status[2].value,
),
@@ -120,27 +120,27 @@ class ThreeGangInterfaceBody extends StatelessWidget {
onTap: () {
DevicesCubit.getInstance().deviceControl(
DeviceControlModel(
deviceId: device.id,
deviceId: device.uuid,
code: 'switch_1',
value: true,
),
device.id!,
device.uuid!,
);
DevicesCubit.getInstance().deviceControl(
DeviceControlModel(
deviceId: device.id,
deviceId: device.uuid,
code: 'switch_2',
value: true,
),
device.id!,
device.uuid!,
);
DevicesCubit.getInstance().deviceControl(
DeviceControlModel(
deviceId: device.id,
deviceId: device.uuid,
code: 'switch_3',
value: true,
),
device.id!,
device.uuid!,
);
},
child: Stack(
@@ -252,27 +252,27 @@ class ThreeGangInterfaceBody extends StatelessWidget {
onTap: () {
DevicesCubit.getInstance().deviceControl(
DeviceControlModel(
deviceId: device.id,
deviceId: device.uuid,
code: 'switch_1',
value: false,
),
device.id!,
device.uuid!,
);
DevicesCubit.getInstance().deviceControl(
DeviceControlModel(
deviceId: device.id,
deviceId: device.uuid,
code: 'switch_2',
value: false,
),
device.id!,
device.uuid!,
);
DevicesCubit.getInstance().deviceControl(
DeviceControlModel(
deviceId: device.id,
deviceId: device.uuid,
code: 'switch_3',
value: false,
),
device.id!,
device.uuid!,
);
},
child: Stack(
@@ -26,7 +26,7 @@ class CustomSwitch extends StatelessWidget {
onTap: () {
DevicesCubit.getInstance().deviceControl(
DeviceControlModel(
deviceId: device.id,
deviceId: device.uuid,
code: device.status
.firstWhere((status) => status.code == "switch")
.code,
@@ -34,7 +34,7 @@ class CustomSwitch extends StatelessWidget {
.firstWhere((status) => status.code == "switch")
.value!,
),
device.id!,
device.uuid!,
);
},
child: Container(