mirror of
https://github.com/SyncrowIOT/syncrow-app.git
synced 2026-03-11 08:41:44 +00:00
Compare commits
29 Commits
password_c
...
feat/refac
| Author | SHA1 | Date | |
|---|---|---|---|
| 391d6349cc | |||
| 9c873fb0c5 | |||
| e9615cd351 | |||
| 52f6be3db0 | |||
| 34536e6584 | |||
| 7d51ca1f12 | |||
| ff31c54e7b | |||
| 944de7b373 | |||
| ab4f8c593d | |||
| 977fd12721 | |||
| e4a3d4c50b | |||
| 29f82945a6 | |||
| 87a4a88417 | |||
| dcccc4db3a | |||
| 36e5df38ee | |||
| 7571e35a70 | |||
| 995fd8d0a6 | |||
| b7b48006af | |||
| ea202812cd | |||
| 79f224f481 | |||
| 80d2651370 | |||
| 7071f50d49 | |||
| 13a4bf25b3 | |||
| f6a12f2e92 | |||
| 5c65bac076 | |||
| 489789da0a | |||
| d025da6daf | |||
| 5a7ed3ec7c | |||
| 1558996891 |
@ -1,7 +1,7 @@
|
|||||||
import UIKit
|
import UIKit
|
||||||
import Flutter
|
import Flutter
|
||||||
|
|
||||||
@UIApplicationMain
|
@main
|
||||||
@objc class AppDelegate: FlutterAppDelegate {
|
@objc class AppDelegate: FlutterAppDelegate {
|
||||||
override func application(
|
override func application(
|
||||||
_ application: UIApplication,
|
_ application: UIApplication,
|
||||||
|
|||||||
@ -11,7 +11,7 @@ import 'package:syncrow_app/features/app_layout/view/widgets/app_bar_home_dropdo
|
|||||||
import 'package:syncrow_app/features/auth/model/user_model.dart';
|
import 'package:syncrow_app/features/auth/model/user_model.dart';
|
||||||
import 'package:syncrow_app/features/dashboard/view/dashboard_view.dart';
|
import 'package:syncrow_app/features/dashboard/view/dashboard_view.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/room_model.dart';
|
import 'package:syncrow_app/features/devices/model/subspace_model.dart';
|
||||||
import 'package:syncrow_app/features/devices/view/widgets/devices_view_body.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/devices_view_body.dart';
|
||||||
import 'package:syncrow_app/features/menu/view/menu_view.dart';
|
import 'package:syncrow_app/features/menu/view/menu_view.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';
|
||||||
@ -55,7 +55,8 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
|
|
||||||
Future fetchUserInfo() async {
|
Future fetchUserInfo() async {
|
||||||
try {
|
try {
|
||||||
var uuid = await const FlutterSecureStorage().read(key: UserModel.userUuidKey);
|
var uuid =
|
||||||
|
await const FlutterSecureStorage().read(key: UserModel.userUuidKey);
|
||||||
user = await ProfileApi().fetchUserInfo(uuid);
|
user = await ProfileApi().fetchUserInfo(uuid);
|
||||||
emit(HomeUserInfoLoaded(user!)); // Emit state after fetching user info
|
emit(HomeUserInfoLoaded(user!)); // Emit state after fetching user info
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -76,9 +77,12 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
selectedSpace = null;
|
selectedSpace = null;
|
||||||
selectedRoom = null;
|
selectedRoom = null;
|
||||||
pageIndex = 0;
|
pageIndex = 0;
|
||||||
OneSignal.User.pushSubscription.removeObserver((stateChanges) => oneSignalSubscriptionObserver);
|
OneSignal.User.pushSubscription
|
||||||
OneSignal.Notifications.removePermissionObserver((permission) => oneSignalPermissionObserver);
|
.removeObserver((stateChanges) => oneSignalSubscriptionObserver);
|
||||||
OneSignal.Notifications.removeClickListener((event) => oneSignalClickListenerObserver);
|
OneSignal.Notifications.removePermissionObserver(
|
||||||
|
(permission) => oneSignalPermissionObserver);
|
||||||
|
OneSignal.Notifications.removeClickListener(
|
||||||
|
(event) => oneSignalClickListenerObserver);
|
||||||
return super.close();
|
return super.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,7 +92,7 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
|
|
||||||
SpaceModel? selectedSpace;
|
SpaceModel? selectedSpace;
|
||||||
|
|
||||||
RoomModel? selectedRoom;
|
SubSpaceModel? selectedRoom;
|
||||||
|
|
||||||
PageController devicesPageController = PageController();
|
PageController devicesPageController = PageController();
|
||||||
|
|
||||||
@ -120,7 +124,9 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var userUuid = await const FlutterSecureStorage().read(key: UserModel.userUuidKey) ?? '';
|
var userUuid =
|
||||||
|
await const FlutterSecureStorage().read(key: UserModel.userUuidKey) ??
|
||||||
|
'';
|
||||||
if (userUuid.isNotEmpty) {
|
if (userUuid.isNotEmpty) {
|
||||||
await OneSignal.login(userUuid);
|
await OneSignal.login(userUuid);
|
||||||
}
|
}
|
||||||
@ -128,21 +134,24 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
await OneSignal.User.pushSubscription.optIn();
|
await OneSignal.User.pushSubscription.optIn();
|
||||||
|
|
||||||
//this function will be called once a user is subscribed
|
//this function will be called once a user is subscribed
|
||||||
oneSignalSubscriptionObserver = OneSignal.User.pushSubscription.addObserver((state) async {
|
oneSignalSubscriptionObserver =
|
||||||
|
OneSignal.User.pushSubscription.addObserver((state) async {
|
||||||
if (state.current.optedIn) {
|
if (state.current.optedIn) {
|
||||||
await _sendSubscriptionId();
|
await _sendSubscriptionId();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Send the player id when a user allows notifications
|
// Send the player id when a user allows notifications
|
||||||
oneSignalPermissionObserver = OneSignal.Notifications.addPermissionObserver((state) async {
|
oneSignalPermissionObserver =
|
||||||
|
OneSignal.Notifications.addPermissionObserver((state) async {
|
||||||
await _sendSubscriptionId();
|
await _sendSubscriptionId();
|
||||||
});
|
});
|
||||||
|
|
||||||
//check if the player id is sent, if not send it again
|
//check if the player id is sent, if not send it again
|
||||||
await _sendSubscriptionId();
|
await _sendSubscriptionId();
|
||||||
|
|
||||||
oneSignalClickListenerObserver = OneSignal.Notifications.addClickListener((event) async {
|
oneSignalClickListenerObserver =
|
||||||
|
OneSignal.Notifications.addClickListener((event) async {
|
||||||
//Once the user clicks on the notification
|
//Once the user clicks on the notification
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@ -173,7 +182,7 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
if (index == 0) {
|
if (index == 0) {
|
||||||
unselectRoom();
|
unselectRoom();
|
||||||
} else {
|
} else {
|
||||||
selectedRoom = selectedSpace!.rooms![index - 1];
|
selectedRoom = selectedSpace!.subspaces[index - 1];
|
||||||
emitSafe(RoomSelected(selectedRoom!));
|
emitSafe(RoomSelected(selectedRoom!));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -188,7 +197,7 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
if (index <= 0) {
|
if (index <= 0) {
|
||||||
unselectRoom();
|
unselectRoom();
|
||||||
} else {
|
} else {
|
||||||
selectedRoom = selectedSpace!.rooms![index - 1];
|
selectedRoom = selectedSpace!.subspaces[index - 1];
|
||||||
emitSafe(RoomSelected(selectedRoom!));
|
emitSafe(RoomSelected(selectedRoom!));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -211,9 +220,10 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////// API ////////////////////////////////////////
|
//////////////////////////////////////// API ////////////////////////////////////////
|
||||||
generateInvitation(String unitId) async {
|
generateInvitation(SpaceModel unit) async {
|
||||||
try {
|
try {
|
||||||
final invitationCode = await SpacesAPI.generateInvitationCode(unitId);
|
final invitationCode =
|
||||||
|
await SpacesAPI.generateInvitationCode(unit.id, unit.community.uuid);
|
||||||
if (invitationCode.isNotEmpty) {
|
if (invitationCode.isNotEmpty) {
|
||||||
Share.share('The invitation code is $invitationCode');
|
Share.share('The invitation code is $invitationCode');
|
||||||
CustomSnackBar.displaySnackBar(
|
CustomSnackBar.displaySnackBar(
|
||||||
@ -229,10 +239,12 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
|
|
||||||
Future<bool> joinAUnit(String code) async {
|
Future<bool> joinAUnit(String code) async {
|
||||||
try {
|
try {
|
||||||
var uuid = await const FlutterSecureStorage().read(key: UserModel.userUuidKey) ?? '';
|
var userUuid =
|
||||||
Map<String, String> body = {'userUuid': uuid, 'inviteCode': code};
|
await const FlutterSecureStorage().read(key: UserModel.userUuidKey) ??
|
||||||
|
'';
|
||||||
|
Map<String, String> body = {'inviteCode': code};
|
||||||
|
|
||||||
final success = await SpacesAPI.joinUnit(body);
|
final success = await SpacesAPI.joinUnit(userUuid, body);
|
||||||
if (success) {
|
if (success) {
|
||||||
await fetchUnitsByUserId();
|
await fetchUnitsByUserId();
|
||||||
CustomSnackBar.displaySnackBar('Done successfully');
|
CustomSnackBar.displaySnackBar('Done successfully');
|
||||||
@ -247,7 +259,7 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
fetchUnitsByUserId() async {
|
fetchUnitsByUserId() async {
|
||||||
emitSafe(GetSpacesLoading());
|
emitSafe(GetSpacesLoading());
|
||||||
try {
|
try {
|
||||||
spaces = await SpacesAPI.getUnitsByUserId();
|
spaces = await SpacesAPI.getSpacesByUserId();
|
||||||
} catch (failure) {
|
} catch (failure) {
|
||||||
emitSafe(GetSpacesError("No units found"));
|
emitSafe(GetSpacesError("No units found"));
|
||||||
return;
|
return;
|
||||||
@ -265,13 +277,14 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
fetchRoomsByUnitId(SpaceModel space) async {
|
fetchRoomsByUnitId(SpaceModel space) async {
|
||||||
emitSafe(GetSpaceRoomsLoading());
|
emitSafe(GetSpaceRoomsLoading());
|
||||||
try {
|
try {
|
||||||
space.rooms = await SpacesAPI.getRoomsBySpaceId(space.id!);
|
space.subspaces =
|
||||||
|
await SpacesAPI.getSubSpaceBySpaceId(space.community.uuid, space.id);
|
||||||
} catch (failure) {
|
} catch (failure) {
|
||||||
emitSafe(GetSpaceRoomsError(failure.toString()));
|
emitSafe(GetSpaceRoomsError(failure.toString()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (space.rooms != null && space.rooms!.isNotEmpty) {
|
if (space.subspaces != null && space.subspaces!.isNotEmpty) {
|
||||||
emitSafe(GetSpaceRoomsSuccess(space.rooms!));
|
emitSafe(GetSpaceRoomsSuccess(space.subspaces!));
|
||||||
} else {
|
} else {
|
||||||
emitSafe(GetSpaceRoomsError("No rooms found"));
|
emitSafe(GetSpaceRoomsError("No rooms found"));
|
||||||
}
|
}
|
||||||
@ -347,7 +360,8 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
size: 32,
|
size: 32,
|
||||||
),
|
),
|
||||||
style: ButtonStyle(
|
style: ButtonStyle(
|
||||||
foregroundColor: WidgetStateProperty.all(ColorsManager.textPrimaryColor),
|
foregroundColor:
|
||||||
|
WidgetStateProperty.all(ColorsManager.textPrimaryColor),
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.pushNamed(
|
Navigator.pushNamed(
|
||||||
@ -368,7 +382,8 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
NavigationService.navigatorKey.currentContext!
|
NavigationService.navigatorKey.currentContext!
|
||||||
.read<SmartSceneSelectBloc>()
|
.read<SmartSceneSelectBloc>()
|
||||||
.add(const SmartSceneClearEvent());
|
.add(const SmartSceneClearEvent());
|
||||||
BlocProvider.of<EffectPeriodBloc>(NavigationService.navigatorKey.currentState!.context)
|
BlocProvider.of<EffectPeriodBloc>(
|
||||||
|
NavigationService.navigatorKey.currentState!.context)
|
||||||
.add(ResetEffectivePeriod());
|
.add(ResetEffectivePeriod());
|
||||||
NavigationService.navigatorKey.currentContext!
|
NavigationService.navigatorKey.currentContext!
|
||||||
.read<CreateSceneBloc>()
|
.read<CreateSceneBloc>()
|
||||||
@ -381,7 +396,8 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
size: 28,
|
size: 28,
|
||||||
),
|
),
|
||||||
style: ButtonStyle(
|
style: ButtonStyle(
|
||||||
foregroundColor: WidgetStateProperty.all(ColorsManager.textPrimaryColor),
|
foregroundColor:
|
||||||
|
WidgetStateProperty.all(ColorsManager.textPrimaryColor),
|
||||||
),
|
),
|
||||||
onPressed: () {},
|
onPressed: () {},
|
||||||
),
|
),
|
||||||
@ -414,7 +430,8 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static var bottomNavItems = [
|
static var bottomNavItems = [
|
||||||
defaultBottomNavBarItem(icon: Assets.assetsIconsDashboard, label: 'Dashboard'),
|
defaultBottomNavBarItem(
|
||||||
|
icon: Assets.assetsIconsDashboard, label: 'Dashboard'),
|
||||||
// defaultBottomNavBarItem(icon: Assets.assetsIconslayout, label: 'Layout'),
|
// defaultBottomNavBarItem(icon: Assets.assetsIconslayout, label: 'Layout'),
|
||||||
defaultBottomNavBarItem(icon: Assets.assetsIconsDevices, label: 'Devices'),
|
defaultBottomNavBarItem(icon: Assets.assetsIconsDevices, label: 'Devices'),
|
||||||
defaultBottomNavBarItem(icon: Assets.assetsIconsRoutines, label: 'Routine'),
|
defaultBottomNavBarItem(icon: Assets.assetsIconsRoutines, label: 'Routine'),
|
||||||
@ -440,7 +457,8 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
|
|
||||||
void updateDevice(String deviceId) async {
|
void updateDevice(String deviceId) async {
|
||||||
try {
|
try {
|
||||||
final response = await DevicesAPI.firmwareDevice(deviceId: deviceId, firmwareVersion: '0');
|
final response = await DevicesAPI.firmwareDevice(
|
||||||
|
deviceId: deviceId, firmwareVersion: '0');
|
||||||
if (response['success'] ?? false) {
|
if (response['success'] ?? false) {
|
||||||
CustomSnackBar.displaySnackBar('No updates available');
|
CustomSnackBar.displaySnackBar('No updates available');
|
||||||
}
|
}
|
||||||
@ -448,7 +466,8 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BottomNavigationBarItem defaultBottomNavBarItem({required String icon, required String label}) {
|
BottomNavigationBarItem defaultBottomNavBarItem(
|
||||||
|
{required String icon, required String label}) {
|
||||||
return BottomNavigationBarItem(
|
return BottomNavigationBarItem(
|
||||||
icon: SvgPicture.asset(icon),
|
icon: SvgPicture.asset(icon),
|
||||||
activeIcon: SvgPicture.asset(
|
activeIcon: SvgPicture.asset(
|
||||||
|
|||||||
@ -33,7 +33,7 @@ class GetSpacesError extends HomeError {
|
|||||||
class GetSpaceRoomsLoading extends HomeLoading {}
|
class GetSpaceRoomsLoading extends HomeLoading {}
|
||||||
|
|
||||||
class GetSpaceRoomsSuccess extends HomeSuccess {
|
class GetSpaceRoomsSuccess extends HomeSuccess {
|
||||||
final List<RoomModel> rooms;
|
final List<SubSpaceModel> rooms;
|
||||||
|
|
||||||
GetSpaceRoomsSuccess(this.rooms);
|
GetSpaceRoomsSuccess(this.rooms);
|
||||||
}
|
}
|
||||||
@ -50,7 +50,7 @@ class SpaceSelected extends HomeState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class RoomSelected extends HomeState {
|
class RoomSelected extends HomeState {
|
||||||
final RoomModel room;
|
final SubSpaceModel room;
|
||||||
|
|
||||||
RoomSelected(this.room);
|
RoomSelected(this.room);
|
||||||
}
|
}
|
||||||
|
|||||||
27
lib/features/app_layout/model/community_model.dart
Normal file
27
lib/features/app_layout/model/community_model.dart
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
class Community {
|
||||||
|
final String uuid;
|
||||||
|
final String name;
|
||||||
|
final String description;
|
||||||
|
|
||||||
|
Community({
|
||||||
|
required this.uuid,
|
||||||
|
required this.name,
|
||||||
|
this.description = '',
|
||||||
|
});
|
||||||
|
|
||||||
|
factory Community.fromJson(Map<String, dynamic> json) {
|
||||||
|
return Community(
|
||||||
|
uuid: json['uuid'] ?? '',
|
||||||
|
name: json['name'] ?? 'Unnamed Community',
|
||||||
|
description: json['description'] ?? '',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return {
|
||||||
|
'uuid': uuid,
|
||||||
|
'name': name,
|
||||||
|
'description': description,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,37 +1,53 @@
|
|||||||
import 'package:syncrow_app/features/devices/model/room_model.dart';
|
import 'package:syncrow_app/features/app_layout/model/community_model.dart';
|
||||||
import 'package:syncrow_app/utils/resource_manager/constants.dart';
|
import 'package:syncrow_app/features/devices/model/subspace_model.dart';
|
||||||
|
|
||||||
class SpaceModel {
|
class SpaceModel {
|
||||||
final String? id;
|
final String id;
|
||||||
final String? name;
|
final String name;
|
||||||
final SpaceType type;
|
final Community community;
|
||||||
late List<RoomModel>? rooms;
|
late List<SubSpaceModel> subspaces;
|
||||||
|
|
||||||
SpaceModel({
|
SpaceModel({
|
||||||
required this.type,
|
|
||||||
required this.id,
|
required this.id,
|
||||||
required this.name,
|
required this.name,
|
||||||
required this.rooms,
|
required this.community,
|
||||||
|
this.subspaces = const [], // Default to an empty list
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/// Converts the instance into JSON format.
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
return {
|
return {
|
||||||
'id': id,
|
'id': id,
|
||||||
'name': name,
|
'spaceName': name,
|
||||||
'rooms': rooms,
|
'community': community.toJson(),
|
||||||
|
'subspaces': subspaces.map((room) => room.toJson()).toList(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Factory constructor to create an instance from JSON.
|
||||||
factory SpaceModel.fromJson(Map<String, dynamic> json) {
|
factory SpaceModel.fromJson(Map<String, dynamic> json) {
|
||||||
|
// Extract and log each part of space data
|
||||||
|
final id = json['uuid'] ?? '';
|
||||||
|
final name = json['spaceName'] ?? 'Unnamed Space';
|
||||||
|
final communityJson = json['community'] ?? {};
|
||||||
|
|
||||||
return SpaceModel(
|
return SpaceModel(
|
||||||
id: json['uuid'],
|
id: id,
|
||||||
name: json['name'],
|
name: name,
|
||||||
type: spaceTypesMap[json['type']]!,
|
community: Community.fromJson(
|
||||||
rooms: [],
|
communityJson), // Ensure Community is created correctly
|
||||||
|
subspaces: (json['subspaces'] as List<dynamic>?)
|
||||||
|
?.map((item) => SubSpaceModel.fromJson(item))
|
||||||
|
.toList() ??
|
||||||
|
[],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Helper method to parse a list of SpaceModel from JSON.
|
||||||
static List<SpaceModel> fromJsonList(List<dynamic> jsonList) {
|
static List<SpaceModel> fromJsonList(List<dynamic> jsonList) {
|
||||||
return jsonList.map((item) => SpaceModel.fromJson(item)).toList();
|
return jsonList.map((item) {
|
||||||
|
final spaceData = item['space']; // Extract the `space` object
|
||||||
|
return SpaceModel.fromJson(spaceData); // Pass to SpaceModel.fromJson
|
||||||
|
}).toList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -284,11 +284,13 @@ class AuthCubit extends Cubit<AuthState> {
|
|||||||
await login();
|
await login();
|
||||||
}
|
}
|
||||||
emit(AuthOtpSuccess());
|
emit(AuthOtpSuccess());
|
||||||
} else {
|
|
||||||
emit(AuthLoginError(message: 'Something went wrong'));
|
|
||||||
}
|
}
|
||||||
|
// else {
|
||||||
|
// emit(AuthLoginError(message: 'Something went wrong'));
|
||||||
|
// }
|
||||||
} catch (failure) {
|
} catch (failure) {
|
||||||
emit(AuthLoginError(message: 'Something went wrong'));
|
emit(AuthErrorStatusWithoutMsg());
|
||||||
|
//emit(AuthLoginError(message: 'Something went wrong'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,12 +25,14 @@ class DeviceManagerBloc extends Bloc<DeviceManagerEvent, DeviceManagerState> {
|
|||||||
|
|
||||||
static List<DevicesCategoryModel>? allCategories;
|
static List<DevicesCategoryModel>? allCategories;
|
||||||
|
|
||||||
Future<void> _onFetchAllDevices(FetchAllDevices event, Emitter<DeviceManagerState> emit) async {
|
Future<void> _onFetchAllDevices(
|
||||||
|
FetchAllDevices event, Emitter<DeviceManagerState> emit) async {
|
||||||
emit(state.copyWith(loading: true));
|
emit(state.copyWith(loading: true));
|
||||||
try {
|
try {
|
||||||
final allDevices = await HomeManagementAPI.fetchDevicesByUnitId();
|
final allDevices = await HomeManagementAPI.fetchDevicesByUnitId();
|
||||||
emit(state.copyWith(devices: allDevices, loading: false));
|
emit(state.copyWith(devices: allDevices, loading: false));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
emit(state.copyWith(error: e.toString(), loading: false));
|
emit(state.copyWith(error: e.toString(), loading: false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -39,21 +41,27 @@ class DeviceManagerBloc extends Bloc<DeviceManagerEvent, DeviceManagerState> {
|
|||||||
FetchDevicesByRoomId event, Emitter<DeviceManagerState> emit) async {
|
FetchDevicesByRoomId event, Emitter<DeviceManagerState> emit) async {
|
||||||
emit(state.copyWith(loading: true));
|
emit(state.copyWith(loading: true));
|
||||||
try {
|
try {
|
||||||
final devices = await DevicesAPI.getDevicesByRoomId(event.roomId);
|
final devices = await DevicesAPI.getDevicesByRoomId(
|
||||||
|
communityUuid: event.unit.community.uuid,
|
||||||
|
spaceUuid: event.unit.id,
|
||||||
|
roomId: event.roomId,
|
||||||
|
);
|
||||||
emit(state.copyWith(devices: devices, loading: false));
|
emit(state.copyWith(devices: devices, loading: false));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(state.copyWith(error: e.toString(), loading: false));
|
emit(state.copyWith(error: e.toString(), loading: false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onSelectCategory(SelectCategory event, Emitter<DeviceManagerState> emit) {
|
void _onSelectCategory(
|
||||||
|
SelectCategory event, Emitter<DeviceManagerState> emit) {
|
||||||
for (var i = 0; i < allCategories!.length; i++) {
|
for (var i = 0; i < allCategories!.length; i++) {
|
||||||
allCategories![i].isSelected = i == event.index;
|
allCategories![i].isSelected = i == event.index;
|
||||||
}
|
}
|
||||||
emit(state.copyWith(categoryChanged: true));
|
emit(state.copyWith(categoryChanged: true));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onUnselectAllCategories(UnselectAllCategories event, Emitter<DeviceManagerState> emit) {
|
void _onUnselectAllCategories(
|
||||||
|
UnselectAllCategories event, Emitter<DeviceManagerState> emit) {
|
||||||
for (var category in allCategories!) {
|
for (var category in allCategories!) {
|
||||||
category.isSelected = false;
|
category.isSelected = false;
|
||||||
}
|
}
|
||||||
@ -97,7 +105,8 @@ class DeviceManagerBloc extends Bloc<DeviceManagerEvent, DeviceManagerState> {
|
|||||||
_updateDevicesStatus(category, emit);
|
_updateDevicesStatus(category, emit);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onTurnOnOffDevice(TurnOnOffDevice event, Emitter<DeviceManagerState> emit) {
|
void _onTurnOnOffDevice(
|
||||||
|
TurnOnOffDevice event, Emitter<DeviceManagerState> emit) {
|
||||||
var device = event.device;
|
var device = event.device;
|
||||||
device.isOnline = !device.isOnline!;
|
device.isOnline = !device.isOnline!;
|
||||||
DevicesCategoryModel category = allCategories!.firstWhere((category) {
|
DevicesCategoryModel category = allCategories!.firstWhere((category) {
|
||||||
@ -120,7 +129,8 @@ class DeviceManagerBloc extends Bloc<DeviceManagerEvent, DeviceManagerState> {
|
|||||||
emit(state.copyWith(categoryChanged: true)); // Set category changed state
|
emit(state.copyWith(categoryChanged: true)); // Set category changed state
|
||||||
}
|
}
|
||||||
|
|
||||||
void _updateDevicesStatus(DevicesCategoryModel category, Emitter<DeviceManagerState> emit) {
|
void _updateDevicesStatus(
|
||||||
|
DevicesCategoryModel category, Emitter<DeviceManagerState> emit) {
|
||||||
if (category.devices != null && category.devices!.isNotEmpty) {
|
if (category.devices != null && category.devices!.isNotEmpty) {
|
||||||
bool? tempStatus = category.devices![0].isOnline;
|
bool? tempStatus = category.devices![0].isOnline;
|
||||||
for (var device in category.devices!) {
|
for (var device in category.devices!) {
|
||||||
@ -140,7 +150,8 @@ class DeviceManagerBloc extends Bloc<DeviceManagerEvent, DeviceManagerState> {
|
|||||||
try {
|
try {
|
||||||
final deviceFunctions = await DevicesAPI.deviceFunctions(event.deviceId);
|
final deviceFunctions = await DevicesAPI.deviceFunctions(event.deviceId);
|
||||||
|
|
||||||
emit(state.copyWith(functionsLoading: false, deviceFunctions: deviceFunctions));
|
emit(state.copyWith(
|
||||||
|
functionsLoading: false, deviceFunctions: deviceFunctions));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(state.copyWith(functionsLoading: false, error: e.toString()));
|
emit(state.copyWith(functionsLoading: false, error: e.toString()));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:syncrow_app/features/app_layout/model/space_model.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/device_category_model.dart';
|
import 'package:syncrow_app/features/devices/model/device_category_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';
|
||||||
@ -15,8 +16,9 @@ class FetchAllDevices extends DeviceManagerEvent {}
|
|||||||
|
|
||||||
class FetchDevicesByRoomId extends DeviceManagerEvent {
|
class FetchDevicesByRoomId extends DeviceManagerEvent {
|
||||||
final String roomId;
|
final String roomId;
|
||||||
|
final SpaceModel unit;
|
||||||
|
|
||||||
const FetchDevicesByRoomId(this.roomId);
|
const FetchDevicesByRoomId(this.roomId, this.unit);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [roomId];
|
List<Object> get props => [roomId];
|
||||||
|
|||||||
@ -23,14 +23,22 @@ import 'package:syncrow_app/utils/resource_manager/constants.dart';
|
|||||||
part 'devices_state.dart';
|
part 'devices_state.dart';
|
||||||
|
|
||||||
class DevicesCubit extends Cubit<DevicesState> {
|
class DevicesCubit extends Cubit<DevicesState> {
|
||||||
|
Future<void> _initializeDevices(SpaceModel selectedSpace) async {
|
||||||
|
// Fetch devices for each room in the selected space
|
||||||
|
for (var room in selectedSpace.subspaces ?? []) {
|
||||||
|
await fetchDevicesByRoomId(selectedSpace, room.id!);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch groups based on the selected space ID
|
||||||
|
await fetchGroups(selectedSpace.id ?? '');
|
||||||
|
}
|
||||||
|
|
||||||
DevicesCubit._() : super(DevicesInitial()) {
|
DevicesCubit._() : super(DevicesInitial()) {
|
||||||
if (HomeCubit.getInstance().selectedSpace != null &&
|
final selectedSpace = HomeCubit.getInstance().selectedSpace;
|
||||||
HomeCubit.getInstance().spaces!.isNotEmpty) {
|
final spaces = HomeCubit.getInstance().spaces;
|
||||||
// fetchGroups(HomeCubit.getInstance().selectedSpace!.id!);
|
|
||||||
for (var room in HomeCubit.getInstance().selectedSpace!.rooms!) {
|
if (selectedSpace != null && spaces != null && spaces.isNotEmpty) {
|
||||||
fetchDevicesByRoomId(room.id!);
|
_initializeDevices(selectedSpace);
|
||||||
}
|
|
||||||
fetchGroups(HomeCubit.getInstance().selectedSpace?.id ?? '');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,10 +95,10 @@ class DevicesCubit extends Cubit<DevicesState> {
|
|||||||
return const DoorsListView();
|
return const DoorsListView();
|
||||||
case DeviceType.Curtain:
|
case DeviceType.Curtain:
|
||||||
return const CurtainListView();
|
return const CurtainListView();
|
||||||
// case DeviceType.ThreeGang:
|
// case DeviceType.ThreeGang:
|
||||||
// return const ThreeGangSwitchesView();
|
// return const ThreeGangSwitchesView();
|
||||||
// case DeviceType.Gateway:
|
// case DeviceType.Gateway:
|
||||||
// return const GateWayView();
|
// return const GateWayView();
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -104,8 +112,8 @@ class DevicesCubit extends Cubit<DevicesState> {
|
|||||||
List<DeviceModel> get allDevices {
|
List<DeviceModel> get allDevices {
|
||||||
List<DeviceModel> devices = [];
|
List<DeviceModel> devices = [];
|
||||||
if (HomeCubit.getInstance().selectedSpace != null &&
|
if (HomeCubit.getInstance().selectedSpace != null &&
|
||||||
HomeCubit.getInstance().selectedSpace!.rooms != null) {
|
HomeCubit.getInstance().selectedSpace!.subspaces != null) {
|
||||||
for (var room in HomeCubit.getInstance().selectedSpace!.rooms!) {
|
for (var room in HomeCubit.getInstance().selectedSpace!.subspaces!) {
|
||||||
if (room.devices != null) {
|
if (room.devices != null) {
|
||||||
devices.addAll(room.devices!);
|
devices.addAll(room.devices!);
|
||||||
}
|
}
|
||||||
@ -275,7 +283,7 @@ class DevicesCubit extends Cubit<DevicesState> {
|
|||||||
deviceId,
|
deviceId,
|
||||||
HomeCubit.getInstance()
|
HomeCubit.getInstance()
|
||||||
.selectedSpace!
|
.selectedSpace!
|
||||||
.rooms!
|
.subspaces!
|
||||||
.indexOf(HomeCubit.getInstance().selectedRoom!),
|
.indexOf(HomeCubit.getInstance().selectedRoom!),
|
||||||
code: control.code);
|
code: control.code);
|
||||||
});
|
});
|
||||||
@ -303,20 +311,26 @@ class DevicesCubit extends Cubit<DevicesState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchDevicesByRoomId(String? roomId) async {
|
fetchDevicesByRoomId(SpaceModel? unit, String? roomId) async {
|
||||||
if (roomId == null) return;
|
if (roomId == null) return;
|
||||||
|
|
||||||
emitSafe(GetDevicesLoading());
|
emitSafe(GetDevicesLoading());
|
||||||
int roomIndex =
|
int roomIndex = HomeCubit.getInstance()
|
||||||
HomeCubit.getInstance().selectedSpace!.rooms!.indexWhere((element) => element.id == roomId);
|
.selectedSpace!
|
||||||
|
.subspaces!
|
||||||
|
.indexWhere((element) => element.id == roomId);
|
||||||
try {
|
try {
|
||||||
HomeCubit.getInstance().selectedSpace!.rooms![roomIndex].devices =
|
HomeCubit.getInstance().selectedSpace!.subspaces![roomIndex].devices =
|
||||||
await DevicesAPI.getDevicesByRoomId(roomId);
|
await DevicesAPI.getDevicesByRoomId(
|
||||||
|
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!.rooms![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
|
||||||
@ -333,7 +347,7 @@ class DevicesCubit extends Cubit<DevicesState> {
|
|||||||
emitSafe(GetDeviceStatusLoading(code: code));
|
emitSafe(GetDeviceStatusLoading(code: code));
|
||||||
int deviceIndex = HomeCubit.getInstance()
|
int deviceIndex = HomeCubit.getInstance()
|
||||||
.selectedSpace!
|
.selectedSpace!
|
||||||
.rooms![roomIndex]
|
.subspaces![roomIndex]
|
||||||
.devices!
|
.devices!
|
||||||
.indexWhere((element) => element.uuid == deviceUuid);
|
.indexWhere((element) => element.uuid == deviceUuid);
|
||||||
List<StatusModel> statuses = [];
|
List<StatusModel> statuses = [];
|
||||||
@ -346,8 +360,11 @@ class DevicesCubit extends Cubit<DevicesState> {
|
|||||||
emitSafe(GetDeviceStatusError(e.toString()));
|
emitSafe(GetDeviceStatusError(e.toString()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
HomeCubit.getInstance().selectedSpace!.rooms![roomIndex].devices![deviceIndex].status =
|
HomeCubit.getInstance()
|
||||||
statuses;
|
.selectedSpace!
|
||||||
|
.subspaces![roomIndex]
|
||||||
|
.devices![deviceIndex]
|
||||||
|
.status = statuses;
|
||||||
emitSafe(GetDeviceStatusSuccess(code: code));
|
emitSafe(GetDeviceStatusSuccess(code: code));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -396,8 +413,6 @@ class DevicesCubit extends Cubit<DevicesState> {
|
|||||||
// emitSafe(LightBrightnessChanged(value));
|
// emitSafe(LightBrightnessChanged(value));
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum LightMode {
|
enum LightMode {
|
||||||
|
|||||||
35
lib/features/devices/model/subspace_model.dart
Normal file
35
lib/features/devices/model/subspace_model.dart
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||||
|
|
||||||
|
class SubSpaceModel {
|
||||||
|
final String? id;
|
||||||
|
final String? name;
|
||||||
|
List<DeviceModel>? devices;
|
||||||
|
|
||||||
|
SubSpaceModel({
|
||||||
|
required this.id,
|
||||||
|
required this.name,
|
||||||
|
required this.devices,
|
||||||
|
});
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return {
|
||||||
|
'id': id,
|
||||||
|
'name': name,
|
||||||
|
'devices': devices?.map((device) => device.toJson()).toList(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
factory SubSpaceModel.fromJson(Map<String, dynamic> json) {
|
||||||
|
List<DeviceModel> devices = [];
|
||||||
|
if (json['devices'] != null) {
|
||||||
|
for (var device in json['devices']) {
|
||||||
|
devices.add(DeviceModel.fromJson(device));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return SubSpaceModel(
|
||||||
|
id: json['uuid'],
|
||||||
|
name: json['subspaceName'],
|
||||||
|
devices: devices,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -22,6 +22,8 @@ class ACsView extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
print("ACsView deviceModel UUID: ${deviceModel?.uuid}");
|
||||||
|
|
||||||
return BlocProvider(
|
return BlocProvider(
|
||||||
create: (context) => ACsBloc(acId: deviceModel?.uuid ?? '')
|
create: (context) => ACsBloc(acId: deviceModel?.uuid ?? '')
|
||||||
..add(AcsInitial(allAcs: deviceModel != null ? false : true)),
|
..add(AcsInitial(allAcs: deviceModel != null ? false : true)),
|
||||||
@ -66,12 +68,14 @@ class ACsView extends StatelessWidget {
|
|||||||
child: state is AcsLoadingState
|
child: state is AcsLoadingState
|
||||||
? const Center(
|
? const Center(
|
||||||
child: DefaultContainer(
|
child: DefaultContainer(
|
||||||
width: 50, height: 50, child: CircularProgressIndicator()),
|
width: 50,
|
||||||
|
height: 50,
|
||||||
|
child: CircularProgressIndicator()),
|
||||||
)
|
)
|
||||||
: RefreshIndicator(
|
: RefreshIndicator(
|
||||||
onRefresh: () async {
|
onRefresh: () async {
|
||||||
BlocProvider.of<ACsBloc>(context)
|
BlocProvider.of<ACsBloc>(context).add(AcsInitial(
|
||||||
.add(AcsInitial(allAcs: deviceModel != null ? false : true));
|
allAcs: deviceModel != null ? false : true));
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: const EdgeInsets.only(top: 40),
|
padding: const EdgeInsets.only(top: 40),
|
||||||
|
|||||||
@ -69,6 +69,7 @@ class DevicesViewBody extends StatelessWidget {
|
|||||||
|
|
||||||
Expanded(
|
Expanded(
|
||||||
child: PageView(
|
child: PageView(
|
||||||
|
|
||||||
controller: HomeCubit.getInstance().devicesPageController,
|
controller: HomeCubit.getInstance().devicesPageController,
|
||||||
onPageChanged: (index) {
|
onPageChanged: (index) {
|
||||||
HomeCubit.getInstance().devicesPageChanged(index);
|
HomeCubit.getInstance().devicesPageChanged(index);
|
||||||
@ -78,8 +79,8 @@ class DevicesViewBody extends StatelessWidget {
|
|||||||
groupsList: DevicesCubit.getInstance().allCategories ?? [],
|
groupsList: DevicesCubit.getInstance().allCategories ?? [],
|
||||||
),
|
),
|
||||||
if (HomeCubit.getInstance().selectedSpace != null)
|
if (HomeCubit.getInstance().selectedSpace != null)
|
||||||
if (HomeCubit.getInstance().selectedSpace!.rooms != null)
|
if (HomeCubit.getInstance().selectedSpace!.subspaces != null)
|
||||||
...HomeCubit.getInstance().selectedSpace!.rooms!.map((room) {
|
...HomeCubit.getInstance().selectedSpace!.subspaces!.map((room) {
|
||||||
return RoomPage(
|
return RoomPage(
|
||||||
room: room,
|
room: room,
|
||||||
);
|
);
|
||||||
@ -95,7 +96,7 @@ class DevicesViewBody extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
child: SmoothPageIndicator(
|
child: SmoothPageIndicator(
|
||||||
controller: HomeCubit.getInstance().devicesPageController,
|
controller: HomeCubit.getInstance().devicesPageController,
|
||||||
count: HomeCubit.getInstance().selectedSpace!.rooms!.length + 1,
|
count: HomeCubit.getInstance().selectedSpace!.subspaces!.length + 1,
|
||||||
effect: const WormEffect(
|
effect: const WormEffect(
|
||||||
paintStyle: PaintingStyle.stroke,
|
paintStyle: PaintingStyle.stroke,
|
||||||
dotHeight: 8,
|
dotHeight: 8,
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/model/subspace_model.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/room_model.dart';
|
import 'package:syncrow_app/features/devices/model/room_model.dart';
|
||||||
import 'package:syncrow_app/features/devices/view/widgets/room_page_switch.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/room_page_switch.dart';
|
||||||
@ -8,7 +9,7 @@ import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
|||||||
class RoomPage extends StatefulWidget {
|
class RoomPage extends StatefulWidget {
|
||||||
const RoomPage({super.key, required this.room});
|
const RoomPage({super.key, required this.room});
|
||||||
|
|
||||||
final RoomModel room;
|
final SubSpaceModel room;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_RoomPageState createState() => _RoomPageState();
|
_RoomPageState createState() => _RoomPageState();
|
||||||
|
|||||||
@ -87,6 +87,7 @@ class RoomPageSwitch extends StatelessWidget {
|
|||||||
///
|
///
|
||||||
/// The [device] parameter represents the device model.
|
/// The [device] parameter represents the device model.
|
||||||
void showDeviceInterface(DeviceModel device, BuildContext context) {
|
void showDeviceInterface(DeviceModel device, BuildContext context) {
|
||||||
|
|
||||||
switch (device.productType) {
|
switch (device.productType) {
|
||||||
case DeviceType.AC:
|
case DeviceType.AC:
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
|
|||||||
@ -39,14 +39,14 @@ class RoomsSlider extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (HomeCubit.getInstance().selectedSpace != null)
|
if (HomeCubit.getInstance().selectedSpace != null)
|
||||||
if (HomeCubit.getInstance().selectedSpace!.rooms != null)
|
if (HomeCubit.getInstance().selectedSpace!.subspaces != null)
|
||||||
...HomeCubit.getInstance().selectedSpace!.rooms!.map(
|
...HomeCubit.getInstance().selectedSpace!.subspaces!.map(
|
||||||
(room) => InkWell(
|
(room) => InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
HomeCubit.getInstance().roomSliderPageChanged(
|
HomeCubit.getInstance().roomSliderPageChanged(
|
||||||
HomeCubit.getInstance()
|
HomeCubit.getInstance()
|
||||||
.selectedSpace!
|
.selectedSpace!
|
||||||
.rooms!
|
.subspaces!
|
||||||
.indexOf(room));
|
.indexOf(room));
|
||||||
},
|
},
|
||||||
child: TitleMedium(
|
child: TitleMedium(
|
||||||
|
|||||||
@ -40,10 +40,13 @@ class SceneListview extends StatelessWidget {
|
|||||||
sceneName: scene.name,
|
sceneName: scene.name,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
context.read<SmartSceneSelectBloc>().add(const SmartSceneClearEvent());
|
context
|
||||||
|
.read<SmartSceneSelectBloc>()
|
||||||
|
.add(const SmartSceneClearEvent());
|
||||||
|
|
||||||
BlocProvider.of<CreateSceneBloc>(context)
|
BlocProvider.of<CreateSceneBloc>(context).add(
|
||||||
.add(FetchSceneTasksEvent(sceneId: scene.id, isAutomation: false));
|
FetchSceneTasksEvent(
|
||||||
|
sceneId: scene.id, isAutomation: false));
|
||||||
|
|
||||||
/// the state to set the scene type must be after the fetch
|
/// the state to set the scene type must be after the fetch
|
||||||
BlocProvider.of<CreateSceneBloc>(context)
|
BlocProvider.of<CreateSceneBloc>(context)
|
||||||
@ -56,14 +59,27 @@ class SceneListview extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
child: Image.memory(
|
child: scene.iconInBytes != null &&
|
||||||
height: 32,
|
scene.iconInBytes.isNotEmpty
|
||||||
width: 32,
|
? Image.memory(
|
||||||
scene.iconInBytes,
|
scene.iconInBytes,
|
||||||
fit: BoxFit.fill,
|
height: 32,
|
||||||
errorBuilder: (context, error, stackTrace) => Image.asset(
|
width: 32,
|
||||||
height: 32, width: 32, fit: BoxFit.fill, Assets.assetsIconsLogo),
|
fit: BoxFit.fill,
|
||||||
),
|
errorBuilder: (context, error, stackTrace) =>
|
||||||
|
Image.asset(
|
||||||
|
Assets.assetsIconsLogo,
|
||||||
|
height: 32,
|
||||||
|
width: 32,
|
||||||
|
fit: BoxFit.fill,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: Image.asset(
|
||||||
|
Assets.assetsIconsLogo,
|
||||||
|
height: 32,
|
||||||
|
width: 32,
|
||||||
|
fit: BoxFit.fill,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: BodyMedium(
|
child: BodyMedium(
|
||||||
|
|||||||
@ -61,7 +61,9 @@ class CreateUnitBloc extends Bloc<CreateUnitEvent, CreateUnitState> {
|
|||||||
var storage = const FlutterSecureStorage();
|
var storage = const FlutterSecureStorage();
|
||||||
var userId = await storage.read(key: UserModel.userUuidKey) ?? '';
|
var userId = await storage.read(key: UserModel.userUuidKey) ?? '';
|
||||||
|
|
||||||
Map<String, String> communityBody = {'communityName': event.communityName};
|
Map<String, String> communityBody = {
|
||||||
|
'communityName': event.communityName
|
||||||
|
};
|
||||||
final response = await HomeCreation.createCommunity(communityBody);
|
final response = await HomeCreation.createCommunity(communityBody);
|
||||||
if (response['data']['uuid'] != '') {
|
if (response['data']['uuid'] != '') {
|
||||||
// final result =
|
// final result =
|
||||||
@ -75,15 +77,22 @@ class CreateUnitBloc extends Bloc<CreateUnitEvent, CreateUnitState> {
|
|||||||
|
|
||||||
if (buildingId.isNotEmpty) {
|
if (buildingId.isNotEmpty) {
|
||||||
final floorId = await _createFloor(
|
final floorId = await _createFloor(
|
||||||
floorName: event.floorName, buildingId: buildingId, userId: userId);
|
floorName: event.floorName,
|
||||||
|
buildingId: buildingId,
|
||||||
|
userId: userId);
|
||||||
|
|
||||||
if (floorId.isNotEmpty) {
|
if (floorId.isNotEmpty) {
|
||||||
final unitId =
|
final unitId = await _createUnit(
|
||||||
await _createUnit(unitName: event.unitName, floorId: floorId, userId: userId);
|
unitName: event.unitName, floorId: floorId, userId: userId);
|
||||||
|
|
||||||
if (unitId.isNotEmpty && rooms.isNotEmpty) {
|
if (unitId.isNotEmpty && rooms.isNotEmpty) {
|
||||||
rooms.forEach((room) async {
|
rooms.forEach((room) async {
|
||||||
await _createNewRoom(roomName: room, unitId: unitId, userId: userId);
|
await _createNewRoom(
|
||||||
|
roomName: room,
|
||||||
|
unitId: unitId,
|
||||||
|
userId: userId,
|
||||||
|
communityId: response['data']['uuid'],
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -99,7 +108,8 @@ class CreateUnitBloc extends Bloc<CreateUnitEvent, CreateUnitState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> _assignToCommunity({required String communityId, required String userId}) async {
|
Future<bool> _assignToCommunity(
|
||||||
|
{required String communityId, required String userId}) async {
|
||||||
try {
|
try {
|
||||||
Map<String, String> body = {
|
Map<String, String> body = {
|
||||||
'communityUuid': communityId,
|
'communityUuid': communityId,
|
||||||
@ -114,9 +124,14 @@ Future<bool> _assignToCommunity({required String communityId, required String us
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<String> _createBuilding(
|
Future<String> _createBuilding(
|
||||||
{required String buildingName, required String communityId, required String userId}) async {
|
{required String buildingName,
|
||||||
|
required String communityId,
|
||||||
|
required String userId}) async {
|
||||||
try {
|
try {
|
||||||
Map<String, String> body = {'buildingName': buildingName, 'communityUuid': communityId};
|
Map<String, String> body = {
|
||||||
|
'buildingName': buildingName,
|
||||||
|
'communityUuid': communityId
|
||||||
|
};
|
||||||
final response = await HomeCreation.createBuilding(body);
|
final response = await HomeCreation.createBuilding(body);
|
||||||
// if (response['data']['uuid'] != '') {
|
// if (response['data']['uuid'] != '') {
|
||||||
// final result = await _assignToBuilding(buildingId: response['data']['uuid'], userId: userId);
|
// final result = await _assignToBuilding(buildingId: response['data']['uuid'], userId: userId);
|
||||||
@ -130,7 +145,8 @@ Future<String> _createBuilding(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> _assignToBuilding({required String buildingId, required String userId}) async {
|
Future<bool> _assignToBuilding(
|
||||||
|
{required String buildingId, required String userId}) async {
|
||||||
try {
|
try {
|
||||||
Map<String, String> body = {
|
Map<String, String> body = {
|
||||||
'buildingUuid': buildingId,
|
'buildingUuid': buildingId,
|
||||||
@ -145,9 +161,14 @@ Future<bool> _assignToBuilding({required String buildingId, required String user
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<String> _createFloor(
|
Future<String> _createFloor(
|
||||||
{required String floorName, required String buildingId, required String userId}) async {
|
{required String floorName,
|
||||||
|
required String buildingId,
|
||||||
|
required String userId}) async {
|
||||||
try {
|
try {
|
||||||
Map<String, String> body = {'floorName': floorName, 'buildingUuid': buildingId};
|
Map<String, String> body = {
|
||||||
|
'floorName': floorName,
|
||||||
|
'buildingUuid': buildingId
|
||||||
|
};
|
||||||
final response = await HomeCreation.createFloor(body);
|
final response = await HomeCreation.createFloor(body);
|
||||||
// if (response['data']['uuid'] != '') {
|
// if (response['data']['uuid'] != '') {
|
||||||
// final result = await _assignToFloor(buildingId: response['data']['uuid'], userId: userId);
|
// final result = await _assignToFloor(buildingId: response['data']['uuid'], userId: userId);
|
||||||
@ -161,7 +182,8 @@ Future<String> _createFloor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> _assignToFloor({required String buildingId, required String userId}) async {
|
Future<bool> _assignToFloor(
|
||||||
|
{required String buildingId, required String userId}) async {
|
||||||
try {
|
try {
|
||||||
Map<String, String> body = {
|
Map<String, String> body = {
|
||||||
'floorUuid': buildingId,
|
'floorUuid': buildingId,
|
||||||
@ -176,12 +198,15 @@ Future<bool> _assignToFloor({required String buildingId, required String userId}
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<String> _createUnit(
|
Future<String> _createUnit(
|
||||||
{required String unitName, required String floorId, required String userId}) async {
|
{required String unitName,
|
||||||
|
required String floorId,
|
||||||
|
required String userId}) async {
|
||||||
try {
|
try {
|
||||||
Map<String, String> body = {'unitName': unitName, 'floorUuid': floorId};
|
Map<String, String> body = {'unitName': unitName, 'floorUuid': floorId};
|
||||||
final response = await HomeCreation.createUnit(body);
|
final response = await HomeCreation.createUnit(body);
|
||||||
if (response['data']['uuid'] != '') {
|
if (response['data']['uuid'] != '') {
|
||||||
final result = await _assignToUnit(unitId: response['data']['uuid'], userId: userId);
|
final result =
|
||||||
|
await _assignToUnit(unitId: response['data']['uuid'], userId: userId);
|
||||||
|
|
||||||
return result ? response['data']['uuid'] : '';
|
return result ? response['data']['uuid'] : '';
|
||||||
} else {
|
} else {
|
||||||
@ -192,7 +217,8 @@ Future<String> _createUnit(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> _assignToUnit({required String unitId, required String userId}) async {
|
Future<bool> _assignToUnit(
|
||||||
|
{required String unitId, required String userId}) async {
|
||||||
try {
|
try {
|
||||||
Map<String, String> body = {
|
Map<String, String> body = {
|
||||||
'unitUuid': unitId,
|
'unitUuid': unitId,
|
||||||
@ -207,10 +233,14 @@ Future<bool> _assignToUnit({required String unitId, required String userId}) asy
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<String> _createNewRoom(
|
Future<String> _createNewRoom(
|
||||||
{required String roomName, required String unitId, required String userId}) async {
|
{required String roomName,
|
||||||
|
required String unitId,
|
||||||
|
required String userId,
|
||||||
|
required String communityId}) async {
|
||||||
try {
|
try {
|
||||||
Map<String, String> body = {'roomName': roomName, 'unitUuid': unitId};
|
Map<String, String> body = {'subspaceName': roomName};
|
||||||
final response = await HomeCreation.createRoom(body);
|
final response = await HomeCreation.createRoom(
|
||||||
|
communityId: communityId, spaceId: unitId, body: body);
|
||||||
// if (response['data']['uuid'] != '') {
|
// if (response['data']['uuid'] != '') {
|
||||||
// final result = await _assignToRoom(roomId: response['data']['uuid'], userId: userId);
|
// final result = await _assignToRoom(roomId: response['data']['uuid'], userId: userId);
|
||||||
|
|
||||||
@ -223,7 +253,8 @@ Future<String> _createNewRoom(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> _assignToRoom({required String roomId, required String userId}) async {
|
Future<bool> _assignToRoom(
|
||||||
|
{required String roomId, required String userId}) async {
|
||||||
try {
|
try {
|
||||||
Map<String, String> body = {
|
Map<String, String> body = {
|
||||||
'roomUuid': roomId,
|
'roomUuid': roomId,
|
||||||
|
|||||||
@ -17,12 +17,15 @@ class ManageUnitBloc extends Bloc<ManageUnitEvent, ManageUnitState> {
|
|||||||
on<FetchDevicesByRoomIdEvent>(_fetchDevicesByRoomId);
|
on<FetchDevicesByRoomIdEvent>(_fetchDevicesByRoomId);
|
||||||
on<AssignRoomEvent>(_assignDevice);
|
on<AssignRoomEvent>(_assignDevice);
|
||||||
on<AddNewRoom>(_addNewRoom);
|
on<AddNewRoom>(_addNewRoom);
|
||||||
|
on<UnassignRoomEvent>(_unassignDevice);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _fetchRoomsAndDevices(FetchRoomsEvent event, Emitter<ManageUnitState> emit) async {
|
void _fetchRoomsAndDevices(
|
||||||
|
FetchRoomsEvent event, Emitter<ManageUnitState> emit) async {
|
||||||
try {
|
try {
|
||||||
emit(LoadingState());
|
emit(LoadingState());
|
||||||
final roomsList = await SpacesAPI.getRoomsBySpaceId(event.unitId);
|
final roomsList = await SpacesAPI.getSubSpaceBySpaceId(
|
||||||
|
event.unit.community.uuid, event.unit.id);
|
||||||
emit(FetchRoomsState(devicesList: allDevices, roomsList: roomsList));
|
emit(FetchRoomsState(devicesList: allDevices, roomsList: roomsList));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(const ErrorState(message: 'Something went wrong'));
|
emit(const ErrorState(message: 'Something went wrong'));
|
||||||
@ -30,11 +33,15 @@ class ManageUnitBloc extends Bloc<ManageUnitEvent, ManageUnitState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _fetchDevicesByRoomId(FetchDevicesByRoomIdEvent event, Emitter<ManageUnitState> emit) async {
|
void _fetchDevicesByRoomId(
|
||||||
|
FetchDevicesByRoomIdEvent event, Emitter<ManageUnitState> emit) async {
|
||||||
try {
|
try {
|
||||||
Map<String, bool> roomDevicesId = {};
|
Map<String, bool> roomDevicesId = {};
|
||||||
emit(LoadingState());
|
emit(LoadingState());
|
||||||
final devicesList = await DevicesAPI.getDevicesByRoomId(event.roomId);
|
final devicesList = await DevicesAPI.getDevicesByRoomId(
|
||||||
|
communityUuid: event.unit.community.uuid,
|
||||||
|
spaceUuid: event.unit.id,
|
||||||
|
roomId: event.roomId);
|
||||||
allDevices = await HomeManagementAPI.fetchDevicesByUserId();
|
allDevices = await HomeManagementAPI.fetchDevicesByUserId();
|
||||||
|
|
||||||
List<String> allDevicesIds = [];
|
List<String> allDevicesIds = [];
|
||||||
@ -61,13 +68,18 @@ class ManageUnitBloc extends Bloc<ManageUnitEvent, ManageUnitState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _assignDevice(AssignRoomEvent event, Emitter<ManageUnitState> emit) async {
|
void _assignDevice(
|
||||||
|
AssignRoomEvent event, Emitter<ManageUnitState> emit) async {
|
||||||
try {
|
try {
|
||||||
Map<String, bool> roomDevicesId = {};
|
Map<String, bool> roomDevicesId = {};
|
||||||
emit(LoadingState());
|
emit(LoadingState());
|
||||||
Map<String, String> body = {"deviceUuid": event.deviceId, "roomUuid": event.roomId};
|
|
||||||
await HomeManagementAPI.assignDeviceToRoom(body);
|
await HomeManagementAPI.assignDeviceToRoom(
|
||||||
final devicesList = await DevicesAPI.getDevicesByRoomId(event.roomId);
|
event.unit.community.uuid, event.unit.id, event.roomId, event.deviceId);
|
||||||
|
final devicesList = await DevicesAPI.getDevicesByRoomId(
|
||||||
|
communityUuid: event.unit.community.uuid,
|
||||||
|
spaceUuid: event.unit.id,
|
||||||
|
roomId: event.roomId);
|
||||||
|
|
||||||
List<String> allDevicesIds = [];
|
List<String> allDevicesIds = [];
|
||||||
|
|
||||||
@ -93,13 +105,56 @@ class ManageUnitBloc extends Bloc<ManageUnitEvent, ManageUnitState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void _unassignDevice(
|
||||||
|
UnassignRoomEvent event, Emitter<ManageUnitState> emit) async {
|
||||||
|
try {
|
||||||
|
Map<String, bool> roomDevicesId = {};
|
||||||
|
emit(LoadingState());
|
||||||
|
|
||||||
|
await HomeManagementAPI.unAssignDeviceToRoom(
|
||||||
|
event.unit.community.uuid, event.unit.id, event.roomId, event.deviceId);
|
||||||
|
final devicesList = await DevicesAPI.getDevicesByRoomId(
|
||||||
|
communityUuid: event.unit.community.uuid,
|
||||||
|
spaceUuid: event.unit.id,
|
||||||
|
roomId: event.roomId);
|
||||||
|
|
||||||
|
List<String> allDevicesIds = [];
|
||||||
|
|
||||||
|
allDevices.forEach((element) {
|
||||||
|
allDevicesIds.add(element.uuid!);
|
||||||
|
});
|
||||||
|
|
||||||
|
devicesList.forEach((e) {
|
||||||
|
if (allDevicesIds.contains(e.uuid!)) {
|
||||||
|
roomDevicesId[e.uuid!] = true;
|
||||||
|
} else {
|
||||||
|
roomDevicesId[e.uuid!] = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
emit(FetchDeviceByRoomIdState(
|
||||||
|
roomDevices: devicesList,
|
||||||
|
allDevices: allDevices,
|
||||||
|
roomDevicesId: roomDevicesId,
|
||||||
|
roomId: event.roomId));
|
||||||
|
} catch (e) {
|
||||||
|
emit(const ErrorState(message: 'Something went wrong'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
_addNewRoom(AddNewRoom event, Emitter<ManageUnitState> emit) async {
|
_addNewRoom(AddNewRoom event, Emitter<ManageUnitState> emit) async {
|
||||||
Map<String, String> body = {'roomName': event.roomName, 'unitUuid': event.unitId};
|
Map<String, String> body = {'subspaceName': event.roomName};
|
||||||
try {
|
try {
|
||||||
emit(LoadingState());
|
emit(LoadingState());
|
||||||
final response = await HomeCreation.createRoom(body);
|
final response = await HomeCreation.createRoom(
|
||||||
|
communityId: event.unit.community.uuid,
|
||||||
|
spaceId: event.unit.id,
|
||||||
|
body: body);
|
||||||
if (response['data']['uuid'] != '') {
|
if (response['data']['uuid'] != '') {
|
||||||
final roomsList = await SpacesAPI.getRoomsBySpaceId(event.unitId);
|
final roomsList = await SpacesAPI.getSubSpaceBySpaceId(
|
||||||
|
event.unit.community.uuid, event.unit.id);
|
||||||
allDevices = await HomeManagementAPI.fetchDevicesByUserId();
|
allDevices = await HomeManagementAPI.fetchDevicesByUserId();
|
||||||
emit(FetchRoomsState(devicesList: allDevices, roomsList: roomsList));
|
emit(FetchRoomsState(devicesList: allDevices, roomsList: roomsList));
|
||||||
await HomeCubit.getInstance().fetchUnitsByUserId();
|
await HomeCubit.getInstance().fetchUnitsByUserId();
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
|
import 'package:syncrow_app/features/app_layout/model/space_model.dart';
|
||||||
|
|
||||||
abstract class ManageUnitEvent extends Equatable {
|
abstract class ManageUnitEvent extends Equatable {
|
||||||
const ManageUnitEvent();
|
const ManageUnitEvent();
|
||||||
@ -12,39 +13,54 @@ class InitialEvent extends ManageUnitEvent {}
|
|||||||
class LoadingEvent extends ManageUnitEvent {}
|
class LoadingEvent extends ManageUnitEvent {}
|
||||||
|
|
||||||
class FetchRoomsEvent extends ManageUnitEvent {
|
class FetchRoomsEvent extends ManageUnitEvent {
|
||||||
final String unitId;
|
final SpaceModel unit;
|
||||||
|
|
||||||
const FetchRoomsEvent({required this.unitId});
|
const FetchRoomsEvent({required this.unit});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [unitId];
|
List<Object> get props => [unit];
|
||||||
}
|
}
|
||||||
|
|
||||||
class FetchDevicesByRoomIdEvent extends ManageUnitEvent {
|
class FetchDevicesByRoomIdEvent extends ManageUnitEvent {
|
||||||
final String roomId;
|
final String roomId;
|
||||||
|
final SpaceModel unit;
|
||||||
|
|
||||||
const FetchDevicesByRoomIdEvent({required this.roomId});
|
const FetchDevicesByRoomIdEvent({required this.roomId, required this.unit});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [roomId];
|
List<Object> get props => [roomId, unit];
|
||||||
}
|
}
|
||||||
|
|
||||||
class AddNewRoom extends ManageUnitEvent {
|
class AddNewRoom extends ManageUnitEvent {
|
||||||
final String roomName;
|
final String roomName;
|
||||||
final String unitId;
|
final SpaceModel unit;
|
||||||
|
|
||||||
const AddNewRoom({required this.roomName, required this.unitId});
|
const AddNewRoom({required this.roomName, required this.unit});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [roomName, unitId];
|
List<Object> get props => [roomName, unit];
|
||||||
}
|
}
|
||||||
|
|
||||||
class AssignRoomEvent extends ManageUnitEvent {
|
class AssignRoomEvent extends ManageUnitEvent {
|
||||||
final String roomId;
|
final String roomId;
|
||||||
final String deviceId;
|
final String deviceId;
|
||||||
|
final SpaceModel unit;
|
||||||
|
|
||||||
const AssignRoomEvent({required this.roomId, required this.deviceId});
|
const AssignRoomEvent(
|
||||||
|
{required this.roomId, required this.deviceId, required this.unit});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [roomId];
|
List<Object> get props => [roomId, unit];
|
||||||
|
}
|
||||||
|
|
||||||
|
class UnassignRoomEvent extends ManageUnitEvent {
|
||||||
|
final String roomId;
|
||||||
|
final String deviceId;
|
||||||
|
final SpaceModel unit;
|
||||||
|
|
||||||
|
const UnassignRoomEvent(
|
||||||
|
{required this.roomId, required this.deviceId, required this.unit});
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [roomId, unit];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/room_model.dart';
|
import 'package:syncrow_app/features/devices/model/room_model.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/model/subspace_model.dart';
|
||||||
|
|
||||||
abstract class ManageUnitState extends Equatable {
|
abstract class ManageUnitState extends Equatable {
|
||||||
const ManageUnitState();
|
const ManageUnitState();
|
||||||
@ -14,7 +15,7 @@ class InitialState extends ManageUnitState {}
|
|||||||
class LoadingState extends ManageUnitState {}
|
class LoadingState extends ManageUnitState {}
|
||||||
|
|
||||||
class FetchRoomsState extends ManageUnitState {
|
class FetchRoomsState extends ManageUnitState {
|
||||||
final List<RoomModel> roomsList;
|
final List<SubSpaceModel> roomsList;
|
||||||
final List<DeviceModel> devicesList;
|
final List<DeviceModel> devicesList;
|
||||||
|
|
||||||
const FetchRoomsState({required this.devicesList, required this.roomsList});
|
const FetchRoomsState({required this.devicesList, required this.roomsList});
|
||||||
|
|||||||
@ -44,7 +44,8 @@ class JoinHomeView extends StatelessWidget {
|
|||||||
controller: textEditingController,
|
controller: textEditingController,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText: 'Invitatoin code',
|
hintText: 'Invitatoin code',
|
||||||
hintStyle: context.bodyMedium.copyWith(color: Colors.grey),
|
hintStyle:
|
||||||
|
context.bodyMedium.copyWith(color: Colors.grey),
|
||||||
border: InputBorder.none,
|
border: InputBorder.none,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -52,10 +53,12 @@ class JoinHomeView extends StatelessWidget {
|
|||||||
IconButton(
|
IconButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
if (textEditingController.text.isEmpty) {
|
if (textEditingController.text.isEmpty) {
|
||||||
CustomSnackBar.displaySnackBar('Please enter the invitation code');
|
CustomSnackBar.displaySnackBar(
|
||||||
|
'Please enter the invitation code');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (await HomeCubit.getInstance().joinAUnit(textEditingController.text)) {
|
if (await HomeCubit.getInstance()
|
||||||
|
.joinAUnit(textEditingController.text)) {
|
||||||
CustomSnackBar.displaySnackBar('Done successfully');
|
CustomSnackBar.displaySnackBar('Done successfully');
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -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:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
|
import 'package:syncrow_app/features/app_layout/model/space_model.dart';
|
||||||
import 'package:syncrow_app/features/menu/bloc/manage_unit_bloc/manage_unit_bloc.dart';
|
import 'package:syncrow_app/features/menu/bloc/manage_unit_bloc/manage_unit_bloc.dart';
|
||||||
import 'package:syncrow_app/features/menu/bloc/manage_unit_bloc/manage_unit_event.dart';
|
import 'package:syncrow_app/features/menu/bloc/manage_unit_bloc/manage_unit_event.dart';
|
||||||
import 'package:syncrow_app/features/menu/bloc/manage_unit_bloc/manage_unit_state.dart';
|
import 'package:syncrow_app/features/menu/bloc/manage_unit_bloc/manage_unit_state.dart';
|
||||||
@ -11,16 +12,24 @@ import 'package:syncrow_app/utils/helpers/snack_bar.dart';
|
|||||||
class AssignDeviceView extends StatelessWidget {
|
class AssignDeviceView extends StatelessWidget {
|
||||||
final String unitId;
|
final String unitId;
|
||||||
final String roomId;
|
final String roomId;
|
||||||
const AssignDeviceView({super.key, required this.unitId, required this.roomId});
|
final SpaceModel unit;
|
||||||
|
const AssignDeviceView(
|
||||||
|
{super.key,
|
||||||
|
required this.unitId,
|
||||||
|
required this.roomId,
|
||||||
|
required this.unit});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocProvider(
|
return BlocProvider(
|
||||||
create: (context) => ManageUnitBloc()..add(FetchDevicesByRoomIdEvent(roomId: roomId)),
|
create: (context) => ManageUnitBloc()
|
||||||
child: BlocConsumer<ManageUnitBloc, ManageUnitState>(listener: (context, state) {
|
..add(FetchDevicesByRoomIdEvent(roomId: roomId, unit: unit)),
|
||||||
|
child: BlocConsumer<ManageUnitBloc, ManageUnitState>(
|
||||||
|
listener: (context, state) {
|
||||||
if (state is FetchDeviceByRoomIdState) {
|
if (state is FetchDeviceByRoomIdState) {
|
||||||
if (state.allDevices.isEmpty) {
|
if (state.allDevices.isEmpty) {
|
||||||
CustomSnackBar.displaySnackBar('You do not have the permission to assign devices');
|
CustomSnackBar.displaySnackBar(
|
||||||
|
'You do not have the permission to assign devices');
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -34,7 +43,8 @@ class AssignDeviceView extends StatelessWidget {
|
|||||||
width: MediaQuery.sizeOf(context).width,
|
width: MediaQuery.sizeOf(context).width,
|
||||||
height: MediaQuery.sizeOf(context).height,
|
height: MediaQuery.sizeOf(context).height,
|
||||||
child: GridView.builder(
|
child: GridView.builder(
|
||||||
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
gridDelegate:
|
||||||
|
const SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
crossAxisCount: 2,
|
crossAxisCount: 2,
|
||||||
crossAxisSpacing: 10.0,
|
crossAxisSpacing: 10.0,
|
||||||
mainAxisSpacing: 10.0,
|
mainAxisSpacing: 10.0,
|
||||||
@ -52,11 +62,14 @@ class AssignDeviceView extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment:
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
CrossAxisAlignment.start,
|
||||||
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
SvgPicture.asset(
|
SvgPicture.asset(
|
||||||
state.allDevices[index].icon!,
|
state.allDevices[index].icon!,
|
||||||
@ -64,19 +77,42 @@ class AssignDeviceView extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if (state.roomDevicesId[
|
bool isAssigned =
|
||||||
state.allDevices[index].uuid!] ??
|
state.roomDevicesId[state
|
||||||
false == false) {
|
.allDevices[index]
|
||||||
BlocProvider.of<ManageUnitBloc>(context).add(
|
.uuid!] ??
|
||||||
AssignRoomEvent(
|
false;
|
||||||
deviceId:
|
if (isAssigned) {
|
||||||
state.allDevices[index].uuid ?? '',
|
BlocProvider.of<
|
||||||
|
ManageUnitBloc>(
|
||||||
|
context)
|
||||||
|
.add(UnassignRoomEvent(
|
||||||
|
deviceId: state
|
||||||
|
.allDevices[
|
||||||
|
index]
|
||||||
|
.uuid ??
|
||||||
|
'',
|
||||||
|
unit: unit,
|
||||||
|
roomId: roomId));
|
||||||
|
} else {
|
||||||
|
// Tick (assign) the device
|
||||||
|
BlocProvider.of<
|
||||||
|
ManageUnitBloc>(
|
||||||
|
context)
|
||||||
|
.add(AssignRoomEvent(
|
||||||
|
deviceId: state
|
||||||
|
.allDevices[
|
||||||
|
index]
|
||||||
|
.uuid ??
|
||||||
|
'',
|
||||||
|
unit: unit,
|
||||||
roomId: roomId));
|
roomId: roomId));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.asset(
|
||||||
state.roomDevicesId[
|
state.roomDevicesId[state
|
||||||
state.allDevices[index].uuid!] ??
|
.allDevices[index]
|
||||||
|
.uuid!] ??
|
||||||
false
|
false
|
||||||
? Assets.blueCheckboxIcon
|
? Assets.blueCheckboxIcon
|
||||||
: Assets.emptyCheckboxIcon,
|
: Assets.emptyCheckboxIcon,
|
||||||
|
|||||||
@ -60,7 +60,7 @@ class HomeSettingsView extends StatelessWidget {
|
|||||||
onTap: () {
|
onTap: () {
|
||||||
Navigator.of(context).push(CustomPageRoute(
|
Navigator.of(context).push(CustomPageRoute(
|
||||||
builder: (context) => RoomsView(
|
builder: (context) => RoomsView(
|
||||||
unitId: space?.id ?? '',
|
unit: space!,
|
||||||
)));
|
)));
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
@ -112,7 +112,7 @@ class HomeSettingsView extends StatelessWidget {
|
|||||||
padding: const EdgeInsets.only(bottom: 10),
|
padding: const EdgeInsets.only(bottom: 10),
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await HomeCubit.getInstance().generateInvitation(space?.id ?? '');
|
await HomeCubit.getInstance().generateInvitation(space!);
|
||||||
},
|
},
|
||||||
child: const Row(
|
child: const Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:syncrow_app/features/app_layout/model/space_model.dart';
|
||||||
import 'package:syncrow_app/features/menu/bloc/manage_unit_bloc/manage_unit_bloc.dart';
|
import 'package:syncrow_app/features/menu/bloc/manage_unit_bloc/manage_unit_bloc.dart';
|
||||||
import 'package:syncrow_app/features/menu/bloc/manage_unit_bloc/manage_unit_event.dart';
|
import 'package:syncrow_app/features/menu/bloc/manage_unit_bloc/manage_unit_event.dart';
|
||||||
import 'package:syncrow_app/features/menu/bloc/manage_unit_bloc/manage_unit_state.dart';
|
import 'package:syncrow_app/features/menu/bloc/manage_unit_bloc/manage_unit_state.dart';
|
||||||
@ -11,14 +12,14 @@ import 'package:syncrow_app/utils/helpers/snack_bar.dart';
|
|||||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||||
|
|
||||||
class RoomsView extends StatelessWidget {
|
class RoomsView extends StatelessWidget {
|
||||||
final String unitId;
|
final SpaceModel unit;
|
||||||
const RoomsView({super.key, required this.unitId});
|
const RoomsView({super.key, required this.unit});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
TextEditingController textEditingController = TextEditingController();
|
TextEditingController textEditingController = TextEditingController();
|
||||||
return BlocProvider(
|
return BlocProvider(
|
||||||
create: (context) => ManageUnitBloc()..add(FetchRoomsEvent(unitId: unitId)),
|
create: (context) => ManageUnitBloc()..add(FetchRoomsEvent(unit:unit )),
|
||||||
child: BlocConsumer<ManageUnitBloc, ManageUnitState>(
|
child: BlocConsumer<ManageUnitBloc, ManageUnitState>(
|
||||||
listener: (context, state) {},
|
listener: (context, state) {},
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
@ -62,7 +63,8 @@ class RoomsView extends StatelessWidget {
|
|||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
builder: (context) => AssignDeviceView(
|
builder: (context) => AssignDeviceView(
|
||||||
roomId: state.roomsList[index].id ?? '',
|
roomId: state.roomsList[index].id ?? '',
|
||||||
unitId: unitId,
|
unitId: unit.id,
|
||||||
|
unit: unit,
|
||||||
)),
|
)),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -100,14 +102,14 @@ class RoomsView extends StatelessWidget {
|
|||||||
BlocProvider.of<ManageUnitBloc>(context).add(
|
BlocProvider.of<ManageUnitBloc>(context).add(
|
||||||
AddNewRoom(
|
AddNewRoom(
|
||||||
roomName: textEditingController.text,
|
roomName: textEditingController.text,
|
||||||
unitId: unitId));
|
unit: unit));
|
||||||
textEditingController.clear();
|
textEditingController.clear();
|
||||||
},
|
},
|
||||||
child: const Row(
|
child: const Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
BodyMedium(
|
BodyMedium(
|
||||||
text: 'Add Space',
|
text: 'Add Room',
|
||||||
fontColor: ColorsManager.primaryColor,
|
fontColor: ColorsManager.primaryColor,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@ -60,7 +60,8 @@ class CreateSceneBloc extends Bloc<CreateSceneEvent, CreateSceneState>
|
|||||||
String selectedIcon = '';
|
String selectedIcon = '';
|
||||||
bool showInDeviceScreen = false;
|
bool showInDeviceScreen = false;
|
||||||
|
|
||||||
FutureOr<void> _onAddSceneTask(AddTaskEvent event, Emitter<CreateSceneState> emit) {
|
FutureOr<void> _onAddSceneTask(
|
||||||
|
AddTaskEvent event, Emitter<CreateSceneState> emit) {
|
||||||
emit(CreateSceneLoading());
|
emit(CreateSceneLoading());
|
||||||
if (event.isAutomation == true) {
|
if (event.isAutomation == true) {
|
||||||
final copyList = List<SceneStaticFunction>.from(automationTempTasksList);
|
final copyList = List<SceneStaticFunction>.from(automationTempTasksList);
|
||||||
@ -95,7 +96,8 @@ class CreateSceneBloc extends Bloc<CreateSceneEvent, CreateSceneState>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void addToTempTaskList(TempHoldSceneTasksEvent event, Emitter<CreateSceneState> emit) {
|
void addToTempTaskList(
|
||||||
|
TempHoldSceneTasksEvent event, Emitter<CreateSceneState> emit) {
|
||||||
emit(CreateSceneLoading());
|
emit(CreateSceneLoading());
|
||||||
bool updated = false;
|
bool updated = false;
|
||||||
|
|
||||||
@ -180,7 +182,8 @@ class CreateSceneBloc extends Bloc<CreateSceneEvent, CreateSceneState>
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
void addToTempAutomationTaskList(TempHoldSceneTasksEvent event, Emitter<CreateSceneState> emit) {
|
void addToTempAutomationTaskList(
|
||||||
|
TempHoldSceneTasksEvent event, Emitter<CreateSceneState> emit) {
|
||||||
emit(CreateSceneLoading());
|
emit(CreateSceneLoading());
|
||||||
bool updated = false;
|
bool updated = false;
|
||||||
for (var element in automationTempTasksList) {
|
for (var element in automationTempTasksList) {
|
||||||
@ -202,8 +205,10 @@ class CreateSceneBloc extends Bloc<CreateSceneEvent, CreateSceneState>
|
|||||||
],
|
],
|
||||||
comparator: automationComparatorValues[element.code],
|
comparator: automationComparatorValues[element.code],
|
||||||
);
|
);
|
||||||
automationTempTasksList[automationTempTasksList.indexOf(element)] = updatedElement;
|
automationTempTasksList[automationTempTasksList.indexOf(element)] =
|
||||||
automationSelectedValues[updatedElement.code] = event.deviceControlModel.value;
|
updatedElement;
|
||||||
|
automationSelectedValues[updatedElement.code] =
|
||||||
|
event.deviceControlModel.value;
|
||||||
updated = true;
|
updated = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -223,10 +228,12 @@ class CreateSceneBloc extends Bloc<CreateSceneEvent, CreateSceneState>
|
|||||||
icon: '',
|
icon: '',
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
comparator: automationComparatorValues[event.deviceControlModel.code] ?? '==',
|
comparator:
|
||||||
|
automationComparatorValues[event.deviceControlModel.code] ?? '==',
|
||||||
);
|
);
|
||||||
automationTempTasksList.add(newElement);
|
automationTempTasksList.add(newElement);
|
||||||
automationSelectedValues[newElement.code] = event.deviceControlModel.value;
|
automationSelectedValues[newElement.code] =
|
||||||
|
event.deviceControlModel.value;
|
||||||
}
|
}
|
||||||
emit(AddSceneTask(
|
emit(AddSceneTask(
|
||||||
tasksList: tasksList,
|
tasksList: tasksList,
|
||||||
@ -235,7 +242,8 @@ class CreateSceneBloc extends Bloc<CreateSceneEvent, CreateSceneState>
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _selectedValue(SelectedValueEvent event, Emitter<CreateSceneState> emit) {
|
FutureOr<void> _selectedValue(
|
||||||
|
SelectedValueEvent event, Emitter<CreateSceneState> emit) {
|
||||||
if (event.isAutomation == true) {
|
if (event.isAutomation == true) {
|
||||||
automationSelectedValues[event.code] = event.value;
|
automationSelectedValues[event.code] = event.value;
|
||||||
automationComparatorValues[event.code] = event.comparator ?? '==';
|
automationComparatorValues[event.code] = event.comparator ?? '==';
|
||||||
@ -272,7 +280,8 @@ class CreateSceneBloc extends Bloc<CreateSceneEvent, CreateSceneState>
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _removeTaskById(RemoveTaskByIdEvent event, Emitter<CreateSceneState> emit) {
|
FutureOr<void> _removeTaskById(
|
||||||
|
RemoveTaskByIdEvent event, Emitter<CreateSceneState> emit) {
|
||||||
emit(CreateSceneLoading());
|
emit(CreateSceneLoading());
|
||||||
if (event.isAutomation == true) {
|
if (event.isAutomation == true) {
|
||||||
for (var element in automationTasksList) {
|
for (var element in automationTasksList) {
|
||||||
@ -345,7 +354,8 @@ class CreateSceneBloc extends Bloc<CreateSceneEvent, CreateSceneState>
|
|||||||
: await SceneApi.createScene(event.createSceneModel!);
|
: await SceneApi.createScene(event.createSceneModel!);
|
||||||
} else if (event.createAutomationModel != null) {
|
} else if (event.createAutomationModel != null) {
|
||||||
response = event.updateScene
|
response = event.updateScene
|
||||||
? await SceneApi.updateAutomation(event.createAutomationModel!, event.sceneId)
|
? await SceneApi.updateAutomation(
|
||||||
|
event.createAutomationModel!, event.sceneId)
|
||||||
: await SceneApi.createAutomation(event.createAutomationModel!);
|
: await SceneApi.createAutomation(event.createAutomationModel!);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -359,12 +369,14 @@ class CreateSceneBloc extends Bloc<CreateSceneEvent, CreateSceneState>
|
|||||||
automationComparatorValues.clear();
|
automationComparatorValues.clear();
|
||||||
selectedIcon = '';
|
selectedIcon = '';
|
||||||
showInDeviceScreen = false;
|
showInDeviceScreen = false;
|
||||||
effectiveTime = EffectiveTime(start: '00:00', end: '23:59', loops: '1111111');
|
effectiveTime =
|
||||||
|
EffectiveTime(start: '00:00', end: '23:59', loops: '1111111');
|
||||||
sceneType = CreateSceneEnum.none;
|
sceneType = CreateSceneEnum.none;
|
||||||
conditionRule = 'or';
|
conditionRule = 'or';
|
||||||
emit(const CreateSceneWithTasks(success: true));
|
emit(const CreateSceneWithTasks(success: true));
|
||||||
CustomSnackBar.greenSnackBar(
|
CustomSnackBar.greenSnackBar(event.updateScene
|
||||||
event.updateScene ? 'Scene updated successfully' : 'Scene created successfully');
|
? 'Scene updated successfully'
|
||||||
|
: 'Scene created successfully');
|
||||||
} else {
|
} else {
|
||||||
emit(const CreateSceneError(message: 'Something went wrong'));
|
emit(const CreateSceneError(message: 'Something went wrong'));
|
||||||
}
|
}
|
||||||
@ -378,7 +390,8 @@ class CreateSceneBloc extends Bloc<CreateSceneEvent, CreateSceneState>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _clearTaskList(ClearTaskListEvent event, Emitter<CreateSceneState> emit) {
|
FutureOr<void> _clearTaskList(
|
||||||
|
ClearTaskListEvent event, Emitter<CreateSceneState> emit) {
|
||||||
emit(CreateSceneLoading());
|
emit(CreateSceneLoading());
|
||||||
automationTasksList.clear();
|
automationTasksList.clear();
|
||||||
tasksList.clear();
|
tasksList.clear();
|
||||||
@ -389,7 +402,8 @@ class CreateSceneBloc extends Bloc<CreateSceneEvent, CreateSceneState>
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _clearTabToRunSetting(ClearTabToRunSetting event, Emitter<CreateSceneState> emit) {
|
FutureOr<void> _clearTabToRunSetting(
|
||||||
|
ClearTabToRunSetting event, Emitter<CreateSceneState> emit) {
|
||||||
emit(CreateSceneLoading());
|
emit(CreateSceneLoading());
|
||||||
selectedIcon = '';
|
selectedIcon = '';
|
||||||
showInDeviceScreen = false;
|
showInDeviceScreen = false;
|
||||||
@ -416,7 +430,8 @@ class CreateSceneBloc extends Bloc<CreateSceneEvent, CreateSceneState>
|
|||||||
automationComparatorValues.clear();
|
automationComparatorValues.clear();
|
||||||
selectedIcon = '';
|
selectedIcon = '';
|
||||||
showInDeviceScreen = false;
|
showInDeviceScreen = false;
|
||||||
effectiveTime = EffectiveTime(start: '00:00', end: '23:59', loops: '1111111');
|
effectiveTime =
|
||||||
|
EffectiveTime(start: '00:00', end: '23:59', loops: '1111111');
|
||||||
sceneType = CreateSceneEnum.none;
|
sceneType = CreateSceneEnum.none;
|
||||||
conditionRule = 'or';
|
conditionRule = 'or';
|
||||||
|
|
||||||
@ -425,10 +440,14 @@ class CreateSceneBloc extends Bloc<CreateSceneEvent, CreateSceneState>
|
|||||||
: await SceneApi.getSceneDetails(event.sceneId);
|
: await SceneApi.getSceneDetails(event.sceneId);
|
||||||
if (response.id.isNotEmpty) {
|
if (response.id.isNotEmpty) {
|
||||||
if (event.isAutomation) {
|
if (event.isAutomation) {
|
||||||
automationTasksList = List<SceneStaticFunction>.from(getTaskListFunctionsFromApi(
|
automationTasksList = List<SceneStaticFunction>.from(
|
||||||
actions: [], isAutomation: true, conditions: response.conditions));
|
getTaskListFunctionsFromApi(
|
||||||
|
actions: [],
|
||||||
|
isAutomation: true,
|
||||||
|
conditions: response.conditions));
|
||||||
tasksList = List<SceneStaticFunction>.from(
|
tasksList = List<SceneStaticFunction>.from(
|
||||||
getTaskListFunctionsFromApi(actions: response.actions, isAutomation: false));
|
getTaskListFunctionsFromApi(
|
||||||
|
actions: response.actions, isAutomation: false));
|
||||||
|
|
||||||
conditionRule = response.decisionExpr ?? conditionRule;
|
conditionRule = response.decisionExpr ?? conditionRule;
|
||||||
|
|
||||||
@ -441,11 +460,13 @@ class CreateSceneBloc extends Bloc<CreateSceneEvent, CreateSceneState>
|
|||||||
: EffectiveTime(start: '00:00', end: '23:59', loops: '1111111');
|
: EffectiveTime(start: '00:00', end: '23:59', loops: '1111111');
|
||||||
|
|
||||||
// Set the days directly from the API response
|
// Set the days directly from the API response
|
||||||
BlocProvider.of<EffectPeriodBloc>(NavigationService.navigatorKey.currentContext!)
|
BlocProvider.of<EffectPeriodBloc>(
|
||||||
|
NavigationService.navigatorKey.currentContext!)
|
||||||
.add(SetDays(response.effectiveTime?.loops ?? '1111111'));
|
.add(SetDays(response.effectiveTime?.loops ?? '1111111'));
|
||||||
|
|
||||||
// Set Custom Time and reset days first
|
// Set Custom Time and reset days first
|
||||||
BlocProvider.of<EffectPeriodBloc>(NavigationService.navigatorKey.currentContext!)
|
BlocProvider.of<EffectPeriodBloc>(
|
||||||
|
NavigationService.navigatorKey.currentContext!)
|
||||||
.add(SetCustomTime(effectiveTime!.start, effectiveTime!.end));
|
.add(SetCustomTime(effectiveTime!.start, effectiveTime!.end));
|
||||||
|
|
||||||
emit(AddSceneTask(
|
emit(AddSceneTask(
|
||||||
@ -457,7 +478,8 @@ class CreateSceneBloc extends Bloc<CreateSceneEvent, CreateSceneState>
|
|||||||
showInDevice: showInDeviceScreen));
|
showInDevice: showInDeviceScreen));
|
||||||
} else {
|
} else {
|
||||||
tasksList = List<SceneStaticFunction>.from(
|
tasksList = List<SceneStaticFunction>.from(
|
||||||
getTaskListFunctionsFromApi(actions: response.actions, isAutomation: false));
|
getTaskListFunctionsFromApi(
|
||||||
|
actions: response.actions, isAutomation: false));
|
||||||
selectedIcon = response.icon!;
|
selectedIcon = response.icon!;
|
||||||
showInDeviceScreen = response.showInDevice!;
|
showInDeviceScreen = response.showInDevice!;
|
||||||
emit(AddSceneTask(
|
emit(AddSceneTask(
|
||||||
@ -475,7 +497,8 @@ class CreateSceneBloc extends Bloc<CreateSceneEvent, CreateSceneState>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _fetchIconScene(SceneIconEvent event, Emitter<CreateSceneState> emit) async {
|
FutureOr<void> _fetchIconScene(
|
||||||
|
SceneIconEvent event, Emitter<CreateSceneState> emit) async {
|
||||||
emit(CreateSceneLoading());
|
emit(CreateSceneLoading());
|
||||||
try {
|
try {
|
||||||
iconModelList = await SceneApi.getIcon();
|
iconModelList = await SceneApi.getIcon();
|
||||||
@ -491,7 +514,8 @@ class CreateSceneBloc extends Bloc<CreateSceneEvent, CreateSceneState>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _iconSelected(IconSelected event, Emitter<CreateSceneState> emit) async {
|
FutureOr<void> _iconSelected(
|
||||||
|
IconSelected event, Emitter<CreateSceneState> emit) async {
|
||||||
try {
|
try {
|
||||||
if (event.confirmSelection) {
|
if (event.confirmSelection) {
|
||||||
selectedIcon = event.iconId;
|
selectedIcon = event.iconId;
|
||||||
@ -531,7 +555,8 @@ class CreateSceneBloc extends Bloc<CreateSceneEvent, CreateSceneState>
|
|||||||
return days[index];
|
return days[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _clearTempTaskList(ClearTempTaskListEvent event, Emitter<CreateSceneState> emit) {
|
FutureOr<void> _clearTempTaskList(
|
||||||
|
ClearTempTaskListEvent event, Emitter<CreateSceneState> emit) {
|
||||||
emit(CreateSceneLoading());
|
emit(CreateSceneLoading());
|
||||||
if (event.isAutomation == true) {
|
if (event.isAutomation == true) {
|
||||||
automationTempTasksList.clear();
|
automationTempTasksList.clear();
|
||||||
@ -575,13 +600,18 @@ class CreateSceneBloc extends Bloc<CreateSceneEvent, CreateSceneState>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _deleteScene(DeleteSceneEvent event, Emitter<CreateSceneState> emit) async {
|
FutureOr<void> _deleteScene(
|
||||||
|
DeleteSceneEvent event, Emitter<CreateSceneState> emit) async {
|
||||||
emit(DeleteSceneLoading());
|
emit(DeleteSceneLoading());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final response = sceneType.name == CreateSceneEnum.deviceStatusChanges.name
|
final response =
|
||||||
? await SceneApi.deleteAutomation(automationId: event.sceneId, unitUuid: event.unitUuid)
|
sceneType.name == CreateSceneEnum.deviceStatusChanges.name
|
||||||
: await SceneApi.deleteScene(sceneId: event.sceneId, unitUuid: event.unitUuid);
|
? await SceneApi.deleteAutomation(
|
||||||
|
automationId: event.sceneId, unitUuid: event.unitUuid)
|
||||||
|
: await SceneApi.deleteScene(
|
||||||
|
sceneId: event.sceneId,
|
||||||
|
);
|
||||||
if (response == true) {
|
if (response == true) {
|
||||||
emit(const DeleteSceneSuccess(true));
|
emit(const DeleteSceneSuccess(true));
|
||||||
} else {
|
} else {
|
||||||
@ -592,7 +622,8 @@ class CreateSceneBloc extends Bloc<CreateSceneEvent, CreateSceneState>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _updateTaskValue(UpdateTaskEvent event, Emitter<CreateSceneState> emit) {
|
FutureOr<void> _updateTaskValue(
|
||||||
|
UpdateTaskEvent event, Emitter<CreateSceneState> emit) {
|
||||||
emit(CreateSceneLoading());
|
emit(CreateSceneLoading());
|
||||||
if (event.isAutomation == true) {
|
if (event.isAutomation == true) {
|
||||||
for (var i = 0; i < automationTasksList.length; i++) {
|
for (var i = 0; i < automationTasksList.length; i++) {
|
||||||
@ -628,7 +659,8 @@ class CreateSceneBloc extends Bloc<CreateSceneEvent, CreateSceneState>
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _selectConditionRule(SelectConditionEvent event, Emitter<CreateSceneState> emit) {
|
FutureOr<void> _selectConditionRule(
|
||||||
|
SelectConditionEvent event, Emitter<CreateSceneState> emit) {
|
||||||
emit(CreateSceneInitial());
|
emit(CreateSceneInitial());
|
||||||
if (event.condition.contains('any')) {
|
if (event.condition.contains('any')) {
|
||||||
conditionRule = 'or';
|
conditionRule = 'or';
|
||||||
@ -643,7 +675,8 @@ class CreateSceneBloc extends Bloc<CreateSceneEvent, CreateSceneState>
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _sceneTypeEvent(SceneTypeEvent event, Emitter<CreateSceneState> emit) {
|
FutureOr<void> _sceneTypeEvent(
|
||||||
|
SceneTypeEvent event, Emitter<CreateSceneState> emit) {
|
||||||
// emit(CreateSceneInitial());
|
// emit(CreateSceneInitial());
|
||||||
|
|
||||||
if (event.type == CreateSceneEnum.tabToRun) {
|
if (event.type == CreateSceneEnum.tabToRun) {
|
||||||
|
|||||||
@ -24,7 +24,9 @@ class SceneBloc extends Bloc<SceneEvent, SceneState> {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
if (event.unitId.isNotEmpty) {
|
if (event.unitId.isNotEmpty) {
|
||||||
scenes = await SceneApi.getScenesByUnitId(event.unitId, showInDevice: event.showInDevice);
|
scenes = await SceneApi.getScenesByUnitId(
|
||||||
|
event.unitId, event.unit.community.uuid,
|
||||||
|
showInDevice: event.showInDevice);
|
||||||
emit(SceneLoaded(scenes, automationList));
|
emit(SceneLoaded(scenes, automationList));
|
||||||
} else {
|
} else {
|
||||||
emit(const SceneError(message: 'Unit ID is empty'));
|
emit(const SceneError(message: 'Unit ID is empty'));
|
||||||
@ -34,7 +36,8 @@ class SceneBloc extends Bloc<SceneEvent, SceneState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onLoadAutomation(LoadAutomation event, Emitter<SceneState> emit) async {
|
Future<void> _onLoadAutomation(
|
||||||
|
LoadAutomation event, Emitter<SceneState> emit) async {
|
||||||
emit(SceneLoading());
|
emit(SceneLoading());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -49,7 +52,8 @@ class SceneBloc extends Bloc<SceneEvent, SceneState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onSceneTrigger(SceneTrigger event, Emitter<SceneState> emit) async {
|
Future<void> _onSceneTrigger(
|
||||||
|
SceneTrigger event, Emitter<SceneState> emit) async {
|
||||||
final currentState = state;
|
final currentState = state;
|
||||||
if (currentState is SceneLoaded) {
|
if (currentState is SceneLoaded) {
|
||||||
emit(SceneLoaded(
|
emit(SceneLoaded(
|
||||||
@ -76,8 +80,9 @@ class SceneBloc extends Bloc<SceneEvent, SceneState> {
|
|||||||
UpdateAutomationStatus event, Emitter<SceneState> emit) async {
|
UpdateAutomationStatus event, Emitter<SceneState> emit) async {
|
||||||
final currentState = state;
|
final currentState = state;
|
||||||
if (currentState is SceneLoaded) {
|
if (currentState is SceneLoaded) {
|
||||||
final newLoadingStates = Map<String, bool>.from(currentState.loadingStates)
|
final newLoadingStates =
|
||||||
..[event.automationId] = true;
|
Map<String, bool>.from(currentState.loadingStates)
|
||||||
|
..[event.automationId] = true;
|
||||||
|
|
||||||
emit(SceneLoaded(
|
emit(SceneLoaded(
|
||||||
currentState.scenes,
|
currentState.scenes,
|
||||||
@ -86,11 +91,11 @@ class SceneBloc extends Bloc<SceneEvent, SceneState> {
|
|||||||
));
|
));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final success =
|
final success = await SceneApi.updateAutomationStatus(
|
||||||
await SceneApi.updateAutomationStatus(event.automationId, event.automationStatusUpdate);
|
event.automationId, event.automationStatusUpdate);
|
||||||
if (success) {
|
if (success) {
|
||||||
automationList =
|
automationList = await SceneApi.getAutomationByUnitId(
|
||||||
await SceneApi.getAutomationByUnitId(event.automationStatusUpdate.unitUuid);
|
event.automationStatusUpdate.spaceUuid);
|
||||||
newLoadingStates[event.automationId] = false;
|
newLoadingStates[event.automationId] = false;
|
||||||
emit(SceneLoaded(
|
emit(SceneLoaded(
|
||||||
currentState.scenes,
|
currentState.scenes,
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
|
import 'package:syncrow_app/features/app_layout/model/space_model.dart';
|
||||||
import 'package:syncrow_app/features/scene/model/update_automation.dart';
|
import 'package:syncrow_app/features/scene/model/update_automation.dart';
|
||||||
|
|
||||||
abstract class SceneEvent extends Equatable {
|
abstract class SceneEvent extends Equatable {
|
||||||
@ -11,8 +12,9 @@ abstract class SceneEvent extends Equatable {
|
|||||||
class LoadScenes extends SceneEvent {
|
class LoadScenes extends SceneEvent {
|
||||||
final String unitId;
|
final String unitId;
|
||||||
final bool showInDevice;
|
final bool showInDevice;
|
||||||
|
final SpaceModel unit;
|
||||||
|
|
||||||
const LoadScenes(this.unitId, {this.showInDevice = false});
|
const LoadScenes(this.unitId, this.unit, {this.showInDevice = false});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [unitId, showInDevice];
|
List<Object> get props => [unitId, showInDevice];
|
||||||
|
|||||||
@ -17,7 +17,7 @@ class TabBarBloc extends Bloc<TabBarEvent, TabBarState> {
|
|||||||
if (event.roomId == "-1") {
|
if (event.roomId == "-1") {
|
||||||
deviceManagerBloc.add(FetchAllDevices());
|
deviceManagerBloc.add(FetchAllDevices());
|
||||||
} else {
|
} else {
|
||||||
deviceManagerBloc.add(FetchDevicesByRoomId(event.roomId));
|
deviceManagerBloc.add(FetchDevicesByRoomId(event.roomId,event.unit));
|
||||||
}
|
}
|
||||||
emit(TabSelected(
|
emit(TabSelected(
|
||||||
roomId: event.roomId, selectedTabIndex: event.selectedIndex));
|
roomId: event.roomId, selectedTabIndex: event.selectedIndex));
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
import 'package:syncrow_app/features/app_layout/model/space_model.dart';
|
||||||
|
|
||||||
abstract class TabBarEvent {
|
abstract class TabBarEvent {
|
||||||
const TabBarEvent();
|
const TabBarEvent();
|
||||||
}
|
}
|
||||||
@ -5,5 +7,7 @@ abstract class TabBarEvent {
|
|||||||
class TabChanged extends TabBarEvent {
|
class TabChanged extends TabBarEvent {
|
||||||
final int selectedIndex;
|
final int selectedIndex;
|
||||||
final String roomId;
|
final String roomId;
|
||||||
const TabChanged({required this.selectedIndex, required this.roomId});
|
final SpaceModel unit;
|
||||||
|
const TabChanged(
|
||||||
|
{required this.selectedIndex, required this.roomId, required this.unit});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -124,7 +124,7 @@ mixin SceneLogicHelper {
|
|||||||
));
|
));
|
||||||
} else {
|
} else {
|
||||||
final createSceneModel = CreateSceneModel(
|
final createSceneModel = CreateSceneModel(
|
||||||
unitUuid: HomeCubit.getInstance().selectedSpace!.id ?? '',
|
spaceUuid: HomeCubit.getInstance().selectedSpace!.id ?? '',
|
||||||
iconId: sceneBloc.selectedIcon,
|
iconId: sceneBloc.selectedIcon,
|
||||||
showInDevice: sceneBloc.showInDeviceScreen,
|
showInDevice: sceneBloc.showInDeviceScreen,
|
||||||
sceneName: sceneName.text,
|
sceneName: sceneName.text,
|
||||||
|
|||||||
@ -39,7 +39,7 @@ class CreateAutomationModel {
|
|||||||
|
|
||||||
Map<String, dynamic> toMap([String? automationId]) {
|
Map<String, dynamic> toMap([String? automationId]) {
|
||||||
return {
|
return {
|
||||||
if (automationId == null) 'unitUuid': unitUuid,
|
if (automationId == null) 'spaceUuid': unitUuid,
|
||||||
'automationName': automationName,
|
'automationName': automationName,
|
||||||
'decisionExpr': decisionExpr,
|
'decisionExpr': decisionExpr,
|
||||||
'effectiveTime': effectiveTime.toMap(),
|
'effectiveTime': effectiveTime.toMap(),
|
||||||
@ -50,7 +50,7 @@ class CreateAutomationModel {
|
|||||||
|
|
||||||
factory CreateAutomationModel.fromMap(Map<String, dynamic> map) {
|
factory CreateAutomationModel.fromMap(Map<String, dynamic> map) {
|
||||||
return CreateAutomationModel(
|
return CreateAutomationModel(
|
||||||
unitUuid: map['unitUuid'] ?? '',
|
unitUuid: map['spaceUuid'] ?? '',
|
||||||
automationName: map['automationName'] ?? '',
|
automationName: map['automationName'] ?? '',
|
||||||
decisionExpr: map['decisionExpr'] ?? '',
|
decisionExpr: map['decisionExpr'] ?? '',
|
||||||
effectiveTime: EffectiveTime.fromMap(map['effectiveTime']),
|
effectiveTime: EffectiveTime.fromMap(map['effectiveTime']),
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import 'dart:convert';
|
|||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
|
|
||||||
class CreateSceneModel {
|
class CreateSceneModel {
|
||||||
String unitUuid;
|
String spaceUuid;
|
||||||
String iconId;
|
String iconId;
|
||||||
bool showInDevice;
|
bool showInDevice;
|
||||||
String sceneName;
|
String sceneName;
|
||||||
@ -11,7 +11,7 @@ class CreateSceneModel {
|
|||||||
List<CreateSceneAction> actions;
|
List<CreateSceneAction> actions;
|
||||||
|
|
||||||
CreateSceneModel({
|
CreateSceneModel({
|
||||||
required this.unitUuid,
|
required this.spaceUuid,
|
||||||
required this.iconId,
|
required this.iconId,
|
||||||
required this.showInDevice,
|
required this.showInDevice,
|
||||||
required this.sceneName,
|
required this.sceneName,
|
||||||
@ -20,15 +20,16 @@ class CreateSceneModel {
|
|||||||
});
|
});
|
||||||
|
|
||||||
CreateSceneModel copyWith({
|
CreateSceneModel copyWith({
|
||||||
String? unitUuid,
|
String? spaceUuid,
|
||||||
String? iconId,
|
String? iconId,
|
||||||
bool? showInDevice,
|
bool? showInDevice,
|
||||||
String? sceneName,
|
String? sceneName,
|
||||||
String? decisionExpr,
|
String? decisionExpr,
|
||||||
List<CreateSceneAction>? actions,
|
List<CreateSceneAction>? actions,
|
||||||
|
bool? showInHomePage,
|
||||||
}) {
|
}) {
|
||||||
return CreateSceneModel(
|
return CreateSceneModel(
|
||||||
unitUuid: unitUuid ?? this.unitUuid,
|
spaceUuid: spaceUuid ?? this.spaceUuid,
|
||||||
iconId: iconId ?? this.iconId,
|
iconId: iconId ?? this.iconId,
|
||||||
showInDevice: showInDevice ?? this.showInDevice,
|
showInDevice: showInDevice ?? this.showInDevice,
|
||||||
sceneName: sceneName ?? this.sceneName,
|
sceneName: sceneName ?? this.sceneName,
|
||||||
@ -39,7 +40,7 @@ class CreateSceneModel {
|
|||||||
|
|
||||||
Map<String, dynamic> toMap([String? sceneId]) {
|
Map<String, dynamic> toMap([String? sceneId]) {
|
||||||
return {
|
return {
|
||||||
if (sceneId == null) 'unitUuid': unitUuid,
|
if (sceneId == null) 'spaceUuid': spaceUuid,
|
||||||
if (iconId.isNotEmpty) 'iconUuid': iconId,
|
if (iconId.isNotEmpty) 'iconUuid': iconId,
|
||||||
'showInHomePage': showInDevice,
|
'showInHomePage': showInDevice,
|
||||||
'sceneName': sceneName,
|
'sceneName': sceneName,
|
||||||
@ -50,23 +51,24 @@ class CreateSceneModel {
|
|||||||
|
|
||||||
factory CreateSceneModel.fromMap(Map<String, dynamic> map) {
|
factory CreateSceneModel.fromMap(Map<String, dynamic> map) {
|
||||||
return CreateSceneModel(
|
return CreateSceneModel(
|
||||||
unitUuid: map['unitUuid'] ?? '',
|
spaceUuid: map['spaceUuid'] ?? '',
|
||||||
iconId: map['iconUuid'] ?? '',
|
|
||||||
showInDevice: map['showInHomePage'] ?? false,
|
showInDevice: map['showInHomePage'] ?? false,
|
||||||
|
iconId: map['iconUuid'] ?? '',
|
||||||
sceneName: map['sceneName'] ?? '',
|
sceneName: map['sceneName'] ?? '',
|
||||||
decisionExpr: map['decisionExpr'] ?? '',
|
decisionExpr: map['decisionExpr'] ?? '',
|
||||||
actions:
|
actions: List<CreateSceneAction>.from(
|
||||||
List<CreateSceneAction>.from(map['actions']?.map((x) => CreateSceneAction.fromMap(x))),
|
map['actions']?.map((x) => CreateSceneAction.fromMap(x))),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
String toJson([String? sceneId]) => json.encode(toMap(sceneId));
|
String toJson([String? sceneId]) => json.encode(toMap(sceneId));
|
||||||
|
|
||||||
factory CreateSceneModel.fromJson(String source) => CreateSceneModel.fromMap(json.decode(source));
|
factory CreateSceneModel.fromJson(String source) =>
|
||||||
|
CreateSceneModel.fromMap(json.decode(source));
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'CreateSceneModel(unitUuid: $unitUuid, sceneName: $sceneName, decisionExpr: $decisionExpr, actions: $actions)';
|
return 'CreateSceneModel(unitUuid: $spaceUuid, sceneName: $sceneName, decisionExpr: $decisionExpr, actions: $actions)';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -74,7 +76,7 @@ class CreateSceneModel {
|
|||||||
if (identical(this, other)) return true;
|
if (identical(this, other)) return true;
|
||||||
|
|
||||||
return other is CreateSceneModel &&
|
return other is CreateSceneModel &&
|
||||||
other.unitUuid == unitUuid &&
|
other.spaceUuid == spaceUuid &&
|
||||||
other.iconId == iconId &&
|
other.iconId == iconId &&
|
||||||
other.showInDevice == showInDevice &&
|
other.showInDevice == showInDevice &&
|
||||||
other.sceneName == sceneName &&
|
other.sceneName == sceneName &&
|
||||||
@ -84,7 +86,10 @@ class CreateSceneModel {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode {
|
int get hashCode {
|
||||||
return unitUuid.hashCode ^ sceneName.hashCode ^ decisionExpr.hashCode ^ actions.hashCode;
|
return spaceUuid.hashCode ^
|
||||||
|
sceneName.hashCode ^
|
||||||
|
decisionExpr.hashCode ^
|
||||||
|
actions.hashCode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,7 +135,8 @@ class CreateSceneAction {
|
|||||||
return CreateSceneAction(
|
return CreateSceneAction(
|
||||||
entityId: map['entityId'] ?? '',
|
entityId: map['entityId'] ?? '',
|
||||||
actionExecutor: map['actionExecutor'] ?? '',
|
actionExecutor: map['actionExecutor'] ?? '',
|
||||||
executorProperty: CreateSceneExecutorProperty.fromMap(map['executorProperty']),
|
executorProperty:
|
||||||
|
CreateSceneExecutorProperty.fromMap(map['executorProperty']),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,7 +160,8 @@ class CreateSceneAction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => entityId.hashCode ^ actionExecutor.hashCode ^ executorProperty.hashCode;
|
int get hashCode =>
|
||||||
|
entityId.hashCode ^ actionExecutor.hashCode ^ executorProperty.hashCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
class CreateSceneExecutorProperty {
|
class CreateSceneExecutorProperty {
|
||||||
@ -218,5 +225,6 @@ class CreateSceneExecutorProperty {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => functionCode.hashCode ^ functionValue.hashCode ^ delaySeconds.hashCode;
|
int get hashCode =>
|
||||||
|
functionCode.hashCode ^ functionValue.hashCode ^ delaySeconds.hashCode;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,28 +25,34 @@ class SceneDetailsModel {
|
|||||||
this.effectiveTime,
|
this.effectiveTime,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory SceneDetailsModel.fromRawJson(String str) => SceneDetailsModel.fromJson(json.decode(str));
|
factory SceneDetailsModel.fromRawJson(String str) =>
|
||||||
|
SceneDetailsModel.fromJson(json.decode(str));
|
||||||
|
|
||||||
String toRawJson() => json.encode(toJson());
|
String toRawJson() => json.encode(toJson());
|
||||||
|
|
||||||
factory SceneDetailsModel.fromJson(Map<String, dynamic> json) => SceneDetailsModel(
|
factory SceneDetailsModel.fromJson(Map<String, dynamic> json) =>
|
||||||
id: json["id"],
|
SceneDetailsModel(
|
||||||
name: json["name"],
|
id: json["uuid"] ?? json["id"],
|
||||||
status: json["status"],
|
name: json["name"],
|
||||||
type: json["type"],
|
status: json["status"],
|
||||||
actions: (json["actions"] as List)
|
type: json["type"],
|
||||||
.map((x) => Action.fromJson(x))
|
actions: (json["actions"] as List)
|
||||||
.where((x) => x != null)
|
.map((x) => Action.fromJson(x))
|
||||||
.toList()
|
.where((x) => x != null)
|
||||||
.cast<Action>(),
|
.toList()
|
||||||
conditions: json["conditions"] != null
|
.cast<Action>(),
|
||||||
? (json["conditions"] as List).map((x) => Condition.fromJson(x)).toList()
|
conditions: json["conditions"] != null
|
||||||
: null,
|
? (json["conditions"] as List)
|
||||||
decisionExpr: json["decisionExpr"],
|
.map((x) => Condition.fromJson(x))
|
||||||
effectiveTime:
|
.toList()
|
||||||
json["effectiveTime"] != null ? EffectiveTime.fromJson(json["effectiveTime"]) : null,
|
: null,
|
||||||
icon: json["iconUuid"] != null ? json["iconUuid"] ?? '' : '',
|
decisionExpr: json["decisionExpr"],
|
||||||
showInDevice: json['showInHome'] != null ? json['showInHome'] ?? false : false);
|
effectiveTime: json["effectiveTime"] != null
|
||||||
|
? EffectiveTime.fromJson(json["effectiveTime"])
|
||||||
|
: null,
|
||||||
|
icon: json["iconUuid"] != null ? json["iconUuid"] ?? '' : '',
|
||||||
|
showInDevice:
|
||||||
|
json['showInHome'] != null ? json['showInHome'] ?? false : false);
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
Map<String, dynamic> toJson() => {
|
||||||
"id": id,
|
"id": id,
|
||||||
@ -54,8 +60,9 @@ class SceneDetailsModel {
|
|||||||
"status": status,
|
"status": status,
|
||||||
"type": type,
|
"type": type,
|
||||||
"actions": List<dynamic>.from(actions.map((x) => x.toJson())),
|
"actions": List<dynamic>.from(actions.map((x) => x.toJson())),
|
||||||
"conditions":
|
"conditions": conditions != null
|
||||||
conditions != null ? List<dynamic>.from(conditions!.map((x) => x.toJson())) : null,
|
? List<dynamic>.from(conditions!.map((x) => x.toJson()))
|
||||||
|
: null,
|
||||||
"decisionExpr": decisionExpr,
|
"decisionExpr": decisionExpr,
|
||||||
"effectiveTime": effectiveTime?.toJson(),
|
"effectiveTime": effectiveTime?.toJson(),
|
||||||
};
|
};
|
||||||
@ -116,7 +123,8 @@ class ExecutorProperty {
|
|||||||
this.delaySeconds,
|
this.delaySeconds,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory ExecutorProperty.fromJson(Map<String, dynamic> json) => ExecutorProperty(
|
factory ExecutorProperty.fromJson(Map<String, dynamic> json) =>
|
||||||
|
ExecutorProperty(
|
||||||
functionCode: json["functionCode"] ?? '',
|
functionCode: json["functionCode"] ?? '',
|
||||||
functionValue: json["functionValue"] ?? '',
|
functionValue: json["functionValue"] ?? '',
|
||||||
delaySeconds: json["delaySeconds"] ?? 0,
|
delaySeconds: json["delaySeconds"] ?? 0,
|
||||||
@ -142,7 +150,8 @@ class Condition {
|
|||||||
required this.expr,
|
required this.expr,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory Condition.fromRawJson(String str) => Condition.fromJson(json.decode(str));
|
factory Condition.fromRawJson(String str) =>
|
||||||
|
Condition.fromJson(json.decode(str));
|
||||||
|
|
||||||
String toRawJson() => json.encode(toJson());
|
String toRawJson() => json.encode(toJson());
|
||||||
|
|
||||||
@ -200,7 +209,8 @@ class EffectiveTime {
|
|||||||
required this.loops,
|
required this.loops,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory EffectiveTime.fromRawJson(String str) => EffectiveTime.fromJson(json.decode(str));
|
factory EffectiveTime.fromRawJson(String str) =>
|
||||||
|
EffectiveTime.fromJson(json.decode(str));
|
||||||
|
|
||||||
String toRawJson() => json.encode(toJson());
|
String toRawJson() => json.encode(toJson());
|
||||||
|
|
||||||
|
|||||||
@ -3,32 +3,40 @@ import 'dart:typed_data';
|
|||||||
|
|
||||||
class ScenesModel {
|
class ScenesModel {
|
||||||
final String id;
|
final String id;
|
||||||
|
final String? sceneTuyaId;
|
||||||
final String name;
|
final String name;
|
||||||
final String status;
|
final String status;
|
||||||
final String type;
|
final String type;
|
||||||
final String icon;
|
final String? icon;
|
||||||
|
|
||||||
ScenesModel(
|
ScenesModel(
|
||||||
{required this.id,
|
{required this.id,
|
||||||
|
this.sceneTuyaId,
|
||||||
required this.name,
|
required this.name,
|
||||||
required this.status,
|
required this.status,
|
||||||
required this.type,
|
required this.type,
|
||||||
required this.icon});
|
this.icon});
|
||||||
|
|
||||||
factory ScenesModel.fromRawJson(String str) => ScenesModel.fromJson(json.decode(str));
|
factory ScenesModel.fromRawJson(String str) =>
|
||||||
|
ScenesModel.fromJson(json.decode(str));
|
||||||
|
|
||||||
String toRawJson() => json.encode(toJson());
|
String toRawJson() => json.encode(toJson());
|
||||||
Uint8List get iconInBytes => base64Decode(icon);
|
Uint8List get iconInBytes => base64Decode(icon ?? '');
|
||||||
|
|
||||||
factory ScenesModel.fromJson(Map<String, dynamic> json) => ScenesModel(
|
|
||||||
id: json["id"],
|
|
||||||
name: json["name"] ?? '',
|
|
||||||
status: json["status"] ?? '',
|
|
||||||
type: json["type"] ?? '',
|
|
||||||
icon: json["icon"] ?? '');
|
|
||||||
|
|
||||||
|
factory ScenesModel.fromJson(Map<String, dynamic> json) {
|
||||||
|
return ScenesModel(
|
||||||
|
id: json["id"] ?? json["uuid"] ?? '', // Fallback to empty string if id is null
|
||||||
|
sceneTuyaId: json["sceneTuyaId"] as String?, // Nullable
|
||||||
|
name: json["name"] ?? '', // Fallback to empty string if name is null
|
||||||
|
status:
|
||||||
|
json["status"] ?? '', // Fallback to empty string if status is null
|
||||||
|
type: json["type"] ?? '', // Fallback to empty string if type is null
|
||||||
|
icon: json["icon"] as String?, // Nullable
|
||||||
|
);
|
||||||
|
}
|
||||||
Map<String, dynamic> toJson() => {
|
Map<String, dynamic> toJson() => {
|
||||||
"id": id,
|
"id": id,
|
||||||
|
"sceneTuyaId": sceneTuyaId ?? '',
|
||||||
"name": name,
|
"name": name,
|
||||||
"status": status,
|
"status": status,
|
||||||
"type": type,
|
"type": type,
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
class AutomationStatusUpdate {
|
class AutomationStatusUpdate {
|
||||||
final String unitUuid;
|
final String spaceUuid;
|
||||||
final bool isEnable;
|
final bool isEnable;
|
||||||
|
|
||||||
AutomationStatusUpdate({
|
AutomationStatusUpdate({
|
||||||
required this.unitUuid,
|
required this.spaceUuid,
|
||||||
required this.isEnable,
|
required this.isEnable,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -16,23 +16,23 @@ class AutomationStatusUpdate {
|
|||||||
|
|
||||||
factory AutomationStatusUpdate.fromJson(Map<String, dynamic> json) =>
|
factory AutomationStatusUpdate.fromJson(Map<String, dynamic> json) =>
|
||||||
AutomationStatusUpdate(
|
AutomationStatusUpdate(
|
||||||
unitUuid: json["unitUuid"],
|
spaceUuid: json["spaceUuid"],
|
||||||
isEnable: json["isEnable"],
|
isEnable: json["isEnable"],
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
Map<String, dynamic> toJson() => {
|
||||||
"unitUuid": unitUuid,
|
"spaceUuid": spaceUuid,
|
||||||
"isEnable": isEnable,
|
"isEnable": isEnable,
|
||||||
};
|
};
|
||||||
|
|
||||||
factory AutomationStatusUpdate.fromMap(Map<String, dynamic> map) =>
|
factory AutomationStatusUpdate.fromMap(Map<String, dynamic> map) =>
|
||||||
AutomationStatusUpdate(
|
AutomationStatusUpdate(
|
||||||
unitUuid: map["unitUuid"],
|
spaceUuid: map["spaceUuid"],
|
||||||
isEnable: map["isEnable"],
|
isEnable: map["isEnable"],
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> toMap() => {
|
Map<String, dynamic> toMap() => {
|
||||||
"unitUuid": unitUuid,
|
"spaceUuid": spaceUuid,
|
||||||
"isEnable": isEnable,
|
"isEnable": isEnable,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package: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/app_layout/model/space_model.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/room_model.dart';
|
import 'package:syncrow_app/features/devices/model/subspace_model.dart';
|
||||||
import 'package:syncrow_app/features/scene/bloc/tab_change/tab_change_bloc.dart';
|
import 'package:syncrow_app/features/scene/bloc/tab_change/tab_change_bloc.dart';
|
||||||
import 'package:syncrow_app/features/scene/bloc/tab_change/tab_change_event.dart';
|
import 'package:syncrow_app/features/scene/bloc/tab_change/tab_change_event.dart';
|
||||||
import 'package:syncrow_app/features/scene/widgets/scene_devices/scene_devices_body.dart';
|
import 'package:syncrow_app/features/scene/widgets/scene_devices/scene_devices_body.dart';
|
||||||
@ -26,20 +27,21 @@ class _SceneRoomsTabBarDevicesViewState
|
|||||||
extends State<SceneRoomsTabBarDevicesView>
|
extends State<SceneRoomsTabBarDevicesView>
|
||||||
with SingleTickerProviderStateMixin {
|
with SingleTickerProviderStateMixin {
|
||||||
late final TabController _tabController;
|
late final TabController _tabController;
|
||||||
List<RoomModel>? rooms = [];
|
List<SubSpaceModel>? rooms = [];
|
||||||
|
late final SpaceModel selectedSpace;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
rooms = List.from(HomeCubit.getInstance().selectedSpace?.rooms ?? []);
|
selectedSpace = HomeCubit.getInstance().selectedSpace!;
|
||||||
|
rooms = List.from(HomeCubit.getInstance().selectedSpace?.subspaces ?? []);
|
||||||
if (rooms != null) {
|
if (rooms != null) {
|
||||||
if (rooms![0].id != '-1') {
|
if (rooms![0].id != '-1') {
|
||||||
rooms?.insert(
|
rooms?.insert(
|
||||||
0,
|
0,
|
||||||
RoomModel(
|
SubSpaceModel(
|
||||||
name: 'All Devices',
|
name: 'All Devices',
|
||||||
devices: DevicesCubit.getInstance().allDevices,
|
devices: DevicesCubit.getInstance().allDevices,
|
||||||
id: '-1',
|
id: '-1',
|
||||||
type: SpaceType.Room,
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -56,8 +58,10 @@ class _SceneRoomsTabBarDevicesViewState
|
|||||||
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 ?? ''));
|
selectedIndex: value,
|
||||||
|
roomId: rooms?[value].id ?? '',
|
||||||
|
unit: selectedSpace));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
|
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
|
||||||
|
import 'package:syncrow_app/features/app_layout/model/community_model.dart';
|
||||||
|
import 'package:syncrow_app/features/app_layout/model/space_model.dart';
|
||||||
import 'package:syncrow_app/features/devices/view/widgets/scene_listview.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/scene_listview.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';
|
||||||
import 'package:syncrow_app/features/scene/bloc/scene_bloc/scene_bloc.dart';
|
import 'package:syncrow_app/features/scene/bloc/scene_bloc/scene_bloc.dart';
|
||||||
@ -21,32 +23,47 @@ class SceneView extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocProvider(
|
return BlocProvider(
|
||||||
create: (BuildContext context) => SceneBloc()
|
create: (BuildContext context) => SceneBloc()
|
||||||
..add(LoadScenes(HomeCubit.getInstance().selectedSpace?.id ?? '', showInDevice: pageType))
|
..add(LoadScenes(
|
||||||
|
HomeCubit.getInstance().selectedSpace?.id ?? '',
|
||||||
|
HomeCubit.getInstance().selectedSpace ??
|
||||||
|
SpaceModel(
|
||||||
|
id: '-1',
|
||||||
|
name: '',
|
||||||
|
community: Community(
|
||||||
|
uuid: '-1',
|
||||||
|
name: '',
|
||||||
|
)),
|
||||||
|
showInDevice: pageType))
|
||||||
..add(LoadAutomation(HomeCubit.getInstance().selectedSpace?.id ?? '')),
|
..add(LoadAutomation(HomeCubit.getInstance().selectedSpace?.id ?? '')),
|
||||||
child: BlocBuilder<CreateSceneBloc, CreateSceneState>(
|
child: BlocBuilder<CreateSceneBloc, CreateSceneState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
if (state is DeleteSceneSuccess) {
|
if (state is DeleteSceneSuccess) {
|
||||||
if (state.success) {
|
if (state.success) {
|
||||||
|
BlocProvider.of<SceneBloc>(context).add(LoadScenes(
|
||||||
|
HomeCubit.getInstance().selectedSpace!.id!,HomeCubit.getInstance().selectedSpace!,
|
||||||
|
showInDevice: pageType));
|
||||||
BlocProvider.of<SceneBloc>(context).add(
|
BlocProvider.of<SceneBloc>(context).add(
|
||||||
LoadScenes(HomeCubit.getInstance().selectedSpace!.id!, showInDevice: pageType));
|
LoadAutomation(HomeCubit.getInstance().selectedSpace!.id!));
|
||||||
BlocProvider.of<SceneBloc>(context)
|
|
||||||
.add(LoadAutomation(HomeCubit.getInstance().selectedSpace!.id!));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (state is CreateSceneWithTasks) {
|
if (state is CreateSceneWithTasks) {
|
||||||
if (state.success == true) {
|
if (state.success == true) {
|
||||||
|
BlocProvider.of<SceneBloc>(context).add(LoadScenes(
|
||||||
|
HomeCubit.getInstance().selectedSpace!.id!,HomeCubit.getInstance().selectedSpace!,
|
||||||
|
showInDevice: pageType));
|
||||||
BlocProvider.of<SceneBloc>(context).add(
|
BlocProvider.of<SceneBloc>(context).add(
|
||||||
LoadScenes(HomeCubit.getInstance().selectedSpace!.id!, showInDevice: pageType));
|
LoadAutomation(HomeCubit.getInstance().selectedSpace!.id!));
|
||||||
BlocProvider.of<SceneBloc>(context)
|
context
|
||||||
.add(LoadAutomation(HomeCubit.getInstance().selectedSpace!.id!));
|
.read<SmartSceneSelectBloc>()
|
||||||
context.read<SmartSceneSelectBloc>().add(const SmartSceneClearEvent());
|
.add(const SmartSceneClearEvent());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return BlocListener<SceneBloc, SceneState>(
|
return BlocListener<SceneBloc, SceneState>(
|
||||||
listener: (context, state) {
|
listener: (context, state) {
|
||||||
if (state is SceneTriggerSuccess) {
|
if (state is SceneTriggerSuccess) {
|
||||||
context.showCustomSnackbar(
|
context.showCustomSnackbar(
|
||||||
message: 'Scene ${state.sceneName} triggered successfully!');
|
message:
|
||||||
|
'Scene ${state.sceneName} triggered successfully!');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: HomeCubit.getInstance().spaces?.isEmpty ?? true
|
child: HomeCubit.getInstance().spaces?.isEmpty ?? true
|
||||||
@ -83,25 +100,30 @@ class SceneView extends StatelessWidget {
|
|||||||
child: ListView(
|
child: ListView(
|
||||||
children: [
|
children: [
|
||||||
Theme(
|
Theme(
|
||||||
data: ThemeData()
|
data: ThemeData().copyWith(
|
||||||
.copyWith(dividerColor: Colors.transparent),
|
dividerColor: Colors.transparent),
|
||||||
child: ExpansionTile(
|
child: ExpansionTile(
|
||||||
tilePadding: const EdgeInsets.symmetric(horizontal: 6),
|
tilePadding:
|
||||||
|
const EdgeInsets.symmetric(
|
||||||
|
horizontal: 6),
|
||||||
initiallyExpanded: true,
|
initiallyExpanded: true,
|
||||||
iconColor: ColorsManager.grayColor,
|
iconColor: ColorsManager.grayColor,
|
||||||
title: const BodyMedium(text: 'Tap to run routines'),
|
title: const BodyMedium(
|
||||||
|
text: 'Tap to run routines'),
|
||||||
children: [
|
children: [
|
||||||
scenes.isNotEmpty
|
scenes.isNotEmpty
|
||||||
? SceneGrid(
|
? SceneGrid(
|
||||||
scenes: scenes,
|
scenes: scenes,
|
||||||
loadingSceneId: state.loadingSceneId,
|
loadingSceneId:
|
||||||
|
state.loadingSceneId,
|
||||||
disablePlayButton: false,
|
disablePlayButton: false,
|
||||||
loadingStates:
|
loadingStates: state
|
||||||
state.loadingStates, // Add this line
|
.loadingStates, // Add this line
|
||||||
)
|
)
|
||||||
: const Center(
|
: const Center(
|
||||||
child: BodyMedium(
|
child: BodyMedium(
|
||||||
text: 'No scenes have been added yet',
|
text:
|
||||||
|
'No scenes have been added yet',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
@ -111,25 +133,30 @@ class SceneView extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
Theme(
|
Theme(
|
||||||
data: ThemeData()
|
data: ThemeData().copyWith(
|
||||||
.copyWith(dividerColor: Colors.transparent),
|
dividerColor: Colors.transparent),
|
||||||
child: ExpansionTile(
|
child: ExpansionTile(
|
||||||
initiallyExpanded: true,
|
initiallyExpanded: true,
|
||||||
iconColor: ColorsManager.grayColor,
|
iconColor: ColorsManager.grayColor,
|
||||||
tilePadding: const EdgeInsets.symmetric(horizontal: 6),
|
tilePadding:
|
||||||
title: const BodyMedium(text: 'Automation'),
|
const EdgeInsets.symmetric(
|
||||||
|
horizontal: 6),
|
||||||
|
title: const BodyMedium(
|
||||||
|
text: 'Automation'),
|
||||||
children: [
|
children: [
|
||||||
automationList.isNotEmpty
|
automationList.isNotEmpty
|
||||||
? SceneGrid(
|
? SceneGrid(
|
||||||
scenes: automationList,
|
scenes: automationList,
|
||||||
loadingSceneId: state.loadingSceneId,
|
loadingSceneId:
|
||||||
|
state.loadingSceneId,
|
||||||
disablePlayButton: true,
|
disablePlayButton: true,
|
||||||
loadingStates:
|
loadingStates: state
|
||||||
state.loadingStates, // Add this line
|
.loadingStates, // Add this line
|
||||||
)
|
)
|
||||||
: const Center(
|
: const Center(
|
||||||
child: BodyMedium(
|
child: BodyMedium(
|
||||||
text: 'No automations have been added yet',
|
text:
|
||||||
|
'No automations have been added yet',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
|
|||||||
@ -24,7 +24,7 @@ class DeleteRoutineButton extends StatelessWidget {
|
|||||||
if (state.success) {
|
if (state.success) {
|
||||||
navigateToRoute(context, Routes.homeRoute);
|
navigateToRoute(context, Routes.homeRoute);
|
||||||
BlocProvider.of<SceneBloc>(context)
|
BlocProvider.of<SceneBloc>(context)
|
||||||
.add(LoadScenes(HomeCubit.getInstance().selectedSpace!.id!));
|
.add(LoadScenes(HomeCubit.getInstance().selectedSpace!.id!,HomeCubit.getInstance().selectedSpace!));
|
||||||
BlocProvider.of<SceneBloc>(context).add(
|
BlocProvider.of<SceneBloc>(context).add(
|
||||||
LoadAutomation(HomeCubit.getInstance().selectedSpace!.id!));
|
LoadAutomation(HomeCubit.getInstance().selectedSpace!.id!));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import 'package:flutter_svg/flutter_svg.dart';
|
|||||||
import 'package:syncrow_app/features/devices/bloc/device_manager_bloc/device_manager_bloc.dart';
|
import 'package:syncrow_app/features/devices/bloc/device_manager_bloc/device_manager_bloc.dart';
|
||||||
import 'package:syncrow_app/features/devices/bloc/device_manager_bloc/device_manager_state.dart';
|
import 'package:syncrow_app/features/devices/bloc/device_manager_bloc/device_manager_state.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/room_model.dart';
|
import 'package:syncrow_app/features/devices/model/room_model.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/model/subspace_model.dart';
|
||||||
import 'package:syncrow_app/features/scene/bloc/tab_change/tab_change_bloc.dart';
|
import 'package:syncrow_app/features/scene/bloc/tab_change/tab_change_bloc.dart';
|
||||||
import 'package:syncrow_app/features/scene/bloc/tab_change/tab_change_state.dart';
|
import 'package:syncrow_app/features/scene/bloc/tab_change/tab_change_state.dart';
|
||||||
import 'package:syncrow_app/features/scene/enum/create_scene_enum.dart';
|
import 'package:syncrow_app/features/scene/enum/create_scene_enum.dart';
|
||||||
@ -24,7 +25,7 @@ class SceneDevicesBody extends StatelessWidget {
|
|||||||
}) : _tabController = tabController;
|
}) : _tabController = tabController;
|
||||||
|
|
||||||
final TabController _tabController;
|
final TabController _tabController;
|
||||||
final List<RoomModel>? rooms;
|
final List<SubSpaceModel>? rooms;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -76,7 +77,7 @@ class SceneDevicesBody extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildRoomTab(
|
Widget _buildRoomTab(
|
||||||
RoomModel room, BuildContext context, bool isAutomationDeviceStatus) {
|
SubSpaceModel room, BuildContext context, bool isAutomationDeviceStatus) {
|
||||||
return BlocBuilder<DeviceManagerBloc, DeviceManagerState>(
|
return BlocBuilder<DeviceManagerBloc, DeviceManagerState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
if (state.loading && state.devices == null) {
|
if (state.loading && state.devices == null) {
|
||||||
|
|||||||
@ -38,8 +38,8 @@ class SceneItem extends StatelessWidget {
|
|||||||
onTap: () {
|
onTap: () {
|
||||||
context.read<SmartSceneSelectBloc>().add(const SmartSceneClearEvent());
|
context.read<SmartSceneSelectBloc>().add(const SmartSceneClearEvent());
|
||||||
if (disablePlayButton == false) {
|
if (disablePlayButton == false) {
|
||||||
BlocProvider.of<CreateSceneBloc>(context)
|
BlocProvider.of<CreateSceneBloc>(context).add(
|
||||||
.add(FetchSceneTasksEvent(sceneId: scene.id, isAutomation: false));
|
FetchSceneTasksEvent(sceneId: scene.id, isAutomation: false));
|
||||||
|
|
||||||
/// the state to set the scene type must be after the fetch
|
/// the state to set the scene type must be after the fetch
|
||||||
BlocProvider.of<CreateSceneBloc>(context)
|
BlocProvider.of<CreateSceneBloc>(context)
|
||||||
@ -73,22 +73,32 @@ class SceneItem extends StatelessWidget {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
if (!disablePlayButton)
|
if (!disablePlayButton && scene.iconInBytes != null && scene.iconInBytes.isNotEmpty)
|
||||||
Image.memory(
|
Image.memory(
|
||||||
|
scene.iconInBytes,
|
||||||
|
height: 32,
|
||||||
|
width: 32,
|
||||||
|
fit: BoxFit.fill,
|
||||||
|
errorBuilder: (context, error, stackTrace) => Image.asset(
|
||||||
|
Assets.assetsIconsLogo,
|
||||||
|
height: 32,
|
||||||
|
width: 32,
|
||||||
|
fit: BoxFit.fill),
|
||||||
|
),
|
||||||
|
if (disablePlayButton || scene.iconInBytes == null || scene.iconInBytes.isEmpty)
|
||||||
|
SvgPicture.asset(
|
||||||
|
Assets.automationIcon,
|
||||||
height: 32,
|
height: 32,
|
||||||
width: 32,
|
width: 32,
|
||||||
scene.iconInBytes,
|
|
||||||
fit: BoxFit.fill,
|
fit: BoxFit.fill,
|
||||||
errorBuilder: (context, error, stackTrace) =>
|
|
||||||
Image.asset(height: 32, width: 32, fit: BoxFit.fill, Assets.assetsIconsLogo),
|
|
||||||
),
|
),
|
||||||
if (disablePlayButton)
|
|
||||||
SvgPicture.asset(height: 32, width: 32, fit: BoxFit.fill, Assets.automationIcon),
|
|
||||||
disablePlayButton == false
|
disablePlayButton == false
|
||||||
? IconButton(
|
? IconButton(
|
||||||
padding: EdgeInsets.zero,
|
padding: EdgeInsets.zero,
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
context.read<SceneBloc>().add(SceneTrigger(scene.id, scene.name));
|
context
|
||||||
|
.read<SceneBloc>()
|
||||||
|
.add(SceneTrigger(scene.id, scene.name));
|
||||||
},
|
},
|
||||||
icon: isLoading
|
icon: isLoading
|
||||||
? const Center(
|
? const Center(
|
||||||
@ -110,11 +120,15 @@ class SceneItem extends StatelessWidget {
|
|||||||
activeColor: ColorsManager.primaryColor,
|
activeColor: ColorsManager.primaryColor,
|
||||||
value: scene.status == 'enable' ? true : false,
|
value: scene.status == 'enable' ? true : false,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
context.read<SceneBloc>().add(UpdateAutomationStatus(
|
context.read<SceneBloc>().add(
|
||||||
automationStatusUpdate: AutomationStatusUpdate(
|
UpdateAutomationStatus(
|
||||||
isEnable: value,
|
automationStatusUpdate:
|
||||||
unitUuid: HomeCubit.getInstance().selectedSpace!.id!),
|
AutomationStatusUpdate(
|
||||||
automationId: scene.id));
|
isEnable: value,
|
||||||
|
spaceUuid: HomeCubit.getInstance()
|
||||||
|
.selectedSpace!
|
||||||
|
.id!),
|
||||||
|
automationId: scene.id));
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@ -17,7 +17,7 @@ class SmartEnableTabRun extends StatelessWidget {
|
|||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
child: BlocBuilder<SceneBloc, SceneState>(
|
child: BlocBuilder<SceneBloc, SceneState>(
|
||||||
bloc: context.read<SceneBloc>()
|
bloc: context.read<SceneBloc>()
|
||||||
..add(LoadScenes(HomeCubit.getInstance().selectedSpace?.id ?? '')),
|
..add(LoadScenes(HomeCubit.getInstance().selectedSpace?.id ?? '',HomeCubit.getInstance().selectedSpace!)),
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
if (state is SceneLoading) {
|
if (state is SceneLoading) {
|
||||||
return const Align(
|
return const Align(
|
||||||
|
|||||||
@ -1,5 +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/app_layout/model/community_model.dart';
|
||||||
|
import 'package:syncrow_app/features/app_layout/model/space_model.dart';
|
||||||
import 'package:syncrow_app/features/app_layout/view/app_layout.dart';
|
import 'package:syncrow_app/features/app_layout/view/app_layout.dart';
|
||||||
import 'package:syncrow_app/features/auth/view/otp_view.dart';
|
import 'package:syncrow_app/features/auth/view/otp_view.dart';
|
||||||
import 'package:syncrow_app/features/auth/view/login_view.dart';
|
import 'package:syncrow_app/features/auth/view/login_view.dart';
|
||||||
@ -84,9 +86,18 @@ class Router {
|
|||||||
DeviceManagerBloc()..add(FetchAllDevices()),
|
DeviceManagerBloc()..add(FetchAllDevices()),
|
||||||
),
|
),
|
||||||
BlocProvider(
|
BlocProvider(
|
||||||
create: (BuildContext context) => TabBarBloc(
|
create: (BuildContext context) =>
|
||||||
context.read<DeviceManagerBloc>())
|
TabBarBloc(context.read<DeviceManagerBloc>())
|
||||||
..add(const TabChanged(selectedIndex: 0, roomId: '-1')),
|
..add(TabChanged(
|
||||||
|
selectedIndex: 0,
|
||||||
|
roomId: '-1',
|
||||||
|
unit: SpaceModel(
|
||||||
|
id: '-1',
|
||||||
|
name: '',
|
||||||
|
community: Community(
|
||||||
|
uuid: '-1',
|
||||||
|
name: '',
|
||||||
|
)))),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
child: const SceneRoomsTabBarDevicesView(),
|
child: const SceneRoomsTabBarDevicesView(),
|
||||||
|
|||||||
@ -53,17 +53,26 @@ abstract class ApiEndpoints {
|
|||||||
//POST
|
//POST
|
||||||
static const String addUnit = '/unit';
|
static const String addUnit = '/unit';
|
||||||
static const String addUnitToUser = '/unit/user';
|
static const String addUnitToUser = '/unit/user';
|
||||||
|
static const String verifyInvitationCode =
|
||||||
|
'/user/{userUuid}/spaces/verify-code';
|
||||||
|
|
||||||
//GET
|
//GET
|
||||||
static const String unitByUuid = '/unit/';
|
static const String unitByUuid = '/unit/';
|
||||||
static const String unitChild = '/unit/child/';
|
static const String listSubspace =
|
||||||
|
'/communities/{communityUuid}/spaces/{spaceUuid}/subspaces';
|
||||||
static const String unitParent = '/unit/parent/{unitUuid}';
|
static const String unitParent = '/unit/parent/{unitUuid}';
|
||||||
static const String unitUser = '/unit/user/';
|
static const String unitUser = '/unit/user/';
|
||||||
static const String invitationCode = '/unit/{unitUuid}/invitation-code';
|
static const String invitationCode =
|
||||||
static const String verifyInvitationCode = '/unit/user/verify-code';
|
'/communities/{communityUuid}/spaces/{unitUuid}/invitation-code';
|
||||||
|
|
||||||
//PUT
|
//PUT
|
||||||
static const String renameUnit = '/unit/{unitUuid}';
|
static const String renameUnit = '/unit/{unitUuid}';
|
||||||
|
|
||||||
|
//Subspace Module
|
||||||
|
//POST
|
||||||
|
static const String addSubSpace =
|
||||||
|
'/communities/{communityUuid}/spaces/{spaceUuid}/subspaces';
|
||||||
|
|
||||||
///Room Module
|
///Room Module
|
||||||
//POST
|
//POST
|
||||||
static const String addRoom = '/room';
|
static const String addRoom = '/room';
|
||||||
@ -75,6 +84,12 @@ abstract class ApiEndpoints {
|
|||||||
//PUT
|
//PUT
|
||||||
static const String renameRoom = '/room/{roomUuid}';
|
static const String renameRoom = '/room/{roomUuid}';
|
||||||
|
|
||||||
|
//SPACE Module
|
||||||
|
//GET
|
||||||
|
static const String userSpaces = '/user/{userUuid}/spaces';
|
||||||
|
static const String spaceDevices =
|
||||||
|
'/communities/{communityUuid}/spaces/{spaceUuid}/devices';
|
||||||
|
|
||||||
///Group Module
|
///Group Module
|
||||||
//POST
|
//POST
|
||||||
static const String addGroup = '/group';
|
static const String addGroup = '/group';
|
||||||
@ -101,12 +116,15 @@ abstract class ApiEndpoints {
|
|||||||
static const String openDoorLock = '/door-lock/open/{doorLockUuid}';
|
static const String openDoorLock = '/door-lock/open/{doorLockUuid}';
|
||||||
|
|
||||||
//GET
|
//GET
|
||||||
static const String deviceByRoom = '/device/room';
|
static const String deviceByRoom =
|
||||||
|
'/communities/{communityUuid}/spaces/{spaceUuid}/subspaces/{subSpaceUuid}/devices';
|
||||||
static const String deviceByUuid = '/device/{deviceUuid}';
|
static const String deviceByUuid = '/device/{deviceUuid}';
|
||||||
static const String deviceFunctions = '/device/{deviceUuid}/functions';
|
static const String deviceFunctions = '/device/{deviceUuid}/functions';
|
||||||
static const String gatewayApi = '/device/gateway/{gatewayUuid}/devices';
|
static const String gatewayApi = '/device/gateway/{gatewayUuid}/devices';
|
||||||
static const String deviceFunctionsStatus = '/device/{deviceUuid}/functions/status';
|
static const String deviceFunctionsStatus =
|
||||||
static const String powerClamp = '/device/{powerClampUuid}/power-clamp/status';
|
'/device/{deviceUuid}/functions/status';
|
||||||
|
static const String powerClamp =
|
||||||
|
'/device/{powerClampUuid}/power-clamp/status';
|
||||||
|
|
||||||
///Device Permission Module
|
///Device Permission Module
|
||||||
//POST
|
//POST
|
||||||
@ -116,18 +134,20 @@ abstract class ApiEndpoints {
|
|||||||
//PUT
|
//PUT
|
||||||
static const String editDevicePermission = '/device-permission/edit/{userId}';
|
static const String editDevicePermission = '/device-permission/edit/{userId}';
|
||||||
|
|
||||||
static const String assignDeviceToRoom = '/device/room';
|
static const String assignDeviceToRoom =
|
||||||
|
'/communities/{communityUuid}/spaces/{spaceUuid}/subspaces/{subSpaceUuid}/devices/{deviceUuid}';
|
||||||
|
|
||||||
/// Scene & Automation API ////////////////////
|
/// Scene & Automation API ////////////////////
|
||||||
/// POST
|
/// POST
|
||||||
static const String createScene = '/scene/tap-to-run';
|
static const String createScene = '/scene/tap-to-run';
|
||||||
static const String triggerScene = '/scene/tap-to-run/trigger/{sceneId}';
|
static const String triggerScene = '/scene/tap-to-run/{sceneId}/trigger';
|
||||||
static const String createAutomation = '/automation';
|
static const String createAutomation = '/automation';
|
||||||
|
|
||||||
/// GET
|
/// GET
|
||||||
static const String getUnitScenes = '/scene/tap-to-run/{unitUuid}';
|
static const String getUnitScenes =
|
||||||
|
'/communities/{communityUuid}/spaces/{spaceUuid}/scenes';
|
||||||
|
|
||||||
static const String getScene = '/scene/tap-to-run/details/{sceneId}';
|
static const String getScene = '/scene/tap-to-run/{sceneId}';
|
||||||
static const String getIconScene = '/scene/icon';
|
static const String getIconScene = '/scene/icon';
|
||||||
|
|
||||||
static const String getUnitAutomation = '/automation/{unitUuid}';
|
static const String getUnitAutomation = '/automation/{unitUuid}';
|
||||||
@ -144,10 +164,9 @@ abstract class ApiEndpoints {
|
|||||||
'/automation/status/{automationId}';
|
'/automation/status/{automationId}';
|
||||||
|
|
||||||
/// DELETE
|
/// DELETE
|
||||||
static const String deleteScene = '/scene/tap-to-run/{unitUuid}/{sceneId}';
|
static const String deleteScene = '/scene/tap-to-run/{sceneId}';
|
||||||
|
|
||||||
static const String deleteAutomation =
|
static const String deleteAutomation = '/automation/{automationId}';
|
||||||
'/automation/{unitUuid}/{automationId}';
|
|
||||||
|
|
||||||
//////////////////////Door Lock //////////////////////
|
//////////////////////Door Lock //////////////////////
|
||||||
//online
|
//online
|
||||||
|
|||||||
@ -65,6 +65,7 @@ class DevicesAPI {
|
|||||||
showServerMessage: false,
|
showServerMessage: false,
|
||||||
expectedResponseModel: (json) => DevicesCategoryModel.fromJsonList(json),
|
expectedResponseModel: (json) => DevicesCategoryModel.fromJsonList(json),
|
||||||
);
|
);
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,23 +143,41 @@ class DevicesAPI {
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<List<DeviceModel>> getDevicesByRoomId(String roomId) async {
|
static Future<List<DeviceModel>> getDevicesByRoomId({
|
||||||
final response = await _httpService.get(
|
required String communityUuid,
|
||||||
path: ApiEndpoints.deviceByRoom,
|
required String spaceUuid,
|
||||||
queryParameters: {"roomUuid": roomId},
|
required String roomId,
|
||||||
showServerMessage: false,
|
}) async {
|
||||||
expectedResponseModel: (json) {
|
try {
|
||||||
if (json == null || json.isEmpty || json == []) {
|
final String path = ApiEndpoints.deviceByRoom
|
||||||
return <DeviceModel>[];
|
.replaceAll('{communityUuid}', communityUuid)
|
||||||
}
|
.replaceAll('{spaceUuid}', spaceUuid)
|
||||||
List<DeviceModel> devices = [];
|
.replaceAll('{subSpaceUuid}', roomId);
|
||||||
for (var device in json) {
|
|
||||||
devices.add(DeviceModel.fromJson(device));
|
final response = await _httpService.get(
|
||||||
}
|
path: path,
|
||||||
return devices;
|
showServerMessage: false,
|
||||||
},
|
expectedResponseModel: (json) {
|
||||||
);
|
final data = json['data'];
|
||||||
return response;
|
|
||||||
|
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>[];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<List<DeviceModel>> getDevicesByGatewayId(
|
static Future<List<DeviceModel>> getDevicesByGatewayId(
|
||||||
|
|||||||
@ -4,7 +4,8 @@ import 'package:syncrow_app/services/api/http_service.dart';
|
|||||||
class HomeCreation {
|
class HomeCreation {
|
||||||
static final HTTPService _httpService = HTTPService();
|
static final HTTPService _httpService = HTTPService();
|
||||||
|
|
||||||
static Future<Map<String, dynamic>> createCommunity(Map<String, String> body) async {
|
static Future<Map<String, dynamic>> createCommunity(
|
||||||
|
Map<String, String> body) async {
|
||||||
try {
|
try {
|
||||||
final response = await _httpService.post(
|
final response = await _httpService.post(
|
||||||
path: ApiEndpoints.addCommunity,
|
path: ApiEndpoints.addCommunity,
|
||||||
@ -20,7 +21,8 @@ class HomeCreation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<Map<String, dynamic>> assignUserToCommunity(Map<String, String> body) async {
|
static Future<Map<String, dynamic>> assignUserToCommunity(
|
||||||
|
Map<String, String> body) async {
|
||||||
try {
|
try {
|
||||||
final response = await _httpService.post(
|
final response = await _httpService.post(
|
||||||
path: ApiEndpoints.addCommunityToUser,
|
path: ApiEndpoints.addCommunityToUser,
|
||||||
@ -36,7 +38,8 @@ class HomeCreation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<Map<String, dynamic>> createBuilding(Map<String, String> body) async {
|
static Future<Map<String, dynamic>> createBuilding(
|
||||||
|
Map<String, String> body) async {
|
||||||
try {
|
try {
|
||||||
final response = await _httpService.post(
|
final response = await _httpService.post(
|
||||||
path: ApiEndpoints.addBuilding,
|
path: ApiEndpoints.addBuilding,
|
||||||
@ -52,7 +55,8 @@ class HomeCreation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<Map<String, dynamic>> assignUserToBuilding(Map<String, String> body) async {
|
static Future<Map<String, dynamic>> assignUserToBuilding(
|
||||||
|
Map<String, String> body) async {
|
||||||
try {
|
try {
|
||||||
final response = await _httpService.post(
|
final response = await _httpService.post(
|
||||||
path: ApiEndpoints.addBuildingToUser,
|
path: ApiEndpoints.addBuildingToUser,
|
||||||
@ -68,7 +72,8 @@ class HomeCreation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<Map<String, dynamic>> createFloor(Map<String, String> body) async {
|
static Future<Map<String, dynamic>> createFloor(
|
||||||
|
Map<String, String> body) async {
|
||||||
try {
|
try {
|
||||||
final response = await _httpService.post(
|
final response = await _httpService.post(
|
||||||
path: ApiEndpoints.addFloor,
|
path: ApiEndpoints.addFloor,
|
||||||
@ -84,7 +89,8 @@ class HomeCreation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<Map<String, dynamic>> assignUserToFloor(Map<String, String> body) async {
|
static Future<Map<String, dynamic>> assignUserToFloor(
|
||||||
|
Map<String, String> body) async {
|
||||||
try {
|
try {
|
||||||
final response = await _httpService.post(
|
final response = await _httpService.post(
|
||||||
path: ApiEndpoints.addBuildingToUser,
|
path: ApiEndpoints.addBuildingToUser,
|
||||||
@ -100,7 +106,8 @@ class HomeCreation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<Map<String, dynamic>> createUnit(Map<String, String> body) async {
|
static Future<Map<String, dynamic>> createUnit(
|
||||||
|
Map<String, String> body) async {
|
||||||
try {
|
try {
|
||||||
final response = await _httpService.post(
|
final response = await _httpService.post(
|
||||||
path: ApiEndpoints.addUnit,
|
path: ApiEndpoints.addUnit,
|
||||||
@ -116,7 +123,8 @@ class HomeCreation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<Map<String, dynamic>> assignUserToUnit(Map<String, String> body) async {
|
static Future<Map<String, dynamic>> assignUserToUnit(
|
||||||
|
Map<String, String> body) async {
|
||||||
try {
|
try {
|
||||||
final response = await _httpService.post(
|
final response = await _httpService.post(
|
||||||
path: ApiEndpoints.addUnitToUser,
|
path: ApiEndpoints.addUnitToUser,
|
||||||
@ -132,10 +140,17 @@ class HomeCreation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<Map<String, dynamic>> createRoom(Map<String, String> body) async {
|
static Future<Map<String, dynamic>> createRoom({
|
||||||
|
required String communityId,
|
||||||
|
required String spaceId,
|
||||||
|
required Map<String, String> body,
|
||||||
|
}) async {
|
||||||
try {
|
try {
|
||||||
|
final fullPath = ApiEndpoints.addSubSpace
|
||||||
|
.replaceAll('{communityUuid}', communityId)
|
||||||
|
.replaceAll('{spaceUuid}', spaceId);
|
||||||
final response = await _httpService.post(
|
final response = await _httpService.post(
|
||||||
path: ApiEndpoints.addRoom,
|
path: fullPath,
|
||||||
body: body,
|
body: body,
|
||||||
showServerMessage: false,
|
showServerMessage: false,
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
@ -148,7 +163,8 @@ class HomeCreation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<Map<String, dynamic>> assignUserToRoom(Map<String, String> body) async {
|
static Future<Map<String, dynamic>> assignUserToRoom(
|
||||||
|
Map<String, String> body) async {
|
||||||
try {
|
try {
|
||||||
final response = await _httpService.post(
|
final response = await _httpService.post(
|
||||||
path: ApiEndpoints.addRoomToUser,
|
path: ApiEndpoints.addRoomToUser,
|
||||||
|
|||||||
@ -28,24 +28,46 @@ class HomeManagementAPI {
|
|||||||
|
|
||||||
static Future<List<DeviceModel>> fetchDevicesByUnitId() async {
|
static Future<List<DeviceModel>> fetchDevicesByUnitId() async {
|
||||||
List<DeviceModel> list = [];
|
List<DeviceModel> list = [];
|
||||||
await _httpService.get(
|
|
||||||
path: ApiEndpoints.getDevicesByUnitId.replaceAll(
|
try {
|
||||||
"{unitUuid}", HomeCubit.getInstance().selectedSpace?.id ?? ''),
|
// Retrieve selected space details
|
||||||
|
final selectedSpace = HomeCubit.getInstance().selectedSpace;
|
||||||
|
final communityUuid = selectedSpace?.community?.uuid ?? '';
|
||||||
|
final spaceUuid = selectedSpace?.id ?? '';
|
||||||
|
|
||||||
|
// Ensure both placeholders are replaced
|
||||||
|
final path = ApiEndpoints.spaceDevices
|
||||||
|
.replaceAll('{communityUuid}', communityUuid)
|
||||||
|
.replaceAll('{spaceUuid}', spaceUuid);
|
||||||
|
await _httpService.get(
|
||||||
|
path: path,
|
||||||
showServerMessage: false,
|
showServerMessage: false,
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
json.forEach((value) {
|
if (json['data'] != null) {
|
||||||
list.add(DeviceModel.fromJson(value));
|
json['data'].forEach((value) {
|
||||||
});
|
list.add(DeviceModel.fromJson(value));
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
// Debugging: Log successful fetch
|
||||||
|
} catch (e) {
|
||||||
|
// Log the error for debugging
|
||||||
|
}
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<Map<String, dynamic>> assignDeviceToRoom(
|
static Future<Map<String, dynamic>> assignDeviceToRoom(String communityId,
|
||||||
Map<String, String> body) async {
|
String spaceId, String subSpaceId, String deviceId) async {
|
||||||
try {
|
try {
|
||||||
final response = await _httpService.put(
|
final response = await _httpService.post(
|
||||||
path: ApiEndpoints.assignDeviceToRoom,
|
path: ApiEndpoints.assignDeviceToRoom
|
||||||
body: body,
|
.replaceAll('{communityUuid}', communityId)
|
||||||
|
.replaceAll('{spaceUuid}', spaceId)
|
||||||
|
.replaceAll('{subSpaceUuid}', subSpaceId)
|
||||||
|
.replaceAll('{deviceUuid}', deviceId),
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
return json;
|
return json;
|
||||||
},
|
},
|
||||||
@ -55,4 +77,24 @@ class HomeManagementAPI {
|
|||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Future<Map<String, dynamic>> unAssignDeviceToRoom(String communityId,
|
||||||
|
String spaceId, String subSpaceId, String deviceId) async {
|
||||||
|
try {
|
||||||
|
final response = await _httpService.delete(
|
||||||
|
path: ApiEndpoints.assignDeviceToRoom
|
||||||
|
.replaceAll('{communityUuid}', communityId)
|
||||||
|
.replaceAll('{spaceUuid}', spaceId)
|
||||||
|
.replaceAll('{subSpaceUuid}', subSpaceId)
|
||||||
|
.replaceAll('{deviceUuid}', deviceId),
|
||||||
|
expectedResponseModel: (json) {
|
||||||
|
return json;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
return response;
|
||||||
|
} catch (e) {
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:syncrow_app/features/scene/model/create_automation_model.dart';
|
import 'package:syncrow_app/features/scene/model/create_automation_model.dart';
|
||||||
import 'package:syncrow_app/features/scene/model/create_scene_model.dart';
|
import 'package:syncrow_app/features/scene/model/create_scene_model.dart';
|
||||||
import 'package:syncrow_app/features/scene/model/icon_model.dart';
|
import 'package:syncrow_app/features/scene/model/icon_model.dart';
|
||||||
@ -11,7 +13,8 @@ class SceneApi {
|
|||||||
static final HTTPService _httpService = HTTPService();
|
static final HTTPService _httpService = HTTPService();
|
||||||
|
|
||||||
//create scene
|
//create scene
|
||||||
static Future<Map<String, dynamic>> createScene(CreateSceneModel createSceneModel) async {
|
static Future<Map<String, dynamic>> createScene(
|
||||||
|
CreateSceneModel createSceneModel) async {
|
||||||
try {
|
try {
|
||||||
final response = await _httpService.post(
|
final response = await _httpService.post(
|
||||||
path: ApiEndpoints.createScene,
|
path: ApiEndpoints.createScene,
|
||||||
@ -47,15 +50,21 @@ class SceneApi {
|
|||||||
|
|
||||||
//get scene by unit id
|
//get scene by unit id
|
||||||
|
|
||||||
static Future<List<ScenesModel>> getScenesByUnitId(String unitId, {showInDevice = false}) async {
|
static Future<List<ScenesModel>> getScenesByUnitId(
|
||||||
|
String unitId, String communityId,
|
||||||
|
{showInDevice = false}) async {
|
||||||
try {
|
try {
|
||||||
final response = await _httpService.get(
|
final response = await _httpService.get(
|
||||||
path: ApiEndpoints.getUnitScenes.replaceAll('{unitUuid}', unitId),
|
path: ApiEndpoints.getUnitScenes
|
||||||
|
.replaceAll('{spaceUuid}', unitId)
|
||||||
|
.replaceAll('{communityUuid}', communityId),
|
||||||
queryParameters: {'showInHomePage': showInDevice},
|
queryParameters: {'showInHomePage': showInDevice},
|
||||||
showServerMessage: false,
|
showServerMessage: false,
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
|
final scenesJson = json['data'] as List;
|
||||||
|
|
||||||
List<ScenesModel> scenes = [];
|
List<ScenesModel> scenes = [];
|
||||||
for (var scene in json) {
|
for (var scene in scenesJson) {
|
||||||
scenes.add(ScenesModel.fromJson(scene));
|
scenes.add(ScenesModel.fromJson(scene));
|
||||||
}
|
}
|
||||||
return scenes;
|
return scenes;
|
||||||
@ -102,10 +111,12 @@ class SceneApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//automation details
|
//automation details
|
||||||
static Future<SceneDetailsModel> getAutomationDetails(String automationId) async {
|
static Future<SceneDetailsModel> getAutomationDetails(
|
||||||
|
String automationId) async {
|
||||||
try {
|
try {
|
||||||
final response = await _httpService.get(
|
final response = await _httpService.get(
|
||||||
path: ApiEndpoints.getAutomationDetails.replaceAll('{automationId}', automationId),
|
path: ApiEndpoints.getAutomationDetails
|
||||||
|
.replaceAll('{automationId}', automationId),
|
||||||
showServerMessage: false,
|
showServerMessage: false,
|
||||||
expectedResponseModel: (json) => SceneDetailsModel.fromJson(json),
|
expectedResponseModel: (json) => SceneDetailsModel.fromJson(json),
|
||||||
);
|
);
|
||||||
@ -116,11 +127,12 @@ class SceneApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//updateAutomationStatus
|
//updateAutomationStatus
|
||||||
static Future<bool> updateAutomationStatus(
|
static Future<bool> updateAutomationStatus(String automationId,
|
||||||
String automationId, AutomationStatusUpdate createAutomationEnable) async {
|
AutomationStatusUpdate createAutomationEnable) async {
|
||||||
try {
|
try {
|
||||||
final response = await _httpService.put(
|
final response = await _httpService.put(
|
||||||
path: ApiEndpoints.updateAutomationStatus.replaceAll('{automationId}', automationId),
|
path: ApiEndpoints.updateAutomationStatus
|
||||||
|
.replaceAll('{automationId}', automationId),
|
||||||
body: createAutomationEnable.toMap(),
|
body: createAutomationEnable.toMap(),
|
||||||
expectedResponseModel: (json) => json['success'],
|
expectedResponseModel: (json) => json['success'],
|
||||||
);
|
);
|
||||||
@ -135,7 +147,13 @@ class SceneApi {
|
|||||||
final response = await _httpService.get(
|
final response = await _httpService.get(
|
||||||
path: ApiEndpoints.getScene.replaceAll('{sceneId}', sceneId),
|
path: ApiEndpoints.getScene.replaceAll('{sceneId}', sceneId),
|
||||||
showServerMessage: false,
|
showServerMessage: false,
|
||||||
expectedResponseModel: (json) => SceneDetailsModel.fromJson(json),
|
expectedResponseModel: (json) {
|
||||||
|
if (json != null && json['data'] != null) {
|
||||||
|
return SceneDetailsModel.fromJson(json['data']);
|
||||||
|
} else {
|
||||||
|
throw Exception('Data field is null');
|
||||||
|
}
|
||||||
|
},
|
||||||
);
|
);
|
||||||
return response;
|
return response;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -163,7 +181,8 @@ class SceneApi {
|
|||||||
try {
|
try {
|
||||||
final response = await _httpService.put(
|
final response = await _httpService.put(
|
||||||
path: ApiEndpoints.updateScene.replaceAll('{sceneId}', sceneId),
|
path: ApiEndpoints.updateScene.replaceAll('{sceneId}', sceneId),
|
||||||
body: createSceneModel.toJson(sceneId.isNotEmpty == true ? sceneId : null),
|
body: createSceneModel
|
||||||
|
.toJson(sceneId.isNotEmpty == true ? sceneId : null),
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
return json;
|
return json;
|
||||||
},
|
},
|
||||||
@ -175,11 +194,14 @@ class SceneApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//update automation
|
//update automation
|
||||||
static updateAutomation(CreateAutomationModel createAutomationModel, String automationId) async {
|
static updateAutomation(
|
||||||
|
CreateAutomationModel createAutomationModel, String automationId) async {
|
||||||
try {
|
try {
|
||||||
final response = await _httpService.put(
|
final response = await _httpService.put(
|
||||||
path: ApiEndpoints.updateAutomation.replaceAll('{automationId}', automationId),
|
path: ApiEndpoints.updateAutomation
|
||||||
body: createAutomationModel.toJson(automationId.isNotEmpty == true ? automationId : null),
|
.replaceAll('{automationId}', automationId),
|
||||||
|
body: createAutomationModel
|
||||||
|
.toJson(automationId.isNotEmpty == true ? automationId : null),
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
return json;
|
return json;
|
||||||
},
|
},
|
||||||
@ -192,12 +214,10 @@ class SceneApi {
|
|||||||
|
|
||||||
//delete Scene
|
//delete Scene
|
||||||
|
|
||||||
static Future<bool> deleteScene({required String unitUuid, required String sceneId}) async {
|
static Future<bool> deleteScene({required String sceneId}) async {
|
||||||
try {
|
try {
|
||||||
final response = await _httpService.delete(
|
final response = await _httpService.delete(
|
||||||
path: ApiEndpoints.deleteScene
|
path: ApiEndpoints.deleteScene.replaceAll('{sceneId}', sceneId),
|
||||||
.replaceAll('{sceneId}', sceneId)
|
|
||||||
.replaceAll('{unitUuid}', unitUuid),
|
|
||||||
showServerMessage: false,
|
showServerMessage: false,
|
||||||
expectedResponseModel: (json) => json['statusCode'] == 200,
|
expectedResponseModel: (json) => json['statusCode'] == 200,
|
||||||
);
|
);
|
||||||
@ -213,8 +233,7 @@ class SceneApi {
|
|||||||
try {
|
try {
|
||||||
final response = await _httpService.delete(
|
final response = await _httpService.delete(
|
||||||
path: ApiEndpoints.deleteAutomation
|
path: ApiEndpoints.deleteAutomation
|
||||||
.replaceAll('{automationId}', automationId)
|
.replaceAll('{automationId}', automationId),
|
||||||
.replaceAll('{unitUuid}', unitUuid),
|
|
||||||
showServerMessage: false,
|
showServerMessage: false,
|
||||||
expectedResponseModel: (json) => json['statusCode'] == 200,
|
expectedResponseModel: (json) => json['statusCode'] == 200,
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,55 +1,89 @@
|
|||||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||||
import 'package:syncrow_app/features/app_layout/model/space_model.dart';
|
import 'package:syncrow_app/features/app_layout/model/space_model.dart';
|
||||||
import 'package:syncrow_app/features/auth/model/user_model.dart';
|
import 'package:syncrow_app/features/auth/model/user_model.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/room_model.dart';
|
import 'package:syncrow_app/features/devices/model/subspace_model.dart';
|
||||||
import 'package:syncrow_app/services/api/api_links_endpoints.dart';
|
import 'package:syncrow_app/services/api/api_links_endpoints.dart';
|
||||||
import 'package:syncrow_app/services/api/http_service.dart';
|
import 'package:syncrow_app/services/api/http_service.dart';
|
||||||
|
|
||||||
class SpacesAPI {
|
class SpacesAPI {
|
||||||
static final HTTPService _httpService = HTTPService();
|
static final HTTPService _httpService = HTTPService();
|
||||||
|
|
||||||
static Future<List<SpaceModel>> getUnitsByUserId() async {
|
static Future<List<SpaceModel>> getSpacesByUserId() async {
|
||||||
var uuid = await const FlutterSecureStorage().read(key: UserModel.userUuidKey);
|
try {
|
||||||
final response = await _httpService.get(
|
var uuid =
|
||||||
path: "${ApiEndpoints.unitUser}$uuid",
|
await const FlutterSecureStorage().read(key: UserModel.userUuidKey);
|
||||||
showServerMessage: false,
|
if (uuid == null) throw Exception("User UUID is missing");
|
||||||
expectedResponseModel: (json) => SpaceModel.fromJsonList(json),
|
|
||||||
);
|
final path = ApiEndpoints.userSpaces.replaceFirst('{userUuid}', uuid);
|
||||||
return response;
|
final response = await _httpService.get(
|
||||||
|
path: path,
|
||||||
|
showServerMessage: false,
|
||||||
|
expectedResponseModel: (json) {
|
||||||
|
return SpaceModel.fromJsonList(json['data']);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
return response;
|
||||||
|
} catch (error) {
|
||||||
|
rethrow; // Rethrow the error to be caught by `fetchUnitsByUserId`
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<List<RoomModel>> getRoomsBySpaceId(String unitId) async {
|
static Future<List<SubSpaceModel>> getSubSpaceBySpaceId(
|
||||||
|
String communityId, String spaceId) async {
|
||||||
|
try {
|
||||||
|
// Construct the API path
|
||||||
|
final path = ApiEndpoints.listSubspace
|
||||||
|
.replaceFirst('{communityUuid}', communityId)
|
||||||
|
.replaceFirst('{spaceUuid}', spaceId);
|
||||||
|
|
||||||
|
final response = await _httpService.get(
|
||||||
|
path: path,
|
||||||
|
queryParameters: {"page": 1, "pageSize": 10},
|
||||||
|
showServerMessage: false,
|
||||||
|
expectedResponseModel: (json) {
|
||||||
|
List<SubSpaceModel> rooms = [];
|
||||||
|
if (json['data'] != null) {
|
||||||
|
for (var subspace in json['data']) {
|
||||||
|
rooms.add(SubSpaceModel.fromJson(subspace));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
print("Warning: 'data' key is missing or null in response JSON.");
|
||||||
|
}
|
||||||
|
return rooms;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
return response;
|
||||||
|
} catch (error, stackTrace) {
|
||||||
|
return []; // Return an empty list if there's an error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<String> generateInvitationCode(
|
||||||
|
String unitId, String communityId) async {
|
||||||
final response = await _httpService.get(
|
final response = await _httpService.get(
|
||||||
path: "${ApiEndpoints.unitChild}$unitId",
|
path: ApiEndpoints.invitationCode
|
||||||
queryParameters: {"page": 1, "pageSize": 10},
|
.replaceAll('{unitUuid}', unitId)
|
||||||
|
.replaceAll('{communityUuid}', communityId),
|
||||||
showServerMessage: false,
|
showServerMessage: false,
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
List<RoomModel> rooms = [];
|
if (json != null && json['data'] != null) {
|
||||||
for (var room in json['children']) {
|
return json['data']['invitationCode'];
|
||||||
rooms.add(RoomModel.fromJson(room));
|
} else {
|
||||||
|
throw Exception('Data field is null');
|
||||||
}
|
}
|
||||||
return rooms;
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<String> generateInvitationCode(
|
|
||||||
String unitId,
|
|
||||||
) async {
|
|
||||||
final response = await _httpService.get(
|
|
||||||
path: ApiEndpoints.invitationCode.replaceAll('{unitUuid}', unitId),
|
|
||||||
showServerMessage: false,
|
|
||||||
expectedResponseModel: (json) => json['invitationCode'],
|
|
||||||
);
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Future<bool> joinUnit(
|
static Future<bool> joinUnit(
|
||||||
|
String userId,
|
||||||
Map<String, String> body,
|
Map<String, String> body,
|
||||||
) async {
|
) async {
|
||||||
final response = await _httpService.post(
|
final response = await _httpService.post(
|
||||||
path: ApiEndpoints.verifyInvitationCode,
|
path: ApiEndpoints.verifyInvitationCode.replaceAll('{userUuid}', userId),
|
||||||
showServerMessage: false,
|
showServerMessage: false,
|
||||||
body: body,
|
body: body,
|
||||||
expectedResponseModel: (json) => json['success'],
|
expectedResponseModel: (json) => json['success'],
|
||||||
|
|||||||
Reference in New Issue
Block a user