✨ Support named alert config
This commit is contained in:
		| @@ -1,15 +1,20 @@ | |||||||
|  | import 'package:dietary_guard/models/food_data.dart'; | ||||||
|  |  | ||||||
| class AlertConfiguration { | class AlertConfiguration { | ||||||
|  |   String name; | ||||||
|   int nutrientId; |   int nutrientId; | ||||||
|   double maxValue; |   double maxValue; | ||||||
|   double minValue; |   double minValue; | ||||||
|  |  | ||||||
|   AlertConfiguration({ |   AlertConfiguration({ | ||||||
|  |     required this.name, | ||||||
|     required this.nutrientId, |     required this.nutrientId, | ||||||
|     required this.maxValue, |     required this.maxValue, | ||||||
|     required this.minValue, |     required this.minValue, | ||||||
|   }); |   }); | ||||||
|  |  | ||||||
|   Map<String, dynamic> toJson() => { |   Map<String, dynamic> toJson() => { | ||||||
|  |         'name': name, | ||||||
|         'nutrient_id': nutrientId, |         'nutrient_id': nutrientId, | ||||||
|         'min_value': minValue, |         'min_value': minValue, | ||||||
|         'max_value': maxValue, |         'max_value': maxValue, | ||||||
| @@ -17,6 +22,7 @@ class AlertConfiguration { | |||||||
|  |  | ||||||
|   factory AlertConfiguration.fromJson(Map<String, dynamic> json) => |   factory AlertConfiguration.fromJson(Map<String, dynamic> json) => | ||||||
|       AlertConfiguration( |       AlertConfiguration( | ||||||
|  |         name: json['name'], | ||||||
|         nutrientId: json['nutrient_id'], |         nutrientId: json['nutrient_id'], | ||||||
|         minValue: json['min_value'], |         minValue: json['min_value'], | ||||||
|         maxValue: json['max_value'], |         maxValue: json['max_value'], | ||||||
| @@ -25,18 +31,18 @@ class AlertConfiguration { | |||||||
|  |  | ||||||
| class AlertDetectResult { | class AlertDetectResult { | ||||||
|   AlertConfiguration config; |   AlertConfiguration config; | ||||||
|  |   FoodNutrient? nutrient; | ||||||
|   String name; |   String name; | ||||||
|   String? unitName; |   String? unitName; | ||||||
|   double? current; |  | ||||||
|   double? difference; |   double? difference; | ||||||
|   bool isOutOfRange; |   bool isOutOfRange; | ||||||
|   bool isUndetected; |   bool isUndetected; | ||||||
|  |  | ||||||
|   AlertDetectResult({ |   AlertDetectResult({ | ||||||
|     required this.config, |     required this.config, | ||||||
|  |     required this.nutrient, | ||||||
|     required this.name, |     required this.name, | ||||||
|     required this.unitName, |     required this.unitName, | ||||||
|     required this.current, |  | ||||||
|     required this.difference, |     required this.difference, | ||||||
|     required this.isOutOfRange, |     required this.isOutOfRange, | ||||||
|     required this.isUndetected, |     required this.isUndetected, | ||||||
|   | |||||||
| @@ -33,14 +33,14 @@ class _FoodDetailsScreenState extends State<FoodDetailsScreen> { | |||||||
|       double? difference; |       double? difference; | ||||||
|       String name = 'undetected'.tr; |       String name = 'undetected'.tr; | ||||||
|       String? unitName; |       String? unitName; | ||||||
|       double? current; |       FoodNutrient? current; | ||||||
|       for (final nutrient in widget.item.foodNutrients) { |       for (final nutrient in widget.item.foodNutrients) { | ||||||
|         if (item.nutrientId != nutrient.nutrientId) continue; |         if (item.nutrientId != nutrient.nutrientId) continue; | ||||||
|         name = nutrient.nutrientName; |         name = nutrient.nutrientName; | ||||||
|         unitName = unitNameValues.reverse[nutrient.unitName]; |         unitName = unitNameValues.reverse[nutrient.unitName]; | ||||||
|         if (nutrient.value != null) { |         if (nutrient.value != null) { | ||||||
|  |           current = nutrient; | ||||||
|           final value = nutrient.value!; |           final value = nutrient.value!; | ||||||
|           current = value; |  | ||||||
|           if (value > item.maxValue) { |           if (value > item.maxValue) { | ||||||
|             difference = value - item.maxValue; |             difference = value - item.maxValue; | ||||||
|             isOutOfRange = true; |             isOutOfRange = true; | ||||||
| @@ -54,9 +54,9 @@ class _FoodDetailsScreenState extends State<FoodDetailsScreen> { | |||||||
|  |  | ||||||
|       _alertDetectResult.add(AlertDetectResult( |       _alertDetectResult.add(AlertDetectResult( | ||||||
|         config: item, |         config: item, | ||||||
|  |         nutrient: current, | ||||||
|         name: name, |         name: name, | ||||||
|         unitName: unitName, |         unitName: unitName, | ||||||
|         current: current, |  | ||||||
|         difference: difference, |         difference: difference, | ||||||
|         isOutOfRange: isOutOfRange, |         isOutOfRange: isOutOfRange, | ||||||
|         isUndetected: isUndetected, |         isUndetected: isUndetected, | ||||||
|   | |||||||
| @@ -16,6 +16,7 @@ class _AlertSettingsScreenState extends State<AlertSettingsScreen> { | |||||||
|   void _addAlert() { |   void _addAlert() { | ||||||
|     setState(() { |     setState(() { | ||||||
|       _currentAlerts.add(AlertConfiguration( |       _currentAlerts.add(AlertConfiguration( | ||||||
|  |         name: 'Alert #${_currentAlerts.length}', | ||||||
|         nutrientId: 0, |         nutrientId: 0, | ||||||
|         maxValue: 0, |         maxValue: 0, | ||||||
|         minValue: 0, |         minValue: 0, | ||||||
| @@ -64,16 +65,16 @@ class _AlertSettingsScreenState extends State<AlertSettingsScreen> { | |||||||
|                       children: [ |                       children: [ | ||||||
|                         Expanded( |                         Expanded( | ||||||
|                           child: TextFormField( |                           child: TextFormField( | ||||||
|                             initialValue: x.nutrientId.toString(), |                             initialValue: x.name, | ||||||
|                             decoration: InputDecoration( |                             decoration: InputDecoration( | ||||||
|                               border: const OutlineInputBorder(), |                               border: const OutlineInputBorder(), | ||||||
|                               label: Text("alertNutrientId".tr), |                               label: Text("alertName".tr), | ||||||
|                               isDense: true, |                               isDense: true, | ||||||
|                             ), |                             ), | ||||||
|                             onTapOutside: (_) => |                             onTapOutside: (_) => | ||||||
|                                 FocusManager.instance.primaryFocus?.unfocus(), |                                 FocusManager.instance.primaryFocus?.unfocus(), | ||||||
|                             onChanged: (value) { |                             onChanged: (value) { | ||||||
|                               x.nutrientId = int.tryParse(value) ?? 0; |                               x.name = value; | ||||||
|                             }, |                             }, | ||||||
|                           ), |                           ), | ||||||
|                         ), |                         ), | ||||||
| @@ -87,6 +88,20 @@ class _AlertSettingsScreenState extends State<AlertSettingsScreen> { | |||||||
|                       ], |                       ], | ||||||
|                     ), |                     ), | ||||||
|                     const SizedBox(height: 12), |                     const SizedBox(height: 12), | ||||||
|  |                     TextFormField( | ||||||
|  |                       initialValue: x.nutrientId.toString(), | ||||||
|  |                       decoration: InputDecoration( | ||||||
|  |                         border: const OutlineInputBorder(), | ||||||
|  |                         label: Text("alertNutrientId".tr), | ||||||
|  |                         isDense: true, | ||||||
|  |                       ), | ||||||
|  |                       onTapOutside: (_) => | ||||||
|  |                           FocusManager.instance.primaryFocus?.unfocus(), | ||||||
|  |                       onChanged: (value) { | ||||||
|  |                         x.nutrientId = int.tryParse(value) ?? 0; | ||||||
|  |                       }, | ||||||
|  |                     ), | ||||||
|  |                     const SizedBox(height: 12), | ||||||
|                     Row( |                     Row( | ||||||
|                       children: [ |                       children: [ | ||||||
|                         Expanded( |                         Expanded( | ||||||
|   | |||||||
| @@ -17,6 +17,7 @@ const i18nEnglish = { | |||||||
|   'alertNutrientId': 'Nutrient ID', |   'alertNutrientId': 'Nutrient ID', | ||||||
|   'alertMaxValue': 'Alert Max Value', |   'alertMaxValue': 'Alert Max Value', | ||||||
|   'alertMinValue': 'Alert Min Value', |   'alertMinValue': 'Alert Min Value', | ||||||
|  |   'alertName': 'Alert Name', | ||||||
|   'alerts': 'Alerts', |   'alerts': 'Alerts', | ||||||
|   'alertOutOfRange': |   'alertOutOfRange': | ||||||
|       '@count alert rules triggered, click the button on the right for details', |       '@count alert rules triggered, click the button on the right for details', | ||||||
|   | |||||||
| @@ -17,6 +17,7 @@ const i18nSimplifiedChinese = { | |||||||
|   'alertNutrientId': '营养物质编号', |   'alertNutrientId': '营养物质编号', | ||||||
|   'alertMaxValue': '告警上限', |   'alertMaxValue': '告警上限', | ||||||
|   'alertMinValue': '告警下限', |   'alertMinValue': '告警下限', | ||||||
|  |   'alertName': '告警规则名', | ||||||
|   'alerts': '告警', |   'alerts': '告警', | ||||||
|   'alertOutOfRange': '有 @count 项告警规则触发,点击右侧按钮了解详情', |   'alertOutOfRange': '有 @count 项告警规则触发,点击右侧按钮了解详情', | ||||||
|   'alertUnclear': '有 @count 项告警规则并无数据支持,点击右侧按钮了解详情', |   'alertUnclear': '有 @count 项告警规则并无数据支持,点击右侧按钮了解详情', | ||||||
|   | |||||||
| @@ -60,13 +60,13 @@ class AlertDetectResultDialog extends StatelessWidget { | |||||||
|                   title: Row( |                   title: Row( | ||||||
|                     crossAxisAlignment: CrossAxisAlignment.center, |                     crossAxisAlignment: CrossAxisAlignment.center, | ||||||
|                     children: [ |                     children: [ | ||||||
|                       Text(item.name), |                       Text(item.config.name), | ||||||
|                       const SizedBox(width: 6), |                       const SizedBox(width: 6), | ||||||
|                       Badge(label: Text('#${item.config.nutrientId}')) |                       Badge(label: Text('#${item.config.nutrientId}')) | ||||||
|                     ], |                     ], | ||||||
|                   ), |                   ), | ||||||
|                   subtitle: Text( |                   subtitle: Text( | ||||||
|                     '${item.current ?? 'undetected'.tr} ${(item.difference ?? 0) > 0 ? '↑' : '↓'}${item.difference?.abs().toPrecision(2) ?? '-'} ${item.unitName ?? ''}', |                     '${item.nutrient?.value ?? 'undetected'.tr} ${(item.difference ?? 0) > 0 ? '↑' : '↓'}${item.difference?.abs().toPrecision(2) ?? '-'} ${item.unitName ?? ''}', | ||||||
|                   ), |                   ), | ||||||
|                 ); |                 ); | ||||||
|               }, |               }, | ||||||
|   | |||||||
| @@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev | |||||||
| # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html | ||||||
| # In Windows, build-name is used as the major, minor, and patch parts | # In Windows, build-name is used as the major, minor, and patch parts | ||||||
| # of the product and file versions while build-number is used as the build suffix. | # of the product and file versions while build-number is used as the build suffix. | ||||||
| version: 1.0.0+1 | version: 1.0.0+2 | ||||||
|  |  | ||||||
| environment: | environment: | ||||||
|   sdk: ^3.5.0 |   sdk: ^3.5.0 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user