finished adding tasks and removing them , added error handling

This commit is contained in:
ashrafzarkanisala
2024-06-26 20:32:34 +03:00
parent ae47e48832
commit 9fe25b9bd3
22 changed files with 605 additions and 231 deletions

View File

@ -1,7 +1,7 @@
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.dart';
import 'package:syncrow_app/features/devices/model/device_category_model.dart'; import 'package:syncrow_app/features/devices/model/device_category_model.dart';
import 'package:syncrow_app/features/devices/model/device_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 { class DeviceManagerState extends Equatable {
final bool loading; final bool loading;
@ -11,7 +11,7 @@ class DeviceManagerState extends Equatable {
final bool categoryChanged; final bool categoryChanged;
final bool deviceSelected; final bool deviceSelected;
final bool functionsLoading; final bool functionsLoading;
final FunctionsEntity? deviceFunctions; final FunctionModel? deviceFunctions;
const DeviceManagerState({ const DeviceManagerState({
required this.loading, required this.loading,
@ -45,7 +45,7 @@ class DeviceManagerState extends Equatable {
bool? categoryChanged, bool? categoryChanged,
bool? deviceSelected, bool? deviceSelected,
bool? functionsLoading, bool? functionsLoading,
FunctionsEntity? deviceFunctions, FunctionModel? deviceFunctions,
}) { }) {
return DeviceManagerState( return DeviceManagerState(
loading: loading ?? this.loading, loading: loading ?? this.loading,

View File

@ -2,6 +2,8 @@ import 'dart:async';
import 'package:bloc/bloc.dart'; import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.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_event.dart';
part 'create_scene_state.dart'; part 'create_scene_state.dart';
@ -9,5 +11,51 @@ part 'create_scene_state.dart';
class CreateSceneBloc extends Bloc<CreateSceneEvent, CreateSceneState> { class CreateSceneBloc extends Bloc<CreateSceneEvent, CreateSceneState> {
CreateSceneBloc() : super(CreateSceneInitial()) { CreateSceneBloc() : super(CreateSceneInitial()) {
on<CreateSceneEvent>((event, emit) => null as FutureOr<void>); 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;
}
}
} }
} }

View File

@ -7,4 +7,40 @@ sealed class CreateSceneEvent extends Equatable {
List<Object> get props => []; 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];
}

View File

@ -2,7 +2,7 @@ part of 'create_scene_bloc.dart';
sealed class CreateSceneState extends Equatable { sealed class CreateSceneState extends Equatable {
const CreateSceneState(); const CreateSceneState();
@override @override
List<Object> get props => []; List<Object> get props => [];
} }
@ -11,4 +11,18 @@ final class CreateSceneInitial extends CreateSceneState {}
class CreateSceneLoading 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];
}

View File

@ -5,27 +5,40 @@ import 'package:syncrow_app/generated/assets.dart';
import 'package:syncrow_app/utils/resource_manager/constants.dart'; import 'package:syncrow_app/utils/resource_manager/constants.dart';
mixin SceneHelper { mixin SceneHelper {
List<SceneStaticFunction> getFunctionsWithIcons( List<SceneStaticFunction> getFunctionsWithIcons({
{DeviceType? type, required List<FunctionModel> functions}) { DeviceType? type,
required List<FunctionModel> functions,
required String deviceId,
required String deviceName,
}) {
switch (type) { switch (type) {
case DeviceType.LightBulb: case DeviceType.LightBulb:
return lightBulbFunctions(functions); return lightBulbFunctions(
functions: functions, deviceId: deviceId, deviceName: deviceName);
case DeviceType.CeilingSensor: case DeviceType.CeilingSensor:
return ceilingSensorFunctions(functions); return ceilingSensorFunctions(
functions: functions, deviceId: deviceId, deviceName: deviceName);
case DeviceType.WallSensor: case DeviceType.WallSensor:
return wallSensorFunctions(functions); return wallSensorFunctions(
functions: functions, deviceId: deviceId, deviceName: deviceName);
case DeviceType.AC: case DeviceType.AC:
return acFunctions(functions); return acFunctions(
functions: functions, deviceId: deviceId, deviceName: deviceName);
case DeviceType.DoorLock: case DeviceType.DoorLock:
return doorLockFunctions(functions); return doorLockFunctions(
functions: functions, deviceId: deviceId, deviceName: deviceName);
case DeviceType.Curtain: case DeviceType.Curtain:
return curtainFunctions(functions); return curtainFunctions(
functions: functions, deviceId: deviceId, deviceName: deviceName);
case DeviceType.ThreeGang: case DeviceType.ThreeGang:
return threeGangFunctions(functions); return threeGangFunctions(
functions: functions, deviceId: deviceId, deviceName: deviceName);
case DeviceType.Gateway: case DeviceType.Gateway:
return gatewayFunctions(functions); return gatewayFunctions(
functions: functions, deviceId: deviceId, deviceName: deviceName);
default: default:
return lightBulbFunctions(functions); return lightBulbFunctions(
functions: functions, deviceId: deviceId, deviceName: deviceName);
} }
} }
@ -54,32 +67,36 @@ mixin SceneHelper {
/// presence sensor /// presence sensor
List<SceneStaticFunction> ceilingSensorFunctions( List<SceneStaticFunction> ceilingSensorFunctions(
List<FunctionModel> functions) { {required List<FunctionModel> functions,
required String deviceId,
required String deviceName}) {
return [ return [
SceneStaticFunction( SceneStaticFunction(
deviceId: deviceId,
deviceName: deviceName,
icon: Assets.assetsSensitivityFunction, icon: Assets.assetsSensitivityFunction,
name: 'Sensitivity', operationName: 'Sensitivity',
code: 'sensitivity', code: 'sensitivity',
operationalValues: [ operationalValues: [
StaticFunctionOperationHelper( SceneOperationalValue(
icon: Assets.assetsSensitivityOperationIcon, value: "1"), icon: Assets.assetsSensitivityOperationIcon, value: "1"),
StaticFunctionOperationHelper( SceneOperationalValue(
icon: Assets.assetsSensitivityOperationIcon, value: "2"), icon: Assets.assetsSensitivityOperationIcon, value: "2"),
StaticFunctionOperationHelper( SceneOperationalValue(
icon: Assets.assetsSensitivityOperationIcon, value: "3"), icon: Assets.assetsSensitivityOperationIcon, value: "3"),
StaticFunctionOperationHelper( SceneOperationalValue(
icon: Assets.assetsSensitivityOperationIcon, value: "4"), icon: Assets.assetsSensitivityOperationIcon, value: "4"),
StaticFunctionOperationHelper( SceneOperationalValue(
icon: Assets.assetsSensitivityOperationIcon, value: "5"), icon: Assets.assetsSensitivityOperationIcon, value: "5"),
StaticFunctionOperationHelper( SceneOperationalValue(
icon: Assets.assetsSensitivityOperationIcon, value: "6"), icon: Assets.assetsSensitivityOperationIcon, value: "6"),
StaticFunctionOperationHelper( SceneOperationalValue(
icon: Assets.assetsSensitivityOperationIcon, value: "7"), icon: Assets.assetsSensitivityOperationIcon, value: "7"),
StaticFunctionOperationHelper( SceneOperationalValue(
icon: Assets.assetsSensitivityOperationIcon, value: "8"), icon: Assets.assetsSensitivityOperationIcon, value: "8"),
StaticFunctionOperationHelper( SceneOperationalValue(
icon: Assets.assetsSensitivityOperationIcon, value: "9"), icon: Assets.assetsSensitivityOperationIcon, value: "9"),
StaticFunctionOperationHelper( SceneOperationalValue(
icon: Assets.assetsSensitivityOperationIcon, value: "10"), 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 []; return [];
} }
List<SceneStaticFunction> doorLockFunctions(List<FunctionModel> functions) { List<SceneStaticFunction> doorLockFunctions(
{required List<FunctionModel> functions,
required String deviceId,
required String deviceName}) {
return []; return [];
} }
List<SceneStaticFunction> wallSensorFunctions(List<FunctionModel> functions) { List<SceneStaticFunction> wallSensorFunctions(
{required List<FunctionModel> functions,
required String deviceId,
required String deviceName}) {
return []; return [];
} }
List<SceneStaticFunction> lightBulbFunctions(List<FunctionModel> functions) { List<SceneStaticFunction> lightBulbFunctions(
{required List<FunctionModel> functions,
required String deviceId,
required String deviceName}) {
return []; return [];
} }
List<SceneStaticFunction> gatewayFunctions(List<FunctionModel> functions) { List<SceneStaticFunction> gatewayFunctions(
{required List<FunctionModel> functions,
required String deviceId,
required String deviceName}) {
return []; return [];
} }
List<SceneStaticFunction> threeGangFunctions(List<FunctionModel> functions) { List<SceneStaticFunction> threeGangFunctions(
{required List<FunctionModel> functions,
required String deviceId,
required String deviceName}) {
return [ return [
SceneStaticFunction( SceneStaticFunction(
deviceId: deviceId,
deviceName: deviceName,
icon: Assets.assetsAcPower, icon: Assets.assetsAcPower,
name: 'Light 1 Switch', operationName: 'Light 1 Switch',
code: 'switch_1', code: 'switch_1',
operationalValues: [ operationalValues: [
StaticFunctionOperationHelper(icon: Assets.assetsAcPower, value: "ON"), SceneOperationalValue(icon: Assets.assetsAcPower, value: "ON"),
StaticFunctionOperationHelper( SceneOperationalValue(icon: Assets.assetsAcPowerOFF, value: "OFF"),
icon: Assets.assetsAcPowerOFF, value: "OFF"), SceneOperationalValue(
StaticFunctionOperationHelper(
icon: Assets.assetsSceneRefresh, value: "Reverse Switch"), icon: Assets.assetsSceneRefresh, value: "Reverse Switch"),
], ],
), ),
SceneStaticFunction( SceneStaticFunction(
deviceId: deviceId,
deviceName: deviceName,
icon: Assets.assetsAcPower, icon: Assets.assetsAcPower,
name: 'Light 2 Switch', operationName: 'Light 2 Switch',
code: 'switch_2', code: 'switch_2',
operationalValues: [ operationalValues: [
StaticFunctionOperationHelper(icon: Assets.assetsAcPower, value: "ON"), SceneOperationalValue(icon: Assets.assetsAcPower, value: "ON"),
StaticFunctionOperationHelper( SceneOperationalValue(icon: Assets.assetsAcPowerOFF, value: "OFF"),
icon: Assets.assetsAcPowerOFF, value: "OFF"), SceneOperationalValue(
StaticFunctionOperationHelper(
icon: Assets.assetsSceneRefresh, value: "Reverse Switch"), icon: Assets.assetsSceneRefresh, value: "Reverse Switch"),
], ],
), ),
SceneStaticFunction( SceneStaticFunction(
deviceId: deviceId,
deviceName: deviceName,
icon: Assets.assetsAcPower, icon: Assets.assetsAcPower,
name: 'Light 3 Switch', operationName: 'Light 3 Switch',
code: 'switch_3', code: 'switch_3',
operationalValues: [ operationalValues: [
StaticFunctionOperationHelper(icon: Assets.assetsAcPower, value: "ON"), SceneOperationalValue(icon: Assets.assetsAcPower, value: "ON"),
StaticFunctionOperationHelper( SceneOperationalValue(icon: Assets.assetsAcPowerOFF, value: "OFF"),
icon: Assets.assetsAcPowerOFF, value: "OFF"), SceneOperationalValue(
StaticFunctionOperationHelper(
icon: Assets.assetsSceneRefresh, value: "Reverse Switch"), icon: Assets.assetsSceneRefresh, value: "Reverse Switch"),
], ],
), ),
SceneStaticFunction( SceneStaticFunction(
deviceId: deviceId,
deviceName: deviceName,
icon: Assets.assetsLightCountdown, icon: Assets.assetsLightCountdown,
name: 'Light 1 CountDown', operationName: 'Light 1 CountDown',
code: 'countdown_1', code: 'countdown_1',
operationalValues: [ operationalValues: [
StaticFunctionOperationHelper(icon: '', value: "12610"), SceneOperationalValue(icon: '', value: "0"),
], ],
), ),
SceneStaticFunction( SceneStaticFunction(
deviceId: deviceId,
deviceName: deviceName,
icon: Assets.assetsLightCountdown, icon: Assets.assetsLightCountdown,
name: 'Light 2 CountDown', operationName: 'Light 2 CountDown',
code: 'countdown_1', code: 'countdown_1',
operationalValues: [ operationalValues: [
StaticFunctionOperationHelper(icon: '', value: "0"), SceneOperationalValue(icon: '', value: "0"),
], ],
), ),
SceneStaticFunction( SceneStaticFunction(
deviceId: deviceId,
deviceName: deviceName,
icon: Assets.assetsLightCountdown, icon: Assets.assetsLightCountdown,
name: 'Light 3 CountDown', operationName: 'Light 3 CountDown',
code: 'countdown_1', code: 'countdown_1',
operationalValues: [ operationalValues: [
StaticFunctionOperationHelper(icon: '', value: "0"), SceneOperationalValue(icon: '', value: "0"),
], ],
), ),
]; ];
} }
/// smart ac thermostat /// smart ac thermostat
List<SceneStaticFunction> acFunctions(List<FunctionModel> functions) { List<SceneStaticFunction> acFunctions(
{required List<FunctionModel> functions,
required String deviceId,
required String deviceName}) {
return [ return [
SceneStaticFunction( SceneStaticFunction(
deviceId: deviceId,
deviceName: deviceName,
icon: Assets.assetsAcPower, icon: Assets.assetsAcPower,
name: 'Power', operationName: 'Power',
code: 'switch', code: 'switch',
operationalValues: [ operationalValues: [
StaticFunctionOperationHelper(icon: Assets.assetsAcPower, value: "ON"), SceneOperationalValue(icon: Assets.assetsAcPower, value: "ON"),
StaticFunctionOperationHelper( SceneOperationalValue(icon: Assets.assetsAcPowerOFF, value: "OFF"),
icon: Assets.assetsAcPowerOFF, value: "OFF"),
], ],
), ),
SceneStaticFunction( SceneStaticFunction(
deviceId: deviceId,
deviceName: deviceName,
icon: Assets.assetsFreezing, icon: Assets.assetsFreezing,
name: 'Mode', operationName: 'Mode',
code: 'mode', code: 'mode',
operationalValues: [ operationalValues: [
StaticFunctionOperationHelper( SceneOperationalValue(
icon: Assets.assetsAcCooling, icon: Assets.assetsAcCooling,
value: AcValuesEnums.Cooling.name, value: AcValuesEnums.Cooling.name,
), ),
StaticFunctionOperationHelper( SceneOperationalValue(
icon: Assets.assetsAcHeating, icon: Assets.assetsAcHeating,
value: AcValuesEnums.Heating.name, value: AcValuesEnums.Heating.name,
), ),
StaticFunctionOperationHelper( SceneOperationalValue(
icon: Assets.assetsFanSpeed, icon: Assets.assetsFanSpeed,
value: AcValuesEnums.Ventilation.name, value: AcValuesEnums.Ventilation.name,
), ),
], ],
), ),
SceneStaticFunction( SceneStaticFunction(
deviceId: deviceId,
deviceName: deviceName,
icon: Assets.assetsTempreture, icon: Assets.assetsTempreture,
name: 'Set Temperature', operationName: 'Set Temperature',
code: 'temp_set', code: 'temp_set',
operationalValues: [ operationalValues: [
StaticFunctionOperationHelper( SceneOperationalValue(
icon: Assets.assetsCelsiusDegrees, value: "COOL TO"), icon: Assets.assetsCelsiusDegrees, value: "COOL TO"),
], ],
), ),
SceneStaticFunction( SceneStaticFunction(
deviceId: deviceId,
deviceName: deviceName,
icon: Assets.assetsFanSpeed, icon: Assets.assetsFanSpeed,
name: 'Fan Speed', operationName: 'Fan Speed',
code: 'level', code: 'level',
operationalValues: [ operationalValues: [
StaticFunctionOperationHelper( SceneOperationalValue(
icon: Assets.assetsAcFanLow, icon: Assets.assetsAcFanLow,
value: ValueACRange.LOW.name, value: ValueACRange.LOW.name,
), ),
StaticFunctionOperationHelper( SceneOperationalValue(
icon: Assets.assetsAcFanMiddle, icon: Assets.assetsAcFanMiddle,
value: ValueACRange.MIDDLE.name, value: ValueACRange.MIDDLE.name,
), ),
StaticFunctionOperationHelper( SceneOperationalValue(
icon: Assets.assetsAcFanHigh, icon: Assets.assetsAcFanHigh,
value: ValueACRange.HIGH.name, value: ValueACRange.HIGH.name,
), ),
StaticFunctionOperationHelper( SceneOperationalValue(
icon: Assets.assetsAcFanAuto, icon: Assets.assetsAcFanAuto,
value: ValueACRange.AUTO.name, value: ValueACRange.AUTO.name,
), ),
], ],
), ),
SceneStaticFunction( SceneStaticFunction(
deviceId: deviceId,
deviceName: deviceName,
icon: Assets.assetsChildLock, icon: Assets.assetsChildLock,
name: 'Child Lock', operationName: 'Child Lock',
code: 'child_lock', code: 'child_lock',
operationalValues: [ operationalValues: [
StaticFunctionOperationHelper( SceneOperationalValue(
icon: Assets.assetsSceneChildLock, icon: Assets.assetsSceneChildLock,
value: 'Lock', value: 'Lock',
), ),
StaticFunctionOperationHelper( SceneOperationalValue(
icon: Assets.assetsSceneChildUnlock, icon: Assets.assetsSceneChildUnlock,
value: 'Unlock', value: 'Unlock',
), ),

View File

@ -1,51 +1,65 @@
import 'dart:convert'; import 'dart:convert';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:uuid/uuid.dart';
class SceneStaticFunction { class SceneStaticFunction {
final String icon; final String icon;
final String name; final String deviceName;
final String code; final String code;
final List<StaticFunctionOperationHelper> operationalValues; final List<SceneOperationalValue> operationalValues;
final String deviceId;
final String operationName;
final String uniqueCustomId;
SceneStaticFunction({ SceneStaticFunction({
required this.icon, required this.icon,
required this.name, required this.deviceName,
required this.code, required this.code,
required this.operationalValues, required this.operationalValues,
}); required this.deviceId,
required this.operationName,
}) : uniqueCustomId = const Uuid().v4();
SceneStaticFunction copyWith({ SceneStaticFunction copyWith({
String? icon, String? icon,
String? name, String? name,
String? code, String? code,
List<StaticFunctionOperationHelper>? operationalValues, List<SceneOperationalValue>? operationalValues,
String? deviceId,
String? operationName,
}) { }) {
return SceneStaticFunction( return SceneStaticFunction(
icon: icon ?? this.icon, icon: icon ?? this.icon,
name: name ?? this.name, deviceName: name ?? this.deviceName,
code: code ?? this.code, code: code ?? this.code,
operationalValues: operationalValues ?? this.operationalValues, operationalValues: operationalValues ?? this.operationalValues,
deviceId: deviceId ?? this.deviceId,
operationName: operationName ?? this.operationName,
); );
} }
Map<String, dynamic> toMap() { Map<String, dynamic> toMap() {
return { return {
'icon': icon, 'icon': icon,
'name': name, 'name': deviceName,
'code': code, 'code': code,
'operationalValues': operationalValues.map((x) => x.toMap()).toList(), 'operationalValues': operationalValues.map((x) => x.toMap()).toList(),
'deviceId': deviceId,
'operationName': operationName
}; };
} }
factory SceneStaticFunction.fromMap(Map<String, dynamic> map) { factory SceneStaticFunction.fromMap(Map<String, dynamic> map) {
return SceneStaticFunction( return SceneStaticFunction(
icon: map['icon'] ?? '', icon: map['icon'] ?? '',
name: map['name'] ?? '', deviceName: map['name'] ?? '',
code: map['code'] ?? '', code: map['code'] ?? '',
operationalValues: List<StaticFunctionOperationHelper>.from( operationalValues: List<SceneOperationalValue>.from(
map['operationalValues'] map['operationalValues']?.map((x) => SceneOperationalValue.fromMap(x)),
?.map((x) => StaticFunctionOperationHelper.fromMap(x))), ),
deviceId: map['deviceId'] ?? '',
operationName: map['operationName'] ?? '',
); );
} }
@ -56,7 +70,7 @@ class SceneStaticFunction {
@override @override
String toString() { 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 @override
@ -65,34 +79,38 @@ class SceneStaticFunction {
return other is SceneStaticFunction && return other is SceneStaticFunction &&
other.icon == icon && other.icon == icon &&
other.name == name && other.deviceName == deviceName &&
other.code == code && other.code == code &&
listEquals(other.operationalValues, operationalValues); other.operationName == operationName &&
listEquals(other.operationalValues, operationalValues) &&
other.deviceId == deviceId;
} }
@override @override
int get hashCode { int get hashCode {
return icon.hashCode ^ return icon.hashCode ^
name.hashCode ^ deviceName.hashCode ^
code.hashCode ^ code.hashCode ^
deviceId.hashCode ^
operationName.hashCode ^
operationalValues.hashCode; operationalValues.hashCode;
} }
} }
class StaticFunctionOperationHelper { class SceneOperationalValue {
final String icon; final String icon;
final String value; final String value;
StaticFunctionOperationHelper({ SceneOperationalValue({
required this.icon, required this.icon,
required this.value, required this.value,
}); });
StaticFunctionOperationHelper copyWith({ SceneOperationalValue copyWith({
String? icon, String? icon,
String? value, String? value,
}) { }) {
return StaticFunctionOperationHelper( return SceneOperationalValue(
icon: icon ?? this.icon, icon: icon ?? this.icon,
value: value ?? this.value, value: value ?? this.value,
); );
@ -105,8 +123,8 @@ class StaticFunctionOperationHelper {
}; };
} }
factory StaticFunctionOperationHelper.fromMap(Map<String, dynamic> map) { factory SceneOperationalValue.fromMap(Map<String, dynamic> map) {
return StaticFunctionOperationHelper( return SceneOperationalValue(
icon: map['icon'] ?? '', icon: map['icon'] ?? '',
value: map['value'] ?? '', value: map['value'] ?? '',
); );
@ -114,8 +132,8 @@ class StaticFunctionOperationHelper {
String toJson() => json.encode(toMap()); String toJson() => json.encode(toMap());
factory StaticFunctionOperationHelper.fromJson(String source) => factory SceneOperationalValue.fromJson(String source) =>
StaticFunctionOperationHelper.fromMap(json.decode(source)); SceneOperationalValue.fromMap(json.decode(source));
@override @override
String toString() => String toString() =>
@ -125,7 +143,7 @@ class StaticFunctionOperationHelper {
bool operator ==(Object other) { bool operator ==(Object other) {
if (identical(this, other)) return true; if (identical(this, other)) return true;
return other is StaticFunctionOperationHelper && return other is SceneOperationalValue &&
other.icon == icon && other.icon == icon &&
other.value == value; other.value == value;
} }

View 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;
}
}
}

View File

@ -1,4 +1,6 @@
import 'package:flutter/material.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';
import 'package:syncrow_app/features/scene/enum/create_scene_enum.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/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';
@ -27,11 +29,14 @@ class CreateSceneView extends StatelessWidget {
titleString: StringsManager.tapToRun, titleString: StringsManager.tapToRun,
subtitleString: StringsManager.turnOffAllLights, subtitleString: StringsManager.turnOffAllLights,
), ),
onTap: () => Navigator.pushNamed( onTap: () {
context, Navigator.pushNamed(
Routes.sceneTasksRoute, context,
arguments: CreateSceneEnum.tabToRun, Routes.sceneTasksRoute,
), arguments: CreateSceneEnum.tabToRun,
);
context.read<CreateSceneBloc>().tasksList.clear();
},
), ),
DefaultContainer( DefaultContainer(
width: double.infinity, width: double.infinity,

View File

@ -1,5 +1,8 @@
import 'package:flutter/material.dart'; 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/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/helper/scene_helper.dart';
import 'package:syncrow_app/features/scene/model/scene_static_function.dart'; import 'package:syncrow_app/features/scene/model/scene_static_function.dart';
import 'package:syncrow_app/features/scene/widgets/alert_dialog_countdown.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/default_scaffold.dart';
import 'package:syncrow_app/features/shared_widgets/light_divider.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/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/context_extension.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
@ -29,14 +33,22 @@ class DeviceFunctionsView extends StatelessWidget with SceneHelper {
List<SceneStaticFunction> functions = []; List<SceneStaticFunction> functions = [];
if (device.functions.isNotEmpty) { if (device.functions.isNotEmpty) {
functions = getFunctionsWithIcons( functions = getFunctionsWithIcons(
type: device.productType, functions: device.functions); type: device.productType,
functions: device.functions,
deviceId: device.uuid ?? '',
deviceName: device.name ?? '',
);
} }
return DefaultScaffold( return DefaultScaffold(
title: getTitle(type: device.productType), title: getTitle(type: device.productType),
actions: [ actions: [
TextButton( TextButton(
onPressed: () {}, onPressed: () {
Navigator.popUntil(context, (route) {
return route.settings.name == Routes.sceneTasksRoute;
});
},
child: BodyMedium( child: BodyMedium(
text: 'Save', text: 'Save',
fontWeight: FontWeight.normal, fontWeight: FontWeight.normal,
@ -81,38 +93,60 @@ class DeviceFunctionsView extends StatelessWidget with SceneHelper {
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
SceneListTile( BlocBuilder<CreateSceneBloc, CreateSceneState>(
iconsSize: 32, builder: (context, state) {
minLeadingWidth: 20, return SceneListTile(
assetPath: functions[index].icon, iconsSize: 32,
titleString: functions[index].name, minLeadingWidth: 20,
trailingWidget: const Row( assetPath: functions[index].icon,
mainAxisSize: MainAxisSize.min, titleString: functions[index].operationName,
children: [ trailingWidget: const Row(
/// selected value or the default value mainAxisSize: MainAxisSize.min,
// BodyMedium(text: ), children: [
Icon( /// selected value or the default value
Icons.arrow_forward_ios_rounded, // BodyMedium(text: ),
color: ColorsManager.greyColor, Icon(
size: 16, Icons.arrow_forward_ios_rounded,
color: ColorsManager.greyColor,
size: 16,
),
],
), ),
], onPressed: () {
), context.customAlertDialog(
onPressed: () { alertBody: functions[index].code == 'temp_set'
context.customAlertDialog( ? AlertDialogTemperatureBody(
alertBody: functions[index].code == 'temp_set' index: index, functions: functions)
? AlertDialogTemperatureBody( : functions[index].code.contains('countdown')
index: index, functions: functions) ? AlertDialogCountdown(
: functions[index].code.contains('countdown') durationValue: functions[index]
? AlertDialogCountdown( .operationalValues
durationValue: functions[index] .first
.operationalValues .value)
.first : AlertDialogFunctionsOperationsBody(
.value) index: index, functions: functions),
: AlertDialogFunctionsOperationsBody( title: functions[index].operationName,
index: index, functions: functions), onConfirm: () {
title: functions[index].name, final selectedValue = context
onConfirm: () {}, .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);
},
);
},
); );
}, },
), ),

View File

@ -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/constants.dart';
import 'package:syncrow_app/utils/resource_manager/strings_manager.dart'; import 'package:syncrow_app/utils/resource_manager/strings_manager.dart';
class SceneControlDevicesView extends StatefulWidget { class SceneRoomsTabBarDevicesView extends StatefulWidget {
const SceneControlDevicesView({super.key}); const SceneRoomsTabBarDevicesView({super.key});
@override @override
State<SceneControlDevicesView> createState() => State<SceneRoomsTabBarDevicesView> createState() =>
_SceneControlDevicesViewState(); _SceneRoomsTabBarDevicesViewState();
} }
class _SceneControlDevicesViewState extends State<SceneControlDevicesView> class _SceneRoomsTabBarDevicesViewState
extends State<SceneRoomsTabBarDevicesView>
with SingleTickerProviderStateMixin { with SingleTickerProviderStateMixin {
late final TabController _tabController; late final TabController _tabController;
List<RoomModel>? rooms = []; List<RoomModel>? rooms = [];

View File

@ -1,7 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.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/if_container.dart';
import 'package:syncrow_app/features/scene/widgets/if_then_containers/then_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'; 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/color_manager.dart';
import 'package:syncrow_app/utils/resource_manager/strings_manager.dart'; import 'package:syncrow_app/utils/resource_manager/strings_manager.dart';
class SceneAddTasksView extends StatelessWidget { class SceneTasksView extends StatelessWidget {
const SceneAddTasksView({super.key}); const SceneTasksView({super.key});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -36,27 +34,24 @@ class SceneAddTasksView extends StatelessWidget {
], ],
child: Stack( child: Stack(
children: [ children: [
SingleChildScrollView( const SingleChildScrollView(
child: BlocProvider( child: Column(
create: (context) => CreateSceneBloc(), mainAxisSize: MainAxisSize.min,
child: const Column( children: [
mainAxisSize: MainAxisSize.min, SizedBox(
children: [ height: 24,
SizedBox( ),
height: 24, // IF
), IFDefaultContainer(),
// IF SizedBox(
IFDefaultContainer(), height: 8,
SizedBox( ),
height: 8, // THEN
), ThenDefaultContainer(),
// THEN SizedBox(
ThenDefaultContainer(), height: 100,
SizedBox( ),
height: 100, ],
),
],
),
), ),
), ),
Positioned( Positioned(

View File

@ -1,6 +1,7 @@
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.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 { class AlertDialogCountdown extends StatefulWidget {
const AlertDialogCountdown({super.key, required this.durationValue}); const AlertDialogCountdown({super.key, required this.durationValue});
@ -29,6 +30,9 @@ class _AlertDialogCountdownState extends State<AlertDialogCountdown> {
setState(() { setState(() {
durationInSeconds = newDuration.inSeconds; durationInSeconds = newDuration.inSeconds;
}); });
context
.read<CreateSceneBloc>()
.add(SelectedValueEvent(value: newDuration.inSeconds.toString()));
}, },
), ),
); );

View File

@ -1,4 +1,6 @@
import 'package:flutter/material.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';
import 'package:syncrow_app/features/scene/model/scene_static_function.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/scene/widgets/scene_list_tile.dart';
@ -27,26 +29,38 @@ class _AlertDialogFunctionsOperationsBodyState
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
...widget.functions[widget.index].operationalValues.map( ...widget.functions[widget.index].operationalValues.map(
(operation) => SceneListTile( (operation) => BlocBuilder<CreateSceneBloc, CreateSceneState>(
iconsSize: 25, builder: (context, state) {
minLeadingWidth: 15, return SceneListTile(
padding: const EdgeInsets.symmetric(horizontal: 16), iconsSize: 25,
assetPath: operation.icon, minLeadingWidth: 15,
titleString: operation.value, padding: const EdgeInsets.symmetric(horizontal: 16),
textAlign: TextAlign.start, assetPath: operation.icon,
trailingWidget: Radio( titleString: operation.value,
value: operation.value, textAlign: TextAlign.start,
groupValue: groupValue, trailingWidget: Radio(
onChanged: (value) { value: operation.value,
setState(() { groupValue: (state is SelectedTaskValueState)
groupValue = value; ? state.value
}); : groupValue,
}, onChanged: (value) {
), setState(() {
onPressed: () { groupValue = value;
setState(() { });
groupValue = operation.value; context
}); .read<CreateSceneBloc>()
.add(SelectedValueEvent(value: value!));
},
),
onPressed: () {
setState(() {
groupValue = operation.value;
});
context
.read<CreateSceneBloc>()
.add(SelectedValueEvent(value: groupValue!));
},
);
}, },
), ),
), ),

View File

@ -1,5 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.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/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/body_large.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';
@ -24,7 +26,7 @@ class AlertDialogTemperatureBody extends StatefulWidget {
class _AlertDialogTemperatureBodyState class _AlertDialogTemperatureBodyState
extends State<AlertDialogTemperatureBody> { extends State<AlertDialogTemperatureBody> {
double temperature = 16; int temperature = 24;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ListTile( return ListTile(
@ -32,8 +34,13 @@ class _AlertDialogTemperatureBodyState
leading: IconButton( leading: IconButton(
onPressed: () { onPressed: () {
setState(() { setState(() {
temperature--; if (temperature > 20) {
temperature--;
}
}); });
context
.read<CreateSceneBloc>()
.add(SelectedValueEvent(value: temperature.toString()));
}, },
icon: const Icon( icon: const Icon(
Icons.remove, Icons.remove,
@ -69,8 +76,13 @@ class _AlertDialogTemperatureBodyState
trailing: IconButton( trailing: IconButton(
onPressed: () { onPressed: () {
setState(() { setState(() {
temperature++; if (temperature < 30) {
temperature++;
}
}); });
context
.read<CreateSceneBloc>()
.add(SelectedValueEvent(value: temperature.toString()));
}, },
icon: const Icon( icon: const Icon(
Icons.add, Icons.add,

View File

@ -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,
),
],
),
),
),
);
}
}

View File

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.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/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/scene_list_tile.dart';
import 'package:syncrow_app/features/scene/widgets/bottom_sheet_widget.dart'; import 'package:syncrow_app/features/scene/widgets/bottom_sheet_widget.dart';
import 'package:syncrow_app/features/shared_widgets/default_container.dart'; import 'package:syncrow_app/features/shared_widgets/default_container.dart';
@ -48,6 +49,28 @@ class ThenDefaultContainer extends StatelessWidget {
const LightDivider(), const LightDivider(),
BlocBuilder<CreateSceneBloc, CreateSceneState>( BlocBuilder<CreateSceneBloc, CreateSceneState>(
builder: (context, state) { 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( return SceneListTile(
titleString: '+ Add Task', titleString: '+ Add Task',
textAlign: TextAlign.center, textAlign: TextAlign.center,

View File

@ -1,6 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/auth/bloc/auth_cubit.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/navigation/navigation_service.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/constants.dart'; import 'package:syncrow_app/utils/resource_manager/constants.dart';
@ -19,8 +20,11 @@ class MyApp extends StatelessWidget {
MediaQuery.sizeOf(context).height * Constants.appBarHeightPercentage; MediaQuery.sizeOf(context).height * Constants.appBarHeightPercentage;
Constants.bottomNavBarHeight = MediaQuery.sizeOf(context).height * Constants.bottomNavBarHeight = MediaQuery.sizeOf(context).height *
Constants.bottomNavBarHeightPercentage; Constants.bottomNavBarHeightPercentage;
return BlocProvider( return MultiBlocProvider(
create: (context) => AuthCubit(), providers: [
BlocProvider(create: (context) => AuthCubit()),
BlocProvider(create: (context) => CreateSceneBloc())
],
child: MaterialApp( child: MaterialApp(
navigatorKey: NavigationService.navigatorKey, navigatorKey: NavigationService.navigatorKey,
scaffoldMessengerKey: NavigationService.snackbarKey, scaffoldMessengerKey: NavigationService.snackbarKey,

View File

@ -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_bloc.dart';
import 'package:syncrow_app/features/scene/bloc/tab_change/tab_change_event.dart'; import 'package:syncrow_app/features/scene/bloc/tab_change/tab_change_event.dart';
import 'package:syncrow_app/features/scene/view/device_functions_view.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_tasks_view.dart';
import 'package:syncrow_app/features/scene/view/scene_control_devices.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/scene/view/scene_view.dart';
import 'package:syncrow_app/features/splash/view/splash_view.dart'; import 'package:syncrow_app/features/splash/view/splash_view.dart';
import 'routing_constants.dart'; import 'routing_constants.dart';
@ -72,7 +72,7 @@ class Router {
builder: (_) => const CreateUnitView(), settings: settings); builder: (_) => const CreateUnitView(), settings: settings);
case Routes.sceneTasksRoute: case Routes.sceneTasksRoute:
return MaterialPageRoute( return MaterialPageRoute(
builder: (_) => const SceneAddTasksView(), settings: settings); builder: (_) => const SceneTasksView(), settings: settings);
case Routes.sceneControlDevicesRoute: case Routes.sceneControlDevicesRoute:
return MaterialPageRoute( return MaterialPageRoute(
builder: (_) => MultiBlocProvider( builder: (_) => MultiBlocProvider(
@ -87,7 +87,7 @@ class Router {
..add(const TabChanged(selectedIndex: 0, roomId: '-1')), ..add(const TabChanged(selectedIndex: 0, roomId: '-1')),
), ),
], ],
child: const SceneControlDevicesView(), child: const SceneRoomsTabBarDevicesView(),
), ),
settings: settings); settings: settings);
case Routes.deviceFunctionsRoute: case Routes.deviceFunctionsRoute:

View File

@ -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_category_model.dart';
import 'package:syncrow_app/features/devices/model/device_control_model.dart'; import 'package:syncrow_app/features/devices/model/device_control_model.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart'; import 'package:syncrow_app/features/devices/model/device_model.dart';
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/api_links_endpoints.dart';
import 'package:syncrow_app/services/api/http_service.dart'; import 'package:syncrow_app/services/api/http_service.dart';
@ -57,12 +57,12 @@ class DevicesAPI {
} }
/// Get Device Functions /// Get Device Functions
static Future<FunctionsEntity> deviceFunctions(String deviceId) async { static Future<FunctionModel> deviceFunctions(String deviceId) async {
final response = await _httpService.get( final response = await _httpService.get(
path: ApiEndpoints.deviceFunctions.replaceAll('{deviceUuid}', deviceId), path: ApiEndpoints.deviceFunctions.replaceAll('{deviceUuid}', deviceId),
showServerMessage: false, showServerMessage: false,
expectedResponseModel: (json) { expectedResponseModel: (json) {
final functions = FunctionsEntity.fromJson(json); final functions = FunctionModel.fromJson(json);
return functions; return functions;
}, },
); );

View File

@ -50,7 +50,7 @@ extension ContextExtension on BuildContext {
void customAlertDialog( void customAlertDialog(
{required Widget alertBody, {required Widget alertBody,
required String title, required String title,
required Function()? onConfirm}) { required VoidCallback onConfirm}) {
showDialog( showDialog(
context: this, context: this,
builder: (BuildContext context) { builder: (BuildContext context) {
@ -98,7 +98,7 @@ extension ContextExtension on BuildContext {
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly, mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [ children: [
InkWell( GestureDetector(
onTap: () { onTap: () {
Navigator.pop(context); Navigator.pop(context);
}, },
@ -115,7 +115,7 @@ extension ContextExtension on BuildContext {
width: 1, width: 1,
color: ColorsManager.greyColor, color: ColorsManager.greyColor,
), ),
InkWell( GestureDetector(
onTap: onConfirm, onTap: onConfirm,
child: Center( child: Center(
child: BodyMedium( child: BodyMedium(

View File

@ -907,13 +907,13 @@ packages:
source: hosted source: hosted
version: "3.1.1" version: "3.1.1"
uuid: uuid:
dependency: transitive dependency: "direct main"
description: description:
name: uuid name: uuid
sha256: cd210a09f7c18cbe5a02511718e0334de6559871052c90a90c0cca46a4aa81c8 sha256: "814e9e88f21a176ae1359149021870e87f7cddaf633ab678a5d2b0bff7fd1ba8"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.3.3" version: "4.4.0"
vector_graphics: vector_graphics:
dependency: transitive dependency: transitive
description: description:

View File

@ -1,5 +1,6 @@
name: syncrow_app 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 # The following line prevents the package from being accidentally published to
# pub.dev using `flutter pub publish`. This is preferred for private packages. # 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 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" sdk: ">=3.0.6 <4.0.0"
dependencies: 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: flutter:
sdk: flutter sdk: flutter
#UI Packages
cupertino_icons: ^1.0.6
shared_preferences: ^2.2.2
flutter_animated_dialog: ^2.0.1 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 flutter_bloc: ^8.1.4
firebase_core: ^2.25.5 flutter_dotenv: ^5.1.0
firebase_analytics: ^10.8.7 flutter_localization: ^0.2.0
firebase_crashlytics: ^3.4.16 flutter_secure_storage: ^9.0.0
smooth_page_indicator: ^1.1.0 flutter_svg: ^2.0.10+1
get_it: ^7.6.7
html: ^0.15.4 html: ^0.15.4
equatable: ^2.0.5 intl: ^0.19.0
onesignal_flutter: ^5.2.0 onesignal_flutter: ^5.2.0
permission_handler: ^11.3.1 permission_handler: ^11.3.1
pin_code_fields: ^8.0.1 pin_code_fields: ^8.0.1
share_plus: ^9.0.0 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: dev_dependencies:
flutter_lints: ^3.0.1
flutter_test: flutter_test:
sdk: flutter sdk: flutter
flutter_lints: ^3.0.1
flutter_assets: flutter_assets:
assets_path: assets/ assets_path: assets/
@ -78,7 +74,6 @@ flutter:
- family: Aftika - family: Aftika
fonts: fonts:
- asset: assets/fonts/AftikaRegular.ttf - asset: assets/fonts/AftikaRegular.ttf
#
# - family: Trajan Pro # - family: Trajan Pro
# fonts: # fonts:
# - asset: fonts/TrajanPro.ttf # - asset: fonts/TrajanPro.ttf