mirror of
https://github.com/SyncrowIOT/syncrow-app.git
synced 2025-07-16 18:16:21 +00:00
push automation details and update automation
This commit is contained in:
@ -1,6 +1,3 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
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/scene/bloc/create_scene/create_scene_bloc.dart';
|
import 'package:syncrow_app/features/scene/bloc/create_scene/create_scene_bloc.dart';
|
||||||
@ -12,7 +9,6 @@ import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dar
|
|||||||
import 'package:syncrow_app/generated/assets.dart';
|
import 'package:syncrow_app/generated/assets.dart';
|
||||||
import 'package:syncrow_app/navigation/routing_constants.dart';
|
import 'package:syncrow_app/navigation/routing_constants.dart';
|
||||||
|
|
||||||
|
|
||||||
class SceneListview extends StatelessWidget {
|
class SceneListview extends StatelessWidget {
|
||||||
final List<ScenesModel> scenes;
|
final List<ScenesModel> scenes;
|
||||||
final String? loadingSceneId;
|
final String? loadingSceneId;
|
||||||
@ -24,8 +20,7 @@ class SceneListview extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return
|
return ListView.builder(
|
||||||
ListView.builder(
|
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
scrollDirection: Axis.horizontal,
|
scrollDirection: Axis.horizontal,
|
||||||
itemCount: scenes.length,
|
itemCount: scenes.length,
|
||||||
@ -34,7 +29,7 @@ class SceneListview extends StatelessWidget {
|
|||||||
final isLoading = loadingSceneId == scene.id;
|
final isLoading = loadingSceneId == scene.id;
|
||||||
return Container(
|
return Container(
|
||||||
padding: const EdgeInsets.only(right: 10),
|
padding: const EdgeInsets.only(right: 10),
|
||||||
child:DefaultContainer(
|
child: DefaultContainer(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Navigator.pushNamed(
|
Navigator.pushNamed(
|
||||||
context,
|
context,
|
||||||
@ -45,10 +40,11 @@ class SceneListview extends StatelessWidget {
|
|||||||
sceneName: scene.name,
|
sceneName: scene.name,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
BlocProvider.of<CreateSceneBloc>(context).add(FetchSceneTasksEvent(sceneId: scene.id));
|
BlocProvider.of<CreateSceneBloc>(context)
|
||||||
|
.add(FetchSceneTasksEvent(sceneId: scene.id));
|
||||||
},
|
},
|
||||||
child:SizedBox(
|
child: SizedBox(
|
||||||
width: MediaQuery.of(context).size.width*0.4,
|
width: MediaQuery.of(context).size.width * 0.4,
|
||||||
child: Row(
|
child: Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
@ -73,8 +69,7 @@ class SceneListview extends StatelessWidget {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
));
|
||||||
);
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -276,8 +276,10 @@ class CreateSceneBloc extends Bloc<CreateSceneEvent, CreateSceneState>
|
|||||||
? await SceneApi.updateScene(event.createSceneModel!, event.sceneId)
|
? await SceneApi.updateScene(event.createSceneModel!, event.sceneId)
|
||||||
: await SceneApi.createScene(event.createSceneModel!);
|
: await SceneApi.createScene(event.createSceneModel!);
|
||||||
} else if (event.createAutomationModel != null) {
|
} else if (event.createAutomationModel != null) {
|
||||||
response =
|
response = event.updateScene
|
||||||
await SceneApi.createAutomation(event.createAutomationModel!);
|
? await SceneApi.updateAutomation(
|
||||||
|
event.createAutomationModel!, event.sceneId)
|
||||||
|
: await SceneApi.createAutomation(event.createAutomationModel!);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response['success'] == true) {
|
if (response['success'] == true) {
|
||||||
@ -315,13 +317,31 @@ class CreateSceneBloc extends Bloc<CreateSceneEvent, CreateSceneState>
|
|||||||
emit(CreateSceneLoading());
|
emit(CreateSceneLoading());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final response = await SceneApi.getSceneDetails(event.sceneId);
|
final response = event.isAutomation
|
||||||
|
? await SceneApi.getAutomationDetails(event.sceneId)
|
||||||
|
: await SceneApi.getSceneDetails(event.sceneId);
|
||||||
if (response.id.isNotEmpty) {
|
if (response.id.isNotEmpty) {
|
||||||
tasksList = List<SceneStaticFunction>.from(getTaskListFunctionsFromApi(
|
if (event.isAutomation) {
|
||||||
actions: response.actions, isAutomation: false));
|
automationTasksList = List<SceneStaticFunction>.from(
|
||||||
emit(AddSceneTask(
|
getTaskListFunctionsFromApi(
|
||||||
tasksList: tasksList,
|
actions: [],
|
||||||
));
|
isAutomation: true,
|
||||||
|
conditions: response.conditions));
|
||||||
|
tasksList = List<SceneStaticFunction>.from(
|
||||||
|
getTaskListFunctionsFromApi(
|
||||||
|
actions: response.actions, isAutomation: false));
|
||||||
|
emit(AddSceneTask(
|
||||||
|
automationTasksList: automationTasksList,
|
||||||
|
tasksList: tasksList,
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
tasksList = List<SceneStaticFunction>.from(
|
||||||
|
getTaskListFunctionsFromApi(
|
||||||
|
actions: response.actions, isAutomation: false));
|
||||||
|
emit(AddSceneTask(
|
||||||
|
tasksList: tasksList,
|
||||||
|
));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
emit(const CreateSceneError(message: 'Something went wrong'));
|
emit(const CreateSceneError(message: 'Something went wrong'));
|
||||||
}
|
}
|
||||||
@ -420,7 +440,11 @@ class CreateSceneBloc extends Bloc<CreateSceneEvent, CreateSceneState>
|
|||||||
conditionRule = 'and';
|
conditionRule = 'and';
|
||||||
}
|
}
|
||||||
|
|
||||||
emit(ConditionSelectedState(event.condition));
|
emit(AddSceneTask(
|
||||||
|
tasksList: tasksList,
|
||||||
|
automationTasksList: automationTasksList,
|
||||||
|
condition: conditionRule,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _sceneTypeEvent(
|
FutureOr<void> _sceneTypeEvent(
|
||||||
|
@ -147,10 +147,13 @@ class ClearTempTaskListEvent extends CreateSceneEvent {
|
|||||||
|
|
||||||
class FetchSceneTasksEvent extends CreateSceneEvent {
|
class FetchSceneTasksEvent extends CreateSceneEvent {
|
||||||
final String sceneId;
|
final String sceneId;
|
||||||
const FetchSceneTasksEvent({required this.sceneId});
|
final bool isAutomation;
|
||||||
|
|
||||||
|
const FetchSceneTasksEvent(
|
||||||
|
{this.isAutomation = false, required this.sceneId});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [];
|
List<Object> get props => [sceneId, isAutomation];
|
||||||
}
|
}
|
||||||
|
|
||||||
class DeleteSceneEvent extends CreateSceneEvent {
|
class DeleteSceneEvent extends CreateSceneEvent {
|
||||||
|
@ -22,7 +22,9 @@ class CreateSceneError extends CreateSceneState {
|
|||||||
class AddSceneTask extends CreateSceneState {
|
class AddSceneTask extends CreateSceneState {
|
||||||
final List<SceneStaticFunction> tasksList;
|
final List<SceneStaticFunction> tasksList;
|
||||||
final List<SceneStaticFunction>? automationTasksList;
|
final List<SceneStaticFunction>? automationTasksList;
|
||||||
const AddSceneTask({required this.tasksList, this.automationTasksList});
|
final String? condition;
|
||||||
|
const AddSceneTask(
|
||||||
|
{required this.tasksList, this.automationTasksList, this.condition});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [tasksList];
|
List<Object> get props => [tasksList];
|
||||||
|
@ -11,16 +11,20 @@ part 'scene_state.dart';
|
|||||||
class SceneBloc extends Bloc<SceneEvent, SceneState> {
|
class SceneBloc extends Bloc<SceneEvent, SceneState> {
|
||||||
SceneBloc() : super(SceneInitial()) {
|
SceneBloc() : super(SceneInitial()) {
|
||||||
on<LoadScenes>(_onLoadScenes);
|
on<LoadScenes>(_onLoadScenes);
|
||||||
|
on<LoadAutomation>(_onLoadAutomation);
|
||||||
on<SceneTrigger>(_onSceneTrigger);
|
on<SceneTrigger>(_onSceneTrigger);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<ScenesModel> scenes = [];
|
||||||
|
List<ScenesModel> automationList = [];
|
||||||
|
|
||||||
Future<void> _onLoadScenes(LoadScenes event, Emitter<SceneState> emit) async {
|
Future<void> _onLoadScenes(LoadScenes event, Emitter<SceneState> emit) async {
|
||||||
emit(SceneLoading());
|
emit(SceneLoading());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (event.unitId.isNotEmpty) {
|
if (event.unitId.isNotEmpty) {
|
||||||
final scenes = await SceneApi.getScenesByUnitId(event.unitId);
|
scenes = await SceneApi.getScenesByUnitId(event.unitId);
|
||||||
emit(SceneLoaded(scenes));
|
emit(SceneLoaded(scenes, automationList));
|
||||||
} else {
|
} else {
|
||||||
const SceneError(message: '');
|
const SceneError(message: '');
|
||||||
}
|
}
|
||||||
@ -29,16 +33,34 @@ class SceneBloc extends Bloc<SceneEvent, SceneState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onSceneTrigger(SceneTrigger event, Emitter<SceneState> emit) async {
|
Future<void> _onLoadAutomation(
|
||||||
|
LoadAutomation event, Emitter<SceneState> emit) async {
|
||||||
|
emit(SceneLoading());
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (event.unitId.isNotEmpty) {
|
||||||
|
automationList = await SceneApi.getAutomationByUnitId(event.unitId);
|
||||||
|
emit(SceneLoaded(scenes, automationList));
|
||||||
|
} else {
|
||||||
|
emit(const SceneError(message: 'Unit ID is empty'));
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
emit(const SceneError(message: 'Something went wrong'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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(currentState.scenes, loadingSceneId: event.sceneId));
|
emit(SceneLoaded(currentState.scenes, currentState.automationList,
|
||||||
|
loadingSceneId: event.sceneId));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final success = await SceneApi.triggerScene(event.sceneId);
|
final success = await SceneApi.triggerScene(event.sceneId);
|
||||||
if (success) {
|
if (success) {
|
||||||
emit(SceneTriggerSuccess(event.name));
|
emit(SceneTriggerSuccess(event.name));
|
||||||
emit(SceneLoaded(currentState.scenes));
|
emit(SceneLoaded(currentState.scenes, currentState.automationList));
|
||||||
} else {
|
} else {
|
||||||
emit(const SceneError(message: 'Something went wrong'));
|
emit(const SceneError(message: 'Something went wrong'));
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,15 @@ class LoadScenes extends SceneEvent {
|
|||||||
List<Object> get props => [unitId];
|
List<Object> get props => [unitId];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class LoadAutomation extends SceneEvent {
|
||||||
|
final String unitId;
|
||||||
|
|
||||||
|
const LoadAutomation(this.unitId);
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [unitId];
|
||||||
|
}
|
||||||
|
|
||||||
class SceneTrigger extends SceneEvent {
|
class SceneTrigger extends SceneEvent {
|
||||||
final String sceneId;
|
final String sceneId;
|
||||||
final String name;
|
final String name;
|
||||||
|
@ -13,12 +13,13 @@ class SceneLoading extends SceneState {}
|
|||||||
|
|
||||||
class SceneLoaded extends SceneState {
|
class SceneLoaded extends SceneState {
|
||||||
final List<ScenesModel> scenes;
|
final List<ScenesModel> scenes;
|
||||||
|
final List<ScenesModel> automationList;
|
||||||
final String? loadingSceneId;
|
final String? loadingSceneId;
|
||||||
|
|
||||||
const SceneLoaded(this.scenes, {this.loadingSceneId});
|
const SceneLoaded(this.scenes, this.automationList, {this.loadingSceneId});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object?> get props => [scenes, loadingSceneId];
|
List<Object?> get props => [scenes, loadingSceneId, automationList];
|
||||||
}
|
}
|
||||||
|
|
||||||
class SceneError extends SceneState {
|
class SceneError extends SceneState {
|
||||||
|
@ -100,45 +100,56 @@ mixin SceneLogicHelper {
|
|||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Handle Scene Creation
|
if (isOnlyDelayOrDelayLast(actions)) {
|
||||||
final createSceneModel = CreateSceneModel(
|
Navigator.pop(context);
|
||||||
unitUuid: HomeCubit.getInstance().selectedSpace!.id ?? '',
|
context.showCustomSnackbar(
|
||||||
sceneName: sceneName.text,
|
message: 'A single delay or delay-last operations are NOT allowed.',
|
||||||
decisionExpr: 'and',
|
icon: const Icon(
|
||||||
actions: List.generate(
|
Icons.error,
|
||||||
actions.length,
|
color: Colors.red,
|
||||||
(index) {
|
),
|
||||||
final task = actions[index];
|
);
|
||||||
if (task.deviceId == 'delay') {
|
} else {
|
||||||
|
// Handle Scene Creation
|
||||||
|
final createSceneModel = CreateSceneModel(
|
||||||
|
unitUuid: HomeCubit.getInstance().selectedSpace!.id ?? '',
|
||||||
|
sceneName: sceneName.text,
|
||||||
|
decisionExpr: 'and',
|
||||||
|
actions: List.generate(
|
||||||
|
actions.length,
|
||||||
|
(index) {
|
||||||
|
final task = actions[index];
|
||||||
|
if (task.deviceId == 'delay') {
|
||||||
|
return CreateSceneAction(
|
||||||
|
entityId: actions[index].deviceId,
|
||||||
|
actionExecutor: 'delay',
|
||||||
|
executorProperty: CreateSceneExecutorProperty(
|
||||||
|
functionCode: '',
|
||||||
|
functionValue: '',
|
||||||
|
delaySeconds: task.functionValue,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
return CreateSceneAction(
|
return CreateSceneAction(
|
||||||
entityId: actions[index].deviceId,
|
entityId: task.deviceId,
|
||||||
actionExecutor: 'delay',
|
actionExecutor: 'device_issue',
|
||||||
executorProperty: CreateSceneExecutorProperty(
|
executorProperty: CreateSceneExecutorProperty(
|
||||||
functionCode: '',
|
functionCode: task.code,
|
||||||
functionValue: '',
|
functionValue: task.functionValue,
|
||||||
delaySeconds: task.functionValue,
|
delaySeconds: 0,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
return CreateSceneAction(
|
),
|
||||||
entityId: task.deviceId,
|
);
|
||||||
actionExecutor: 'device_issue',
|
sceneBloc.add(CreateSceneWithTasksEvent(
|
||||||
executorProperty: CreateSceneExecutorProperty(
|
createSceneModel: createSceneModel,
|
||||||
functionCode: task.code,
|
createAutomationModel: null,
|
||||||
functionValue: task.functionValue,
|
updateScene: updateScene,
|
||||||
delaySeconds: 0,
|
sceneId: sceneId,
|
||||||
),
|
));
|
||||||
);
|
Navigator.pop(context);
|
||||||
},
|
}
|
||||||
),
|
|
||||||
);
|
|
||||||
sceneBloc.add(CreateSceneWithTasksEvent(
|
|
||||||
createSceneModel: createSceneModel,
|
|
||||||
createAutomationModel: null,
|
|
||||||
updateScene: updateScene,
|
|
||||||
sceneId: sceneId,
|
|
||||||
));
|
|
||||||
Navigator.pop(context);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -37,9 +37,9 @@ class CreateAutomationModel {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toMap() {
|
Map<String, dynamic> toMap([String? automationId]) {
|
||||||
return {
|
return {
|
||||||
'unitUuid': unitUuid,
|
if (automationId == null) 'unitUuid': unitUuid,
|
||||||
'automationName': automationName,
|
'automationName': automationName,
|
||||||
'decisionExpr': decisionExpr,
|
'decisionExpr': decisionExpr,
|
||||||
'effectiveTime': effectiveTime.toMap(),
|
'effectiveTime': effectiveTime.toMap(),
|
||||||
@ -61,7 +61,7 @@ class CreateAutomationModel {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
String toJson() => json.encode(toMap());
|
String toJson([String? automationId]) => json.encode(toMap(automationId));
|
||||||
|
|
||||||
factory CreateAutomationModel.fromJson(String source) =>
|
factory CreateAutomationModel.fromJson(String source) =>
|
||||||
CreateAutomationModel.fromMap(json.decode(source));
|
CreateAutomationModel.fromMap(json.decode(source));
|
||||||
|
@ -6,6 +6,9 @@ class SceneDetailsModel {
|
|||||||
final String status;
|
final String status;
|
||||||
final String type;
|
final String type;
|
||||||
final List<Action> actions;
|
final List<Action> actions;
|
||||||
|
final List<Condition>? conditions;
|
||||||
|
final String? decisionExpr;
|
||||||
|
final EffectiveTime? effectiveTime;
|
||||||
|
|
||||||
SceneDetailsModel({
|
SceneDetailsModel({
|
||||||
required this.id,
|
required this.id,
|
||||||
@ -13,6 +16,9 @@ class SceneDetailsModel {
|
|||||||
required this.status,
|
required this.status,
|
||||||
required this.type,
|
required this.type,
|
||||||
required this.actions,
|
required this.actions,
|
||||||
|
this.conditions,
|
||||||
|
this.decisionExpr,
|
||||||
|
this.effectiveTime,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory SceneDetailsModel.fromRawJson(String str) =>
|
factory SceneDetailsModel.fromRawJson(String str) =>
|
||||||
@ -28,6 +34,14 @@ class SceneDetailsModel {
|
|||||||
type: json["type"],
|
type: json["type"],
|
||||||
actions:
|
actions:
|
||||||
List<Action>.from(json["actions"].map((x) => Action.fromJson(x))),
|
List<Action>.from(json["actions"].map((x) => Action.fromJson(x))),
|
||||||
|
conditions: json["conditions"] != null
|
||||||
|
? List<Condition>.from(
|
||||||
|
json["conditions"].map((x) => Condition.fromJson(x)))
|
||||||
|
: null,
|
||||||
|
decisionExpr: json["decisionExpr"],
|
||||||
|
effectiveTime: json["effectiveTime"] != null
|
||||||
|
? EffectiveTime.fromJson(json["effectiveTime"])
|
||||||
|
: null,
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
Map<String, dynamic> toJson() => {
|
||||||
@ -36,6 +50,11 @@ 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 != null
|
||||||
|
? List<dynamic>.from(conditions!.map((x) => x.toJson()))
|
||||||
|
: null,
|
||||||
|
"decisionExpr": decisionExpr,
|
||||||
|
"effectiveTime": effectiveTime?.toJson(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,3 +110,93 @@ class ExecutorProperty {
|
|||||||
"delaySeconds": delaySeconds,
|
"delaySeconds": delaySeconds,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class Condition {
|
||||||
|
final int code;
|
||||||
|
final String entityId;
|
||||||
|
final String entityType;
|
||||||
|
final Expr expr;
|
||||||
|
|
||||||
|
Condition({
|
||||||
|
required this.code,
|
||||||
|
required this.entityId,
|
||||||
|
required this.entityType,
|
||||||
|
required this.expr,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory Condition.fromRawJson(String str) =>
|
||||||
|
Condition.fromJson(json.decode(str));
|
||||||
|
|
||||||
|
String toRawJson() => json.encode(toJson());
|
||||||
|
|
||||||
|
factory Condition.fromJson(Map<String, dynamic> json) => Condition(
|
||||||
|
code: json["code"],
|
||||||
|
entityId: json["entityId"],
|
||||||
|
entityType: json["entityType"],
|
||||||
|
expr: Expr.fromJson(json["expr"]),
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => {
|
||||||
|
"code": code,
|
||||||
|
"entityId": entityId,
|
||||||
|
"entityType": entityType,
|
||||||
|
"expr": expr.toJson(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
class Expr {
|
||||||
|
final String comparator;
|
||||||
|
final String statusCode;
|
||||||
|
final dynamic statusValue;
|
||||||
|
|
||||||
|
Expr({
|
||||||
|
required this.comparator,
|
||||||
|
required this.statusCode,
|
||||||
|
required this.statusValue,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory Expr.fromRawJson(String str) => Expr.fromJson(json.decode(str));
|
||||||
|
|
||||||
|
String toRawJson() => json.encode(toJson());
|
||||||
|
|
||||||
|
factory Expr.fromJson(Map<String, dynamic> json) => Expr(
|
||||||
|
comparator: json["comparator"],
|
||||||
|
statusCode: json["statusCode"],
|
||||||
|
statusValue: json["statusValue"],
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => {
|
||||||
|
"comparator": comparator,
|
||||||
|
"statusCode": statusCode,
|
||||||
|
"statusValue": statusValue,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
class EffectiveTime {
|
||||||
|
final String start;
|
||||||
|
final String end;
|
||||||
|
final String loops;
|
||||||
|
|
||||||
|
EffectiveTime({
|
||||||
|
required this.start,
|
||||||
|
required this.end,
|
||||||
|
required this.loops,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory EffectiveTime.fromRawJson(String str) =>
|
||||||
|
EffectiveTime.fromJson(json.decode(str));
|
||||||
|
|
||||||
|
String toRawJson() => json.encode(toJson());
|
||||||
|
|
||||||
|
factory EffectiveTime.fromJson(Map<String, dynamic> json) => EffectiveTime(
|
||||||
|
start: json["start"],
|
||||||
|
end: json["end"],
|
||||||
|
loops: json["loops"],
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => {
|
||||||
|
"start": start,
|
||||||
|
"end": end,
|
||||||
|
"loops": loops,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
@ -37,9 +37,10 @@ enum Status { ENABLE }
|
|||||||
|
|
||||||
final statusValues = EnumValues({"enable": Status.ENABLE});
|
final statusValues = EnumValues({"enable": Status.ENABLE});
|
||||||
|
|
||||||
enum Type { TAP_TO_RUN }
|
enum Type { TAP_TO_RUN, automation }
|
||||||
|
|
||||||
final typeValues = EnumValues({"tap_to_run": Type.TAP_TO_RUN});
|
final typeValues =
|
||||||
|
EnumValues({"tap_to_run": Type.TAP_TO_RUN, "automation": Type.automation});
|
||||||
|
|
||||||
class EnumValues<T> {
|
class EnumValues<T> {
|
||||||
Map<String, T> map;
|
Map<String, T> map;
|
||||||
|
@ -20,7 +20,7 @@ import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
|||||||
|
|
||||||
class DeviceFunctionsView extends StatelessWidget
|
class DeviceFunctionsView extends StatelessWidget
|
||||||
with SceneOperationsDataHelper, SceneLogicHelper {
|
with SceneOperationsDataHelper, SceneLogicHelper {
|
||||||
const DeviceFunctionsView({super.key});
|
DeviceFunctionsView({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -54,7 +54,7 @@ class DeviceFunctionsView extends StatelessWidget
|
|||||||
context
|
context
|
||||||
.read<CreateSceneBloc>()
|
.read<CreateSceneBloc>()
|
||||||
.add(AddTaskEvent(isAutomation: isAutomation));
|
.add(AddTaskEvent(isAutomation: isAutomation));
|
||||||
navigateToRoute(context, Routes.sceneTasksRoute);
|
navigateToRoute(context, Routes.sceneTasksRoute);
|
||||||
},
|
},
|
||||||
child: BodyMedium(
|
child: BodyMedium(
|
||||||
text: 'Save',
|
text: 'Save',
|
||||||
|
@ -13,6 +13,8 @@ import 'package:syncrow_app/features/scene/widgets/scene_list_tile.dart';
|
|||||||
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
|
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
|
||||||
import 'package:syncrow_app/generated/assets.dart';
|
import 'package:syncrow_app/generated/assets.dart';
|
||||||
|
import 'package:syncrow_app/navigation/navigate_to_route.dart';
|
||||||
|
import 'package:syncrow_app/navigation/routing_constants.dart';
|
||||||
import 'package:syncrow_app/utils/context_extension.dart';
|
import 'package:syncrow_app/utils/context_extension.dart';
|
||||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||||
import 'package:syncrow_app/utils/resource_manager/strings_manager.dart';
|
import 'package:syncrow_app/utils/resource_manager/strings_manager.dart';
|
||||||
@ -24,6 +26,7 @@ class SceneTasksView extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final sceneSettings = ModalRoute.of(context)!.settings.arguments
|
final sceneSettings = ModalRoute.of(context)!.settings.arguments
|
||||||
as SceneSettingsRouteArguments;
|
as SceneSettingsRouteArguments;
|
||||||
|
|
||||||
return DefaultScaffold(
|
return DefaultScaffold(
|
||||||
title: sceneSettings.sceneName.isNotEmpty
|
title: sceneSettings.sceneName.isNotEmpty
|
||||||
? sceneSettings.sceneName
|
? sceneSettings.sceneName
|
||||||
@ -107,8 +110,7 @@ class DeleteBottomSheetContent extends StatelessWidget {
|
|||||||
listener: (context, state) {
|
listener: (context, state) {
|
||||||
if (state is DeleteSceneSuccess) {
|
if (state is DeleteSceneSuccess) {
|
||||||
if (state.success) {
|
if (state.success) {
|
||||||
Navigator.pop(context);
|
navigateToRoute(context, Routes.homeRoute);
|
||||||
Navigator.pop(context);
|
|
||||||
BlocProvider.of<SceneBloc>(context).add(
|
BlocProvider.of<SceneBloc>(context).add(
|
||||||
LoadScenes(HomeCubit.getInstance().selectedSpace!.id!));
|
LoadScenes(HomeCubit.getInstance().selectedSpace!.id!));
|
||||||
}
|
}
|
||||||
|
@ -1,7 +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/bloc/home_cubit.dart';
|
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.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';
|
||||||
import 'package:syncrow_app/features/scene/bloc/scene_bloc/scene_event.dart';
|
import 'package:syncrow_app/features/scene/bloc/scene_bloc/scene_event.dart';
|
||||||
@ -9,7 +8,9 @@ import 'package:syncrow_app/features/scene/widgets/scene_view_widget/scene_grid_
|
|||||||
import 'package:syncrow_app/features/scene/widgets/scene_view_widget/scene_header.dart';
|
import 'package:syncrow_app/features/scene/widgets/scene_view_widget/scene_header.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/create_unit.dart';
|
import 'package:syncrow_app/features/shared_widgets/create_unit.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
||||||
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
|
||||||
import 'package:syncrow_app/utils/context_extension.dart';
|
import 'package:syncrow_app/utils/context_extension.dart';
|
||||||
|
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||||
|
|
||||||
class SceneView extends StatelessWidget {
|
class SceneView extends StatelessWidget {
|
||||||
final bool pageType;
|
final bool pageType;
|
||||||
@ -19,7 +20,8 @@ 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 ?? '')),
|
..add(LoadScenes(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) {
|
||||||
@ -32,6 +34,8 @@ class SceneView extends StatelessWidget {
|
|||||||
if (state.success == true) {
|
if (state.success == true) {
|
||||||
BlocProvider.of<SceneBloc>(context)
|
BlocProvider.of<SceneBloc>(context)
|
||||||
.add(LoadScenes(HomeCubit.getInstance().selectedSpace!.id!));
|
.add(LoadScenes(HomeCubit.getInstance().selectedSpace!.id!));
|
||||||
|
BlocProvider.of<SceneBloc>(context).add(
|
||||||
|
LoadAutomation(HomeCubit.getInstance().selectedSpace!.id!));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return BlocListener<SceneBloc, SceneState>(
|
return BlocListener<SceneBloc, SceneState>(
|
||||||
@ -63,29 +67,69 @@ class SceneView extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (state is SceneLoaded) {
|
if (state is SceneLoaded) {
|
||||||
if (state.scenes.isNotEmpty) {
|
final scenes = state.scenes;
|
||||||
return pageType == false
|
final automationList = state.automationList;
|
||||||
? Expanded(
|
|
||||||
child: SceneGrid(
|
return Expanded(
|
||||||
scenes: state.scenes,
|
child: ListView(
|
||||||
loadingSceneId: state.loadingSceneId,
|
children: [
|
||||||
|
ExpansionTile(
|
||||||
|
tilePadding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 6),
|
||||||
|
initiallyExpanded: true,
|
||||||
|
iconColor: ColorsManager.grayColor,
|
||||||
|
title: const BodySmall(
|
||||||
|
text: 'Tap to run routines'),
|
||||||
|
children: [
|
||||||
|
scenes.isNotEmpty
|
||||||
|
? SceneGrid(
|
||||||
|
scenes: scenes,
|
||||||
|
loadingSceneId:
|
||||||
|
state.loadingSceneId,
|
||||||
|
disablePLayButton: false,
|
||||||
|
)
|
||||||
|
: const Center(
|
||||||
|
child: BodyMedium(
|
||||||
|
text:
|
||||||
|
'No scenes have been added yet',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 10,
|
||||||
),
|
),
|
||||||
)
|
],
|
||||||
: Expanded(
|
|
||||||
child: SceneListview(
|
|
||||||
scenes: state.scenes,
|
|
||||||
loadingSceneId: state.loadingSceneId,
|
|
||||||
)
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return const Expanded(
|
|
||||||
child: Center(
|
|
||||||
child: BodyMedium(
|
|
||||||
text: 'No scenes have been added yet',
|
|
||||||
),
|
),
|
||||||
),
|
ExpansionTile(
|
||||||
);
|
initiallyExpanded: true,
|
||||||
}
|
iconColor: ColorsManager.grayColor,
|
||||||
|
tilePadding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 6),
|
||||||
|
title: const BodySmall(text: 'Automation'),
|
||||||
|
children: [
|
||||||
|
automationList.isNotEmpty
|
||||||
|
? SceneGrid(
|
||||||
|
scenes: automationList,
|
||||||
|
loadingSceneId:
|
||||||
|
state.loadingSceneId,
|
||||||
|
disablePLayButton: true,
|
||||||
|
)
|
||||||
|
: const Center(
|
||||||
|
child: BodyMedium(
|
||||||
|
text:
|
||||||
|
'No automations have been added yet',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 10,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 15,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return const SizedBox();
|
return const SizedBox();
|
||||||
},
|
},
|
||||||
|
@ -62,7 +62,7 @@ class _AlertDialogSliderStepsState extends State<AlertDialogSliderSteps> {
|
|||||||
double _normalizeValue(dynamic value) {
|
double _normalizeValue(dynamic value) {
|
||||||
if (widget.taskItem.code == "temp_set" ||
|
if (widget.taskItem.code == "temp_set" ||
|
||||||
widget.taskItem.code == "temp_current") {
|
widget.taskItem.code == "temp_current") {
|
||||||
return (value as double) / 10;
|
return (value) / 10;
|
||||||
}
|
}
|
||||||
return value.toDouble();
|
return value.toDouble();
|
||||||
}
|
}
|
||||||
|
@ -83,8 +83,12 @@ class IFDefaultContainer extends StatelessWidget {
|
|||||||
BlocBuilder<CreateSceneBloc, CreateSceneState>(
|
BlocBuilder<CreateSceneBloc, CreateSceneState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
String conditionText = "When any condition is met";
|
String conditionText = "When any condition is met";
|
||||||
if (state is ConditionSelectedState) {
|
if (state is AddSceneTask) {
|
||||||
conditionText = state.condition;
|
if (state.condition == 'or') {
|
||||||
|
conditionText = "When any condition is met";
|
||||||
|
} else {
|
||||||
|
conditionText = "When all conditions are met";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
width: context.width * 0.6,
|
width: context.width * 0.6,
|
||||||
|
@ -1,21 +1,22 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:syncrow_app/features/scene/model/scenes_model.dart';
|
|
||||||
import 'package:syncrow_app/features/scene/widgets/scene_view_widget/scene_item.dart';
|
import 'package:syncrow_app/features/scene/widgets/scene_view_widget/scene_item.dart';
|
||||||
|
|
||||||
class SceneGrid extends StatelessWidget {
|
class SceneGrid extends StatelessWidget {
|
||||||
final List<ScenesModel> scenes;
|
final List<dynamic> scenes;
|
||||||
final String? loadingSceneId;
|
final String? loadingSceneId;
|
||||||
|
final bool disablePLayButton;
|
||||||
const SceneGrid({
|
const SceneGrid({
|
||||||
required this.scenes,
|
required this.scenes,
|
||||||
required this.loadingSceneId,
|
required this.loadingSceneId,
|
||||||
super.key,
|
super.key,
|
||||||
|
required this.disablePLayButton,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return
|
return GridView.builder(
|
||||||
GridView.builder(
|
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
crossAxisCount: 2,
|
crossAxisCount: 2,
|
||||||
mainAxisSpacing: 12,
|
mainAxisSpacing: 12,
|
||||||
@ -26,7 +27,10 @@ class SceneGrid extends StatelessWidget {
|
|||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
final scene = scenes[index];
|
final scene = scenes[index];
|
||||||
final isLoading = loadingSceneId == scene.id;
|
final isLoading = loadingSceneId == scene.id;
|
||||||
return SceneItem(scene: scene, isLoading: isLoading);
|
return SceneItem(
|
||||||
|
scene: scene,
|
||||||
|
isLoading: isLoading,
|
||||||
|
disablePLayButton: disablePLayButton);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
|
|
||||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/title_medium.dart';
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/title_medium.dart';
|
||||||
|
|
||||||
import 'package:syncrow_app/utils/resource_manager/strings_manager.dart';
|
import 'package:syncrow_app/utils/resource_manager/strings_manager.dart';
|
||||||
@ -20,10 +19,10 @@ class SceneHeader extends StatelessWidget {
|
|||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(height: 20),
|
// SizedBox(height: 20),
|
||||||
BodySmall(
|
// BodySmall(
|
||||||
text: StringsManager.tapToRunRoutine,
|
// text: StringsManager.tapToRunRoutine,
|
||||||
),
|
// ),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -16,11 +16,13 @@ import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
|||||||
class SceneItem extends StatelessWidget {
|
class SceneItem extends StatelessWidget {
|
||||||
final ScenesModel scene;
|
final ScenesModel scene;
|
||||||
final bool isLoading;
|
final bool isLoading;
|
||||||
|
final bool disablePLayButton;
|
||||||
|
|
||||||
const SceneItem({
|
const SceneItem({
|
||||||
required this.scene,
|
required this.scene,
|
||||||
required this.isLoading,
|
required this.isLoading,
|
||||||
super.key,
|
super.key,
|
||||||
|
required this.disablePLayButton,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -31,16 +33,28 @@ class SceneItem extends StatelessWidget {
|
|||||||
context,
|
context,
|
||||||
Routes.sceneTasksRoute,
|
Routes.sceneTasksRoute,
|
||||||
arguments: SceneSettingsRouteArguments(
|
arguments: SceneSettingsRouteArguments(
|
||||||
sceneType: CreateSceneEnum.tabToRun.name,
|
sceneType: disablePLayButton == false
|
||||||
|
? CreateSceneEnum.tabToRun.name
|
||||||
|
: CreateSceneEnum.deviceStatusChanges.name,
|
||||||
sceneId: scene.id,
|
sceneId: scene.id,
|
||||||
sceneName: scene.name,
|
sceneName: scene.name,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
BlocProvider.of<CreateSceneBloc>(context)
|
if (disablePLayButton == false) {
|
||||||
.add(FetchSceneTasksEvent(sceneId: scene.id));
|
BlocProvider.of<CreateSceneBloc>(context)
|
||||||
|
.add(const SceneTypeEvent(CreateSceneEnum.tabToRun));
|
||||||
|
BlocProvider.of<CreateSceneBloc>(context).add(
|
||||||
|
FetchSceneTasksEvent(sceneId: scene.id, isAutomation: false));
|
||||||
|
} else {
|
||||||
|
BlocProvider.of<CreateSceneBloc>(context)
|
||||||
|
.add(const SceneTypeEvent(CreateSceneEnum.deviceStatusChanges));
|
||||||
|
BlocProvider.of<CreateSceneBloc>(context)
|
||||||
|
.add(FetchSceneTasksEvent(sceneId: scene.id, isAutomation: true));
|
||||||
|
}
|
||||||
},
|
},
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Row(
|
Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
@ -52,22 +66,25 @@ class SceneItem extends StatelessWidget {
|
|||||||
Assets.assetsIconsLogo,
|
Assets.assetsIconsLogo,
|
||||||
fit: BoxFit.fill,
|
fit: BoxFit.fill,
|
||||||
),
|
),
|
||||||
IconButton(
|
Visibility(
|
||||||
padding: EdgeInsets.zero,
|
visible: disablePLayButton == false,
|
||||||
onPressed: () {
|
child: IconButton(
|
||||||
context
|
padding: EdgeInsets.zero,
|
||||||
.read<SceneBloc>()
|
onPressed: () {
|
||||||
.add(SceneTrigger(scene.id, scene.name));
|
context
|
||||||
},
|
.read<SceneBloc>()
|
||||||
icon: isLoading
|
.add(SceneTrigger(scene.id, scene.name));
|
||||||
? const Center(
|
},
|
||||||
child: CircularProgressIndicator(),
|
icon: isLoading
|
||||||
)
|
? const Center(
|
||||||
: const Icon(
|
child: CircularProgressIndicator(),
|
||||||
Icons.play_circle,
|
)
|
||||||
size: 40,
|
: const Icon(
|
||||||
color: ColorsManager.greyColor,
|
Icons.play_circle,
|
||||||
),
|
size: 40,
|
||||||
|
color: ColorsManager.greyColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
@ -24,54 +24,67 @@ class Router {
|
|||||||
static Route<dynamic> generateRoute(RouteSettings settings) {
|
static Route<dynamic> generateRoute(RouteSettings settings) {
|
||||||
switch (settings.name) {
|
switch (settings.name) {
|
||||||
case Routes.splash:
|
case Routes.splash:
|
||||||
return MaterialPageRoute(builder: (_) => const SplashView(), settings: settings);
|
return MaterialPageRoute(
|
||||||
|
builder: (_) => const SplashView(), settings: settings);
|
||||||
|
|
||||||
// case Routes.devicesRoute:
|
// case Routes.devicesRoute:
|
||||||
// return MaterialPageRoute(
|
// return MaterialPageRoute(
|
||||||
// builder: (_) => const DevicesView(), settings: settings);
|
// builder: (_) => const DevicesView(), settings: settings);
|
||||||
|
|
||||||
case Routes.profileRoute:
|
case Routes.profileRoute:
|
||||||
return MaterialPageRoute(builder: (_) => const ProfileView(), settings: settings);
|
return MaterialPageRoute(
|
||||||
|
builder: (_) => const ProfileView(), settings: settings);
|
||||||
|
|
||||||
case Routes.sceneRoute:
|
case Routes.sceneRoute:
|
||||||
return MaterialPageRoute(builder: (_) => const SceneView(), settings: settings);
|
return MaterialPageRoute(
|
||||||
|
builder: (_) => const SceneView(), settings: settings);
|
||||||
|
|
||||||
case Routes.layoutRoute:
|
case Routes.layoutRoute:
|
||||||
return MaterialPageRoute(builder: (_) => const LayoutPage(), settings: settings);
|
return MaterialPageRoute(
|
||||||
|
builder: (_) => const LayoutPage(), settings: settings);
|
||||||
|
|
||||||
case Routes.authLogin:
|
case Routes.authLogin:
|
||||||
return MaterialPageRoute(builder: (_) => const LoginView(), settings: settings);
|
return MaterialPageRoute(
|
||||||
|
builder: (_) => const LoginView(), settings: settings);
|
||||||
|
|
||||||
case Routes.otpRoute:
|
case Routes.otpRoute:
|
||||||
return MaterialPageRoute(builder: (_) => const OtpView(), settings: settings);
|
return MaterialPageRoute(
|
||||||
|
builder: (_) => const OtpView(), settings: settings);
|
||||||
|
|
||||||
case Routes.authSignUp:
|
case Routes.authSignUp:
|
||||||
return MaterialPageRoute(builder: (_) => const SignUpView(), settings: settings);
|
return MaterialPageRoute(
|
||||||
|
builder: (_) => const SignUpView(), settings: settings);
|
||||||
|
|
||||||
case Routes.dashboardRoute:
|
case Routes.dashboardRoute:
|
||||||
return MaterialPageRoute(builder: (_) => const DashboardView(), settings: settings);
|
return MaterialPageRoute(
|
||||||
|
builder: (_) => const DashboardView(), settings: settings);
|
||||||
|
|
||||||
case Routes.homeRoute:
|
case Routes.homeRoute:
|
||||||
return MaterialPageRoute(builder: (_) => const AppLayout(), settings: settings);
|
return MaterialPageRoute(
|
||||||
|
builder: (_) => const AppLayout(), settings: settings);
|
||||||
|
|
||||||
case Routes.menuRoute:
|
case Routes.menuRoute:
|
||||||
return MaterialPageRoute(builder: (_) => const MenuView(), settings: settings);
|
return MaterialPageRoute(
|
||||||
|
builder: (_) => const MenuView(), settings: settings);
|
||||||
|
|
||||||
case Routes.createUnit:
|
case Routes.createUnit:
|
||||||
return MaterialPageRoute(builder: (_) => const CreateUnitView(), settings: settings);
|
return MaterialPageRoute(
|
||||||
|
builder: (_) => const CreateUnitView(), settings: settings);
|
||||||
case Routes.sceneTasksRoute:
|
case Routes.sceneTasksRoute:
|
||||||
return MaterialPageRoute(builder: (_) => const SceneTasksView(), settings: settings);
|
return MaterialPageRoute(
|
||||||
|
builder: (_) => const SceneTasksView(), settings: settings);
|
||||||
case Routes.sceneControlDevicesRoute:
|
case Routes.sceneControlDevicesRoute:
|
||||||
return MaterialPageRoute(
|
return MaterialPageRoute(
|
||||||
builder: (_) => MultiBlocProvider(
|
builder: (_) => MultiBlocProvider(
|
||||||
providers: [
|
providers: [
|
||||||
BlocProvider(
|
BlocProvider(
|
||||||
create: (BuildContext context) => DeviceManagerBloc()..add(FetchAllDevices()),
|
create: (BuildContext context) =>
|
||||||
|
DeviceManagerBloc()..add(FetchAllDevices()),
|
||||||
),
|
),
|
||||||
BlocProvider(
|
BlocProvider(
|
||||||
create: (BuildContext context) =>
|
create: (BuildContext context) => TabBarBloc(
|
||||||
TabBarBloc(context.read<DeviceManagerBloc>())
|
context.read<DeviceManagerBloc>())
|
||||||
..add(const TabChanged(selectedIndex: 0, roomId: '-1')),
|
..add(const TabChanged(selectedIndex: 0, roomId: '-1')),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
child: const SceneRoomsTabBarDevicesView(),
|
child: const SceneRoomsTabBarDevicesView(),
|
||||||
@ -79,7 +92,7 @@ class Router {
|
|||||||
settings: settings);
|
settings: settings);
|
||||||
case Routes.deviceFunctionsRoute:
|
case Routes.deviceFunctionsRoute:
|
||||||
return MaterialPageRoute(
|
return MaterialPageRoute(
|
||||||
builder: (_) => const DeviceFunctionsView(),
|
builder: (_) => DeviceFunctionsView(),
|
||||||
settings: settings,
|
settings: settings,
|
||||||
);
|
);
|
||||||
default:
|
default:
|
||||||
|
@ -129,7 +129,7 @@ abstract class ApiEndpoints {
|
|||||||
|
|
||||||
static const String assignDeviceToRoom = '$baseUrl/device/room';
|
static const String assignDeviceToRoom = '$baseUrl/device/room';
|
||||||
|
|
||||||
/// Scene API ////////////////////
|
/// Scene & Automation API ////////////////////
|
||||||
/// POST
|
/// POST
|
||||||
static const String createScene = '$baseUrl/scene/tap-to-run';
|
static const String createScene = '$baseUrl/scene/tap-to-run';
|
||||||
static const String triggerScene =
|
static const String triggerScene =
|
||||||
@ -142,9 +142,16 @@ abstract class ApiEndpoints {
|
|||||||
|
|
||||||
static const String getScene = '$baseUrl/scene/tap-to-run/details/{sceneId}';
|
static const String getScene = '$baseUrl/scene/tap-to-run/details/{sceneId}';
|
||||||
|
|
||||||
|
static const String getUnitAutomation = '$baseUrl/automation/{unitUuid}';
|
||||||
|
|
||||||
|
static const String getAutomationDetails = '$baseUrl/automation/details/{automationId}';
|
||||||
|
|
||||||
/// PUT
|
/// PUT
|
||||||
static const String updateScene = '$baseUrl/scene/tap-to-run/{sceneId}';
|
static const String updateScene = '$baseUrl/scene/tap-to-run/{sceneId}';
|
||||||
|
|
||||||
|
static const String updateAutomation =
|
||||||
|
'$baseUrl/automation/{automationId}';
|
||||||
|
|
||||||
/// DELETE
|
/// DELETE
|
||||||
static const String deleteScene =
|
static const String deleteScene =
|
||||||
'$baseUrl/scene/tap-to-run/{unitUuid}/{sceneId}';
|
'$baseUrl/scene/tap-to-run/{unitUuid}/{sceneId}';
|
||||||
|
@ -8,6 +8,7 @@ import 'package:syncrow_app/services/api/http_service.dart';
|
|||||||
class SceneApi {
|
class SceneApi {
|
||||||
static final HTTPService _httpService = HTTPService();
|
static final HTTPService _httpService = HTTPService();
|
||||||
|
|
||||||
|
//create scene
|
||||||
static Future<Map<String, dynamic>> createScene(
|
static Future<Map<String, dynamic>> createScene(
|
||||||
CreateSceneModel createSceneModel) async {
|
CreateSceneModel createSceneModel) async {
|
||||||
try {
|
try {
|
||||||
@ -25,6 +26,7 @@ class SceneApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// create automation
|
||||||
static Future<Map<String, dynamic>> createAutomation(
|
static Future<Map<String, dynamic>> createAutomation(
|
||||||
CreateAutomationModel createAutomationModel) async {
|
CreateAutomationModel createAutomationModel) async {
|
||||||
try {
|
try {
|
||||||
@ -42,6 +44,8 @@ class SceneApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//get scene by unit id
|
||||||
|
|
||||||
static Future<List<ScenesModel>> getScenesByUnitId(String unitId) async {
|
static Future<List<ScenesModel>> getScenesByUnitId(String unitId) async {
|
||||||
try {
|
try {
|
||||||
final response = await _httpService.get(
|
final response = await _httpService.get(
|
||||||
@ -61,6 +65,27 @@ class SceneApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//getAutomation
|
||||||
|
|
||||||
|
static Future<List<ScenesModel>> getAutomationByUnitId(String unitId) async {
|
||||||
|
try {
|
||||||
|
final response = await _httpService.get(
|
||||||
|
path: ApiEndpoints.getUnitAutomation.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 {
|
static Future<bool> triggerScene(String sceneId) async {
|
||||||
try {
|
try {
|
||||||
final response = await _httpService.post(
|
final response = await _httpService.post(
|
||||||
@ -74,6 +99,22 @@ class SceneApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//getScene
|
//getScene
|
||||||
|
|
||||||
static Future<SceneDetailsModel> getSceneDetails(String sceneId) async {
|
static Future<SceneDetailsModel> getSceneDetails(String sceneId) async {
|
||||||
@ -89,7 +130,7 @@ class SceneApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//updateScene
|
//update Scene
|
||||||
static updateScene(CreateSceneModel createSceneModel, String sceneId) async {
|
static updateScene(CreateSceneModel createSceneModel, String sceneId) async {
|
||||||
try {
|
try {
|
||||||
final response = await _httpService.put(
|
final response = await _httpService.put(
|
||||||
@ -106,7 +147,26 @@ class SceneApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//deleteScene
|
//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(
|
static Future<bool> deleteScene(
|
||||||
{required String unitUuid, required String sceneId}) async {
|
{required String unitUuid, required String sceneId}) async {
|
||||||
|
Reference in New Issue
Block a user