push get scenes and automation

This commit is contained in:
ashrafzarkanisala
2024-11-18 01:13:28 +03:00
parent 458ec3976a
commit 54143b3ba9
10 changed files with 452 additions and 48 deletions

View File

@ -1,13 +1,19 @@
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:syncrow_web/pages/routiens/models/routine_model.dart';
import 'package:syncrow_web/services/routines_api.dart';
part 'routine_event.dart';
part 'routine_state.dart';
const spaceId = '25c96044-fadf-44bb-93c7-3c079e527ce6';
class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
RoutineBloc() : super(const RoutineState()) {
on<AddToIfContainer>(_onAddToIfContainer);
on<AddToThenContainer>(_onAddToThenContainer);
on<LoadScenes>(_onLoadScenes);
on<LoadAutomation>(_onLoadAutomation);
}
void _onAddToIfContainer(AddToIfContainer event, Emitter<RoutineState> emit) {
@ -19,4 +25,38 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
final updatedThenItems = List<Map<String, String>>.from(state.thenItems)..add(event.item);
emit(state.copyWith(thenItems: updatedThenItems));
}
Future<void> _onLoadScenes(LoadScenes event, Emitter<RoutineState> emit) async {
emit(state.copyWith(isLoading: true, errorMessage: null));
try {
final scenes = await SceneApi.getScenesByUnitId(event.unitId);
emit(state.copyWith(
scenes: scenes,
isLoading: false,
));
} catch (e) {
emit(state.copyWith(
isLoading: false,
errorMessage: 'Something went wrong',
));
}
}
Future<void> _onLoadAutomation(LoadAutomation event, Emitter<RoutineState> emit) async {
emit(state.copyWith(isLoading: true, errorMessage: null));
try {
final automations = await SceneApi.getAutomationByUnitId(event.unitId);
emit(state.copyWith(
automations: automations,
isLoading: false,
));
} catch (e) {
emit(state.copyWith(
isLoading: false,
errorMessage: 'Something went wrong',
));
}
}
}

View File

@ -24,3 +24,21 @@ class AddToThenContainer extends RoutineEvent {
@override
List<Object> get props => [item];
}
class LoadScenes extends RoutineEvent {
final String unitId;
const LoadScenes(this.unitId);
@override
List<Object> get props => [unitId];
}
class LoadAutomation extends RoutineEvent {
final String unitId;
const LoadAutomation(this.unitId);
@override
List<Object> get props => [unitId];
}

View File

@ -3,22 +3,47 @@ part of 'routine_bloc.dart';
class RoutineState extends Equatable {
final List<Map<String, String>> ifItems;
final List<Map<String, String>> thenItems;
final List<Map<String, String>> availableCards;
final List<ScenesModel> scenes;
final List<ScenesModel> automations;
final bool isLoading;
final String? errorMessage;
const RoutineState({
this.ifItems = const [],
this.thenItems = const [],
this.availableCards = const [],
this.scenes = const [],
this.automations = const [],
this.isLoading = false,
this.errorMessage,
});
RoutineState copyWith({
List<Map<String, String>>? ifItems,
List<Map<String, String>>? thenItems,
List<ScenesModel>? scenes,
List<ScenesModel>? automations,
bool? isLoading,
String? errorMessage,
}) {
return RoutineState(
ifItems: ifItems ?? this.ifItems,
thenItems: thenItems ?? this.thenItems,
scenes: scenes ?? this.scenes,
automations: automations ?? this.automations,
isLoading: isLoading ?? this.isLoading,
errorMessage: errorMessage ?? this.errorMessage,
);
}
@override
List<Object> get props => [ifItems, thenItems];
List<Object?> get props => [
ifItems,
thenItems,
scenes,
automations,
isLoading,
errorMessage,
];
}

View File

@ -0,0 +1,30 @@
import 'dart:convert';
class ScenesModel {
final String id;
final String name;
final String status;
final String type;
final String? icon;
ScenesModel({required this.id, required this.name, required this.status, required this.type, this.icon});
factory ScenesModel.fromRawJson(String str) => ScenesModel.fromJson(json.decode(str));
String toRawJson() => json.encode(toJson());
factory ScenesModel.fromJson(Map<String, dynamic> json) => ScenesModel(
id: json["id"],
name: json["name"] ?? '',
status: json["status"] ?? '',
type: json["type"] ?? '',
icon: json["icon"] as String?,
);
Map<String, dynamic> toJson() => {
"id": id,
"name": name,
"status": status,
"type": type,
};
}

