mirror of
https://github.com/SyncrowIOT/syncrow-app.git
synced 2025-07-15 09:45:22 +00:00
331 lines
13 KiB
Dart
331 lines
13 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter/widgets.dart';
|
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
import 'package:flutter_svg/svg.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_logic_helper.dart';
|
|
import 'package:syncrow_app/features/scene/helper/scene_operations_data_helper.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/default_scaffold.dart';
|
|
import 'package:syncrow_app/features/shared_widgets/light_divider.dart';
|
|
import 'package:syncrow_app/generated/assets.dart';
|
|
import 'package:syncrow_app/navigation/navigate_to_route.dart';
|
|
import 'package:syncrow_app/navigation/routing_constants.dart';
|
|
import 'package:syncrow_app/utils/context_extension.dart';
|
|
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
|
|
|
class DeviceFunctionsView extends StatelessWidget
|
|
with SceneOperationsDataHelper, SceneLogicHelper {
|
|
DeviceFunctionsView({super.key});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final device = (ModalRoute.of(context)?.settings.arguments as Map)['device']
|
|
as DeviceModel;
|
|
|
|
final isAutomation = (ModalRoute.of(context)?.settings.arguments
|
|
as Map)['isAutomationDeviceStatus'] as bool;
|
|
|
|
List<SceneStaticFunction> functions = [];
|
|
if (device.functions.isNotEmpty) {
|
|
functions = getFunctionsWithIcons(
|
|
type: device.productType,
|
|
functions: device.functions,
|
|
deviceId: device.uuid ?? '',
|
|
deviceName: device.name ?? '',
|
|
isAutomation: isAutomation,
|
|
);
|
|
}
|
|
|
|
return DefaultScaffold(
|
|
title: getTitle(type: device.productType),
|
|
actions: [
|
|
TextButton(
|
|
onPressed: () {
|
|
context
|
|
.read<CreateSceneBloc>()
|
|
.add(AddTaskEvent(isAutomation: isAutomation));
|
|
navigateToRoute(context, Routes.sceneTasksRoute);
|
|
},
|
|
child: SvgPicture.asset(Assets.saveRoutinesIcon),
|
|
),
|
|
],
|
|
leading: TextButton(
|
|
onPressed: () {
|
|
_cancelOperation(context, device, isAutomation);
|
|
},
|
|
child: SvgPicture.asset(Assets.cancelIcon),
|
|
),
|
|
leadingWidth: 80,
|
|
padding: EdgeInsets.zero,
|
|
child: ListView.builder(
|
|
shrinkWrap: true,
|
|
itemCount: functions.length,
|
|
padding: const EdgeInsets.only(top: 24.0),
|
|
itemBuilder: (context, index) {
|
|
if (device.productType!.name.toString() == 'ThreeGang' ||
|
|
device.productType!.name.toString() == 'TwoGang') {
|
|
final bool isFirstInPair = index % 2 == 0;
|
|
final bool isLastInPair =
|
|
index % 2 == 1 || index == functions.length - 1;
|
|
final bool isLastItem = index == functions.length - 1;
|
|
return Column(mainAxisSize: MainAxisSize.min, children: [
|
|
if (isFirstInPair && index != 0) const SizedBox(height: 16),
|
|
DefaultContainer(
|
|
padding: EdgeInsets.only(
|
|
top: isFirstInPair ? 8 : 0,
|
|
bottom: isLastInPair ? 8 : 0,
|
|
),
|
|
margin: EdgeInsets.zero,
|
|
borderRadius: BorderRadius.only(
|
|
topLeft: Radius.circular(isFirstInPair ? 20 : 0),
|
|
topRight: Radius.circular(isFirstInPair ? 20 : 0),
|
|
bottomLeft: Radius.circular(isLastInPair ? 20 : 0),
|
|
bottomRight: Radius.circular(isLastInPair ? 20 : 0),
|
|
),
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
BlocBuilder<CreateSceneBloc, CreateSceneState>(
|
|
builder: (context, state) {
|
|
return SceneListTile(
|
|
iconsSize: 22,
|
|
minLeadingWidth: 20,
|
|
assetPath: functions[index].icon,
|
|
titleString: functions[index].operationName,
|
|
trailingWidget: const Icon(
|
|
Icons.arrow_forward_ios_rounded,
|
|
color: ColorsManager.greyColor,
|
|
size: 16,
|
|
),
|
|
onPressed: () {
|
|
if (isAutomation) {
|
|
_showAutomationDialog(
|
|
context, functions[index], device);
|
|
} else {
|
|
_showTabToRunDialog(
|
|
context, functions[index], device);
|
|
}
|
|
},
|
|
);
|
|
},
|
|
),
|
|
if (isFirstInPair && !isLastItem)
|
|
SizedBox(
|
|
width: context.width * 0.8,
|
|
child: const LightDivider(),
|
|
),
|
|
],
|
|
),
|
|
)
|
|
]);
|
|
} else {
|
|
return DefaultContainer(
|
|
padding: index == 0
|
|
? const EdgeInsets.only(top: 8)
|
|
: index == functions.length - 1
|
|
? const EdgeInsets.only(bottom: 8)
|
|
: EdgeInsets.zero,
|
|
margin: EdgeInsets.zero,
|
|
borderRadius: index == 0 && index == functions.length - 1
|
|
? const BorderRadius.only(
|
|
topLeft: Radius.circular(20),
|
|
topRight: Radius.circular(20),
|
|
bottomLeft: Radius.circular(20),
|
|
bottomRight: Radius.circular(20),
|
|
)
|
|
: index == 0
|
|
? const BorderRadius.only(
|
|
topLeft: Radius.circular(20),
|
|
topRight: Radius.circular(20),
|
|
)
|
|
: index == functions.length - 1
|
|
? const BorderRadius.only(
|
|
bottomLeft: Radius.circular(20),
|
|
bottomRight: Radius.circular(20),
|
|
)
|
|
: BorderRadius.zero,
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
BlocBuilder<CreateSceneBloc, CreateSceneState>(
|
|
builder: (context, state) {
|
|
return SceneListTile(
|
|
iconsSize: 22,
|
|
minLeadingWidth: 20,
|
|
assetPath: functions[index].icon,
|
|
titleString: functions[index].operationName,
|
|
trailingWidget: const Row(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Icon(
|
|
Icons.arrow_forward_ios_rounded,
|
|
color: ColorsManager.greyColor,
|
|
size: 16,
|
|
),
|
|
],
|
|
),
|
|
onPressed: () {
|
|
if (isAutomation) {
|
|
_showAutomationDialog(
|
|
context, functions[index], device);
|
|
} else {
|
|
_showTabToRunDialog(
|
|
context, functions[index], device);
|
|
}
|
|
},
|
|
);
|
|
}),
|
|
index != functions.length - 1
|
|
? SizedBox(
|
|
width: context.width * 0.8,
|
|
child: const LightDivider())
|
|
: const SizedBox(),
|
|
],
|
|
));
|
|
}
|
|
},
|
|
),
|
|
);
|
|
}
|
|
|
|
void _cancelOperation(
|
|
BuildContext context, DeviceModel device, bool isAutomation) {
|
|
final createSceneBloc = context.read<CreateSceneBloc>();
|
|
final automationSelectedValue = createSceneBloc.automationSelectedValues;
|
|
if (automationSelectedValue.isNotEmpty) {
|
|
for (var element in device.functions) {
|
|
if (automationSelectedValue.containsKey(element.code)) {
|
|
createSceneBloc.add(
|
|
RemoveTempTaskByIdEvent(code: element.code!, isAutomation: true));
|
|
createSceneBloc.add(RemoveFromSelectedValueById(
|
|
code: element.code!, isAutomation: true));
|
|
}
|
|
}
|
|
}
|
|
|
|
final selectedValue = createSceneBloc.selectedValues;
|
|
if (selectedValue.isNotEmpty) {
|
|
for (var element in device.functions) {
|
|
if (selectedValue.containsKey(element.code)) {
|
|
createSceneBloc.add(RemoveTempTaskByIdEvent(code: element.code!));
|
|
createSceneBloc.add(RemoveFromSelectedValueById(code: element.code!));
|
|
}
|
|
}
|
|
}
|
|
|
|
Navigator.pop(context);
|
|
|
|
createSceneBloc.add(const ClearTempTaskListEvent(isAutomation: false));
|
|
createSceneBloc.add(const ClearTempTaskListEvent(isAutomation: true));
|
|
}
|
|
|
|
void _showTabToRunDialog(
|
|
BuildContext context,
|
|
SceneStaticFunction function,
|
|
DeviceModel device,
|
|
) {
|
|
final functionValues =
|
|
context.read<CreateSceneBloc>().selectedValues[function.code];
|
|
|
|
context.customAlertDialog(
|
|
alertBody: getTheCorrectDialogBody(
|
|
function,
|
|
functionValues,
|
|
isAutomation: false,
|
|
),
|
|
title: function.operationName,
|
|
onConfirm: () {
|
|
final selectedValue =
|
|
context.read<CreateSceneBloc>().selectedValues[function.code];
|
|
if (selectedValue == null) {
|
|
return;
|
|
}
|
|
context.read<CreateSceneBloc>().add(TempHoldSceneTasksEvent(
|
|
deviceControlModel: DeviceControlModel(
|
|
deviceId: device.uuid,
|
|
code: function.code,
|
|
value: selectedValue,
|
|
),
|
|
deviceId: device.uuid ?? '',
|
|
operation: function.operationName,
|
|
icon: device.icon ?? '',
|
|
deviceName: device.name ?? '',
|
|
uniqueId: function.uniqueCustomId!,
|
|
operationType: function.operationDialogType,
|
|
));
|
|
Navigator.pop(context);
|
|
},
|
|
onDismiss: () {
|
|
final tempTaskList = context.read<CreateSceneBloc>().tempTasksList;
|
|
for (var element in tempTaskList) {
|
|
if (element.code == function.code) {
|
|
context
|
|
.read<CreateSceneBloc>()
|
|
.add(RemoveTempTaskByIdEvent(code: function.code));
|
|
context
|
|
.read<CreateSceneBloc>()
|
|
.add(RemoveFromSelectedValueById(code: function.code));
|
|
}
|
|
}
|
|
Navigator.pop(context);
|
|
},
|
|
);
|
|
}
|
|
|
|
void _showAutomationDialog(
|
|
BuildContext context, SceneStaticFunction function, DeviceModel device) {
|
|
final automationFunctionValues =
|
|
context.read<CreateSceneBloc>().automationSelectedValues[function.code];
|
|
|
|
context.customAlertDialog(
|
|
alertBody: getTheCorrectDialogBody(
|
|
function,
|
|
automationFunctionValues,
|
|
isAutomation: true,
|
|
),
|
|
title: function.operationName,
|
|
onConfirm: () {
|
|
final automationFunctionValues = context
|
|
.read<CreateSceneBloc>()
|
|
.automationSelectedValues[function.code];
|
|
if (automationFunctionValues == null) {
|
|
return;
|
|
}
|
|
context.read<CreateSceneBloc>().add(TempHoldSceneTasksEvent(
|
|
deviceControlModel: DeviceControlModel(
|
|
deviceId: device.uuid,
|
|
code: function.code,
|
|
value: automationFunctionValues,
|
|
),
|
|
deviceId: device.uuid ?? '',
|
|
operation: function.operationName,
|
|
icon: device.icon ?? '',
|
|
deviceName: device.name ?? '',
|
|
uniqueId: function.uniqueCustomId!,
|
|
operationType: function.operationDialogType,
|
|
isAutomation: true,
|
|
));
|
|
Navigator.pop(context);
|
|
},
|
|
onDismiss: () {
|
|
final automationTempTaskList =
|
|
context.read<CreateSceneBloc>().automationTempTasksList;
|
|
for (var element in automationTempTaskList) {
|
|
if (element.code == function.code) {
|
|
context.read<CreateSceneBloc>().add(RemoveTempTaskByIdEvent(
|
|
code: function.code, isAutomation: true));
|
|
context.read<CreateSceneBloc>().add(RemoveFromSelectedValueById(
|
|
code: function.code, isAutomation: true));
|
|
}
|
|
}
|
|
Navigator.pop(context);
|
|
},
|
|
);
|
|
}
|
|
}
|