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 {
String name;
int nutrientId;
double maxValue;
double minValue;
AlertConfiguration({
required this.name,
required this.nutrientId,
required this.maxValue,
required this.minValue,
});
Map<String, dynamic> toJson() => {
'name': name,
'nutrient_id': nutrientId,
'min_value': minValue,
'max_value': maxValue,
@ -17,6 +22,7 @@ class AlertConfiguration {
factory AlertConfiguration.fromJson(Map<String, dynamic> json) =>
AlertConfiguration(
name: json['name'],
nutrientId: json['nutrient_id'],
minValue: json['min_value'],
maxValue: json['max_value'],
@ -25,18 +31,18 @@ class AlertConfiguration {
class AlertDetectResult {
AlertConfiguration config;
FoodNutrient? nutrient;
String name;
String? unitName;
double? current;
double? difference;
bool isOutOfRange;
bool isUndetected;
AlertDetectResult({
required this.config,
required this.nutrient,
required this.name,
required this.unitName,
required this.current,
required this.difference,
required this.isOutOfRange,
required this.isUndetected,

View File

@ -33,14 +33,14 @@ class _FoodDetailsScreenState extends State<FoodDetailsScreen> {
double? difference;
String name = 'undetected'.tr;
String? unitName;
double? current;
FoodNutrient? current;
for (final nutrient in widget.item.foodNutrients) {
if (item.nutrientId != nutrient.nutrientId) continue;
name = nutrient.nutrientName;
unitName = unitNameValues.reverse[nutrient.unitName];
if (nutrient.value != null) {
current = nutrient;
final value = nutrient.value!;
current = value;
if (value > item.maxValue) {
difference = value - item.maxValue;
isOutOfRange = true;
@ -54,9 +54,9 @@ class _FoodDetailsScreenState extends State<FoodDetailsScreen> {
_alertDetectResult.add(AlertDetectResult(
config: item,
nutrient: current,
name: name,
unitName: unitName,
current: current,
difference: difference,
isOutOfRange: isOutOfRange,
isUndetected: isUndetected,

View File

@ -16,6 +16,7 @@ class _AlertSettingsScreenState extends State<AlertSettingsScreen> {
void _addAlert() {
setState(() {
_currentAlerts.add(AlertConfiguration(
name: 'Alert #${_currentAlerts.length}',
nutrientId: 0,
maxValue: 0,
minValue: 0,
@ -64,16 +65,16 @@ class _AlertSettingsScreenState extends State<AlertSettingsScreen> {
children: [
Expanded(
child: TextFormField(
initialValue: x.nutrientId.toString(),
initialValue: x.name,
decoration: InputDecoration(
border: const OutlineInputBorder(),
label: Text("alertNutrientId".tr),
label: Text("alertName".tr),
isDense: true,
),
onTapOutside: (_) =>
FocusManager.instance.primaryFocus?.unfocus(),
onChanged: (value) {
x.nutrientId = int.tryParse(value) ?? 0;
x.name = value;
},
),
),
@ -87,6 +88,20 @@ class _AlertSettingsScreenState extends State<AlertSettingsScreen> {
],
),
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(
children: [
Expanded(

View File

@ -17,6 +17,7 @@ const i18nEnglish = {
'alertNutrientId': 'Nutrient ID',
'alertMaxValue': 'Alert Max Value',
'alertMinValue': 'Alert Min Value',
'alertName': 'Alert Name',
'alerts': 'Alerts',
'alertOutOfRange':
'@count alert rules triggered, click the button on the right for details',

View File

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

View File

@ -60,13 +60,13 @@ class AlertDetectResultDialog extends StatelessWidget {
title: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(item.name),
Text(item.config.name),
const SizedBox(width: 6),
Badge(label: Text('#${item.config.nutrientId}'))
],
),
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
# 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.
version: 1.0.0+1
version: 1.0.0+2
environment:
sdk: ^3.5.0