View File

@ -1,8 +1,8 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/bloc/device_mgmt_bloc/device_managment_bloc.dart';
import 'package:syncrow_web/pages/routiens/widgets/dragable_card.dart';
import 'package:syncrow_web/pages/routiens/widgets/routine_devices.dart';
import 'package:syncrow_web/pages/routiens/widgets/routines_title_widget.dart';
import 'package:syncrow_web/pages/routiens/widgets/scenes_and_automations.dart';
import 'package:syncrow_web/pages/routiens/widgets/search_bar_condition_title.dart';
import 'package:syncrow_web/utils/constants/assets.dart';
@ -50,6 +50,9 @@ class ConditionsRoutinesDevicesView extends StatelessWidget {
title: 'Conditions',
subtitle: '(THEN)',
),
const SizedBox(
height: 10,
),
const Wrap(
spacing: 10,
runSpacing: 10,
@ -71,33 +74,21 @@ class ConditionsRoutinesDevicesView extends StatelessWidget {
title: 'Routines',
subtitle: '(THEN)',
),
const SizedBox(
height: 10,
),
const ScenesAndAutomations(),
const SizedBox(
height: 10,
),
const TitleRoutine(
title: 'Devices',
subtitle: '',
),
BlocProvider(
create: (context) => DeviceManagementBloc()
..add(
FetchDevices(),
),
child: BlocBuilder<DeviceManagementBloc, DeviceManagementState>(
builder: (context, state) {
if (state is DeviceManagementLoaded) {
return Wrap(
spacing: 10,
runSpacing: 10,
children: state.devices
.map((device) => DraggableCard(
imagePath: device.getDefaultIcon(device.productType),
title: device.name ?? '',
))
.toList(),
);
}
return const Center(child: CircularProgressIndicator());
},
),
const SizedBox(
height: 10,
),
const RoutineDevices(),
],
),
),

View File

@ -60,13 +60,17 @@ class DraggableCard extends StatelessWidget {
const SizedBox(
height: 8,
),
Text(
Padding(
padding: const EdgeInsets.symmetric(horizontal: 3),
child: Text(
title,
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
maxLines: 2,
style: context.textTheme.bodySmall?.copyWith(
color: titleColor ?? ColorsManager.blackColor,
fontSize: 12,
),
),
),
],

View File

@ -0,0 +1,44 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/bloc/device_mgmt_bloc/device_managment_bloc.dart';
import 'package:syncrow_web/pages/routiens/widgets/dragable_card.dart';
class RoutineDevices extends StatelessWidget {
const RoutineDevices({
super.key,
});
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => DeviceManagementBloc()
..add(
FetchDevices(),
),
child: BlocBuilder<DeviceManagementBloc, DeviceManagementState>(
builder: (context, state) {
if (state is DeviceManagementLoaded) {
final deviceList = state.devices
.where((device) =>
device.productType == 'AC' ||
device.productType == '1G' ||
device.productType == '2G' ||
device.productType == '3G')
.toList();
return Wrap(
spacing: 10,
runSpacing: 10,
children: deviceList
.map((device) => DraggableCard(
imagePath: device.getDefaultIcon(device.productType),
title: device.name ?? '',
))
.toList(),
);
}
return const Center(child: CircularProgressIndicator());
},
),
);
}
}

View File

@ -0,0 +1,42 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/routiens/bloc/routine_bloc.dart';
import 'package:syncrow_web/pages/routiens/widgets/dragable_card.dart';
import 'package:syncrow_web/utils/constants/assets.dart';
class ScenesAndAutomations extends StatelessWidget {
const ScenesAndAutomations({
super.key,
});
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => RoutineBloc()
..add(
LoadScenes(spaceId),
)
..add(
LoadAutomation(spaceId),
),
child: BlocBuilder<RoutineBloc, RoutineState>(
builder: (context, state) {
if (state.scenes.isNotEmpty || state.automations.isNotEmpty) {
var scenes = [...state.scenes, ...state.automations];
return Wrap(
spacing: 10,
runSpacing: 10,
children: scenes
.map((scene) => DraggableCard(
imagePath: Assets.logo,
title: scene.name ?? '',
))
.toList(),
);
}
return const Center(child: CircularProgressIndicator());
},
),
);
}
}

