Support named alert config

This commit is contained in:
LittleSheep 2024-08-15 22:50:00 +08:00
parent 22b863f2bf
commit cfa61e1a8a
7 changed files with 34 additions and 11 deletions

View File

@ -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,

View File

@ -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,

View File

@ -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(

View File

@ -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',

View File

@ -17,6 +17,7 @@ const i18nSimplifiedChinese = {
'alertNutrientId': '营养物质编号', 'alertNutrientId': '营养物质编号',
'alertMaxValue': '告警上限', 'alertMaxValue': '告警上限',
'alertMinValue': '告警下限', 'alertMinValue': '告警下限',
'alertName': '告警规则名',
'alerts': '告警', 'alerts': '告警',
'alertOutOfRange': '有 @count 项告警规则触发,点击右侧按钮了解详情', 'alertOutOfRange': '有 @count 项告警规则触发,点击右侧按钮了解详情',
'alertUnclear': '有 @count 项告警规则并无数据支持,点击右侧按钮了解详情', 'alertUnclear': '有 @count 项告警规则并无数据支持,点击右侧按钮了解详情',

View File

@ -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 ?? ''}',
), ),
); );
}, },

View File

@ -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