Files
syncrow-web/lib/pages/routiens/helper/one_gang_switch_helper.dart
ashrafzarkanisala 7dccfb5a76 finished ac devices
2024-11-23 21:51:20 +03:00

496 lines
19 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart';
import 'package:syncrow_web/pages/routiens/bloc/functions_bloc/functions_bloc_bloc.dart';
import 'package:syncrow_web/pages/routiens/bloc/routine_bloc/routine_bloc.dart';
import 'package:syncrow_web/pages/routiens/models/ac/ac_function.dart';
import 'package:syncrow_web/pages/routiens/models/ac/ac_operational_value.dart';
import 'package:syncrow_web/pages/routiens/models/device_functions.dart';
import 'package:syncrow_web/pages/routiens/models/gang_switches/base_switch_function.dart';
import 'package:syncrow_web/pages/routiens/models/gang_switches/one_gang_switch/one_gang_switch.dart';
import 'package:syncrow_web/pages/routiens/widgets/dialog_footer.dart';
import 'package:syncrow_web/pages/routiens/widgets/dialog_header.dart';
import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/extension/build_context_x.dart';
class OneGangSwitchHelper {
static Future<Map<String, dynamic>?> showSwitchFunctionsDialog(
BuildContext context,
List<DeviceFunction> functions,
AllDevicesModel? device,
List<DeviceFunctionData>? deviceSelectedFunctions,
) async {
List<ACFunction> acFunctions = functions.whereType<ACFunction>().toList();
return showDialog<Map<String, dynamic>?>(
context: context,
builder: (BuildContext context) {
return BlocProvider(
create: (_) => FunctionBloc()
..add(InitializeFunctions(deviceSelectedFunctions ?? [])),
child: AlertDialog(
contentPadding: EdgeInsets.zero,
content: BlocBuilder<FunctionBloc, FunctionBlocState>(
builder: (context, state) {
final selectedFunction = state.selectedFunction;
final selectedOperationName = state.selectedOperationName;
final selectedFunctionData = state.addedFunctions
.firstWhere((f) => f.functionCode == selectedFunction,
orElse: () => DeviceFunctionData(
entityId: '',
functionCode: selectedFunction ?? '',
operationName: '',
value: null,
));
return Container(
width: selectedFunction != null ? 600 : 360,
height: 450,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20),
),
padding: const EdgeInsets.only(top: 20),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const DialogHeader('1 Gang Light Switch Condition'),
Expanded(
child: Row(
children: [
// Left side: Function list
Expanded(
child: ListView.separated(
itemCount: acFunctions.length,
separatorBuilder: (_, __) => const Divider(
color: ColorsManager.dividerColor,
),
itemBuilder: (context, index) {
final function = acFunctions[index];
return ListTile(
leading: SvgPicture.asset(
function.icon,
width: 24,
height: 24,
),
title: Text(
function.operationName,
style: context.textTheme.bodyMedium,
),
trailing: const Icon(
Icons.arrow_forward_ios,
size: 16,
color: ColorsManager.textGray,
),
onTap: () {
context
.read<FunctionBloc>()
.add(SelectFunction(
functionCode: function.code,
operationName:
function.operationName,
));
},
);
},
),
),
// Right side: Value selector
if (selectedFunction != null)
Expanded(
child: _buildValueSelector(
context: context,
selectedFunction: selectedFunction,
selectedFunctionData: selectedFunctionData,
acFunctions: acFunctions,
device: device,
operationName: selectedOperationName ?? '',
),
),
// ValueListenableBuilder<String?>(
// valueListenable: selectedFunctionNotifier,
// builder: (context, selectedFunction, _) {
// final selectedFn =
// switchFunctions.firstWhere(
// (f) => f.code == selectedFunction,
// );
// return Expanded(
// child: selectedFn
// is OneGangCountdownFunction
// ? _buildCountDownSelector(
// context,
// selectedValueNotifier,
// selectedConditionNotifier,
// selectedConditionsNotifier,
// )
// : _buildOperationalValuesList(
// context,
// selectedFn as BaseSwitchFunction,
// selectedValueNotifier,
// ),
// );
// },
// ),
],
),
),
Container(
height: 1,
width: double.infinity,
color: ColorsManager.greyColor,
),
DialogFooter(
onCancel: () {
Navigator.pop(context);
},
onConfirm: state.addedFunctions.isNotEmpty
? () {
/// add the functions to the routine bloc
for (var function in state.addedFunctions) {
context.read<RoutineBloc>().add(
AddFunctionToRoutine(
function,
),
);
}
// Return the device data to be added to the container
Navigator.pop(context, {
'deviceId': functions.first.deviceId,
});
}
: null,
isConfirmEnabled: selectedFunction != null,
),
],
),
);
},
),
));
},
);
}
static Widget _buildValueSelector({
required BuildContext context,
required String selectedFunction,
required DeviceFunctionData? selectedFunctionData,
required List<ACFunction> acFunctions,
AllDevicesModel? device,
required String operationName,
}) {
if (selectedFunction == 'countdown_1') {
final initialValue = selectedFunctionData?.value ?? 200;
return _buildTemperatureSelector(
context: context,
initialValue: initialValue,
selectCode: selectedFunction,
currentCondition: selectedFunctionData?.condition,
device: device,
operationName: operationName,
selectedFunctionData: selectedFunctionData,
);
}
final selectedFn =
acFunctions.firstWhere((f) => f.code == selectedFunction);
final values = selectedFn.getOperationalValues();
return _buildOperationalValuesList(
context: context,
values: values,
selectedValue: selectedFunctionData?.value,
device: device,
operationName: operationName,
selectCode: selectedFunction,
selectedFunctionData: selectedFunctionData,
);
}
static Widget _buildTemperatureSelector({
required BuildContext context,
required dynamic initialValue,
required String? currentCondition,
required String selectCode,
AllDevicesModel? device,
required String operationName,
DeviceFunctionData? selectedFunctionData,
}) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
_buildConditionToggle(
context,
currentCondition,
selectCode,
device,
operationName,
selectedFunctionData,
),
const SizedBox(height: 20),
_buildTemperatureDisplay(context, initialValue, device, operationName,
selectedFunctionData, selectCode),
const SizedBox(height: 20),
_buildTemperatureSlider(context, initialValue, device, operationName,
selectedFunctionData, selectCode),
],
);
}
/// Build condition toggle for AC functions dialog
static Widget _buildConditionToggle(
BuildContext context,
String? currentCondition,
String selectCode,
AllDevicesModel? device,
String operationName,
DeviceFunctionData? selectedFunctionData,
// Function(String) onConditionChanged,
) {
final conditions = ["<", "==", ">"];
return ToggleButtons(
onPressed: (int index) {
context.read<FunctionBloc>().add(
AddFunction(
functionData: DeviceFunctionData(
entityId: device?.uuid ?? '',
functionCode: selectCode,
operationName: operationName,
condition: conditions[index],
value: selectedFunctionData?.value,
valueDescription: selectedFunctionData?.valueDescription,
),
),
);
},
borderRadius: const BorderRadius.all(Radius.circular(8)),
selectedBorderColor: ColorsManager.primaryColorWithOpacity,
selectedColor: Colors.white,
fillColor: ColorsManager.primaryColorWithOpacity,
color: ColorsManager.primaryColorWithOpacity,
constraints: const BoxConstraints(
minHeight: 40.0,
minWidth: 40.0,
),
isSelected:
conditions.map((c) => c == (currentCondition ?? "==")).toList(),
children: conditions.map((c) => Text(c)).toList(),
);
}
/// Build temperature display for AC functions dialog
static Widget _buildTemperatureDisplay(
BuildContext context,
dynamic initialValue,
AllDevicesModel? device,
String operationName,
DeviceFunctionData? selectedFunctionData,
String selectCode) {
return Container(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
decoration: BoxDecoration(
color: ColorsManager.primaryColorWithOpacity.withOpacity(0.1),
borderRadius: BorderRadius.circular(10),
),
child: Text(
'${initialValue ?? 0} sec',
style: context.textTheme.headlineMedium!.copyWith(
color: ColorsManager.primaryColorWithOpacity,
),
),
);
}
static Widget _buildTemperatureSlider(
BuildContext context,
dynamic initialValue,
AllDevicesModel? device,
String operationName,
DeviceFunctionData? selectedFunctionData,
String selectCode,
) {
return Slider(
value: (initialValue ?? 0).toDouble(),
min: 0,
max: 300,
divisions: 300,
onChanged: (value) {
context.read<FunctionBloc>().add(
AddFunction(
functionData: DeviceFunctionData(
entityId: device?.uuid ?? '',
functionCode: selectCode,
operationName: operationName,
value: value,
condition: selectedFunctionData?.condition,
valueDescription: selectedFunctionData?.valueDescription,
),
),
);
},
);
}
static Widget _buildOperationalValuesList({
required BuildContext context,
required List<ACOperationalValue> values,
required dynamic selectedValue,
AllDevicesModel? device,
required String operationName,
required String selectCode,
DeviceFunctionData? selectedFunctionData,
// required Function(dynamic) onValueChanged,
}) {
return ListView.builder(
shrinkWrap: false,
physics: const AlwaysScrollableScrollPhysics(),
itemCount: values.length,
itemBuilder: (context, index) {
final value = values[index];
final isSelected = selectedValue == value.value;
return ListTile(
leading: SvgPicture.asset(
value.icon,
width: 24,
height: 24,
placeholderBuilder: (BuildContext context) => Container(
width: 24,
height: 24,
color: Colors.transparent,
),
),
title: Text(
value.description,
style: context.textTheme.bodyMedium,
),
trailing: Icon(
isSelected
? Icons.radio_button_checked
: Icons.radio_button_unchecked,
size: 24,
color: isSelected
? ColorsManager.primaryColorWithOpacity
: ColorsManager.textGray,
),
onTap: () {
if (!isSelected) {
context.read<FunctionBloc>().add(
AddFunction(
functionData: DeviceFunctionData(
entityId: device?.uuid ?? '',
functionCode: selectCode,
operationName: operationName,
value: value.value,
condition: selectedFunctionData?.condition,
valueDescription:
selectedFunctionData?.valueDescription,
),
),
);
}
},
);
},
);
}
// static Widget _buildCountDownSelector(
// BuildContext context,
// ValueNotifier<dynamic> valueNotifier,
// ValueNotifier<String?> conditionNotifier,
// ValueNotifier<List<bool>> conditionsNotifier,
// ) {
// return ValueListenableBuilder<dynamic>(
// valueListenable: valueNotifier,
// builder: (context, value, _) {
// return Column(
// mainAxisAlignment: MainAxisAlignment.center,
// children: [
// ValueListenableBuilder<List<bool>>(
// valueListenable: conditionsNotifier,
// builder: (context, selectedConditions, _) {
// return ToggleButtons(
// onPressed: (int index) {
// final newConditions = List<bool>.filled(3, false);
// newConditions[index] = true;
// conditionsNotifier.value = newConditions;
// conditionNotifier.value = index == 0
// ? "<"
// : index == 1
// ? "=="
// : ">";
// },
// borderRadius: const BorderRadius.all(Radius.circular(8)),
// selectedBorderColor: ColorsManager.primaryColorWithOpacity,
// selectedColor: Colors.white,
// fillColor: ColorsManager.primaryColorWithOpacity,
// color: ColorsManager.primaryColorWithOpacity,
// constraints: const BoxConstraints(
// minHeight: 40.0,
// minWidth: 40.0,
// ),
// isSelected: selectedConditions,
// children: const [Text("<"), Text("="), Text(">")],
// );
// },
// ),
// const SizedBox(height: 20),
// Text(
// '${value ?? 0} sec',
// style: Theme.of(context).textTheme.headlineMedium,
// ),
// const SizedBox(height: 20),
// Slider(
// value: (value ?? 0).toDouble(),
// min: 0,
// max: 300,
// divisions: 300,
// onChanged: (newValue) {
// valueNotifier.value = newValue.toInt();
// },
// ),
// ],
// );
// },
// );
// }
// static Widget _buildOperationalValuesList(
// BuildContext context,
// BaseSwitchFunction function,
// ValueNotifier<dynamic> valueNotifier,
// ) {
// final values = function.getOperationalValues();
// return ValueListenableBuilder<dynamic>(
// valueListenable: valueNotifier,
// builder: (context, selectedValue, _) {
// return ListView.builder(
// itemCount: values.length,
// itemBuilder: (context, index) {
// final value = values[index];
// return ListTile(
// leading: SvgPicture.asset(
// value.icon,
// width: 24,
// height: 24,
// ),
// title: Text(
// value.description,
// style: context.textTheme.bodyMedium,
// ),
// trailing: Radio<dynamic>(
// value: value.value,
// groupValue: selectedValue,
// onChanged: (newValue) {
// valueNotifier.value = newValue;
// },
// ),
// );
// },
// );
// },
// );
// }
}