View File

@ -0,0 +1,216 @@
import 'package:syncrow_web/pages/routiens/models/routine_model.dart';
import 'package:syncrow_web/services/api/http_service.dart';
import 'package:syncrow_web/utils/constants/api_const.dart';
class SceneApi {
static final HTTPService _httpService = HTTPService();
// //create scene
// static Future<Map<String, dynamic>> createScene(
// CreateSceneModel createSceneModel) async {
// try {
// final response = await _httpService.post(
// path: ApiEndpoints.createScene,
// body: createSceneModel.toMap(),
// showServerMessage: false,
// expectedResponseModel: (json) {
// return json;
// },
// );
// return response;
// } catch (e) {
// rethrow;
// }
// }
//
// // create automation
// static Future<Map<String, dynamic>> createAutomation(
// CreateAutomationModel createAutomationModel) async {
// try {
// final response = await _httpService.post(
// path: ApiEndpoints.createAutomation,
// body: createAutomationModel.toMap(),
// showServerMessage: false,
// expectedResponseModel: (json) {
// return json;
// },
// );
// return response;
// } catch (e) {
// rethrow;
// }
// }
//get scene by unit id
static Future<List<ScenesModel>> getScenesByUnitId(String unitId) async {
try {
final response = await _httpService.get(
path: ApiEndpoints.getSpaceScenes.replaceAll('{unitUuid}', unitId),
showServerMessage: false,
expectedResponseModel: (json) {
List<ScenesModel> scenes = [];
for (var scene in json) {
scenes.add(ScenesModel.fromJson(scene));
}
return scenes;
},
);
return response;
} catch (e) {
rethrow;
}
}
//getAutomation
static Future<List<ScenesModel>> getAutomationByUnitId(String unitId) async {
try {
final response = await _httpService.get(
path: ApiEndpoints.getSpaceAutomation.replaceAll('{unitUuid}', unitId),
showServerMessage: false,
expectedResponseModel: (json) {
List<ScenesModel> scenes = [];
for (var scene in json) {
scenes.add(ScenesModel.fromJson(scene));
}
return scenes;
},
);
return response;
} catch (e) {
rethrow;
}
}
// static Future<bool> triggerScene(String sceneId) async {
// try {
// final response = await _httpService.post(
// path: ApiEndpoints.triggerScene.replaceAll('{sceneId}', sceneId),
// showServerMessage: false,
// expectedResponseModel: (json) => json['success'],
// );
// return response;
// } catch (e) {
// rethrow;
// }
// }
// //automation details
// static Future<SceneDetailsModel> getAutomationDetails(
// String automationId) async {
// try {
// final response = await _httpService.get(
// path: ApiEndpoints.getAutomationDetails
// .replaceAll('{automationId}', automationId),
// showServerMessage: false,
// expectedResponseModel: (json) => SceneDetailsModel.fromJson(json),
// );
// return response;
// } catch (e) {
// rethrow;
// }
// }
//
// //updateAutomationStatus
// static Future<bool> updateAutomationStatus(String automationId,
// AutomationStatusUpdate createAutomationEnable) async {
// try {
// final response = await _httpService.put(
// path: ApiEndpoints.updateAutomationStatus
// .replaceAll('{automationId}', automationId),
// body: createAutomationEnable.toMap(),
// expectedResponseModel: (json) => json['success'],
// );
// return response;
// } catch (e) {
// rethrow;
// }
// }
// //getScene
//
// static Future<SceneDetailsModel> getSceneDetails(String sceneId) async {
// try {
// final response = await _httpService.get(
// path: ApiEndpoints.getScene.replaceAll('{sceneId}', sceneId),
// showServerMessage: false,
// expectedResponseModel: (json) => SceneDetailsModel.fromJson(json),
// );
// return response;
// } catch (e) {
// rethrow;
// }
// }
//
// //update Scene
// static updateScene(CreateSceneModel createSceneModel, String sceneId) async {
// try {
// final response = await _httpService.put(
// path: ApiEndpoints.updateScene.replaceAll('{sceneId}', sceneId),
// body: createSceneModel
// .toJson(sceneId.isNotEmpty == true ? sceneId : null),
// expectedResponseModel: (json) {
// return json;
// },
// );
// return response;
// } catch (e) {
// rethrow;
// }
// }
//
// //update automation
// static updateAutomation(
// CreateAutomationModel createAutomationModel, String automationId) async {
// try {
// final response = await _httpService.put(
// path: ApiEndpoints.updateAutomation
// .replaceAll('{automationId}', automationId),
// body: createAutomationModel
// .toJson(automationId.isNotEmpty == true ? automationId : null),
// expectedResponseModel: (json) {
// return json;
// },
// );
// return response;
// } catch (e) {
// rethrow;
// }
// }
//
// //delete Scene
//
// static Future<bool> deleteScene(
// {required String unitUuid, required String sceneId}) async {
// try {
// final response = await _httpService.delete(
// path: ApiEndpoints.deleteScene
// .replaceAll('{sceneId}', sceneId)
// .replaceAll('{unitUuid}', unitUuid),
// showServerMessage: false,
// expectedResponseModel: (json) => json['statusCode'] == 200,
// );
// return response;
// } catch (e) {
// rethrow;
// }
// }
//
// // delete automation
// static Future<bool> deleteAutomation(
// {required String unitUuid, required String automationId}) async {
// try {
// final response = await _httpService.delete(
// path: ApiEndpoints.deleteAutomation
// .replaceAll('{automationId}', automationId)
// .replaceAll('{unitUuid}', unitUuid),
// showServerMessage: false,
// expectedResponseModel: (json) => json['statusCode'] == 200,
// );
// return response;
// } catch (e) {
// rethrow;
// }
// }
}

