Files
syncrow-web/lib/pages/routiens/helper/ac_helper.dart
2024-11-22 16:55:30 +03:00

220 lines
8.9 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/routiens/bloc/routine_bloc.dart';
import 'package:syncrow_web/pages/routiens/models/ac/ac_function.dart';
import 'package:syncrow_web/pages/routiens/models/device_functions.dart';
import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/extension/build_context_x.dart';
class ACHelper {
static Future<void> showACFunctionsDialog(
BuildContext context,
List<DeviceFunction<dynamic>> functions,
) async {
List<ACFunction> acFunctions = functions.whereType<ACFunction>().toList();
// Track multiple selections using a map
Map<String, dynamic> selectedValues = {};
List<DeviceFunctionData> selectedFunctions = [];
await showDialog(
context: context,
builder: (BuildContext context) {
return Dialog(
child: Container(
width: 600,
height: 450,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20),
),
padding: const EdgeInsets.only(top: 20),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
'AC Functions',
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
color: ColorsManager.primaryColorWithOpacity,
fontWeight: FontWeight.bold,
),
),
Padding(
padding:
const EdgeInsets.symmetric(vertical: 15, horizontal: 50),
child: Container(
height: 1,
width: double.infinity,
color: ColorsManager.greyColor,
),
),
Expanded(
child: Row(
children: [
Expanded(
child: ListView.separated(
itemCount: acFunctions.length,
separatorBuilder: (_, __) => const Divider(
color: ColorsManager.dividerColor,
),
itemBuilder: (context, index) {
final function = acFunctions[index];
final isSelected =
selectedValues.containsKey(function.code);
return ListTile(
tileColor:
isSelected ? Colors.grey.shade100 : null,
leading: SvgPicture.asset(
function.icon,
width: 24,
height: 24,
),
title: Text(
function.operationName,
style: context.textTheme.bodyMedium,
),
trailing: isSelected
? Icon(
Icons.check_circle,
color:
ColorsManager.primaryColorWithOpacity,
size: 20,
)
: const Icon(
Icons.arrow_forward_ios,
size: 16,
color: ColorsManager.textGray,
),
onTap: () {
if (isSelected) {
selectedValues.remove(function.code);
selectedFunctions.removeWhere(
(f) => f.function == function.code);
}
(context as Element).markNeedsBuild();
},
);
},
),
),
Expanded(
child: Builder(
builder: (context) {
final selectedFunction = acFunctions.firstWhere(
(f) => selectedValues.containsKey(f.code),
orElse: () => acFunctions.first,
);
return _buildValueSelector(
context,
selectedFunction,
selectedValues[selectedFunction.code],
(value) {
selectedValues[selectedFunction.code] = value;
// Update or add the function data
final functionData = DeviceFunctionData(
entityId: selectedFunction.deviceId,
function: selectedFunction.code,
operationName: selectedFunction.operationName,
value: value,
valueDescription: _getValueDescription(
selectedFunction, value),
);
final existingIndex =
selectedFunctions.indexWhere((f) =>
f.function == selectedFunction.code);
if (existingIndex != -1) {
selectedFunctions[existingIndex] =
functionData;
} else {
selectedFunctions.add(functionData);
}
(context as Element).markNeedsBuild();
},
);
},
),
),
],
),
),
Container(
height: 1,
width: double.infinity,
color: ColorsManager.greyColor,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
TextButton(
onPressed: () => Navigator.pop(context),
child: Text(
'Cancel',
style: Theme.of(context)
.textTheme
.bodyMedium!
.copyWith(color: ColorsManager.greyColor),
),
),
TextButton(
onPressed: selectedFunctions.isNotEmpty
? () {
// Add all selected functions to the bloc
for (final function in selectedFunctions) {
context
.read<RoutineBloc>()
.add(AddFunction(function));
}
Navigator.pop(context, true);
}
: null,
child: Text(
'Confirm',
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
color: ColorsManager.primaryColorWithOpacity,
),
),
),
],
),
],
),
),
);
},
);
}
static Widget _buildValueSelector(
BuildContext context,
ACFunction function,
dynamic selectedValue,
Function(dynamic) onValueSelected,
) {
final values = function.getOperationalValues();
return Container(
height: 200,
padding: const EdgeInsets.symmetric(horizontal: 20),
child: ListView.builder(
itemCount: values.length,
itemBuilder: (context, index) {
final value = values[index];
return RadioListTile<dynamic>(
value: value.value,
groupValue: selectedValue,
onChanged: onValueSelected,
title: Text(value.description),
);
},
),
);
}
static String _getValueDescription(ACFunction function, dynamic value) {
final values = function.getOperationalValues();
final selectedValue = values.firstWhere((v) => v.value == value);
return selectedValue.description;
}
}