push design changes

This commit is contained in:
ashrafzarkanisala
2024-11-22 21:38:39 +03:00
parent a52604360f
commit 7e2f605466

View File

@ -13,51 +13,21 @@ class ACHelper {
List<DeviceFunction<dynamic>> functions, List<DeviceFunction<dynamic>> functions,
) async { ) async {
List<ACFunction> acFunctions = functions.whereType<ACFunction>().toList(); List<ACFunction> acFunctions = functions.whereType<ACFunction>().toList();
String? selectedFunction; final selectedFunctionNotifier = ValueNotifier<String?>(null);
dynamic selectedValue = 20; final selectedValueNotifier = ValueNotifier<dynamic>(null);
String? selectedCondition = "=="; final selectedConditionNotifier = ValueNotifier<String?>('==');
List<bool> _selectedConditions = [false, true, false]; final selectedConditionsNotifier =
ValueNotifier<List<bool>>([false, true, false]);
return showDialog<Map<String, dynamic>?>( return showDialog<Map<String, dynamic>?>(
context: context, context: context,
builder: (BuildContext context) { builder: (BuildContext context) {
return StatefulBuilder( return ValueListenableBuilder<String?>(
builder: (context, setState) { valueListenable: selectedFunctionNotifier,
builder: (context, selectedFunction, _) {
return AlertDialog( return AlertDialog(
contentPadding: EdgeInsets.zero, contentPadding: EdgeInsets.zero,
content: _buildDialogContent( content: Container(
context,
setState,
acFunctions,
selectedFunction,
selectedValue,
selectedCondition,
_selectedConditions,
(fn) => selectedFunction = fn,
(val) => selectedValue = val,
(cond) => selectedCondition = cond,
),
);
},
);
},
);
}
/// Build dialog content for AC functions dialog
static Widget _buildDialogContent(
BuildContext context,
StateSetter setState,
List<ACFunction> acFunctions,
String? selectedFunction,
dynamic selectedValue,
String? selectedCondition,
List<bool> selectedConditions,
Function(String?) onFunctionSelected,
Function(dynamic) onValueSelected,
Function(String?) onConditionSelected,
) {
return Container(
width: selectedFunction != null ? 600 : 360, width: selectedFunction != null ? 600 : 360,
height: 450, height: 450,
decoration: BoxDecoration( decoration: BoxDecoration(
@ -69,63 +39,91 @@ class ACHelper {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
const DialogHeader('AC Functions'), const DialogHeader('AC Functions'),
Flexible( Expanded(
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [ children: [
_buildFunctionsList( // Function list
SizedBox(
width: selectedFunction != null ? 320 : 360,
child: _buildFunctionsList(
context, context,
setState,
acFunctions, acFunctions,
selectedFunction, selectedFunctionNotifier,
onFunctionSelected,
), ),
),
// Value selector
if (selectedFunction != null) if (selectedFunction != null)
_buildValueSelector( Expanded(
child: _buildValueSelector(
context, context,
setState,
selectedFunction, selectedFunction,
selectedValue, selectedValueNotifier,
selectedCondition, selectedConditionNotifier,
selectedConditions, selectedConditionsNotifier,
onValueSelected,
onConditionSelected,
acFunctions, acFunctions,
), ),
),
], ],
), ),
), ),
DialogFooter( DialogFooter(
onCancel: () => Navigator.pop(context), onCancel: () {
onConfirm: selectedFunction != null && selectedValue != null selectedFunctionNotifier.dispose();
? () => Navigator.pop(context, { selectedValueNotifier.dispose();
'function': selectedFunction, selectedConditionNotifier.dispose();
'value': selectedValue, selectedConditionsNotifier.dispose();
'condition': selectedCondition ?? "==", Navigator.pop(context);
}) },
onConfirm: selectedFunctionNotifier.value != null &&
selectedValueNotifier.value != null
? () {
selectedFunctionNotifier.dispose();
selectedValueNotifier.dispose();
selectedConditionNotifier.dispose();
selectedConditionsNotifier.dispose();
Navigator.pop(context, {
'function': selectedFunctionNotifier.value,
'value': selectedValueNotifier.value,
'condition':
selectedConditionNotifier.value ?? "==",
});
}
: null, : null,
isConfirmEnabled: selectedFunction != null && selectedValue != null, isConfirmEnabled: selectedFunction != null,
), ),
], ],
), ),
),
); );
},
);
},
).then((value) {
selectedFunctionNotifier.dispose();
selectedValueNotifier.dispose();
selectedConditionNotifier.dispose();
selectedConditionsNotifier.dispose();
return value;
});
} }
/// Build functions list for AC functions dialog /// Build functions list for AC functions dialog
static Widget _buildFunctionsList( static Widget _buildFunctionsList(
BuildContext context, BuildContext context,
StateSetter setState,
List<ACFunction> acFunctions, List<ACFunction> acFunctions,
String? selectedFunction, ValueNotifier<String?> selectedFunctionNotifier,
Function(String?) onFunctionSelected,
) { ) {
return Expanded( return ListView.separated(
child: ListView.separated(
shrinkWrap: false, shrinkWrap: false,
physics: const AlwaysScrollableScrollPhysics(), physics: const AlwaysScrollableScrollPhysics(),
itemCount: acFunctions.length, itemCount: acFunctions.length,
separatorBuilder: (context, index) => const Divider( separatorBuilder: (context, index) => const Padding(
padding: EdgeInsets.symmetric(horizontal: 40.0),
child: Divider(
color: ColorsManager.dividerColor, color: ColorsManager.dividerColor,
), ),
),
itemBuilder: (context, index) { itemBuilder: (context, index) {
final function = acFunctions[index]; final function = acFunctions[index];
return ListTile( return ListTile(
@ -133,6 +131,11 @@ class ACHelper {
function.icon, function.icon,
width: 24, width: 24,
height: 24, height: 24,
placeholderBuilder: (BuildContext context) => Container(
width: 24,
height: 24,
color: Colors.transparent,
),
), ),
title: Text( title: Text(
function.operationName, function.operationName,
@ -143,80 +146,70 @@ class ACHelper {
size: 16, size: 16,
color: ColorsManager.textGray, color: ColorsManager.textGray,
), ),
onTap: () => setState(() => onFunctionSelected(function.code)), onTap: () => selectedFunctionNotifier.value = function.code,
); );
}, },
),
); );
} }
/// Build value selector for AC functions dialog /// Build value selector for AC functions dialog
static Widget _buildValueSelector( static Widget _buildValueSelector(
BuildContext context, BuildContext context,
StateSetter setState,
String selectedFunction, String selectedFunction,
dynamic selectedValue, ValueNotifier<dynamic> selectedValueNotifier,
String? selectedCondition, ValueNotifier<String?> selectedConditionNotifier,
List<bool> selectedConditions, ValueNotifier<List<bool>> selectedConditionsNotifier,
Function(dynamic) onValueSelected,
Function(String?) onConditionSelected,
List<ACFunction> acFunctions, List<ACFunction> acFunctions,
) { ) {
// Handle temperature functions
if (selectedFunction == 'temp_set' || selectedFunction == 'temp_current') { if (selectedFunction == 'temp_set' || selectedFunction == 'temp_current') {
return Expanded( // Initialize with 20°C (200 in internal representation)
child: _buildTemperatureSelector( if (selectedValueNotifier.value == null ||
selectedValueNotifier.value is! int) {
selectedValueNotifier.value = 200;
}
return _buildTemperatureSelector(
context, context,
setState, selectedValueNotifier,
selectedValue, selectedConditionNotifier,
selectedCondition, selectedConditionsNotifier,
selectedConditions,
onValueSelected,
onConditionSelected,
),
); );
} }
// Handle other functions
final selectedFn = final selectedFn =
acFunctions.firstWhere((f) => f.code == selectedFunction); acFunctions.firstWhere((f) => f.code == selectedFunction);
final values = selectedFn.getOperationalValues(); final values = selectedFn.getOperationalValues();
return Expanded(
child: _buildOperationalValuesList( // Don't set any default value for non-temperature functions
return _buildOperationalValuesList(
context, context,
setState,
values, values,
selectedValue, selectedValueNotifier,
onValueSelected,
),
); );
} }
/// Build temperature selector for AC functions dialog /// Build temperature selector for AC functions dialog
static Widget _buildTemperatureSelector( static Widget _buildTemperatureSelector(
BuildContext context, BuildContext context,
StateSetter setState, ValueNotifier<dynamic> selectedValueNotifier,
dynamic selectedValue, ValueNotifier<String?> selectedConditionNotifier,
String? selectedCondition, ValueNotifier<List<bool>> selectedConditionsNotifier,
List<bool> selectedConditions,
Function(dynamic) onValueSelected,
Function(String?) onConditionSelected,
) { ) {
return Column( return Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
_buildConditionToggle( _buildConditionToggle(
context, context,
setState, selectedConditionNotifier,
selectedConditions, selectedConditionsNotifier,
onConditionSelected,
), ),
const SizedBox(height: 20), const SizedBox(height: 20),
_buildTemperatureDisplay(context, selectedValue), _buildTemperatureDisplay(context, selectedValueNotifier),
const SizedBox(height: 20), const SizedBox(height: 20),
_buildTemperatureSlider( _buildTemperatureSlider(
context, context,
setState, selectedValueNotifier,
selectedValue,
onValueSelected,
), ),
], ],
); );
@ -225,22 +218,22 @@ class ACHelper {
/// Build condition toggle for AC functions dialog /// Build condition toggle for AC functions dialog
static Widget _buildConditionToggle( static Widget _buildConditionToggle(
BuildContext context, BuildContext context,
StateSetter setState, ValueNotifier<String?> selectedConditionNotifier,
List<bool> selectedConditions, ValueNotifier<List<bool>> selectedConditionsNotifier,
Function(String?) onConditionSelected,
) { ) {
return ValueListenableBuilder<List<bool>>(
valueListenable: selectedConditionsNotifier,
builder: (context, selectedConditions, _) {
return ToggleButtons( return ToggleButtons(
onPressed: (int index) { onPressed: (int index) {
setState(() { final newConditions = [false, false, false];
for (int i = 0; i < selectedConditions.length; i++) { newConditions[index] = true;
selectedConditions[i] = i == index; selectedConditionsNotifier.value = newConditions;
} selectedConditionNotifier.value = index == 0
onConditionSelected(index == 0
? "<" ? "<"
: index == 1 : index == 1
? "==" ? "=="
: ">"); : ">";
});
}, },
borderRadius: const BorderRadius.all(Radius.circular(8)), borderRadius: const BorderRadius.all(Radius.circular(8)),
selectedBorderColor: ColorsManager.primaryColorWithOpacity, selectedBorderColor: ColorsManager.primaryColorWithOpacity,
@ -254,52 +247,62 @@ class ACHelper {
isSelected: selectedConditions, isSelected: selectedConditions,
children: const [Text("<"), Text("="), Text(">")], children: const [Text("<"), Text("="), Text(">")],
); );
},
);
} }
/// Build temperature display for AC functions dialog /// Build temperature display for AC functions dialog
static Widget _buildTemperatureDisplay( static Widget _buildTemperatureDisplay(
BuildContext context, dynamic selectedValue) { BuildContext context, ValueNotifier<dynamic> selectedValueNotifier) {
return Container( return Container(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10), padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
decoration: BoxDecoration( decoration: BoxDecoration(
color: ColorsManager.primaryColorWithOpacity.withOpacity(0.1), color: ColorsManager.primaryColorWithOpacity.withOpacity(0.1),
borderRadius: BorderRadius.circular(10), borderRadius: BorderRadius.circular(10),
), ),
child: Text( child: ValueListenableBuilder(
'${selectedValue ?? 20}°C', valueListenable: selectedValueNotifier,
builder: (context, selectedValue, child) {
return Text(
'${(selectedValue ?? 200) / 10}°C',
style: context.textTheme.headlineMedium!.copyWith( style: context.textTheme.headlineMedium!.copyWith(
color: ColorsManager.primaryColorWithOpacity, color: ColorsManager.primaryColorWithOpacity,
), ),
);
},
), ),
); );
} }
static Widget _buildTemperatureSlider( static Widget _buildTemperatureSlider(
BuildContext context, BuildContext context,
StateSetter setState, ValueNotifier<dynamic> selectedValueNotifier,
dynamic selectedValue,
Function(dynamic) onValueSelected,
) { ) {
final currentValue = selectedValue is int ? selectedValue.toDouble() : 20.0; return ValueListenableBuilder(
valueListenable: selectedValueNotifier,
builder: (context, selectedValue, child) {
final currentValue =
selectedValue is int ? selectedValue.toDouble() : 200.0;
return Slider( return Slider(
value: currentValue, value: currentValue,
min: 16, min: 160,
max: 30, max: 300,
divisions: 14, divisions: 14,
label: '${currentValue.toInt()}°C', label: '${(currentValue / 10).toInt()}°C',
onChanged: (value) { onChanged: (value) => selectedValueNotifier.value = value.toInt(),
setState(() => onValueSelected(value.toInt())); );
}, },
); );
} }
static Widget _buildOperationalValuesList( static Widget _buildOperationalValuesList(
BuildContext context, BuildContext context,
StateSetter setState,
List<dynamic> values, List<dynamic> values,
dynamic selectedValue, ValueNotifier<dynamic> selectedValueNotifier,
Function(dynamic) onValueSelected,
) { ) {
return ValueListenableBuilder<dynamic>(
valueListenable: selectedValueNotifier,
builder: (context, selectedValue, _) {
return ListView.builder( return ListView.builder(
shrinkWrap: false, shrinkWrap: false,
physics: const AlwaysScrollableScrollPhysics(), physics: const AlwaysScrollableScrollPhysics(),
@ -311,6 +314,11 @@ class ACHelper {
value.icon, value.icon,
width: 24, width: 24,
height: 24, height: 24,
placeholderBuilder: (BuildContext context) => Container(
width: 24,
height: 24,
color: Colors.transparent,
),
), ),
title: Text( title: Text(
value.description, value.description,
@ -319,10 +327,12 @@ class ACHelper {
trailing: Radio<dynamic>( trailing: Radio<dynamic>(
value: value.value, value: value.value,
groupValue: selectedValue, groupValue: selectedValue,
onChanged: (newValue) { onChanged: (_) => selectedValueNotifier.value = value.value,
setState(() => onValueSelected(newValue)); activeColor: ColorsManager.primaryColorWithOpacity,
},
), ),
onTap: () => selectedValueNotifier.value = value.value,
);
},
); );
}, },
); );