View File

@ -11,16 +11,12 @@ abstract class ApiEndpoints {
static const String visitorPassword = '/visitor-password';
static const String getDevices = '/visitor-password/devices';
static const String sendOnlineOneTime =
'/visitor-password/temporary-password/online/one-time';
static const String sendOnlineMultipleTime =
'/visitor-password/temporary-password/online/multiple-time';
static const String sendOnlineOneTime = '/visitor-password/temporary-password/online/one-time';
static const String sendOnlineMultipleTime = '/visitor-password/temporary-password/online/multiple-time';
//offline Password
static const String sendOffLineOneTime =
'/visitor-password/temporary-password/offline/one-time';
static const String sendOffLineMultipleTime =
'/visitor-password/temporary-password/offline/multiple-time';
static const String sendOffLineOneTime = '/visitor-password/temporary-password/offline/one-time';
static const String sendOffLineMultipleTime = '/visitor-password/temporary-password/offline/multiple-time';
static const String getUser = '/user/{userUuid}';
@ -40,14 +36,12 @@ abstract class ApiEndpoints {
'/device/report-logs/{uuid}?code={code}&startTime={startTime}&endTime={endTime}';
static const String scheduleByDeviceId = '/schedule/{deviceUuid}';
static const String getScheduleByDeviceId =
'/schedule/{deviceUuid}?category={category}';
static const String deleteScheduleByDeviceId =
'/schedule/{deviceUuid}/{scheduleUuid}';
static const String updateScheduleByDeviceId =
'/schedule/enable/{deviceUuid}';
static const String getScheduleByDeviceId = '/schedule/{deviceUuid}?category={category}';
static const String deleteScheduleByDeviceId = '/schedule/{deviceUuid}/{scheduleUuid}';
static const String updateScheduleByDeviceId = '/schedule/enable/{deviceUuid}';
static const String factoryReset = '/device/factory/reset/{deviceUuid}';
static const String powerClamp =
'/device/{powerClampUuid}/power-clamp/status';
static const String powerClamp = '/device/{powerClampUuid}/power-clamp/status';
static const String getSpaceScenes = '/scene/tap-to-run/{unitUuid}';
static const String getSpaceAutomation = '/automation/{unitUuid}';
}