mirror of
https://github.com/SyncrowIOT/syncrow-app.git
synced 2025-07-15 01:35:23 +00:00
finished adding tasks and removing them , added error handling
This commit is contained in:
@ -1,7 +1,7 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_category_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/functions.dart';
|
||||
import 'package:syncrow_app/features/devices/model/function_model.dart';
|
||||
|
||||
class DeviceManagerState extends Equatable {
|
||||
final bool loading;
|
||||
@ -11,7 +11,7 @@ class DeviceManagerState extends Equatable {
|
||||
final bool categoryChanged;
|
||||
final bool deviceSelected;
|
||||
final bool functionsLoading;
|
||||
final FunctionsEntity? deviceFunctions;
|
||||
final FunctionModel? deviceFunctions;
|
||||
|
||||
const DeviceManagerState({
|
||||
required this.loading,
|
||||
@ -45,7 +45,7 @@ class DeviceManagerState extends Equatable {
|
||||
bool? categoryChanged,
|
||||
bool? deviceSelected,
|
||||
bool? functionsLoading,
|
||||
FunctionsEntity? deviceFunctions,
|
||||
FunctionModel? deviceFunctions,
|
||||
}) {
|
||||
return DeviceManagerState(
|
||||
loading: loading ?? this.loading,
|
||||
|
@ -2,6 +2,8 @@ import 'dart:async';
|
||||
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_control_model.dart';
|
||||
import 'package:syncrow_app/features/scene/model/scene_static_function.dart';
|
||||
|
||||
part 'create_scene_event.dart';
|
||||
part 'create_scene_state.dart';
|
||||
@ -9,5 +11,51 @@ part 'create_scene_state.dart';
|
||||
class CreateSceneBloc extends Bloc<CreateSceneEvent, CreateSceneState> {
|
||||
CreateSceneBloc() : super(CreateSceneInitial()) {
|
||||
on<CreateSceneEvent>((event, emit) => null as FutureOr<void>);
|
||||
on<AddTaskEvent>(_onAddSceneTask);
|
||||
on<SelectedValueEvent>(_selectedValue);
|
||||
on<RemoveTaskEvent>(_removeTaskById);
|
||||
}
|
||||
|
||||
List<SceneStaticFunction> tasksList = [];
|
||||
String selectedValue = '';
|
||||
|
||||
FutureOr<void> _onAddSceneTask(
|
||||
AddTaskEvent event, Emitter<CreateSceneState> emit) {
|
||||
tasksList.add(
|
||||
SceneStaticFunction(
|
||||
operationName: event.operation,
|
||||
deviceName: event.deviceName,
|
||||
icon: event.icon,
|
||||
code: event.deviceControlModel.code ?? '',
|
||||
deviceId: event.deviceId,
|
||||
operationalValues: [
|
||||
SceneOperationalValue(
|
||||
value: event.deviceControlModel.value,
|
||||
icon: '',
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
emit(AddSceneTask(tasksList: tasksList));
|
||||
}
|
||||
|
||||
FutureOr<void> _selectedValue(
|
||||
SelectedValueEvent event, Emitter<CreateSceneState> emit) {
|
||||
selectedValue = event.value;
|
||||
emit(SelectedTaskValueState(value: event.value));
|
||||
}
|
||||
|
||||
FutureOr<void> _removeTaskById(
|
||||
RemoveTaskEvent event, Emitter<CreateSceneState> emit) {
|
||||
emit(CreateSceneLoading());
|
||||
|
||||
for (var element in tasksList) {
|
||||
if (element.uniqueCustomId == event.taskId) {
|
||||
tasksList.remove(element);
|
||||
|
||||
emit(AddSceneTask(tasksList: tasksList));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,4 +7,40 @@ sealed class CreateSceneEvent extends Equatable {
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class AddTaskEvent extends CreateSceneEvent {
|
||||
final DeviceControlModel deviceControlModel;
|
||||
final String deviceId;
|
||||
final String icon;
|
||||
final String operation;
|
||||
final String deviceName;
|
||||
|
||||
const AddTaskEvent({
|
||||
required this.deviceControlModel,
|
||||
required this.deviceId,
|
||||
required this.icon,
|
||||
required this.operation,
|
||||
required this.deviceName,
|
||||
});
|
||||
|
||||
@override
|
||||
List<Object> get props =>
|
||||
[deviceControlModel, deviceId, deviceName, icon, operation];
|
||||
}
|
||||
|
||||
class SelectedValueEvent extends CreateSceneEvent {
|
||||
final String value;
|
||||
|
||||
const SelectedValueEvent({required this.value});
|
||||
|
||||
@override
|
||||
List<Object> get props => [value];
|
||||
}
|
||||
|
||||
class RemoveTaskEvent extends CreateSceneEvent {
|
||||
final String taskId;
|
||||
|
||||
const RemoveTaskEvent({required this.taskId});
|
||||
|
||||
@override
|
||||
List<Object> get props => [taskId];
|
||||
}
|
||||
|
@ -11,4 +11,18 @@ final class CreateSceneInitial extends CreateSceneState {}
|
||||
|
||||
class CreateSceneLoading extends CreateSceneState {}
|
||||
|
||||
class AddSceneTask extends CreateSceneState {
|
||||
final List<SceneStaticFunction> tasksList;
|
||||
const AddSceneTask({required this.tasksList});
|
||||
|
||||
@override
|
||||
List<Object> get props => [tasksList];
|
||||
}
|
||||
|
||||
class SelectedTaskValueState extends CreateSceneState {
|
||||
final String value;
|
||||
const SelectedTaskValueState({required this.value});
|
||||
|
||||
@override
|
||||
List<Object> get props => [value];
|
||||
}
|
||||
|
@ -5,27 +5,40 @@ import 'package:syncrow_app/generated/assets.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/constants.dart';
|
||||
|
||||
mixin SceneHelper {
|
||||
List<SceneStaticFunction> getFunctionsWithIcons(
|
||||
{DeviceType? type, required List<FunctionModel> functions}) {
|
||||
List<SceneStaticFunction> getFunctionsWithIcons({
|
||||
DeviceType? type,
|
||||
required List<FunctionModel> functions,
|
||||
required String deviceId,
|
||||
required String deviceName,
|
||||
}) {
|
||||
switch (type) {
|
||||
case DeviceType.LightBulb:
|
||||
return lightBulbFunctions(functions);
|
||||
return lightBulbFunctions(
|
||||
functions: functions, deviceId: deviceId, deviceName: deviceName);
|
||||
case DeviceType.CeilingSensor:
|
||||
return ceilingSensorFunctions(functions);
|
||||
return ceilingSensorFunctions(
|
||||
functions: functions, deviceId: deviceId, deviceName: deviceName);
|
||||
case DeviceType.WallSensor:
|
||||
return wallSensorFunctions(functions);
|
||||
return wallSensorFunctions(
|
||||
functions: functions, deviceId: deviceId, deviceName: deviceName);
|
||||
case DeviceType.AC:
|
||||
return acFunctions(functions);
|
||||
return acFunctions(
|
||||
functions: functions, deviceId: deviceId, deviceName: deviceName);
|
||||
case DeviceType.DoorLock:
|
||||
return doorLockFunctions(functions);
|
||||
return doorLockFunctions(
|
||||
functions: functions, deviceId: deviceId, deviceName: deviceName);
|
||||
case DeviceType.Curtain:
|
||||
return curtainFunctions(functions);
|
||||
return curtainFunctions(
|
||||
functions: functions, deviceId: deviceId, deviceName: deviceName);
|
||||
case DeviceType.ThreeGang:
|
||||
return threeGangFunctions(functions);
|
||||
return threeGangFunctions(
|
||||
functions: functions, deviceId: deviceId, deviceName: deviceName);
|
||||
case DeviceType.Gateway:
|
||||
return gatewayFunctions(functions);
|
||||
return gatewayFunctions(
|
||||
functions: functions, deviceId: deviceId, deviceName: deviceName);
|
||||
default:
|
||||
return lightBulbFunctions(functions);
|
||||
return lightBulbFunctions(
|
||||
functions: functions, deviceId: deviceId, deviceName: deviceName);
|
||||
}
|
||||
}
|
||||
|
||||
@ -54,32 +67,36 @@ mixin SceneHelper {
|
||||
|
||||
/// presence sensor
|
||||
List<SceneStaticFunction> ceilingSensorFunctions(
|
||||
List<FunctionModel> functions) {
|
||||
{required List<FunctionModel> functions,
|
||||
required String deviceId,
|
||||
required String deviceName}) {
|
||||
return [
|
||||
SceneStaticFunction(
|
||||
deviceId: deviceId,
|
||||
deviceName: deviceName,
|
||||
icon: Assets.assetsSensitivityFunction,
|
||||
name: 'Sensitivity',
|
||||
operationName: 'Sensitivity',
|
||||
code: 'sensitivity',
|
||||
operationalValues: [
|
||||
StaticFunctionOperationHelper(
|
||||
SceneOperationalValue(
|
||||
icon: Assets.assetsSensitivityOperationIcon, value: "1"),
|
||||
StaticFunctionOperationHelper(
|
||||
SceneOperationalValue(
|
||||
icon: Assets.assetsSensitivityOperationIcon, value: "2"),
|
||||
StaticFunctionOperationHelper(
|
||||
SceneOperationalValue(
|
||||
icon: Assets.assetsSensitivityOperationIcon, value: "3"),
|
||||
StaticFunctionOperationHelper(
|
||||
SceneOperationalValue(
|
||||
icon: Assets.assetsSensitivityOperationIcon, value: "4"),
|
||||
StaticFunctionOperationHelper(
|
||||
SceneOperationalValue(
|
||||
icon: Assets.assetsSensitivityOperationIcon, value: "5"),
|
||||
StaticFunctionOperationHelper(
|
||||
SceneOperationalValue(
|
||||
icon: Assets.assetsSensitivityOperationIcon, value: "6"),
|
||||
StaticFunctionOperationHelper(
|
||||
SceneOperationalValue(
|
||||
icon: Assets.assetsSensitivityOperationIcon, value: "7"),
|
||||
StaticFunctionOperationHelper(
|
||||
SceneOperationalValue(
|
||||
icon: Assets.assetsSensitivityOperationIcon, value: "8"),
|
||||
StaticFunctionOperationHelper(
|
||||
SceneOperationalValue(
|
||||
icon: Assets.assetsSensitivityOperationIcon, value: "9"),
|
||||
StaticFunctionOperationHelper(
|
||||
SceneOperationalValue(
|
||||
icon: Assets.assetsSensitivityOperationIcon, value: "10"),
|
||||
],
|
||||
),
|
||||
@ -87,165 +104,204 @@ mixin SceneHelper {
|
||||
}
|
||||
}
|
||||
|
||||
List<SceneStaticFunction> curtainFunctions(List<FunctionModel> functions) {
|
||||
List<SceneStaticFunction> curtainFunctions(
|
||||
{required List<FunctionModel> functions,
|
||||
required String deviceId,
|
||||
required String deviceName}) {
|
||||
return [];
|
||||
}
|
||||
|
||||
List<SceneStaticFunction> doorLockFunctions(List<FunctionModel> functions) {
|
||||
List<SceneStaticFunction> doorLockFunctions(
|
||||
{required List<FunctionModel> functions,
|
||||
required String deviceId,
|
||||
required String deviceName}) {
|
||||
return [];
|
||||
}
|
||||
|
||||
List<SceneStaticFunction> wallSensorFunctions(List<FunctionModel> functions) {
|
||||
List<SceneStaticFunction> wallSensorFunctions(
|
||||
{required List<FunctionModel> functions,
|
||||
required String deviceId,
|
||||
required String deviceName}) {
|
||||
return [];
|
||||
}
|
||||
|
||||
List<SceneStaticFunction> lightBulbFunctions(List<FunctionModel> functions) {
|
||||
List<SceneStaticFunction> lightBulbFunctions(
|
||||
{required List<FunctionModel> functions,
|
||||
required String deviceId,
|
||||
required String deviceName}) {
|
||||
return [];
|
||||
}
|
||||
|
||||
List<SceneStaticFunction> gatewayFunctions(List<FunctionModel> functions) {
|
||||
List<SceneStaticFunction> gatewayFunctions(
|
||||
{required List<FunctionModel> functions,
|
||||
required String deviceId,
|
||||
required String deviceName}) {
|
||||
return [];
|
||||
}
|
||||
|
||||
List<SceneStaticFunction> threeGangFunctions(List<FunctionModel> functions) {
|
||||
List<SceneStaticFunction> threeGangFunctions(
|
||||
{required List<FunctionModel> functions,
|
||||
required String deviceId,
|
||||
required String deviceName}) {
|
||||
return [
|
||||
SceneStaticFunction(
|
||||
deviceId: deviceId,
|
||||
deviceName: deviceName,
|
||||
icon: Assets.assetsAcPower,
|
||||
name: 'Light 1 Switch',
|
||||
operationName: 'Light 1 Switch',
|
||||
code: 'switch_1',
|
||||
operationalValues: [
|
||||
StaticFunctionOperationHelper(icon: Assets.assetsAcPower, value: "ON"),
|
||||
StaticFunctionOperationHelper(
|
||||
icon: Assets.assetsAcPowerOFF, value: "OFF"),
|
||||
StaticFunctionOperationHelper(
|
||||
SceneOperationalValue(icon: Assets.assetsAcPower, value: "ON"),
|
||||
SceneOperationalValue(icon: Assets.assetsAcPowerOFF, value: "OFF"),
|
||||
SceneOperationalValue(
|
||||
icon: Assets.assetsSceneRefresh, value: "Reverse Switch"),
|
||||
],
|
||||
),
|
||||
SceneStaticFunction(
|
||||
deviceId: deviceId,
|
||||
deviceName: deviceName,
|
||||
icon: Assets.assetsAcPower,
|
||||
name: 'Light 2 Switch',
|
||||
operationName: 'Light 2 Switch',
|
||||
code: 'switch_2',
|
||||
operationalValues: [
|
||||
StaticFunctionOperationHelper(icon: Assets.assetsAcPower, value: "ON"),
|
||||
StaticFunctionOperationHelper(
|
||||
icon: Assets.assetsAcPowerOFF, value: "OFF"),
|
||||
StaticFunctionOperationHelper(
|
||||
SceneOperationalValue(icon: Assets.assetsAcPower, value: "ON"),
|
||||
SceneOperationalValue(icon: Assets.assetsAcPowerOFF, value: "OFF"),
|
||||
SceneOperationalValue(
|
||||
icon: Assets.assetsSceneRefresh, value: "Reverse Switch"),
|
||||
],
|
||||
),
|
||||
SceneStaticFunction(
|
||||
deviceId: deviceId,
|
||||
deviceName: deviceName,
|
||||
icon: Assets.assetsAcPower,
|
||||
name: 'Light 3 Switch',
|
||||
operationName: 'Light 3 Switch',
|
||||
code: 'switch_3',
|
||||
operationalValues: [
|
||||
StaticFunctionOperationHelper(icon: Assets.assetsAcPower, value: "ON"),
|
||||
StaticFunctionOperationHelper(
|
||||
icon: Assets.assetsAcPowerOFF, value: "OFF"),
|
||||
StaticFunctionOperationHelper(
|
||||
SceneOperationalValue(icon: Assets.assetsAcPower, value: "ON"),
|
||||
SceneOperationalValue(icon: Assets.assetsAcPowerOFF, value: "OFF"),
|
||||
SceneOperationalValue(
|
||||
icon: Assets.assetsSceneRefresh, value: "Reverse Switch"),
|
||||
],
|
||||
),
|
||||
SceneStaticFunction(
|
||||
deviceId: deviceId,
|
||||
deviceName: deviceName,
|
||||
icon: Assets.assetsLightCountdown,
|
||||
name: 'Light 1 CountDown',
|
||||
operationName: 'Light 1 CountDown',
|
||||
code: 'countdown_1',
|
||||
operationalValues: [
|
||||
StaticFunctionOperationHelper(icon: '', value: "12610"),
|
||||
SceneOperationalValue(icon: '', value: "0"),
|
||||
],
|
||||
),
|
||||
SceneStaticFunction(
|
||||
deviceId: deviceId,
|
||||
deviceName: deviceName,
|
||||
icon: Assets.assetsLightCountdown,
|
||||
name: 'Light 2 CountDown',
|
||||
operationName: 'Light 2 CountDown',
|
||||
code: 'countdown_1',
|
||||
operationalValues: [
|
||||
StaticFunctionOperationHelper(icon: '', value: "0"),
|
||||
SceneOperationalValue(icon: '', value: "0"),
|
||||
],
|
||||
),
|
||||
SceneStaticFunction(
|
||||
deviceId: deviceId,
|
||||
deviceName: deviceName,
|
||||
icon: Assets.assetsLightCountdown,
|
||||
name: 'Light 3 CountDown',
|
||||
operationName: 'Light 3 CountDown',
|
||||
code: 'countdown_1',
|
||||
operationalValues: [
|
||||
StaticFunctionOperationHelper(icon: '', value: "0"),
|
||||
SceneOperationalValue(icon: '', value: "0"),
|
||||
],
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
/// smart ac thermostat
|
||||
List<SceneStaticFunction> acFunctions(List<FunctionModel> functions) {
|
||||
List<SceneStaticFunction> acFunctions(
|
||||
{required List<FunctionModel> functions,
|
||||
required String deviceId,
|
||||
required String deviceName}) {
|
||||
return [
|
||||
SceneStaticFunction(
|
||||
deviceId: deviceId,
|
||||
deviceName: deviceName,
|
||||
icon: Assets.assetsAcPower,
|
||||
name: 'Power',
|
||||
operationName: 'Power',
|
||||
code: 'switch',
|
||||
operationalValues: [
|
||||
StaticFunctionOperationHelper(icon: Assets.assetsAcPower, value: "ON"),
|
||||
StaticFunctionOperationHelper(
|
||||
icon: Assets.assetsAcPowerOFF, value: "OFF"),
|
||||
SceneOperationalValue(icon: Assets.assetsAcPower, value: "ON"),
|
||||
SceneOperationalValue(icon: Assets.assetsAcPowerOFF, value: "OFF"),
|
||||
],
|
||||
),
|
||||
SceneStaticFunction(
|
||||
deviceId: deviceId,
|
||||
deviceName: deviceName,
|
||||
icon: Assets.assetsFreezing,
|
||||
name: 'Mode',
|
||||
operationName: 'Mode',
|
||||
code: 'mode',
|
||||
operationalValues: [
|
||||
StaticFunctionOperationHelper(
|
||||
SceneOperationalValue(
|
||||
icon: Assets.assetsAcCooling,
|
||||
value: AcValuesEnums.Cooling.name,
|
||||
),
|
||||
StaticFunctionOperationHelper(
|
||||
SceneOperationalValue(
|
||||
icon: Assets.assetsAcHeating,
|
||||
value: AcValuesEnums.Heating.name,
|
||||
),
|
||||
StaticFunctionOperationHelper(
|
||||
SceneOperationalValue(
|
||||
icon: Assets.assetsFanSpeed,
|
||||
value: AcValuesEnums.Ventilation.name,
|
||||
),
|
||||
],
|
||||
),
|
||||
SceneStaticFunction(
|
||||
deviceId: deviceId,
|
||||
deviceName: deviceName,
|
||||
icon: Assets.assetsTempreture,
|
||||
name: 'Set Temperature',
|
||||
operationName: 'Set Temperature',
|
||||
code: 'temp_set',
|
||||
operationalValues: [
|
||||
StaticFunctionOperationHelper(
|
||||
SceneOperationalValue(
|
||||
icon: Assets.assetsCelsiusDegrees, value: "COOL TO"),
|
||||
],
|
||||
),
|
||||
SceneStaticFunction(
|
||||
deviceId: deviceId,
|
||||
deviceName: deviceName,
|
||||
icon: Assets.assetsFanSpeed,
|
||||
name: 'Fan Speed',
|
||||
operationName: 'Fan Speed',
|
||||
code: 'level',
|
||||
operationalValues: [
|
||||
StaticFunctionOperationHelper(
|
||||
SceneOperationalValue(
|
||||
icon: Assets.assetsAcFanLow,
|
||||
value: ValueACRange.LOW.name,
|
||||
),
|
||||
StaticFunctionOperationHelper(
|
||||
SceneOperationalValue(
|
||||
icon: Assets.assetsAcFanMiddle,
|
||||
value: ValueACRange.MIDDLE.name,
|
||||
),
|
||||
StaticFunctionOperationHelper(
|
||||
SceneOperationalValue(
|
||||
icon: Assets.assetsAcFanHigh,
|
||||
value: ValueACRange.HIGH.name,
|
||||
),
|
||||
StaticFunctionOperationHelper(
|
||||
SceneOperationalValue(
|
||||
icon: Assets.assetsAcFanAuto,
|
||||
value: ValueACRange.AUTO.name,
|
||||
),
|
||||
],
|
||||
),
|
||||
SceneStaticFunction(
|
||||
deviceId: deviceId,
|
||||
deviceName: deviceName,
|
||||
icon: Assets.assetsChildLock,
|
||||
name: 'Child Lock',
|
||||
operationName: 'Child Lock',
|
||||
code: 'child_lock',
|
||||
operationalValues: [
|
||||
StaticFunctionOperationHelper(
|
||||
SceneOperationalValue(
|
||||
icon: Assets.assetsSceneChildLock,
|
||||
value: 'Lock',
|
||||
),
|
||||
StaticFunctionOperationHelper(
|
||||
SceneOperationalValue(
|
||||
icon: Assets.assetsSceneChildUnlock,
|
||||
value: 'Unlock',
|
||||
),
|
||||
|
@ -1,51 +1,65 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
class SceneStaticFunction {
|
||||
final String icon;
|
||||
final String name;
|
||||
final String deviceName;
|
||||
final String code;
|
||||
final List<StaticFunctionOperationHelper> operationalValues;
|
||||
final List<SceneOperationalValue> operationalValues;
|
||||
final String deviceId;
|
||||
final String operationName;
|
||||
final String uniqueCustomId;
|
||||
|
||||
SceneStaticFunction({
|
||||
required this.icon,
|
||||
required this.name,
|
||||
required this.deviceName,
|
||||
required this.code,
|
||||
required this.operationalValues,
|
||||
});
|
||||
required this.deviceId,
|
||||
required this.operationName,
|
||||
}) : uniqueCustomId = const Uuid().v4();
|
||||
|
||||
SceneStaticFunction copyWith({
|
||||
String? icon,
|
||||
String? name,
|
||||
String? code,
|
||||
List<StaticFunctionOperationHelper>? operationalValues,
|
||||
List<SceneOperationalValue>? operationalValues,
|
||||
String? deviceId,
|
||||
String? operationName,
|
||||
}) {
|
||||
return SceneStaticFunction(
|
||||
icon: icon ?? this.icon,
|
||||
name: name ?? this.name,
|
||||
deviceName: name ?? this.deviceName,
|
||||
code: code ?? this.code,
|
||||
operationalValues: operationalValues ?? this.operationalValues,
|
||||
deviceId: deviceId ?? this.deviceId,
|
||||
operationName: operationName ?? this.operationName,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return {
|
||||
'icon': icon,
|
||||
'name': name,
|
||||
'name': deviceName,
|
||||
'code': code,
|
||||
'operationalValues': operationalValues.map((x) => x.toMap()).toList(),
|
||||
'deviceId': deviceId,
|
||||
'operationName': operationName
|
||||
};
|
||||
}
|
||||
|
||||
factory SceneStaticFunction.fromMap(Map<String, dynamic> map) {
|
||||
return SceneStaticFunction(
|
||||
icon: map['icon'] ?? '',
|
||||
name: map['name'] ?? '',
|
||||
deviceName: map['name'] ?? '',
|
||||
code: map['code'] ?? '',
|
||||
operationalValues: List<StaticFunctionOperationHelper>.from(
|
||||
map['operationalValues']
|
||||
?.map((x) => StaticFunctionOperationHelper.fromMap(x))),
|
||||
operationalValues: List<SceneOperationalValue>.from(
|
||||
map['operationalValues']?.map((x) => SceneOperationalValue.fromMap(x)),
|
||||
),
|
||||
deviceId: map['deviceId'] ?? '',
|
||||
operationName: map['operationName'] ?? '',
|
||||
);
|
||||
}
|
||||
|
||||
@ -56,7 +70,7 @@ class SceneStaticFunction {
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'SceneStaticFunction(icon: $icon, name: $name, code: $code, operationalValues: $operationalValues)';
|
||||
return 'SceneStaticFunction(icon: $icon, name: $deviceName, code: $code, operationalValues: $operationalValues, deviceId: $deviceId, operationName: $operationName)';
|
||||
}
|
||||
|
||||
@override
|
||||
@ -65,34 +79,38 @@ class SceneStaticFunction {
|
||||
|
||||
return other is SceneStaticFunction &&
|
||||
other.icon == icon &&
|
||||
other.name == name &&
|
||||
other.deviceName == deviceName &&
|
||||
other.code == code &&
|
||||
listEquals(other.operationalValues, operationalValues);
|
||||
other.operationName == operationName &&
|
||||
listEquals(other.operationalValues, operationalValues) &&
|
||||
other.deviceId == deviceId;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return icon.hashCode ^
|
||||
name.hashCode ^
|
||||
deviceName.hashCode ^
|
||||
code.hashCode ^
|
||||
deviceId.hashCode ^
|
||||
operationName.hashCode ^
|
||||
operationalValues.hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
class StaticFunctionOperationHelper {
|
||||
class SceneOperationalValue {
|
||||
final String icon;
|
||||
final String value;
|
||||
|
||||
StaticFunctionOperationHelper({
|
||||
SceneOperationalValue({
|
||||
required this.icon,
|
||||
required this.value,
|
||||
});
|
||||
|
||||
StaticFunctionOperationHelper copyWith({
|
||||
SceneOperationalValue copyWith({
|
||||
String? icon,
|
||||
String? value,
|
||||
}) {
|
||||
return StaticFunctionOperationHelper(
|
||||
return SceneOperationalValue(
|
||||
icon: icon ?? this.icon,
|
||||
value: value ?? this.value,
|
||||
);
|
||||
@ -105,8 +123,8 @@ class StaticFunctionOperationHelper {
|
||||
};
|
||||
}
|
||||
|
||||
factory StaticFunctionOperationHelper.fromMap(Map<String, dynamic> map) {
|
||||
return StaticFunctionOperationHelper(
|
||||
factory SceneOperationalValue.fromMap(Map<String, dynamic> map) {
|
||||
return SceneOperationalValue(
|
||||
icon: map['icon'] ?? '',
|
||||
value: map['value'] ?? '',
|
||||
);
|
||||
@ -114,8 +132,8 @@ class StaticFunctionOperationHelper {
|
||||
|
||||
String toJson() => json.encode(toMap());
|
||||
|
||||
factory StaticFunctionOperationHelper.fromJson(String source) =>
|
||||
StaticFunctionOperationHelper.fromMap(json.decode(source));
|
||||
factory SceneOperationalValue.fromJson(String source) =>
|
||||
SceneOperationalValue.fromMap(json.decode(source));
|
||||
|
||||
@override
|
||||
String toString() =>
|
||||
@ -125,7 +143,7 @@ class StaticFunctionOperationHelper {
|
||||
bool operator ==(Object other) {
|
||||
if (identical(this, other)) return true;
|
||||
|
||||
return other is StaticFunctionOperationHelper &&
|
||||
return other is SceneOperationalValue &&
|
||||
other.icon == icon &&
|
||||
other.value == value;
|
||||
}
|
||||
|
16
lib/features/scene/repo/scene_repo.dart
Normal file
16
lib/features/scene/repo/scene_repo.dart
Normal file
@ -0,0 +1,16 @@
|
||||
import 'package:syncrow_app/features/devices/model/device_control_model.dart';
|
||||
import 'package:syncrow_app/services/api/devices_api.dart';
|
||||
|
||||
class SceneRepo {
|
||||
Future<bool> deviceControl({
|
||||
required DeviceControlModel controlModel,
|
||||
required String deviceId,
|
||||
}) async {
|
||||
final response = await DevicesAPI.controlDevice(controlModel, deviceId);
|
||||
if (response['success'] == true) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,6 @@
|
||||
import 'package:flutter/material.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/enum/create_scene_enum.dart';
|
||||
import 'package:syncrow_app/features/scene/widgets/scene_list_tile.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||
@ -27,11 +29,14 @@ class CreateSceneView extends StatelessWidget {
|
||||
titleString: StringsManager.tapToRun,
|
||||
subtitleString: StringsManager.turnOffAllLights,
|
||||
),
|
||||
onTap: () => Navigator.pushNamed(
|
||||
context,
|
||||
Routes.sceneTasksRoute,
|
||||
arguments: CreateSceneEnum.tabToRun,
|
||||
),
|
||||
onTap: () {
|
||||
Navigator.pushNamed(
|
||||
context,
|
||||
Routes.sceneTasksRoute,
|
||||
arguments: CreateSceneEnum.tabToRun,
|
||||
);
|
||||
context.read<CreateSceneBloc>().tasksList.clear();
|
||||
},
|
||||
),
|
||||
DefaultContainer(
|
||||
width: double.infinity,
|
||||
|
@ -1,5 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.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/scene/bloc/create_scene/create_scene_bloc.dart';
|
||||
import 'package:syncrow_app/features/scene/helper/scene_helper.dart';
|
||||
import 'package:syncrow_app/features/scene/model/scene_static_function.dart';
|
||||
import 'package:syncrow_app/features/scene/widgets/alert_dialog_countdown.dart';
|
||||
@ -10,6 +13,7 @@ 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/light_divider.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
||||
import 'package:syncrow_app/navigation/routing_constants.dart';
|
||||
import 'package:syncrow_app/utils/context_extension.dart';
|
||||
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
@ -29,14 +33,22 @@ class DeviceFunctionsView extends StatelessWidget with SceneHelper {
|
||||
List<SceneStaticFunction> functions = [];
|
||||
if (device.functions.isNotEmpty) {
|
||||
functions = getFunctionsWithIcons(
|
||||
type: device.productType, functions: device.functions);
|
||||
type: device.productType,
|
||||
functions: device.functions,
|
||||
deviceId: device.uuid ?? '',
|
||||
deviceName: device.name ?? '',
|
||||
);
|
||||
}
|
||||
|
||||
return DefaultScaffold(
|
||||
title: getTitle(type: device.productType),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () {},
|
||||
onPressed: () {
|
||||
Navigator.popUntil(context, (route) {
|
||||
return route.settings.name == Routes.sceneTasksRoute;
|
||||
});
|
||||
},
|
||||
child: BodyMedium(
|
||||
text: 'Save',
|
||||
fontWeight: FontWeight.normal,
|
||||
@ -81,38 +93,60 @@ class DeviceFunctionsView extends StatelessWidget with SceneHelper {
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
SceneListTile(
|
||||
iconsSize: 32,
|
||||
minLeadingWidth: 20,
|
||||
assetPath: functions[index].icon,
|
||||
titleString: functions[index].name,
|
||||
trailingWidget: const Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
/// selected value or the default value
|
||||
// BodyMedium(text: ),
|
||||
Icon(
|
||||
Icons.arrow_forward_ios_rounded,
|
||||
color: ColorsManager.greyColor,
|
||||
size: 16,
|
||||
BlocBuilder<CreateSceneBloc, CreateSceneState>(
|
||||
builder: (context, state) {
|
||||
return SceneListTile(
|
||||
iconsSize: 32,
|
||||
minLeadingWidth: 20,
|
||||
assetPath: functions[index].icon,
|
||||
titleString: functions[index].operationName,
|
||||
trailingWidget: const Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
/// selected value or the default value
|
||||
// BodyMedium(text: ),
|
||||
Icon(
|
||||
Icons.arrow_forward_ios_rounded,
|
||||
color: ColorsManager.greyColor,
|
||||
size: 16,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
onPressed: () {
|
||||
context.customAlertDialog(
|
||||
alertBody: functions[index].code == 'temp_set'
|
||||
? AlertDialogTemperatureBody(
|
||||
index: index, functions: functions)
|
||||
: functions[index].code.contains('countdown')
|
||||
? AlertDialogCountdown(
|
||||
durationValue: functions[index]
|
||||
.operationalValues
|
||||
.first
|
||||
.value)
|
||||
: AlertDialogFunctionsOperationsBody(
|
||||
index: index, functions: functions),
|
||||
title: functions[index].name,
|
||||
onConfirm: () {},
|
||||
onPressed: () {
|
||||
context.customAlertDialog(
|
||||
alertBody: functions[index].code == 'temp_set'
|
||||
? AlertDialogTemperatureBody(
|
||||
index: index, functions: functions)
|
||||
: functions[index].code.contains('countdown')
|
||||
? AlertDialogCountdown(
|
||||
durationValue: functions[index]
|
||||
.operationalValues
|
||||
.first
|
||||
.value)
|
||||
: AlertDialogFunctionsOperationsBody(
|
||||
index: index, functions: functions),
|
||||
title: functions[index].operationName,
|
||||
onConfirm: () {
|
||||
final selectedValue = context
|
||||
.read<CreateSceneBloc>()
|
||||
.selectedValue;
|
||||
context
|
||||
.read<CreateSceneBloc>()
|
||||
.add(AddTaskEvent(
|
||||
deviceControlModel: DeviceControlModel(
|
||||
deviceId: device.uuid,
|
||||
code: functions[index].code,
|
||||
value: selectedValue,
|
||||
),
|
||||
deviceId: device.uuid ?? '',
|
||||
operation: functions[index].operationName,
|
||||
icon: device.icon ?? '',
|
||||
deviceName: device.name ?? '',
|
||||
));
|
||||
Navigator.pop(context);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
|
@ -12,15 +12,16 @@ import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/constants.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/strings_manager.dart';
|
||||
|
||||
class SceneControlDevicesView extends StatefulWidget {
|
||||
const SceneControlDevicesView({super.key});
|
||||
class SceneRoomsTabBarDevicesView extends StatefulWidget {
|
||||
const SceneRoomsTabBarDevicesView({super.key});
|
||||
|
||||
@override
|
||||
State<SceneControlDevicesView> createState() =>
|
||||
_SceneControlDevicesViewState();
|
||||
State<SceneRoomsTabBarDevicesView> createState() =>
|
||||
_SceneRoomsTabBarDevicesViewState();
|
||||
}
|
||||
|
||||
class _SceneControlDevicesViewState extends State<SceneControlDevicesView>
|
||||
class _SceneRoomsTabBarDevicesViewState
|
||||
extends State<SceneRoomsTabBarDevicesView>
|
||||
with SingleTickerProviderStateMixin {
|
||||
late final TabController _tabController;
|
||||
List<RoomModel>? rooms = [];
|
@ -1,7 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:syncrow_app/features/scene/bloc/create_scene/create_scene_bloc.dart';
|
||||
import 'package:syncrow_app/features/scene/widgets/if_then_containers/if_container.dart';
|
||||
import 'package:syncrow_app/features/scene/widgets/if_then_containers/then_container.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_button.dart';
|
||||
@ -12,8 +10,8 @@ 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/strings_manager.dart';
|
||||
|
||||
class SceneAddTasksView extends StatelessWidget {
|
||||
const SceneAddTasksView({super.key});
|
||||
class SceneTasksView extends StatelessWidget {
|
||||
const SceneTasksView({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@ -36,27 +34,24 @@ class SceneAddTasksView extends StatelessWidget {
|
||||
],
|
||||
child: Stack(
|
||||
children: [
|
||||
SingleChildScrollView(
|
||||
child: BlocProvider(
|
||||
create: (context) => CreateSceneBloc(),
|
||||
child: const Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: 24,
|
||||
),
|
||||
// IF
|
||||
IFDefaultContainer(),
|
||||
SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
// THEN
|
||||
ThenDefaultContainer(),
|
||||
SizedBox(
|
||||
height: 100,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: 24,
|
||||
),
|
||||
// IF
|
||||
IFDefaultContainer(),
|
||||
SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
// THEN
|
||||
ThenDefaultContainer(),
|
||||
SizedBox(
|
||||
height: 100,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Positioned(
|
@ -1,6 +1,7 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_app/features/scene/bloc/create_scene/create_scene_bloc.dart';
|
||||
|
||||
class AlertDialogCountdown extends StatefulWidget {
|
||||
const AlertDialogCountdown({super.key, required this.durationValue});
|
||||
@ -29,6 +30,9 @@ class _AlertDialogCountdownState extends State<AlertDialogCountdown> {
|
||||
setState(() {
|
||||
durationInSeconds = newDuration.inSeconds;
|
||||
});
|
||||
context
|
||||
.read<CreateSceneBloc>()
|
||||
.add(SelectedValueEvent(value: newDuration.inSeconds.toString()));
|
||||
},
|
||||
),
|
||||
);
|
||||
|
@ -1,4 +1,6 @@
|
||||
import 'package:flutter/material.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/model/scene_static_function.dart';
|
||||
import 'package:syncrow_app/features/scene/widgets/scene_list_tile.dart';
|
||||
|
||||
@ -27,26 +29,38 @@ class _AlertDialogFunctionsOperationsBodyState
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
...widget.functions[widget.index].operationalValues.map(
|
||||
(operation) => SceneListTile(
|
||||
iconsSize: 25,
|
||||
minLeadingWidth: 15,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
assetPath: operation.icon,
|
||||
titleString: operation.value,
|
||||
textAlign: TextAlign.start,
|
||||
trailingWidget: Radio(
|
||||
value: operation.value,
|
||||
groupValue: groupValue,
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
groupValue = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
groupValue = operation.value;
|
||||
});
|
||||
(operation) => BlocBuilder<CreateSceneBloc, CreateSceneState>(
|
||||
builder: (context, state) {
|
||||
return SceneListTile(
|
||||
iconsSize: 25,
|
||||
minLeadingWidth: 15,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
assetPath: operation.icon,
|
||||
titleString: operation.value,
|
||||
textAlign: TextAlign.start,
|
||||
trailingWidget: Radio(
|
||||
value: operation.value,
|
||||
groupValue: (state is SelectedTaskValueState)
|
||||
? state.value
|
||||
: groupValue,
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
groupValue = value;
|
||||
});
|
||||
context
|
||||
.read<CreateSceneBloc>()
|
||||
.add(SelectedValueEvent(value: value!));
|
||||
},
|
||||
),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
groupValue = operation.value;
|
||||
});
|
||||
context
|
||||
.read<CreateSceneBloc>()
|
||||
.add(SelectedValueEvent(value: groupValue!));
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
|
@ -1,5 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:syncrow_app/features/scene/bloc/create_scene/create_scene_bloc.dart';
|
||||
import 'package:syncrow_app/features/scene/model/scene_static_function.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/title_medium.dart';
|
||||
@ -24,7 +26,7 @@ class AlertDialogTemperatureBody extends StatefulWidget {
|
||||
|
||||
class _AlertDialogTemperatureBodyState
|
||||
extends State<AlertDialogTemperatureBody> {
|
||||
double temperature = 16;
|
||||
int temperature = 24;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListTile(
|
||||
@ -32,8 +34,13 @@ class _AlertDialogTemperatureBodyState
|
||||
leading: IconButton(
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
temperature--;
|
||||
if (temperature > 20) {
|
||||
temperature--;
|
||||
}
|
||||
});
|
||||
context
|
||||
.read<CreateSceneBloc>()
|
||||
.add(SelectedValueEvent(value: temperature.toString()));
|
||||
},
|
||||
icon: const Icon(
|
||||
Icons.remove,
|
||||
@ -69,8 +76,13 @@ class _AlertDialogTemperatureBodyState
|
||||
trailing: IconButton(
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
temperature++;
|
||||
if (temperature < 30) {
|
||||
temperature++;
|
||||
}
|
||||
});
|
||||
context
|
||||
.read<CreateSceneBloc>()
|
||||
.add(SelectedValueEvent(value: temperature.toString()));
|
||||
},
|
||||
icon: const Icon(
|
||||
Icons.add,
|
||||
|
@ -0,0 +1,99 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:syncrow_app/features/scene/bloc/create_scene/create_scene_bloc.dart';
|
||||
import 'package:syncrow_app/features/scene/model/scene_static_function.dart';
|
||||
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/text_widgets/body_medium.dart';
|
||||
import 'package:syncrow_app/generated/assets.dart';
|
||||
import 'package:syncrow_app/utils/context_extension.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
|
||||
class ThenAddedTasksContainer extends StatelessWidget {
|
||||
const ThenAddedTasksContainer({
|
||||
super.key,
|
||||
required this.taskList,
|
||||
});
|
||||
|
||||
final SceneStaticFunction taskList;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
String operationValue = '';
|
||||
if (taskList.code.contains('countdown')) {
|
||||
final duration = Duration(
|
||||
seconds:
|
||||
int.tryParse(taskList.operationalValues.first.value.toString()) ??
|
||||
0);
|
||||
operationValue =
|
||||
"${duration.inHours}h ${duration.inMinutes.remainder(60)}m ";
|
||||
} else {
|
||||
operationValue = taskList.operationalValues.first.value.toString();
|
||||
}
|
||||
return DefaultContainer(
|
||||
padding: EdgeInsets.zero,
|
||||
child: Dismissible(
|
||||
key: Key(taskList.uniqueCustomId.toString()),
|
||||
background: Container(
|
||||
padding: const EdgeInsets.only(right: 10),
|
||||
alignment: AlignmentDirectional.centerEnd,
|
||||
decoration: const ShapeDecoration(
|
||||
color: Color(0xFFFF0000),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(20),
|
||||
bottomRight: Radius.circular(20),
|
||||
),
|
||||
),
|
||||
),
|
||||
child: SvgPicture.asset(
|
||||
Assets.assetsDeleteIcon,
|
||||
width: 20,
|
||||
height: 22,
|
||||
),
|
||||
),
|
||||
direction: DismissDirection.endToStart,
|
||||
onDismissed: (direction) {
|
||||
String removeFunctionById = taskList.uniqueCustomId;
|
||||
|
||||
context
|
||||
.read<CreateSceneBloc>()
|
||||
.add(RemoveTaskEvent(taskId: removeFunctionById));
|
||||
|
||||
String removeFunction =
|
||||
"${taskList.operationName} with value ${taskList.operationalValues.first.value}";
|
||||
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('$removeFunction removed')),
|
||||
);
|
||||
},
|
||||
child: SceneListTile(
|
||||
padding: EdgeInsets.zero,
|
||||
assetPath: taskList.icon,
|
||||
iconsSize: 32,
|
||||
titleWidget: BodyMedium(
|
||||
text: taskList.deviceName,
|
||||
style: context.bodyMedium.copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
subtitleWidget: Row(
|
||||
children: [
|
||||
BodyMedium(
|
||||
text: "${taskList.operationName}: ",
|
||||
fontColor: ColorsManager.secondaryTextColor,
|
||||
fontWeight: FontWeight.normal,
|
||||
),
|
||||
BodyMedium(
|
||||
text: operationValue,
|
||||
fontColor: ColorsManager.secondaryTextColor,
|
||||
fontWeight: FontWeight.normal,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:syncrow_app/features/scene/bloc/create_scene/create_scene_bloc.dart';
|
||||
import 'package:syncrow_app/features/scene/widgets/if_then_containers/then_added_tasks.dart';
|
||||
import 'package:syncrow_app/features/scene/widgets/scene_list_tile.dart';
|
||||
import 'package:syncrow_app/features/scene/widgets/bottom_sheet_widget.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||
@ -48,6 +49,28 @@ class ThenDefaultContainer extends StatelessWidget {
|
||||
const LightDivider(),
|
||||
BlocBuilder<CreateSceneBloc, CreateSceneState>(
|
||||
builder: (context, state) {
|
||||
if (state is AddSceneTask) {
|
||||
final taskLists = state.tasksList;
|
||||
if (taskLists.isNotEmpty) {
|
||||
return ListView.builder(
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
itemCount: taskLists.length,
|
||||
itemBuilder: (context, index) {
|
||||
return ThenAddedTasksContainer(
|
||||
taskList: taskLists[index],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
return SceneListTile(
|
||||
titleString: '+ Add Task',
|
||||
textAlign: TextAlign.center,
|
||||
onPressed: () => context.customBottomSheet(
|
||||
child: const CustomBottomSheetWidget(),
|
||||
),
|
||||
);
|
||||
}
|
||||
return SceneListTile(
|
||||
titleString: '+ Add Task',
|
||||
textAlign: TextAlign.center,
|
||||
|
@ -1,6 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_app/features/auth/bloc/auth_cubit.dart';
|
||||
import 'package:syncrow_app/features/scene/bloc/create_scene/create_scene_bloc.dart';
|
||||
import 'package:syncrow_app/navigation/navigation_service.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/constants.dart';
|
||||
@ -19,8 +20,11 @@ class MyApp extends StatelessWidget {
|
||||
MediaQuery.sizeOf(context).height * Constants.appBarHeightPercentage;
|
||||
Constants.bottomNavBarHeight = MediaQuery.sizeOf(context).height *
|
||||
Constants.bottomNavBarHeightPercentage;
|
||||
return BlocProvider(
|
||||
create: (context) => AuthCubit(),
|
||||
return MultiBlocProvider(
|
||||
providers: [
|
||||
BlocProvider(create: (context) => AuthCubit()),
|
||||
BlocProvider(create: (context) => CreateSceneBloc())
|
||||
],
|
||||
child: MaterialApp(
|
||||
navigatorKey: NavigationService.navigatorKey,
|
||||
scaffoldMessengerKey: NavigationService.snackbarKey,
|
||||
|
@ -14,8 +14,8 @@ import 'package:syncrow_app/features/menu/view/widgets/profile/profile_view.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/view/device_functions_view.dart';
|
||||
import 'package:syncrow_app/features/scene/view/scene_add_tasks.dart';
|
||||
import 'package:syncrow_app/features/scene/view/scene_control_devices.dart';
|
||||
import 'package:syncrow_app/features/scene/view/scene_tasks_view.dart';
|
||||
import 'package:syncrow_app/features/scene/view/scene_rooms_tabbar.dart';
|
||||
import 'package:syncrow_app/features/scene/view/scene_view.dart';
|
||||
import 'package:syncrow_app/features/splash/view/splash_view.dart';
|
||||
import 'routing_constants.dart';
|
||||
@ -72,7 +72,7 @@ class Router {
|
||||
builder: (_) => const CreateUnitView(), settings: settings);
|
||||
case Routes.sceneTasksRoute:
|
||||
return MaterialPageRoute(
|
||||
builder: (_) => const SceneAddTasksView(), settings: settings);
|
||||
builder: (_) => const SceneTasksView(), settings: settings);
|
||||
case Routes.sceneControlDevicesRoute:
|
||||
return MaterialPageRoute(
|
||||
builder: (_) => MultiBlocProvider(
|
||||
@ -87,7 +87,7 @@ class Router {
|
||||
..add(const TabChanged(selectedIndex: 0, roomId: '-1')),
|
||||
),
|
||||
],
|
||||
child: const SceneControlDevicesView(),
|
||||
child: const SceneRoomsTabBarDevicesView(),
|
||||
),
|
||||
settings: settings);
|
||||
case Routes.deviceFunctionsRoute:
|
||||
|
@ -3,7 +3,7 @@ import 'dart:async';
|
||||
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_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/functions.dart';
|
||||
import 'package:syncrow_app/features/devices/model/function_model.dart';
|
||||
import 'package:syncrow_app/services/api/api_links_endpoints.dart';
|
||||
import 'package:syncrow_app/services/api/http_service.dart';
|
||||
|
||||
@ -57,12 +57,12 @@ class DevicesAPI {
|
||||
}
|
||||
|
||||
/// Get Device Functions
|
||||
static Future<FunctionsEntity> deviceFunctions(String deviceId) async {
|
||||
static Future<FunctionModel> deviceFunctions(String deviceId) async {
|
||||
final response = await _httpService.get(
|
||||
path: ApiEndpoints.deviceFunctions.replaceAll('{deviceUuid}', deviceId),
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) {
|
||||
final functions = FunctionsEntity.fromJson(json);
|
||||
final functions = FunctionModel.fromJson(json);
|
||||
return functions;
|
||||
},
|
||||
);
|
||||
|
@ -50,7 +50,7 @@ extension ContextExtension on BuildContext {
|
||||
void customAlertDialog(
|
||||
{required Widget alertBody,
|
||||
required String title,
|
||||
required Function()? onConfirm}) {
|
||||
required VoidCallback onConfirm}) {
|
||||
showDialog(
|
||||
context: this,
|
||||
builder: (BuildContext context) {
|
||||
@ -98,7 +98,7 @@ extension ContextExtension on BuildContext {
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
InkWell(
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
@ -115,7 +115,7 @@ extension ContextExtension on BuildContext {
|
||||
width: 1,
|
||||
color: ColorsManager.greyColor,
|
||||
),
|
||||
InkWell(
|
||||
GestureDetector(
|
||||
onTap: onConfirm,
|
||||
child: Center(
|
||||
child: BodyMedium(
|
||||
|
@ -907,13 +907,13 @@ packages:
|
||||
source: hosted
|
||||
version: "3.1.1"
|
||||
uuid:
|
||||
dependency: transitive
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: uuid
|
||||
sha256: cd210a09f7c18cbe5a02511718e0334de6559871052c90a90c0cca46a4aa81c8
|
||||
sha256: "814e9e88f21a176ae1359149021870e87f7cddaf633ab678a5d2b0bff7fd1ba8"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.3.3"
|
||||
version: "4.4.0"
|
||||
vector_graphics:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
49
pubspec.yaml
49
pubspec.yaml
@ -1,5 +1,6 @@
|
||||
name: syncrow_app
|
||||
description: This is the mobile application project, developed with Flutter for Syncrow IOT Project.
|
||||
description: This is the mobile application project, developed with Flutter for
|
||||
Syncrow IOT Project.
|
||||
# The following line prevents the package from being accidentally published to
|
||||
# pub.dev using `flutter pub publish`. This is preferred for private packages.
|
||||
publish_to: "none" # Remove this line if you wish to publish to pub.dev
|
||||
@ -10,44 +11,39 @@ environment:
|
||||
sdk: ">=3.0.6 <4.0.0"
|
||||
|
||||
dependencies:
|
||||
cached_network_image: ^3.3.1
|
||||
cupertino_icons: ^1.0.6
|
||||
dio: ^5.4.1
|
||||
equatable: ^2.0.5
|
||||
firebase_analytics: ^10.8.7
|
||||
firebase_core: ^2.25.5
|
||||
firebase_crashlytics: ^3.4.16
|
||||
fl_chart: ^0.66.2
|
||||
flutter:
|
||||
sdk: flutter
|
||||
|
||||
#UI Packages
|
||||
cupertino_icons: ^1.0.6
|
||||
shared_preferences: ^2.2.2
|
||||
flutter_animated_dialog: ^2.0.1
|
||||
flutter_svg: ^2.0.10+1
|
||||
fl_chart: ^0.66.2
|
||||
sleek_circular_slider: ^2.0.1
|
||||
|
||||
# Utility Packages
|
||||
flutter_secure_storage: ^9.0.0
|
||||
cached_network_image: ^3.3.1
|
||||
flutter_dotenv: ^5.1.0
|
||||
# noinspection YAMLSchemaValidation
|
||||
intl: ^0.19.0
|
||||
get_it: ^7.6.7
|
||||
url_launcher: ^6.2.5
|
||||
dio: ^5.4.1
|
||||
flutter_localization: ^0.2.0
|
||||
flutter_bloc: ^8.1.4
|
||||
firebase_core: ^2.25.5
|
||||
firebase_analytics: ^10.8.7
|
||||
firebase_crashlytics: ^3.4.16
|
||||
smooth_page_indicator: ^1.1.0
|
||||
flutter_dotenv: ^5.1.0
|
||||
flutter_localization: ^0.2.0
|
||||
flutter_secure_storage: ^9.0.0
|
||||
flutter_svg: ^2.0.10+1
|
||||
get_it: ^7.6.7
|
||||
html: ^0.15.4
|
||||
equatable: ^2.0.5
|
||||
intl: ^0.19.0
|
||||
onesignal_flutter: ^5.2.0
|
||||
permission_handler: ^11.3.1
|
||||
pin_code_fields: ^8.0.1
|
||||
share_plus: ^9.0.0
|
||||
|
||||
shared_preferences: ^2.2.2
|
||||
sleek_circular_slider: ^2.0.1
|
||||
smooth_page_indicator: ^1.1.0
|
||||
url_launcher: ^6.2.5
|
||||
uuid: ^4.4.0
|
||||
|
||||
dev_dependencies:
|
||||
flutter_lints: ^3.0.1
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
flutter_lints: ^3.0.1
|
||||
|
||||
flutter_assets:
|
||||
assets_path: assets/
|
||||
@ -78,7 +74,6 @@ flutter:
|
||||
- family: Aftika
|
||||
fonts:
|
||||
- asset: assets/fonts/AftikaRegular.ttf
|
||||
#
|
||||
# - family: Trajan Pro
|
||||
# fonts:
|
||||
# - asset: fonts/TrajanPro.ttf
|
||||
|
Reference in New Issue
Block a user