translations, set name props as unique, set child data as deleted on deleting parents
This commit is contained in:
parent
38f43a48ec
commit
0182bf463b
52
TODO
52
TODO
@ -1,48 +1,45 @@
|
|||||||
MAIN TASKS:
|
MAIN TASKS:
|
||||||
Database:
|
Database:
|
||||||
☐ set name properties as unique (and add checks to forms)
|
|
||||||
☐ implement users
|
|
||||||
☐ check objectbox docs on how to make users
|
|
||||||
☐ tie all data to users
|
|
||||||
☐ add user filters to all getters
|
|
||||||
☐ change settings to not be a singleton, but only one settings instance per user and one default entry
|
|
||||||
☐ add login and authentification
|
|
||||||
☐ enable restoring data from sync
|
|
||||||
☐ find a solution for storage
|
|
||||||
☐ hosting
|
|
||||||
☐ objectbox sync (commercial use is not free)
|
|
||||||
☐ implement alternative data export for now?
|
|
||||||
☐ create default datasets for configuration (meal categories, portion types, accuracies, event types, possibly meal source)
|
☐ create default datasets for configuration (meal categories, portion types, accuracies, event types, possibly meal source)
|
||||||
|
☐ cleanup unneeded models (and make sure the app still runs)
|
||||||
Features:
|
Features:
|
||||||
☐ app icon
|
|
||||||
☐ add explanations to each section
|
|
||||||
☐ german language support
|
|
||||||
☐ indicate nested creation process (creating from dropdown etc)
|
|
||||||
☐ indicate read only fields
|
☐ indicate read only fields
|
||||||
|
☐ indicate nested creation process (creating from dropdown etc)
|
||||||
☐ app info/credits screen
|
☐ app info/credits screen
|
||||||
|
☐ add explanations to each section
|
||||||
|
☐ app icon
|
||||||
Components/Framework:
|
Components/Framework:
|
||||||
|
☐ check through all detail forms and set required fields/according messages
|
||||||
|
☐ show indicator and make all fields readonly if user somehow gets to a deleted record detail view
|
||||||
|
☐ check for changes before navigating as well (not just on cancel)
|
||||||
|
☐ fix bug when navigating while creating/editing a record
|
||||||
|
☐ change placement of delete and floating button because its very easy to accidentally hit delete
|
||||||
|
☐ dropdown tweaks
|
||||||
|
☐ edit item -> cancel: shouldn't clear dropdwon
|
||||||
|
☐ account for deleted/disabled elements
|
||||||
|
☐ change app id from "com.example.diameter" to "at.sarahziesel.diameter"
|
||||||
☐ come up with new concept for duration component
|
☐ come up with new concept for duration component
|
||||||
☐ update duration fields to use corresponding component
|
☐ update duration fields to use corresponding component
|
||||||
☐ log event type detail (reminder duration)
|
☐ log event type detail (reminder duration)
|
||||||
☐ log event detail (reminder duration)
|
☐ log event detail (reminder duration)
|
||||||
☐ meal (bolus delay)
|
☐ meal (bolus delay)
|
||||||
☐ log bolus (delay)
|
☐ log bolus (delay)
|
||||||
☐ check through all detail forms and set required fields/according messages
|
|
||||||
☐ change placement of delete and floating button because its very easy to accidentally hit delete
|
|
||||||
☐ check for changes before navigating as well (not just on cancel)
|
|
||||||
☐ show indicator and make all fields readonly if user somehow gets to a deleted record detail view
|
|
||||||
☐ dropdown tweaks
|
|
||||||
☐ edit item -> cancel: shouldn't clear dropdwon
|
|
||||||
☐ account for deleted/disabled elements
|
|
||||||
Log:
|
Log:
|
||||||
☐ add filters
|
☐ add filters
|
||||||
☐ check if there is still an active bolus when suggesting glucose bolus
|
☐ check if there is still an active bolus when suggesting glucose bolus
|
||||||
|
☐ remember/display setting for correction boli correctly
|
||||||
Log Events:
|
Log Events:
|
||||||
☐ add filters
|
☐ add filters
|
||||||
|
☐ don't show warning for existing event if it's the one being edited
|
||||||
|
☐ add create button to event type dropdown
|
||||||
Categorization:
|
Categorization:
|
||||||
☐ add colors to event types as indicators for log entries and graphs in reports
|
☐ add colors to event types as indicators for log entries and graphs in reports
|
||||||
☐ implement reminders as push notifications
|
☐ implement reminders as push notifications
|
||||||
Settings:
|
Settings:
|
||||||
|
☐ export functionality
|
||||||
|
☐ implement loading from google drive
|
||||||
|
☐ find out pricing for google apis
|
||||||
|
☐ add some options (which data to export, including dead records...)
|
||||||
☐ option to switch theme
|
☐ option to switch theme
|
||||||
☐ add fields for glucose target tiers (as map of cutoff glucose and colors)
|
☐ add fields for glucose target tiers (as map of cutoff glucose and colors)
|
||||||
☐ add field for active insulin duration
|
☐ add field for active insulin duration
|
||||||
@ -50,6 +47,15 @@ MAIN TASKS:
|
|||||||
☐ add functionality to delete dead records (meaning: set deleted flag and no relations to undeleted records)
|
☐ add functionality to delete dead records (meaning: set deleted flag and no relations to undeleted records)
|
||||||
|
|
||||||
Archive:
|
Archive:
|
||||||
|
✔ set child data as deleted on deleting parent (ie. log boli for log entry etc) @done(22-06-19 23:44) @project(MAIN TASKS.Database)
|
||||||
|
✔ set name properties as unique @done(22-06-17 01:34) @project(MAIN TASKS.Database)
|
||||||
|
✔ german language support @done(22-06-17 01:19) @project(MAIN TASKS.Features)
|
||||||
|
✔ add translations for all sections @done(22-06-17 01:19) @project(MAIN TASKS.Features)
|
||||||
|
✔ add data source field to all models @done(22-04-15 00:24) @project(MAIN TASKS.Database)
|
||||||
|
✔ add export methods to all models @done(22-04-12 21:38) @project(MAIN TASKS.Database)
|
||||||
|
✔ add import methods to all models @done(22-04-15 00:24) @project(MAIN TASKS.Database)
|
||||||
|
✔ implement export to json @done(22-04-12 21:43) @project(MAIN TASKS.Settings)
|
||||||
|
✔ implement saving export to google drive @done(22-04-13 15:01) @project(MAIN TASKS.Settings)
|
||||||
✔ switch day on swipe @done(22-03-19 23:20) @project(MAIN TASKS.Log)
|
✔ switch day on swipe @done(22-03-19 23:20) @project(MAIN TASKS.Log)
|
||||||
✔ switch day on swipe @done(22-03-19 23:23) @project(MAIN TASKS.Log Events)
|
✔ switch day on swipe @done(22-03-19 23:23) @project(MAIN TASKS.Log Events)
|
||||||
✔ switch day on swipe @done(22-03-19 23:20) @project(MAIN TASKS.Reports)
|
✔ switch day on swipe @done(22-03-19 23:20) @project(MAIN TASKS.Reports)
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
{"installed":{"client_id":"988592836243-pmdkvghnvd6fdeo4qm0sjgstcqvrbhqs.apps.googleusercontent.com","project_id":"coastal-fiber-347020","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://oauth2.googleapis.com/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs"}}
|
501
assets/i18n/de.json
Normal file
501
assets/i18n/de.json
Normal file
@ -0,0 +1,501 @@
|
|||||||
|
{
|
||||||
|
"accuracy": {
|
||||||
|
"confirmDelete": "Willst du diese Präzision wirklich löschen?",
|
||||||
|
"deleted": "Präzision gelöscht",
|
||||||
|
"detail": {
|
||||||
|
"title": "{status} Präzision"
|
||||||
|
},
|
||||||
|
"empty": "Du hast noch keine Präzisionen erstellt!",
|
||||||
|
"fields": {
|
||||||
|
"confidenceRating": "Reihung",
|
||||||
|
"fürCarbsRatio": "für KH-Verhältnis",
|
||||||
|
"fürPortionSize": "für Portionsgröße",
|
||||||
|
"name": "Name",
|
||||||
|
"notes": "Bemerkung",
|
||||||
|
"validators": {
|
||||||
|
"name": "Name ist leer"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"new": "Neue",
|
||||||
|
"saved": {
|
||||||
|
"1": "{status}Präzision gespeichert",
|
||||||
|
"else": "{status}Präzisionen gespeichert"
|
||||||
|
},
|
||||||
|
"title": "Präzision"
|
||||||
|
},
|
||||||
|
"basal": {
|
||||||
|
"confirmDelete": "Willst du diese Basalrate wirklich löschen?",
|
||||||
|
"deleted": "Basalrate gelöscht",
|
||||||
|
"empty": "Du hast noch keine Basalraten erstellt!",
|
||||||
|
"fields": {
|
||||||
|
"endTime": "Endzeit",
|
||||||
|
"startTime": "Startzeit",
|
||||||
|
"units": "Einheiten"
|
||||||
|
},
|
||||||
|
"new": "Neue",
|
||||||
|
"saved": {
|
||||||
|
"1": "{status}Basalrate gespeichert",
|
||||||
|
"else": "{status}Basalraten gespeichert"
|
||||||
|
},
|
||||||
|
"title": "{status} Basalrate für {profileName}",
|
||||||
|
"warnings": {
|
||||||
|
"duplicate": "Es gibt bereits eine Rate mit dieser Startzeit.",
|
||||||
|
"endTimeLast": "Letzter Basal des Tages muss um 00:00 enden",
|
||||||
|
"gap": "Lücke zwischen dieser und der vorigen Rate",
|
||||||
|
"overlap": "Zeitraum der Rate überlappt mit einer anderen",
|
||||||
|
"startTimeFirst": "Erster Basal des Tages muss um 00:00 beginnen"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"basalProfile": {
|
||||||
|
"activated": "{profileName} wurde als aktives Profil ausgewählt",
|
||||||
|
"active": "Derzeit aktives Profil",
|
||||||
|
"confirmDelete": "Willst du dieseBasal Profile?",
|
||||||
|
"copied": "Kopie von {profileName} hinzugefügt",
|
||||||
|
"copyOf": "Kopie von {profileName}",
|
||||||
|
"default": "Standard-Profil",
|
||||||
|
"deleted": "Basalprofil gelöscht",
|
||||||
|
"detail": {
|
||||||
|
"tabs": {
|
||||||
|
"profile": "Profil",
|
||||||
|
"rates": "Raten"
|
||||||
|
},
|
||||||
|
"title": "{status} Basalprofil {profileName}"
|
||||||
|
},
|
||||||
|
"empty": "Du hast noch kein Basalprofil erstellt!",
|
||||||
|
"fields": {
|
||||||
|
"active": "aktiv",
|
||||||
|
"name": "Name",
|
||||||
|
"notes": "Bemerkung",
|
||||||
|
"validators": {
|
||||||
|
"name": "Name ist leer"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"new": "Neues",
|
||||||
|
"saved": "{status}Basalprofil gespeichert",
|
||||||
|
"title": "Basalprofile",
|
||||||
|
"warnings": {
|
||||||
|
"activeAlreadySet": "Es gibt bereits ein oder mehrere aktive Profile. Was möchtest du tun?",
|
||||||
|
"multipleActive": "Mehr als ein aktives Profil.",
|
||||||
|
"noActive": "Kein aktives Basalprofil.",
|
||||||
|
"noActiveOnCreate": "Im Moment ist kein Profil aktiv. Möchtest du dieses aktivieren?",
|
||||||
|
"resolve": {
|
||||||
|
"activate": "Profil aktivieren",
|
||||||
|
"activateCurrent": "Dieses Profil aktivieren",
|
||||||
|
"create": "Profil erstellen",
|
||||||
|
"createInstead": "Stattdessen neues Profil erstellen",
|
||||||
|
"deactivateOthers": "Alle anderen deaktivieren",
|
||||||
|
"deactivateProfile": "{profileName} deaktivieren",
|
||||||
|
"ignore": "Ignorierem",
|
||||||
|
"pick": "Wähle ein Profil"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"bolus": {
|
||||||
|
"confirmDelete": "Willst du diese Bolusrate wirklich löschen?",
|
||||||
|
"deleted": "Bolusrate gelöscht",
|
||||||
|
"empty": "Du hast noch keine Bolusraten erstellt!",
|
||||||
|
"fields": {
|
||||||
|
"endTime": "Endzeit",
|
||||||
|
"perCarbs": "pro KH",
|
||||||
|
"perGlucose": "pro {glucoseMeasurementSuffix}",
|
||||||
|
"startTime": "Startzeit",
|
||||||
|
"units": "Einheiten"
|
||||||
|
},
|
||||||
|
"new": "Neue",
|
||||||
|
"saved": {
|
||||||
|
"1": "{status}Bolusrate gespeichert",
|
||||||
|
"else": "{status}Bolusraten gespeichert"
|
||||||
|
},
|
||||||
|
"title": "{status} Bolusrate für {profileName}",
|
||||||
|
"warnings": {
|
||||||
|
"duplicate": "Es gibt bereits eine Rate mit dieser Startzeit.",
|
||||||
|
"endTimeLast": "Letzter Bolus des Tages muss um 00:00 enden",
|
||||||
|
"gap": "Lücke zwischen dieser und der vorigen Rate",
|
||||||
|
"overlap": "Zeitraum der Rate überlappt mit einer anderen",
|
||||||
|
"startTimeFirst": "Erster Bolus des Tages muss um 00:00 beginnen"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"bolusProfile": {
|
||||||
|
"activated": "{profileName} wurde als aktives Profil ausgewählt",
|
||||||
|
"active": "Derzeit aktives Profil",
|
||||||
|
"confirmDelete": "Willst du dieses Boluspofil wirklich löschen?",
|
||||||
|
"copied": "Kopie von {profileName} hinzugefügt",
|
||||||
|
"copyOf": "Kopie von {profileName}",
|
||||||
|
"default": "Standardprofil",
|
||||||
|
"deleted": "Bolusprofil gelöscht",
|
||||||
|
"detail": {
|
||||||
|
"tabs": {
|
||||||
|
"profile": "Profil",
|
||||||
|
"rates": "Raten"
|
||||||
|
},
|
||||||
|
"title": "{status} Bolusprofil {profileName}"
|
||||||
|
},
|
||||||
|
"empty": "Du hast noch keine Bolusprofile erstellt!",
|
||||||
|
"fields": {
|
||||||
|
"active": "aktiv",
|
||||||
|
"name": "Name",
|
||||||
|
"notes": "Bemerkung",
|
||||||
|
"validators": {
|
||||||
|
"name": "Bezeichnung ist leer"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"new": "Neues",
|
||||||
|
"saved": "{status}Bolusprofil gespeichert",
|
||||||
|
"title": "Bolusprofile",
|
||||||
|
"warnings": {
|
||||||
|
"activeAlreadySet": "Es gibt bereits ein oder mehrere aktive Profile. Was möchtest du tun?",
|
||||||
|
"multipleActive": "Mehr als ein aktives Profil.",
|
||||||
|
"noActive": "Kein aktives Bolusprofil.",
|
||||||
|
"noActiveOnCreate": "Im Moment ist kein Profil aktiv. Möchtest du dieses aktivieren?",
|
||||||
|
"resolve": {
|
||||||
|
"activate": "Profil aktivieren",
|
||||||
|
"activateCurrent": "Dieses Profil aktivieren",
|
||||||
|
"create": "Profil erstellen",
|
||||||
|
"createInstead": "Stattdessen neues Profil erstellen",
|
||||||
|
"deactivateOthers": "Alle anderen deaktivieren",
|
||||||
|
"deactivateProfile": "{profileName} deaktivieren",
|
||||||
|
"ignore": "Ignorierem",
|
||||||
|
"pick": "Wähle ein Profil"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"categories": "Kategorien",
|
||||||
|
"event": {
|
||||||
|
"confirmDelete": "Willst du dieses Ereignis wirklich löschen?",
|
||||||
|
"confirmEnd": "Willst du dieses Ereignis wirklich beenden?",
|
||||||
|
"deleted": "Log-Ereignis gelöscht",
|
||||||
|
"detail": {
|
||||||
|
"title": "{status} Log-Ereignis {name}"
|
||||||
|
},
|
||||||
|
"empty": "Kkeine Ereigniss für dieses Datum!",
|
||||||
|
"emptyActive": "Keine aktiven Ereignisse!",
|
||||||
|
"end": "Ereignis beenden",
|
||||||
|
"ended": "Log-Ereignis beendet",
|
||||||
|
"fields": {
|
||||||
|
"basalProfile": "Basalprofil",
|
||||||
|
"bolusProfile": "Bolusprofil",
|
||||||
|
"date": "Datum",
|
||||||
|
"endDate": "Enddatum",
|
||||||
|
"endTime": "Endzeit",
|
||||||
|
"eventType": "Ereignis-Typ",
|
||||||
|
"hasEndTime": "hat Endzeitpunkt",
|
||||||
|
"notes": "Bemerkung",
|
||||||
|
"reminderDuration": "Dauer für Erinnerung",
|
||||||
|
"startDate": "Startdatum",
|
||||||
|
"startTime": "Startzeit",
|
||||||
|
"time": "Zeit"
|
||||||
|
},
|
||||||
|
"new": "Neues",
|
||||||
|
"saved": "{status}Log-Ereignis gespeichert",
|
||||||
|
"title": "Log-Ereignisse",
|
||||||
|
"titleActive": "Aktive Ereignisse",
|
||||||
|
"warnings": {
|
||||||
|
"duplicate": "Im angegebenen Zeitraum gibt es bereits ein aktives Ereignis vom selben Typ. Was möchtest du tun?"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"eventType": {
|
||||||
|
"deleted": "Log-Ereignis-Typ gelöscht",
|
||||||
|
"detail": {
|
||||||
|
"title": "{status} Log-Ereignis-Typ {name}"
|
||||||
|
},
|
||||||
|
"empty": "Du hast noch keine Log-Ereignis-Typen erstellt!",
|
||||||
|
"fields": {
|
||||||
|
"basalProfile": "Basalprofil",
|
||||||
|
"bolusProfile": "Bolusprofil",
|
||||||
|
"defaultReminderDuration": "Standarddauer für Erinnerung",
|
||||||
|
"hasEndTime": "hat Endzeitpunkt",
|
||||||
|
"name": "Name",
|
||||||
|
"notes": "Bemerkung",
|
||||||
|
"validators": {
|
||||||
|
"name": "Name ist leer"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"new": "Neuer",
|
||||||
|
"saved": "{status}Log-Ereignis-Typ gespeichert",
|
||||||
|
"title": "Log-Ereignis-Typen"
|
||||||
|
},
|
||||||
|
"export": {
|
||||||
|
"error": "Error beim Import der folgenden Daten: {data}"
|
||||||
|
},
|
||||||
|
"general": {
|
||||||
|
"apply": "Anwenden",
|
||||||
|
"cancel": "Abbrechen",
|
||||||
|
"close": "Schließen",
|
||||||
|
"confirm": "Bestätigen",
|
||||||
|
"confirmDelete": "Willst du diesen Eintrag wirklich löschen?",
|
||||||
|
"confirmDiscard": "Änderungen wurden bereits vorgenommen. Eingaben verwerfen?",
|
||||||
|
"discard": "Verwerfen",
|
||||||
|
"edit": "Bearbeiten",
|
||||||
|
"example": "Beispiel",
|
||||||
|
"keepEditing": "Weiter bearbeiten",
|
||||||
|
"next": "Weiter",
|
||||||
|
"per": "pro",
|
||||||
|
"save": "Speichern",
|
||||||
|
"saveAndClose": "Speichern & Schließen",
|
||||||
|
"saveAsIs": "Aktuellen Stand speichern",
|
||||||
|
"suffixes": {
|
||||||
|
"carbs": "{nutritionMeasurement} KH",
|
||||||
|
"carbsPerU": "{nutritionMeasurementSuffix} KH pro E",
|
||||||
|
"mins": " min",
|
||||||
|
"perDay": "am Tag",
|
||||||
|
"units": "E",
|
||||||
|
"uPerBreadUnit": "E pro BE",
|
||||||
|
"uPerGlucose": "{glucoseMeasurementSuffix} pro Einheit"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"log": {
|
||||||
|
"confirmDelete": "Willst du diesen Logeintrag wirklich löschen?",
|
||||||
|
"deleted": "Logeintrag gelöscht",
|
||||||
|
"empty": "Du hast noch keine Logeinträge für dieses Datum erstellt!",
|
||||||
|
"fields": {
|
||||||
|
"date": "Datum",
|
||||||
|
"glucose": "Blutzucker",
|
||||||
|
"time": "Zeit"
|
||||||
|
},
|
||||||
|
"filter": {
|
||||||
|
"endDate": "Endzeit",
|
||||||
|
"maxGlucose": "max. {glucoseMeasurement}",
|
||||||
|
"meal": "Mahlzeit",
|
||||||
|
"mealNameContains": "Name der Mahlzeit enthält",
|
||||||
|
"minGlucose": "min. {glucoseMeasurement}",
|
||||||
|
"noteContains": "Bemerkung enthält",
|
||||||
|
"startDate": "Startzeit"
|
||||||
|
},
|
||||||
|
"saved": "{status}Logeintrag gespeichert",
|
||||||
|
"tabs": {
|
||||||
|
"bolus": {
|
||||||
|
"confirmDelete": "Willst du diesen Bolus wirklich löschen?",
|
||||||
|
"delayedBy": "(um {delay} verzögert)",
|
||||||
|
"deleted": "Bolus gelöscht",
|
||||||
|
"detail": {
|
||||||
|
"fields": {
|
||||||
|
"carbs": "KH",
|
||||||
|
"correction": "Korrektur",
|
||||||
|
"current": "Aktuell",
|
||||||
|
"delayedBolus": "Verzögerter Bolus",
|
||||||
|
"delayedBolusDuration": "Dauer Verzögerter Bolus",
|
||||||
|
"forGlucose": "für Blutzucker",
|
||||||
|
"forMeal": "für Mahlzeit",
|
||||||
|
"immediateBolus": "Sofortiger Bolus",
|
||||||
|
"meal": "Mahlzeit",
|
||||||
|
"setManually": "manuall einstellen",
|
||||||
|
"target": "Zielwert",
|
||||||
|
"units": "Bolus-Einheiten"
|
||||||
|
},
|
||||||
|
"title": "{status} Bolus"
|
||||||
|
},
|
||||||
|
"empty": "Du hast noch keine Boli für diesen Logeintrag erstellt!",
|
||||||
|
"forMeal": "für {meal}",
|
||||||
|
"new": "Neuer",
|
||||||
|
"saved": "{status}Bolus gespeichert",
|
||||||
|
"title": "Boli",
|
||||||
|
"toCorrect": "zur Korrektur von {correction}"
|
||||||
|
},
|
||||||
|
"general": "Allgemein",
|
||||||
|
"meal": {
|
||||||
|
"confirmDelete": "Willst du diese Mahlzeit wirklich löschen?",
|
||||||
|
"deleted": "Mahlzeit gelöscht",
|
||||||
|
"detail": {
|
||||||
|
"fields": {
|
||||||
|
"amount": "Menge",
|
||||||
|
"carbsRatio": "KH-Verhältnis",
|
||||||
|
"carbsRatioAccuracy": "Präzision KH-Verhältnis",
|
||||||
|
"meal": "Mahlzeit",
|
||||||
|
"mealCategory": "Kategorie",
|
||||||
|
"mealPortionType": "Portionstyp",
|
||||||
|
"mealSource": "Herkunft",
|
||||||
|
"name": "Name",
|
||||||
|
"notes": "Bemerkung",
|
||||||
|
"portionSize": "Portionsgröße",
|
||||||
|
"portionSizeAccuracy": "Präzision Portionsgröße",
|
||||||
|
"setManually": "KH-Verhältnis manuell einstellen",
|
||||||
|
"validators": {
|
||||||
|
"name": "Name ist leer"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"title": "{status} Mahlzeit"
|
||||||
|
},
|
||||||
|
"empty": "Du hast noch keine Mahlzeiten für diesen Logeintrag erstellt!",
|
||||||
|
"new": "Neue",
|
||||||
|
"saved": "{status}Mahlzeit gespeichert",
|
||||||
|
"title": "Mahlzeiten"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"title": "Logeinträge"
|
||||||
|
},
|
||||||
|
"meal": {
|
||||||
|
"confirmDelete": "Willst du diese Mahlzeit wirklich löschen?",
|
||||||
|
"deleted": "Mahlzeit gelöscht",
|
||||||
|
"detail": {
|
||||||
|
"title": "{status} Mahlzeit {name}"
|
||||||
|
},
|
||||||
|
"empty": "Du hast noch keine Mahlzeiten erstellt!",
|
||||||
|
"fields": {
|
||||||
|
"additional": {
|
||||||
|
"carbsRatioAccuracy": "Präzision KH-Verhältnis",
|
||||||
|
"mealCategory": "Kategorie",
|
||||||
|
"portionSizeAccuracy": "Präzision Portionsgröße",
|
||||||
|
"title": "Zusätzliche Felder"
|
||||||
|
},
|
||||||
|
"carbsPerPortion": "KH pro Portion",
|
||||||
|
"carbsRatio": "KH-Verhältnis",
|
||||||
|
"delay": {
|
||||||
|
"duration": "Dauer",
|
||||||
|
"title": "Verzögerter Bolus"
|
||||||
|
},
|
||||||
|
"mealPortionType": "Portionstyp",
|
||||||
|
"mealSource": "Herkunft",
|
||||||
|
"name": "Name",
|
||||||
|
"notes": "Bemerkung",
|
||||||
|
"portionSize": "Portionsgröße",
|
||||||
|
"setManually": "KH-Verhältnis manuell einstellen",
|
||||||
|
"validators": {
|
||||||
|
"name": "Name ist leer"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"new": "Neue",
|
||||||
|
"saved": "{status}Mahlzeit gespeichert",
|
||||||
|
"title": "Mahlzeiten"
|
||||||
|
},
|
||||||
|
"mealCategory": {
|
||||||
|
"deleted": "Mahlzeiten-Kategorie gelöscht",
|
||||||
|
"detail": {
|
||||||
|
"title": "{status} Mahlzeiten-Kategorie {name}"
|
||||||
|
},
|
||||||
|
"empty": "Du hast noch keine Mahlzeiten-Kategorien erstellt!",
|
||||||
|
"fields": {
|
||||||
|
"name": "Name",
|
||||||
|
"notes": "Bemerkung",
|
||||||
|
"validators": {
|
||||||
|
"name": "Name ist leer"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"new": "New",
|
||||||
|
"saved": "{status}Mahlzeiten-Kategorie gespeichert",
|
||||||
|
"title": "Mahlzeiten-Kategorien"
|
||||||
|
},
|
||||||
|
"mealSource": {
|
||||||
|
"deleted": "Mahlzeiten-Herkunft gelöscht",
|
||||||
|
"detail": {
|
||||||
|
"title": "{status} Mahlzeiten-Herkunft {name}"
|
||||||
|
},
|
||||||
|
"empty": "Du hast noch keine Mahlzeiten-Herkünfte erstellt!",
|
||||||
|
"fields": {
|
||||||
|
"defaultCarbsRatioAccuracy": "Standard-Präzision KH-Verhältnis",
|
||||||
|
"defaultMealCategory": "Standard Mahlzeiten-Kategorie",
|
||||||
|
"defaultMealPortionType": "Standard-Portionstyp",
|
||||||
|
"defaultPortionSizeAccuracy": "Standard-Präzision Portionsgröße",
|
||||||
|
"name": "Name",
|
||||||
|
"notes": "Bemerkung",
|
||||||
|
"validators": {
|
||||||
|
"name": "Name ist leer"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"new": "New",
|
||||||
|
"saved": "{status}Mahlzeiten-Herkunft gespeichert",
|
||||||
|
"title": "Mahlzeiten-Herkünfte"
|
||||||
|
},
|
||||||
|
"navigation": {
|
||||||
|
"basalProfiles": "Basalprofile",
|
||||||
|
"bolusProfiles": "Bolusprofile",
|
||||||
|
"categorization": "Kategorisierung",
|
||||||
|
"log": "Log",
|
||||||
|
"logEvent": "Log-Ereignisse",
|
||||||
|
"meals": "Mahlzeiten",
|
||||||
|
"reports": "Berichte",
|
||||||
|
"settings": "Einstellungen"
|
||||||
|
},
|
||||||
|
"portionType": {
|
||||||
|
"deleted": "Mahlzeiten-Portionstyp gelöscht",
|
||||||
|
"detail": {
|
||||||
|
"title": "{status} Mahlzeiten-Portionstyp {name}"
|
||||||
|
},
|
||||||
|
"empty": "Du hast noch keine Mahlzeiten-Portionstypen erstellt!",
|
||||||
|
"fields": {
|
||||||
|
"name": "Name",
|
||||||
|
"notes": "Bemerkung",
|
||||||
|
"validators": {
|
||||||
|
"name": "Name ist leer"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"new": "New",
|
||||||
|
"saved": "{status}Mahlzeiten-Portionstyp gespeichert",
|
||||||
|
"title": "Mahlzeiten-Portionstypen"
|
||||||
|
},
|
||||||
|
"reports": {
|
||||||
|
"dailyChart": {
|
||||||
|
"empty": "Du hast noch keine Logeinträge für dieses Datum erstellt!",
|
||||||
|
"showBasal": "zeige Basal",
|
||||||
|
"showBolus": "zeige Bolus",
|
||||||
|
"showChart": "zeige Grafik",
|
||||||
|
"showMeals": "zeige Mahlzeiten",
|
||||||
|
"title": "Tagesgrafik"
|
||||||
|
},
|
||||||
|
"export": {
|
||||||
|
"date": "Datum",
|
||||||
|
"delayedBy": "(um {delay} verzögert)",
|
||||||
|
"endDate": "Enddatum",
|
||||||
|
"export": "exportieren",
|
||||||
|
"range": "Zeitraum",
|
||||||
|
"showBasal": "zeige Basal",
|
||||||
|
"showBolus": "zeige Bolus",
|
||||||
|
"showChart": "zeige Grafik",
|
||||||
|
"showMahlzeits": "zeige Mahlzeiten",
|
||||||
|
"showTable": "zeige Tabelle",
|
||||||
|
"singleDate": "Bestimmtes Datum",
|
||||||
|
"tableHeaders": {
|
||||||
|
"bolus": "Bolus",
|
||||||
|
"carbs": "Kohlenhydrate",
|
||||||
|
"glucose": "Blutzucker",
|
||||||
|
"mealBolus": "Mahlzeit Bolus",
|
||||||
|
"mealBemerkung": "Mahlzeit Bemerkung",
|
||||||
|
"meals": "Mahlzeit",
|
||||||
|
"notes": "Bemerkung",
|
||||||
|
"portionSize": "Portionsgröße",
|
||||||
|
"time": "Zeit"
|
||||||
|
},
|
||||||
|
"title": "Log-Übersicht"
|
||||||
|
},
|
||||||
|
"ids": {
|
||||||
|
"basal": "Basal",
|
||||||
|
"bolus": "Bolus",
|
||||||
|
"carbs": "Kohlenhydrate",
|
||||||
|
"glucose": "Blutzucker"
|
||||||
|
},
|
||||||
|
"sections": {
|
||||||
|
"dailyReport": "Tagesbericht",
|
||||||
|
"pdfReport": "PDF-Übersicht"
|
||||||
|
},
|
||||||
|
"title": "Berichte"
|
||||||
|
},
|
||||||
|
"settings": {
|
||||||
|
"confirmReset": "Bist du sicher, dass du alle Einstellungen zurücksetzen möchtest?",
|
||||||
|
"fields": {
|
||||||
|
"confirmOnCancel": "beim Abbrechen der Bearbeitung eines Eintrags, wenn bereits Änderungen vorgenommen wurden",
|
||||||
|
"confirmOnDelete": "beim Löschen eines Eintrags",
|
||||||
|
"confirmOnEndEreignis": "beim Beenden eines Ereignisses",
|
||||||
|
"dateformat": "Datumsformat",
|
||||||
|
"displayBothDetail": "zeige beide Blutzucker-Maßeinheiten in der Detailansicht",
|
||||||
|
"displayBothList": "display both glucose measurements in list view",
|
||||||
|
"glucoseMeasurement": "Bevorzugte Maßeinheit für Blutzuckerwerte",
|
||||||
|
"insulinIncrement": "Insulin-Dosierungsschritte",
|
||||||
|
"longDateformat": "Datumsformat lang",
|
||||||
|
"longTimeformat": "Zeitformat lang",
|
||||||
|
"mmolLIncrement": "Schritte Mmol/l",
|
||||||
|
"nutritionIncrement": "Schritte Maßeinheit für Mahlzeiten",
|
||||||
|
"nutritionMeasurement": "Bevorzugte Maßeinheit für Mahlzeiten",
|
||||||
|
"onlyDisplayActive": "zeige nur aktive Blutzucker-Maßeinheit",
|
||||||
|
"targetGlucose": "Ziel-Blutzucker",
|
||||||
|
"timeformat": "Zeitformat"
|
||||||
|
},
|
||||||
|
"reset": "Einstellungen wurden auf Standardeinstellungen zurückgesetzt",
|
||||||
|
"resetAll": "Alle zurücksetzen",
|
||||||
|
"sections": {
|
||||||
|
"confirmation": "Bestätigungen",
|
||||||
|
"dateTimeformat": "Zeit- und Datumsformat",
|
||||||
|
"measurements": "Maßeinheiten"
|
||||||
|
},
|
||||||
|
"title": "Applikationseinstellungen",
|
||||||
|
"updated": "Einstellungen gespeichert"
|
||||||
|
}
|
||||||
|
}
|
501
assets/i18n/en.json
Normal file
501
assets/i18n/en.json
Normal file
@ -0,0 +1,501 @@
|
|||||||
|
{
|
||||||
|
"accuracy": {
|
||||||
|
"confirmDelete": "Are you sure you want to delete this Accuracy?",
|
||||||
|
"deleted": "Accuracy deleted",
|
||||||
|
"detail": {
|
||||||
|
"title": "{status} Accuracy"
|
||||||
|
},
|
||||||
|
"empty": "You have not created any Accuracies yet!",
|
||||||
|
"fields": {
|
||||||
|
"confidenceRating": "Confidence Rating",
|
||||||
|
"forCarbsRatio": "for Carbs Ratio",
|
||||||
|
"forPortionSize": "for Portion Size",
|
||||||
|
"name": "Name",
|
||||||
|
"notes": "Notes",
|
||||||
|
"validators": {
|
||||||
|
"name": "Empty Name"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"new": "New",
|
||||||
|
"saved": {
|
||||||
|
"1": "{status}Accuracy saved",
|
||||||
|
"else": "{status}Accuracy saved"
|
||||||
|
},
|
||||||
|
"title": "Accuracies"
|
||||||
|
},
|
||||||
|
"basal": {
|
||||||
|
"confirmDelete": "Are you sure you want to delete this Basal Rate?",
|
||||||
|
"deleted": "Basal Rate deleted",
|
||||||
|
"empty": "You have not created any Basal Rates yet!",
|
||||||
|
"fields": {
|
||||||
|
"endTime": "End Time",
|
||||||
|
"startTime": "Start Time",
|
||||||
|
"units": "Units"
|
||||||
|
},
|
||||||
|
"new": "New",
|
||||||
|
"saved": {
|
||||||
|
"1": "{status}Basal Rate saved",
|
||||||
|
"else": "{status}Basal Rates saved"
|
||||||
|
},
|
||||||
|
"title": "{status} Basal Rate for {profileName}",
|
||||||
|
"warnings": {
|
||||||
|
"duplicate": "There's already a rate with this start time.",
|
||||||
|
"endTimeLast": "Last Basal of the day needs to end at 00:00",
|
||||||
|
"gap": "There's a time gap between this and the previous rate",
|
||||||
|
"overlap": "This rate's time period overlaps with another one.",
|
||||||
|
"startTimeFirst": "First Basal of the day needs to start at 00:00"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"basalProfile": {
|
||||||
|
"activated": "{profileName} has been set as your active Profile",
|
||||||
|
"active": "Current Active Profile",
|
||||||
|
"confirmDelete": "Are you sure you want to delete this Basal Profile?",
|
||||||
|
"copied": "Added copy of {profileName}",
|
||||||
|
"copyOf": "Copy of {profileName}",
|
||||||
|
"default": "Default Profile",
|
||||||
|
"deleted": "Basal Profile deleted",
|
||||||
|
"detail": {
|
||||||
|
"tabs": {
|
||||||
|
"profile": "Profile",
|
||||||
|
"rates": "Rates"
|
||||||
|
},
|
||||||
|
"title": "{status} Basal Profile {profileName}"
|
||||||
|
},
|
||||||
|
"empty": "You have not created any Basal Profiles yet!",
|
||||||
|
"fields": {
|
||||||
|
"active": "active",
|
||||||
|
"name": "Name",
|
||||||
|
"notes": "Notes",
|
||||||
|
"validators": {
|
||||||
|
"name": "Empty title"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"new": "New",
|
||||||
|
"saved": "{status}Basal Profile saved",
|
||||||
|
"title": "Basal Profiles",
|
||||||
|
"warnings": {
|
||||||
|
"activeAlreadySet": "There are already one or more active profiles. What would you like to do?",
|
||||||
|
"multipleActive": "More than one active Basal Profile has been found.",
|
||||||
|
"noActive": "You currently do not have an active Basal Profile.",
|
||||||
|
"noActiveOnCreate": "There is currently no active profile. Would you like to set this one as active?",
|
||||||
|
"resolve": {
|
||||||
|
"activate": "Activate a Profile",
|
||||||
|
"activateCurrent": "Activate This Profile",
|
||||||
|
"create": "Create a Profile",
|
||||||
|
"createInstead": "Create a New Profile Instead",
|
||||||
|
"deactivateOthers": "Deactivate All Others",
|
||||||
|
"deactivateProfile": "Deactivate {profileName}",
|
||||||
|
"ignore": "Ignore",
|
||||||
|
"pick": "Pick a Profile"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"bolus": {
|
||||||
|
"confirmDelete": "Are you sure you want to delete this Bolus Rate?",
|
||||||
|
"deleted": "Bolus Rate deleted",
|
||||||
|
"empty": "You have not created any Bolus Rates yet!",
|
||||||
|
"fields": {
|
||||||
|
"endTime": "End Time",
|
||||||
|
"perCarbs": "per carns",
|
||||||
|
"perGlucose": "per {glucoseMeasurementSuffix}",
|
||||||
|
"startTime": "Start Time",
|
||||||
|
"units": "Units"
|
||||||
|
},
|
||||||
|
"new": "New",
|
||||||
|
"saved": {
|
||||||
|
"1": "{status}Bolus Rate saved",
|
||||||
|
"else": "{status}Bolus Rates saved"
|
||||||
|
},
|
||||||
|
"title": "{status} Bolus Rate for {profileName}",
|
||||||
|
"warnings": {
|
||||||
|
"duplicate": "There's already a rate with this start time.",
|
||||||
|
"endTimeLast": "Last Bolus of the day needs to end at 00:00",
|
||||||
|
"gap": "There's a time gap between this and the previous rate",
|
||||||
|
"overlap": "This rate's time period overlaps with another one.",
|
||||||
|
"startTimeFirst": "First Bolus of the day needs to start at 00:00"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"bolusProfile": {
|
||||||
|
"activated": "{profileName} has been set as your active Profile",
|
||||||
|
"active": "Current Active Profile",
|
||||||
|
"confirmDelete": "Are you sure you want to delete this Bolus Profile?",
|
||||||
|
"copied": "Added copy of {profileName}",
|
||||||
|
"copyOf": "Copy of {profileName}",
|
||||||
|
"default": "Default Profile",
|
||||||
|
"deleted": "Bolus Profile deleted",
|
||||||
|
"detail": {
|
||||||
|
"tabs": {
|
||||||
|
"profile": "Profile",
|
||||||
|
"rates": "Rates"
|
||||||
|
},
|
||||||
|
"title": "{status} Bolus Profile {profileName}"
|
||||||
|
},
|
||||||
|
"empty": "You have not created any Bolus Profiles yet!",
|
||||||
|
"fields": {
|
||||||
|
"active": "active",
|
||||||
|
"name": "Name",
|
||||||
|
"notes": "Notes",
|
||||||
|
"validators": {
|
||||||
|
"name": "Empty title"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"new": "New",
|
||||||
|
"saved": "{status}Bolus Profile saved",
|
||||||
|
"title": "Bolus Profiles",
|
||||||
|
"warnings": {
|
||||||
|
"activeAlreadySet": "There are already one or more active profiles. What would you like to do?",
|
||||||
|
"multipleActive": "More than one active Bolus Profile has been found.",
|
||||||
|
"noActive": "You currently do not have an active Bolus Profile.",
|
||||||
|
"noActiveOnCreate": "There is currently no active profile. Would you like to set this one as active?",
|
||||||
|
"resolve": {
|
||||||
|
"activate": "Activate a Profile",
|
||||||
|
"activateCurrent": "Activate This Profile",
|
||||||
|
"create": "Create a Profile",
|
||||||
|
"createInstead": "Create a New Profile Instead",
|
||||||
|
"deactivateOthers": "Deactivate All Others",
|
||||||
|
"deactivateProfile": "Deactivate {profileName}",
|
||||||
|
"ignore": "Ignore",
|
||||||
|
"pick": "Pick a Profile"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"categories": "Categories",
|
||||||
|
"event": {
|
||||||
|
"confirmDelete": "Are you sure you want to delete this Log Event?",
|
||||||
|
"confirmEnd": "Are you sure you want to end this Event?",
|
||||||
|
"deleted": "Log Event deleted",
|
||||||
|
"detail": {
|
||||||
|
"title": "{status} Log Event {name}"
|
||||||
|
},
|
||||||
|
"empty": "There are no Events for that date!",
|
||||||
|
"emptyActive": "There are no Active Events!",
|
||||||
|
"end": "End Event",
|
||||||
|
"ended": "Log Event ended",
|
||||||
|
"fields": {
|
||||||
|
"basalProfile": "Basal Profile",
|
||||||
|
"bolusProfile": "Bolus Profile",
|
||||||
|
"date": "Date",
|
||||||
|
"endDate": "End Date",
|
||||||
|
"endTime": "End Time",
|
||||||
|
"eventType": "Event Type",
|
||||||
|
"hasEndTime": "has end time",
|
||||||
|
"notes": "Notes",
|
||||||
|
"reminderDuration": "Reminder Duration",
|
||||||
|
"startDate": "Start Date",
|
||||||
|
"startTime": "Start Time",
|
||||||
|
"time": "Time"
|
||||||
|
},
|
||||||
|
"new": "New",
|
||||||
|
"saved": "{status}Log Event saved",
|
||||||
|
"title": "Log Events",
|
||||||
|
"titleActive": "Active Events",
|
||||||
|
"warnings": {
|
||||||
|
"duplicate": "An Event of this type is already active within the set time frame. What would you like to do?"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"eventType": {
|
||||||
|
"deleted": "Log Event Type deleted",
|
||||||
|
"detail": {
|
||||||
|
"title": "{status} Log Event Type {name}"
|
||||||
|
},
|
||||||
|
"empty": "You have not created any Log Event Types yet!",
|
||||||
|
"fields": {
|
||||||
|
"basalProfile": "Basal Profile",
|
||||||
|
"bolusProfile": "Bolus Profile",
|
||||||
|
"defaultReminderDuration": "Default Reminder Duration",
|
||||||
|
"hasEndTime": "has end time",
|
||||||
|
"name": "Name",
|
||||||
|
"notes": "Notes",
|
||||||
|
"validators": {
|
||||||
|
"name": "Empty name"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"new": "New",
|
||||||
|
"saved": "{status}Log Event Type saved",
|
||||||
|
"title": "Log Event Types"
|
||||||
|
},
|
||||||
|
"export": {
|
||||||
|
"error": "Error importing the following data: {data}"
|
||||||
|
},
|
||||||
|
"general": {
|
||||||
|
"apply": "Apply",
|
||||||
|
"cancel": "Cancel",
|
||||||
|
"close": "Close",
|
||||||
|
"confirm": "Confirm",
|
||||||
|
"confirmDelete": "Are you sure you want to delete this record?",
|
||||||
|
"confirmDiscard": "You already made some changes. Discard your input?",
|
||||||
|
"discard": "Discard",
|
||||||
|
"edit": "Edit",
|
||||||
|
"example": "Example",
|
||||||
|
"keepEditing": "Keep Editing",
|
||||||
|
"next": "Next",
|
||||||
|
"per": "per",
|
||||||
|
"save": "Save",
|
||||||
|
"saveAndClose": "Save & Close",
|
||||||
|
"saveAsIs": "Save As Is",
|
||||||
|
"suffixes": {
|
||||||
|
"carbs": "{nutritionMeasurement} carbs",
|
||||||
|
"carbsPerU": "{nutritionMeasurementSuffix} carbs per U",
|
||||||
|
"mins": " min",
|
||||||
|
"perDay": "per day",
|
||||||
|
"units": "U",
|
||||||
|
"uPerBreadUnit": "U per bread unit",
|
||||||
|
"uPerGlucose": "{glucoseMeasurementSuffix} per unit"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"log": {
|
||||||
|
"confirmDelete": "Are you sure you want to delete this Log Entry?",
|
||||||
|
"deleted": "Log Entry deleted",
|
||||||
|
"empty": "You have not created any Log Entries for this date yet!",
|
||||||
|
"fields": {
|
||||||
|
"date": "Date",
|
||||||
|
"glucose": "Blood Glucose",
|
||||||
|
"time": "Time"
|
||||||
|
},
|
||||||
|
"filter": {
|
||||||
|
"endDate": "End Date",
|
||||||
|
"maxGlucose": "max {glucoseMeasurement}",
|
||||||
|
"meal": "Meal",
|
||||||
|
"mealNameContains": "Meal Name Contains",
|
||||||
|
"minGlucose": "min {glucoseMeasurement}",
|
||||||
|
"noteContains": "Note Contains",
|
||||||
|
"startDate": "Start Date"
|
||||||
|
},
|
||||||
|
"saved": "{status}Log Entry saved",
|
||||||
|
"tabs": {
|
||||||
|
"bolus": {
|
||||||
|
"confirmDelete": "Are you sure you want to delete this Bolus?",
|
||||||
|
"delayedBy": "(delayed by {delay})",
|
||||||
|
"deleted": "Bolus deleted",
|
||||||
|
"detail": {
|
||||||
|
"fields": {
|
||||||
|
"carbs": "Carbs",
|
||||||
|
"correction": "Correction",
|
||||||
|
"current": "Current",
|
||||||
|
"delayedBolus": "Delayed Bolus",
|
||||||
|
"delayedBolusDuration": "Delayed Bolus Duration",
|
||||||
|
"forGlucose": "for glucose",
|
||||||
|
"forMeal": "for meal",
|
||||||
|
"immediateBolus": "Immediate Bolus",
|
||||||
|
"meal": "Meal",
|
||||||
|
"setManually": "set manually",
|
||||||
|
"target": "Target",
|
||||||
|
"units": "Bolus Units"
|
||||||
|
},
|
||||||
|
"title": "{status} Bolus"
|
||||||
|
},
|
||||||
|
"empty": "You have not added any Boli to this Log Entry yet!",
|
||||||
|
"forMeal": "for {meal}",
|
||||||
|
"new": "New",
|
||||||
|
"saved": "{status}Bolus saved",
|
||||||
|
"title": "Boli",
|
||||||
|
"toCorrect": "to correct {correction}"
|
||||||
|
},
|
||||||
|
"general": "General",
|
||||||
|
"meal": {
|
||||||
|
"confirmDelete": "Are you sure you want to delete this Meal?",
|
||||||
|
"deleted": "Meal deleted",
|
||||||
|
"detail": {
|
||||||
|
"fields": {
|
||||||
|
"amount": "Amount",
|
||||||
|
"carbsRatio": "Carbs Ratio",
|
||||||
|
"carbsRatioAccuracy": "Carbs Ratio Accuracy",
|
||||||
|
"meal": "Meal",
|
||||||
|
"mealCategory": "Meal Category",
|
||||||
|
"mealPortionType": "Meal Portion Type",
|
||||||
|
"mealSource": "Meal Source",
|
||||||
|
"name": "Name",
|
||||||
|
"notes": "Notes",
|
||||||
|
"portionSize": "Portion Size",
|
||||||
|
"portionSizeAccuracy": "Portion Size Accuracy",
|
||||||
|
"setManually": "set carbs ratio manually",
|
||||||
|
"validators": {
|
||||||
|
"name": "Empty Name"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"title": "{status} Meal"
|
||||||
|
},
|
||||||
|
"empty": "You have not added any Meals to this Log Entry yet!",
|
||||||
|
"new": "New",
|
||||||
|
"saved": "{status}Meal saved",
|
||||||
|
"title": "Meals"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"title": "Log Entries"
|
||||||
|
},
|
||||||
|
"meal": {
|
||||||
|
"confirmDelete": "Are you sure you want to delete this Meal?",
|
||||||
|
"deleted": "Meal deleted",
|
||||||
|
"detail": {
|
||||||
|
"title": "{status} Meal {name}"
|
||||||
|
},
|
||||||
|
"empty": "You have not created any Meals yet!",
|
||||||
|
"fields": {
|
||||||
|
"additional": {
|
||||||
|
"carbsRatioAccuracy": "Carbs Ratio Accuracy",
|
||||||
|
"mealCategory": "Meal Category",
|
||||||
|
"portionSizeAccuracy": "Portion Size Accuracy",
|
||||||
|
"title": "Additional Fields"
|
||||||
|
},
|
||||||
|
"carbsPerPortion": "Carbs Per Portion",
|
||||||
|
"carbsRatio": "Carbs Ratio",
|
||||||
|
"delay": {
|
||||||
|
"duration": "Duration",
|
||||||
|
"title": "Bolus Delay"
|
||||||
|
},
|
||||||
|
"mealPortionType": "Meal Portion Type",
|
||||||
|
"mealSource": "Meal Source",
|
||||||
|
"name": "Name",
|
||||||
|
"notes": "Notes",
|
||||||
|
"portionSize": "Portion Size",
|
||||||
|
"setManually": "set carbs ratio manually",
|
||||||
|
"validators": {
|
||||||
|
"name": "Empty Name"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"new": "New",
|
||||||
|
"saved": "{status}Meal saved",
|
||||||
|
"title": "Meals"
|
||||||
|
},
|
||||||
|
"mealCategory": {
|
||||||
|
"deleted": "Meal Category deleted",
|
||||||
|
"detail": {
|
||||||
|
"title": "{status} Meal Category {name}"
|
||||||
|
},
|
||||||
|
"empty": "You have not created any Meal Categories yet!",
|
||||||
|
"fields": {
|
||||||
|
"name": "Name",
|
||||||
|
"notes": "Notes",
|
||||||
|
"validators": {
|
||||||
|
"name": "Empty name"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"new": "New",
|
||||||
|
"saved": "{status}Meal Category saved",
|
||||||
|
"title": "Meal Categories"
|
||||||
|
},
|
||||||
|
"mealSource": {
|
||||||
|
"deleted": "Meal Source deleted",
|
||||||
|
"detail": {
|
||||||
|
"title": "{status} Meal Source {name}"
|
||||||
|
},
|
||||||
|
"empty": "You have not created any Meal Sources yet!",
|
||||||
|
"fields": {
|
||||||
|
"defaultCarbsRatioAccuracy": "Default Carbs Ratio Accuracy",
|
||||||
|
"defaultMealCategory": "Default Meal Category",
|
||||||
|
"defaultMealPortionType": "Default Meal Portion Type",
|
||||||
|
"defaultPortionSizeAccuracy": "Default Portion Size Accuracy",
|
||||||
|
"name": "Name",
|
||||||
|
"notes": "Notes",
|
||||||
|
"validators": {
|
||||||
|
"name": "Empty name"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"new": "New",
|
||||||
|
"saved": "{status}Meal Source saved",
|
||||||
|
"title": "Meal Sources"
|
||||||
|
},
|
||||||
|
"navigation": {
|
||||||
|
"basalProfiles": "Basal Profiles",
|
||||||
|
"bolusProfiles": "Bolus Profiles",
|
||||||
|
"categorization": "Categorization",
|
||||||
|
"log": "Log",
|
||||||
|
"logEvents": "Log Events",
|
||||||
|
"meals": "Meals",
|
||||||
|
"reports": "Reports",
|
||||||
|
"settings": "Settings"
|
||||||
|
},
|
||||||
|
"portionType": {
|
||||||
|
"deleted": "Meal Portion Type deleted",
|
||||||
|
"detail": {
|
||||||
|
"title": "{status} Meal Portion Type {name}"
|
||||||
|
},
|
||||||
|
"empty": "You have not created any Meal Portion Types yet!",
|
||||||
|
"fields": {
|
||||||
|
"name": "Name",
|
||||||
|
"notes": "Notes",
|
||||||
|
"validators": {
|
||||||
|
"name": "Empty name"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"new": "New",
|
||||||
|
"saved": "{status}Meal Portion Type saved",
|
||||||
|
"title": "Meal Portion Types"
|
||||||
|
},
|
||||||
|
"reports": {
|
||||||
|
"dailyChart": {
|
||||||
|
"empty": "You have not created any Log Entries for this date yet!",
|
||||||
|
"showBasal": "show Basal",
|
||||||
|
"showBolus": "show Bolus",
|
||||||
|
"showChart": "show Chart",
|
||||||
|
"showMeals": "show Meals",
|
||||||
|
"title": "Daily Chart"
|
||||||
|
},
|
||||||
|
"export": {
|
||||||
|
"date": "Date",
|
||||||
|
"delayedBy": "(delayed by {delay})",
|
||||||
|
"endDate": "End Date",
|
||||||
|
"export": "export",
|
||||||
|
"range": "Range",
|
||||||
|
"showBasal": "show Basal",
|
||||||
|
"showBolus": "show Bolus",
|
||||||
|
"showChart": "show Chart",
|
||||||
|
"showMeals": "show Meals",
|
||||||
|
"showTable": "show Table",
|
||||||
|
"singleDate": "Single Date",
|
||||||
|
"tableHeaders": {
|
||||||
|
"bolus": "Bolus",
|
||||||
|
"carbs": "Carbohydrates",
|
||||||
|
"glucose": "Glucose",
|
||||||
|
"mealBolus": "Meal Bolus",
|
||||||
|
"mealNotes": "Meal Notes",
|
||||||
|
"meals": "Meals",
|
||||||
|
"notes": "Notes",
|
||||||
|
"portionSize": "Portion Size",
|
||||||
|
"time": "Time"
|
||||||
|
},
|
||||||
|
"title": "Log Report"
|
||||||
|
},
|
||||||
|
"ids": {
|
||||||
|
"basal": "Basal",
|
||||||
|
"bolus": "Bolus",
|
||||||
|
"carbs": "Carbohydrates",
|
||||||
|
"glucose": "Glucose"
|
||||||
|
},
|
||||||
|
"sections": {
|
||||||
|
"dailyReport": "Daily Report",
|
||||||
|
"pdfReport": "PDF Report"
|
||||||
|
},
|
||||||
|
"title": "Reports"
|
||||||
|
},
|
||||||
|
"settings": {
|
||||||
|
"confirmReset": "Are you sure you want to reset all settings?",
|
||||||
|
"fields": {
|
||||||
|
"confirmOnCancel": "on cancelling edit or creation of a record if changes have already been made",
|
||||||
|
"confirmOnDelete": "on deleting a record",
|
||||||
|
"confirmOnEndEvent": "on stopping (ending) an event",
|
||||||
|
"dateFormat": "Date Format",
|
||||||
|
"displayBothDetail": "display both glucose measurements in detail view",
|
||||||
|
"displayBothList": "display both glucose measurements in list view",
|
||||||
|
"glucoseMeasurement": "Preferred Glucose Measurement",
|
||||||
|
"insulinIncrement": "Insulin Increment",
|
||||||
|
"longDateFormat": "Long Date Format",
|
||||||
|
"longTimeFormat": "Long Time Format",
|
||||||
|
"mmolLIncrement": "Mmol/l Increment",
|
||||||
|
"nutritionIncrement": "Nutrition Increment",
|
||||||
|
"nutritionMeasurement": "Preferred Nutrition Measurement",
|
||||||
|
"onlyDisplayActive": "only display active glucose measurement",
|
||||||
|
"targetGlucose": "Target Glucose",
|
||||||
|
"timeFormat": "Time Format"
|
||||||
|
},
|
||||||
|
"reset": "Settings have been reset to default",
|
||||||
|
"resetAll": "Reset All",
|
||||||
|
"sections": {
|
||||||
|
"confirmation": "Confirmation Prompts",
|
||||||
|
"dateTimeFormat": "Time & Date Format",
|
||||||
|
"measurements": "Measurements"
|
||||||
|
},
|
||||||
|
"title": "Application Settings",
|
||||||
|
"updated": "Settings updated"
|
||||||
|
}
|
||||||
|
}
|
6
build.yaml
Normal file
6
build.yaml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
targets:
|
||||||
|
$default:
|
||||||
|
sources:
|
||||||
|
include:
|
||||||
|
- assets/i18n/**
|
||||||
|
- lib/**
|
@ -291,7 +291,7 @@
|
|||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.example.tide;
|
PRODUCT_BUNDLE_IDENTIFIER = com.example.diameter;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
@ -415,7 +415,7 @@
|
|||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.example.tide;
|
PRODUCT_BUNDLE_IDENTIFIER = com.example.diameter;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
@ -434,7 +434,7 @@
|
|||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.example.tide;
|
PRODUCT_BUNDLE_IDENTIFIER = com.example.diameter;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
<key>CFBundleInfoDictionaryVersion</key>
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
<string>6.0</string>
|
<string>6.0</string>
|
||||||
<key>CFBundleName</key>
|
<key>CFBundleName</key>
|
||||||
<string>tide</string>
|
<string>diameter</string>
|
||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>APPL</string>
|
<string>APPL</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
|
@ -5,7 +5,7 @@ class AppTheme {
|
|||||||
AppTheme._();
|
AppTheme._();
|
||||||
|
|
||||||
static ThemeData lightTheme = FlexColorScheme.light(
|
static ThemeData lightTheme = FlexColorScheme.light(
|
||||||
surfaceStyle: FlexSurface.medium,
|
// surfaceMode: FlexSurfaceMode.level,
|
||||||
scheme: FlexScheme.aquaBlue,
|
scheme: FlexScheme.aquaBlue,
|
||||||
fontFamily: 'Roboto',
|
fontFamily: 'Roboto',
|
||||||
).toTheme;
|
).toTheme;
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
|
import 'package:diameter/localization_keys.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_translate/flutter_translate.dart';
|
||||||
|
|
||||||
class DetailBottomRow extends StatefulWidget {
|
class DetailBottomRow extends StatefulWidget {
|
||||||
final void Function()? onCancel;
|
final void Function()? onCancel;
|
||||||
final void Function()? onAction;
|
final void Function()? onAction;
|
||||||
final void Function()? onMiddleAction;
|
final void Function()? onMiddleAction;
|
||||||
final String actionText;
|
final String actionTextKey;
|
||||||
final String middleActionText;
|
final String middleActionTextKey;
|
||||||
final IconData actionIcon;
|
final IconData actionIcon;
|
||||||
final IconData middleActionIcon;
|
final IconData middleActionIcon;
|
||||||
|
|
||||||
@ -14,9 +16,9 @@ class DetailBottomRow extends StatefulWidget {
|
|||||||
required this.onCancel,
|
required this.onCancel,
|
||||||
required this.onAction,
|
required this.onAction,
|
||||||
this.onMiddleAction,
|
this.onMiddleAction,
|
||||||
this.actionText = 'SAVE',
|
this.actionTextKey = LocalizationKeys.general_save,
|
||||||
this.actionIcon = Icons.save,
|
this.actionIcon = Icons.save,
|
||||||
this.middleActionText = 'SAVE & CLOSE',
|
this.middleActionTextKey = LocalizationKeys.general_saveAndClose,
|
||||||
this.middleActionIcon = Icons.done})
|
this.middleActionIcon = Icons.done})
|
||||||
: super(key: key);
|
: super(key: key);
|
||||||
|
|
||||||
@ -39,7 +41,7 @@ class _DetailBottomRowState<T> extends State<DetailBottomRow> {
|
|||||||
Icons.close,
|
Icons.close,
|
||||||
size: 18.0,
|
size: 18.0,
|
||||||
),
|
),
|
||||||
label: const Text('CANCEL'),
|
label: Text(translate(LocalizationKeys.general_cancel).toUpperCase()),
|
||||||
),
|
),
|
||||||
widget.onMiddleAction != null
|
widget.onMiddleAction != null
|
||||||
? ElevatedButton.icon(
|
? ElevatedButton.icon(
|
||||||
@ -48,7 +50,7 @@ class _DetailBottomRowState<T> extends State<DetailBottomRow> {
|
|||||||
widget.middleActionIcon,
|
widget.middleActionIcon,
|
||||||
size: 18.0,
|
size: 18.0,
|
||||||
),
|
),
|
||||||
label: Text(widget.middleActionText),
|
label: Text(translate(widget.middleActionTextKey)),
|
||||||
)
|
)
|
||||||
: const Spacer(),
|
: const Spacer(),
|
||||||
ElevatedButton.icon(
|
ElevatedButton.icon(
|
||||||
@ -57,7 +59,7 @@ class _DetailBottomRowState<T> extends State<DetailBottomRow> {
|
|||||||
widget.actionIcon,
|
widget.actionIcon,
|
||||||
size: 18.0,
|
size: 18.0,
|
||||||
),
|
),
|
||||||
label: Text(widget.actionText),
|
label: Text(translate(widget.actionTextKey)),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
@ -6,13 +6,15 @@ class TimeOfDayFormField extends StatefulWidget {
|
|||||||
final TextEditingController controller;
|
final TextEditingController controller;
|
||||||
final String label;
|
final String label;
|
||||||
final void Function(TimeOfDay?) onChanged;
|
final void Function(TimeOfDay?) onChanged;
|
||||||
|
final String? Function(String?)? validator;
|
||||||
|
|
||||||
const TimeOfDayFormField(
|
const TimeOfDayFormField(
|
||||||
{Key? key,
|
{Key? key,
|
||||||
required this.time,
|
required this.time,
|
||||||
required this.controller,
|
required this.controller,
|
||||||
required this.label,
|
required this.label,
|
||||||
required this.onChanged})
|
required this.onChanged,
|
||||||
|
this.validator})
|
||||||
: super(key: key);
|
: super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -35,6 +37,7 @@ class _TimeOfDayFormFieldState extends State<TimeOfDayFormField> {
|
|||||||
);
|
);
|
||||||
widget.onChanged(newTime);
|
widget.onChanged(newTime);
|
||||||
},
|
},
|
||||||
|
validator: widget.validator,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
366
lib/data_export.dart
Normal file
366
lib/data_export.dart
Normal file
@ -0,0 +1,366 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:io';
|
||||||
|
import 'package:diameter/localization_keys.dart';
|
||||||
|
import 'package:diameter/models/accuracy.dart';
|
||||||
|
import 'package:diameter/models/basal.dart';
|
||||||
|
import 'package:diameter/models/basal_profile.dart';
|
||||||
|
import 'package:diameter/models/bolus.dart';
|
||||||
|
import 'package:diameter/models/bolus_profile.dart';
|
||||||
|
import 'package:diameter/models/glucose_target.dart';
|
||||||
|
import 'package:diameter/models/log_bolus.dart';
|
||||||
|
import 'package:diameter/models/log_entry.dart';
|
||||||
|
import 'package:diameter/models/log_event.dart';
|
||||||
|
import 'package:diameter/models/log_event_type.dart';
|
||||||
|
import 'package:diameter/models/log_meal.dart';
|
||||||
|
import 'package:diameter/models/meal.dart';
|
||||||
|
import 'package:diameter/models/meal_category.dart';
|
||||||
|
import 'package:diameter/models/meal_portion_type.dart';
|
||||||
|
import 'package:diameter/models/meal_source.dart';
|
||||||
|
import 'package:diameter/models/settings.dart';
|
||||||
|
import 'package:flutter_translate/flutter_translate.dart';
|
||||||
|
// import 'package:flutter/material.dart';
|
||||||
|
import 'package:google_sign_in/google_sign_in.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:path_provider/path_provider.dart';
|
||||||
|
import 'package:http/http.dart' as http;
|
||||||
|
import 'package:googleapis/drive/v3.dart' as drive;
|
||||||
|
|
||||||
|
class GoogleAuthClient extends http.BaseClient {
|
||||||
|
final Map<String, String> _headers;
|
||||||
|
|
||||||
|
final http.Client _client = http.Client();
|
||||||
|
|
||||||
|
GoogleAuthClient(this._headers);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<http.StreamedResponse> send(http.BaseRequest request) {
|
||||||
|
return _client.send(request..headers.addAll(_headers));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DataExport {
|
||||||
|
static Map<String, dynamic> appDataToJson(DateTime timestamp) {
|
||||||
|
final Map<String, dynamic> data = <String, dynamic>{};
|
||||||
|
|
||||||
|
data['exportDate'] = timestamp.toString();
|
||||||
|
data['accuracies'] =
|
||||||
|
Accuracy.box.getAll().map((accuracy) => accuracy.toJson()).toList();
|
||||||
|
data['basalProfiles'] = BasalProfile.box
|
||||||
|
.getAll()
|
||||||
|
.map((basalProfile) => basalProfile.toJson())
|
||||||
|
.toList();
|
||||||
|
data['basalRates'] =
|
||||||
|
Basal.box.getAll().map((basal) => basal.toJson()).toList();
|
||||||
|
data['bolusProfiles'] = BolusProfile.box
|
||||||
|
.getAll()
|
||||||
|
.map((bolusProfile) => bolusProfile.toJson())
|
||||||
|
.toList();
|
||||||
|
data['bolusRates'] =
|
||||||
|
Bolus.box.getAll().map((bolusRates) => bolusRates.toJson()).toList();
|
||||||
|
data['glucoseTargets'] = GlucoseTarget.box
|
||||||
|
.getAll()
|
||||||
|
.map((glucoseTarget) => glucoseTarget.toJson())
|
||||||
|
.toList();
|
||||||
|
data['logBoli'] =
|
||||||
|
LogBolus.box.getAll().map((logBolus) => logBolus.toJson()).toList();
|
||||||
|
data['logEntries'] =
|
||||||
|
LogEntry.box.getAll().map((logEntry) => logEntry.toJson()).toList();
|
||||||
|
data['logEventTypes'] = LogEventType.box
|
||||||
|
.getAll()
|
||||||
|
.map((logEventType) => logEventType.toJson())
|
||||||
|
.toList();
|
||||||
|
data['logEvents'] =
|
||||||
|
LogEvent.box.getAll().map((logEvent) => logEvent.toJson()).toList();
|
||||||
|
data['logMeals'] =
|
||||||
|
LogMeal.box.getAll().map((logMeal) => logMeal.toJson()).toList();
|
||||||
|
data['mealCategories'] = MealCategory.box
|
||||||
|
.getAll()
|
||||||
|
.map((mealCategory) => mealCategory.toJson())
|
||||||
|
.toList();
|
||||||
|
data['mealPortionTypes'] = MealPortionType.box
|
||||||
|
.getAll()
|
||||||
|
.map((mealPortionType) => mealPortionType.toJson())
|
||||||
|
.toList();
|
||||||
|
data['mealSources'] = MealSource.box
|
||||||
|
.getAll()
|
||||||
|
.map((mealSource) => mealSource.toJson())
|
||||||
|
.toList();
|
||||||
|
data['meals'] = Meal.box.getAll().map((meal) => meal.toJson()).toList();
|
||||||
|
data['settings'] = Settings.toJson();
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> appDataFromJson(File file,
|
||||||
|
{String source = '', bool overrideExisting = true, bool skipDeleted = false}) {
|
||||||
|
final Map<String, dynamic> data = json.decode(file.openRead().toString());
|
||||||
|
final List<String> errors = [];
|
||||||
|
|
||||||
|
final exportDate = DateTime.tryParse(data['exportDate']);
|
||||||
|
if (exportDate != null && Settings.lastExportTimeStamp != null && exportDate.isAfter(Settings.lastExportTimeStamp!)) {
|
||||||
|
if (data.keys.contains('accuracies')) {
|
||||||
|
for (var entry in data['accuracies']) {
|
||||||
|
if (!skipDeleted || entry['deleted'] == false) {
|
||||||
|
final error = Accuracy.putFromJson(entry, overrideExisting, source);
|
||||||
|
if (error != null) {
|
||||||
|
errors.add(translate(LocalizationKeys.export_error, args: {"data": entry}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.keys.contains('basalProfiles')) {
|
||||||
|
for (var entry in data['basalProfiles']) {
|
||||||
|
if (!skipDeleted || entry['deleted'] == false) {
|
||||||
|
final error = BasalProfile.putFromJson(entry, overrideExisting, source);
|
||||||
|
if (error != null) {
|
||||||
|
errors.add(translate(LocalizationKeys.export_error, args: {"data": entry}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.keys.contains('basalRates')) {
|
||||||
|
for (var entry in data['basalRates']) {
|
||||||
|
if (!skipDeleted || entry['deleted'] == false) {
|
||||||
|
final error = Basal.putFromJson(entry, overrideExisting, source);
|
||||||
|
if (error != null) {
|
||||||
|
errors.add(translate(LocalizationKeys.export_error, args: {"data": entry}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.keys.contains('bolusRates')) {
|
||||||
|
for (var entry in data['bolusRates']) {
|
||||||
|
if (!skipDeleted || entry['deleted'] == false) {
|
||||||
|
final error = Bolus.putFromJson(entry, overrideExisting, source);
|
||||||
|
if (error != null) {
|
||||||
|
errors.add(translate(LocalizationKeys.export_error, args: {"data": entry}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.keys.contains('glucoseTargets')) {
|
||||||
|
for (var entry in data['glucoseTargets']) {
|
||||||
|
if (!skipDeleted || entry['deleted'] == false) {
|
||||||
|
final error = GlucoseTarget.putFromJson(entry, overrideExisting, source);
|
||||||
|
if (error != null) {
|
||||||
|
errors.add(translate(LocalizationKeys.export_error, args: {"data": entry}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.keys.contains('logBoli')) {
|
||||||
|
for (var entry in data['logBoli']) {
|
||||||
|
if (!skipDeleted || entry['deleted'] == false) {
|
||||||
|
final error = LogBolus.putFromJson(entry, overrideExisting, source);
|
||||||
|
if (error != null) {
|
||||||
|
errors.add(translate(LocalizationKeys.export_error, args: {"data": entry}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.keys.contains('logEntries')) {
|
||||||
|
for (var entry in data['logEntries']) {
|
||||||
|
if (!skipDeleted || entry['deleted'] == false) {
|
||||||
|
final error = LogEntry.putFromJson(entry, overrideExisting, source);
|
||||||
|
if (error != null) {
|
||||||
|
errors.add(translate(LocalizationKeys.export_error, args: {"data": entry}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.keys.contains('logEvents')) {
|
||||||
|
for (var entry in data['logEvents']) {
|
||||||
|
if (!skipDeleted || entry['deleted'] == false) {
|
||||||
|
final error = LogEvent.putFromJson(entry, overrideExisting, source);
|
||||||
|
if (error != null) {
|
||||||
|
errors.add(translate(LocalizationKeys.export_error, args: {"data": entry}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.keys.contains('logMeals')) {
|
||||||
|
for (var entry in data['logMeals']) {
|
||||||
|
if (!skipDeleted || entry['deleted'] == false) {
|
||||||
|
final error = LogMeal.putFromJson(entry, overrideExisting, source);
|
||||||
|
if (error != null) {
|
||||||
|
errors.add(translate(LocalizationKeys.export_error, args: {"data": entry}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.keys.contains('mealCategories')) {
|
||||||
|
for (var entry in data['mealCategories']) {
|
||||||
|
if (!skipDeleted || entry['deleted'] == false) {
|
||||||
|
final error = MealCategory.putFromJson(entry, overrideExisting, source);
|
||||||
|
if (error != null) {
|
||||||
|
errors.add(translate(LocalizationKeys.export_error, args: {"data": entry}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.keys.contains('mealPortionTypes')) {
|
||||||
|
for (var entry in data['mealPortionTypes']) {
|
||||||
|
if (!skipDeleted || entry['deleted'] == false) {
|
||||||
|
final error = MealPortionType.putFromJson(entry, overrideExisting, source);
|
||||||
|
if (error != null) {
|
||||||
|
errors.add(translate(LocalizationKeys.export_error, args: {"data": entry}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.keys.contains('mealSources')) {
|
||||||
|
for (var entry in data['mealSources']) {
|
||||||
|
if (!skipDeleted || entry['deleted'] == false) {
|
||||||
|
final error = MealSource.putFromJson(entry, overrideExisting, source);
|
||||||
|
if (error != null) {
|
||||||
|
errors.add(translate(LocalizationKeys.export_error, args: {"data": entry}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.keys.contains('meals')) {
|
||||||
|
for (var entry in data['meals']) {
|
||||||
|
if (!skipDeleted || entry['deleted'] == false) {
|
||||||
|
final error = Meal.putFromJson(entry, overrideExisting, source);
|
||||||
|
if (error != null) {
|
||||||
|
errors.add(translate(LocalizationKeys.export_error, args: {"data": entry}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// show confirmation dialog because export is newer than last saved timestamp
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<File> exportDataToFile(DateTime timestamp) async {
|
||||||
|
final appDocDir = await getApplicationDocumentsDirectory();
|
||||||
|
final appDocPath = appDocDir.path;
|
||||||
|
|
||||||
|
final DateFormat formatter = DateFormat(DateFormat.YEAR_MONTH_DAY);
|
||||||
|
final date = DateTime.now();
|
||||||
|
final file = File('$appDocPath/diameter_${formatter.format(date)}.json');
|
||||||
|
|
||||||
|
file.writeAsStringSync(json.encode(appDataToJson(timestamp)));
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<void> exportToGoogleDrive() async {
|
||||||
|
final login = GoogleSignIn.standard(scopes: [drive.DriveApi.driveScope]);
|
||||||
|
final GoogleSignInAccount? account = await login.signIn();
|
||||||
|
|
||||||
|
if (account != null) {
|
||||||
|
final authenticateClient = GoogleAuthClient(await account.authHeaders);
|
||||||
|
final driveApi = drive.DriveApi(authenticateClient);
|
||||||
|
|
||||||
|
final timestamp = DateTime.now();
|
||||||
|
var localFile = await DataExport.exportDataToFile(timestamp);
|
||||||
|
var media = drive.Media(localFile.openRead(), localFile.lengthSync());
|
||||||
|
|
||||||
|
final settings = Settings.get();
|
||||||
|
settings.lastExportTimestamp = timestamp;
|
||||||
|
Settings.put(settings);
|
||||||
|
|
||||||
|
drive.File driveFile = drive.File()..name = 'diameter.json';
|
||||||
|
await driveApi.files.create(driveFile, uploadMedia: media);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<void> importFromGoogleDrive() async {
|
||||||
|
final login = GoogleSignIn.standard(scopes: [drive.DriveApi.driveScope]);
|
||||||
|
final GoogleSignInAccount? account = await login.signIn();
|
||||||
|
|
||||||
|
if (account != null) {
|
||||||
|
final authenticateClient = GoogleAuthClient(await account.authHeaders);
|
||||||
|
final driveApi = drive.DriveApi(authenticateClient);
|
||||||
|
|
||||||
|
final timestamp = DateTime.now();
|
||||||
|
var localFile = await DataExport.exportDataToFile(timestamp);
|
||||||
|
var media = drive.Media(localFile.openRead(), localFile.lengthSync());
|
||||||
|
|
||||||
|
final settings = Settings.get();
|
||||||
|
settings.lastExportTimestamp = timestamp;
|
||||||
|
Settings.put(settings);
|
||||||
|
|
||||||
|
drive.File driveFile = drive.File()..name = 'diameter.json';
|
||||||
|
await driveApi.files.create(driveFile, uploadMedia: media);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// class DataExportDialog extends StatefulWidget {
|
||||||
|
// static const String routeName = '/data-export';
|
||||||
|
// const DataExportDialog({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
// @override
|
||||||
|
// _DataExportDialogState createState() => _DataExportDialogState();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// class _DataExportDialogState extends State<DataExportDialog> {
|
||||||
|
// final ScrollController _scrollController = ScrollController();
|
||||||
|
|
||||||
|
// bool _isSaving = false;
|
||||||
|
|
||||||
|
// @override
|
||||||
|
// void dispose() {
|
||||||
|
// _scrollController.dispose();
|
||||||
|
// super.dispose();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// @override
|
||||||
|
// void initState() {
|
||||||
|
// super.initState();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// void onExport(BuildContext context) async {
|
||||||
|
// setState(() {
|
||||||
|
// _isSaving = true;
|
||||||
|
// });
|
||||||
|
|
||||||
|
// Navigator.pop(context);
|
||||||
|
// setState(() {
|
||||||
|
// _isSaving = false;
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
|
// @override
|
||||||
|
// Widget build(BuildContext context) {
|
||||||
|
// return AlertDialog(
|
||||||
|
// content: Column(
|
||||||
|
// mainAxisSize: MainAxisSize.min,
|
||||||
|
// crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
// children: const [
|
||||||
|
// // CheckboxListTile(
|
||||||
|
// // value: showChart,
|
||||||
|
// // onChanged: (_) => setState(() => showChart = !showChart),
|
||||||
|
// // title: const Text('show Chart'),
|
||||||
|
// // controlAffinity: ListTileControlAffinity.leading,
|
||||||
|
// // ),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// actions: <Widget>[
|
||||||
|
// TextButton(
|
||||||
|
// onPressed: () => Navigator.pop(context),
|
||||||
|
// child: const Text('CANCEL'),
|
||||||
|
// ),
|
||||||
|
// ElevatedButton(
|
||||||
|
// onPressed: !_isSaving ? () => onExport(context) : null,
|
||||||
|
// child: const Text('EXPORT'),
|
||||||
|
// ),
|
||||||
|
// ]);
|
||||||
|
// }
|
||||||
|
// }
|
453
lib/localization_keys.dart
Normal file
453
lib/localization_keys.dart
Normal file
@ -0,0 +1,453 @@
|
|||||||
|
|
||||||
|
// ignore_for_file: constant_identifier_names
|
||||||
|
|
||||||
|
class LocalizationKeys {
|
||||||
|
static const String general = "general";
|
||||||
|
static const String general_apply = "$general.apply";
|
||||||
|
static const String general_cancel = "$general.cancel";
|
||||||
|
static const String general_confirm = "$general.confirm";
|
||||||
|
static const String general_discard = "$general.discard";
|
||||||
|
static const String general_confirmDiscard = "$general.confirmDiscard";
|
||||||
|
static const String general_delete = "$general.delete";
|
||||||
|
static const String general_confirmDelete = "$general.confirmDelete";
|
||||||
|
static const String general_save = "$general.save";
|
||||||
|
static const String general_close = "$general.close";
|
||||||
|
static const String general_saveAndClose = "$general.saveAndClose";
|
||||||
|
static const String general_saveAsIs = "$general.saveAsIs";
|
||||||
|
static const String general_keepEditing = "$general.keepEditing";
|
||||||
|
static const String general_next = "$general.next";
|
||||||
|
static const String general_edit = "$general.edit";
|
||||||
|
static const String general_per = "$general.per";
|
||||||
|
static const String general_example = "$general.example";
|
||||||
|
static const String general_suffixes = "$general.suffixes";
|
||||||
|
static const String general_suffixes_units = "$general_suffixes.units";
|
||||||
|
static const String general_suffixes_carbs = "$general_suffixes.carbs";
|
||||||
|
static const String general_suffixes_mins = "$general_suffixes.mins";
|
||||||
|
static const String general_suffixes_carbsPerU = "$general_suffixes.carbsPerU";
|
||||||
|
static const String general_suffixes_uPerBreadUnit = "$general_suffixes.uPerBreadUnit";
|
||||||
|
static const String general_suffixes_uPerGlucose = "$general_suffixes.uPerGlucose";
|
||||||
|
static const String general_suffixes_perDay = "$general_suffixes.perDay";
|
||||||
|
|
||||||
|
static const String navigation = "navigation";
|
||||||
|
static const String navigation_log = "$navigation.log";
|
||||||
|
static const String navigation_logEvents = "$navigation.logEvents";
|
||||||
|
static const String navigation_reports = "$navigation.reports";
|
||||||
|
static const String navigation_meals = "$navigation.meals";
|
||||||
|
static const String navigation_basalProfiles = "$navigation.basalProfiles";
|
||||||
|
static const String navigation_bolusProfiles = "$navigation.bolusProfiles";
|
||||||
|
static const String navigation_categorization = "$navigation.categorization";
|
||||||
|
static const String navigation_settings = "$navigation.settings";
|
||||||
|
|
||||||
|
static const String accuracy = "accuracy";
|
||||||
|
static const String accuracy_empty = "$accuracy.empty";
|
||||||
|
static const String accuracy_saved = "$accuracy.saved";
|
||||||
|
static const String accuracy_saved_1 = "$accuracy_saved.1";
|
||||||
|
static const String accuracy_saved_else = "$accuracy_saved.else";
|
||||||
|
static const String accuracy_deleted = "$accuracy.deleted";
|
||||||
|
static const String accuracy_confirmDelete = "$accuracy.confirmDelete";
|
||||||
|
static const String accuracy_new = "$accuracy.new";
|
||||||
|
static const String accuracy_fields = "$accuracy.fields";
|
||||||
|
static const String accuracy_fields_name = "$accuracy_fields.name";
|
||||||
|
static const String accuracy_fields_forPortionSize = "$accuracy_fields.forPortionSize";
|
||||||
|
static const String accuracy_fields_forCarbsRatio = "$accuracy_fields.forCarbsRatio";
|
||||||
|
static const String accuracy_fields_confidenceRating = "$accuracy_fields.confidenceRating";
|
||||||
|
static const String accuracy_fields_notes = "$accuracy_fields.notes";
|
||||||
|
static const String accuracy_fields_validators = "$accuracy_fields.validators";
|
||||||
|
static const String accuracy_fields_validators_name = "$accuracy_fields_validators.name";
|
||||||
|
static const String accuracy_title = "$accuracy.title";
|
||||||
|
static const String accuracy_detail = "$accuracy.detail";
|
||||||
|
static const String accuracy_detail_title = "$accuracy_detail.title";
|
||||||
|
|
||||||
|
static const String basal = "basal";
|
||||||
|
static const String basal_empty = "$basal.empty";
|
||||||
|
static const String basal_warnings = "$basal.warnings";
|
||||||
|
static const String basal_warnings_duplicate = "$basal_warnings.duplicate";
|
||||||
|
static const String basal_warnings_overlap = "$basal_warnings.overlap";
|
||||||
|
static const String basal_warnings_startTimeFirst = "$basal_warnings.startTimeFirst";
|
||||||
|
static const String basal_warnings_gap = "$basal_warnings.gap";
|
||||||
|
static const String basal_warnings_endTimeLast = "$basal_warnings.endTimeLast";
|
||||||
|
static const String basal_saved = "$basal.saved";
|
||||||
|
static const String basal_saved_1 = "$basal_saved.1";
|
||||||
|
static const String basal_saved_else = "$basal_saved.else";
|
||||||
|
static const String basal_deleted = "$basal.deleted";
|
||||||
|
static const String basal_confirmDelete = "$basal.confirmDelete";
|
||||||
|
static const String basal_new = "$basal.new";
|
||||||
|
static const String basal_fields = "$basal.fields";
|
||||||
|
static const String basal_fields_startTime = "$basal_fields.startTime";
|
||||||
|
static const String basal_fields_endTime = "$basal_fields.endTime";
|
||||||
|
static const String basal_fields_units = "$basal_fields.units";
|
||||||
|
static const String basal_title = "$basal.title";
|
||||||
|
|
||||||
|
static const String basalProfile = "basalProfile";
|
||||||
|
static const String basalProfile_empty = "$basalProfile.empty";
|
||||||
|
static const String basalProfile_warnings = "$basalProfile.warnings";
|
||||||
|
static const String basalProfile_warnings_noActive = "$basalProfile_warnings.noActive";
|
||||||
|
static const String basalProfile_warnings_noActiveOnCreate = "$basalProfile_warnings.noActiveOnCreate";
|
||||||
|
static const String basalProfile_warnings_multipleActive = "$basalProfile_warnings.multipleActive";
|
||||||
|
static const String basalProfile_warnings_activeAlreadySet = "$basalProfile_warnings.activeAlreadySet";
|
||||||
|
static const String basalProfile_warnings_resolve = "$basalProfile_warnings.resolve";
|
||||||
|
static const String basalProfile_warnings_resolve_activate = "$basalProfile_warnings_resolve.activate";
|
||||||
|
static const String basalProfile_warnings_resolve_activateCurrent = "$basalProfile_warnings_resolve.activateCurrent";
|
||||||
|
static const String basalProfile_warnings_resolve_create = "$basalProfile_warnings_resolve.create";
|
||||||
|
static const String basalProfile_warnings_resolve_createInstead = "$basalProfile_warnings_resolve.createInstead";
|
||||||
|
static const String basalProfile_warnings_resolve_pick = "$basalProfile_warnings_resolve.pick";
|
||||||
|
static const String basalProfile_warnings_resolve_ignore = "$basalProfile_warnings_resolve.ignore";
|
||||||
|
static const String basalProfile_warnings_resolve_deactivateProfile = "$basalProfile_warnings_resolve.deactivateProfile";
|
||||||
|
static const String basalProfile_warnings_resolve_deactivateOthers = "$basalProfile_warnings_resolve.deactivateOthers";
|
||||||
|
static const String basalProfile_saved = "$basalProfile.saved";
|
||||||
|
static const String basalProfile_default = "$basalProfile.default";
|
||||||
|
static const String basalProfile_active = "$basalProfile.active";
|
||||||
|
static const String basalProfile_copied = "$basalProfile.copied";
|
||||||
|
static const String basalProfile_copyOf = "$basalProfile.copyOf";
|
||||||
|
static const String basalProfile_deleted = "$basalProfile.deleted";
|
||||||
|
static const String basalProfile_confirmDelete = "$basalProfile.confirmDelete";
|
||||||
|
static const String basalProfile_activated = "$basalProfile.activated";
|
||||||
|
static const String basalProfile_new = "$basalProfile.new";
|
||||||
|
static const String basalProfile_fields = "$basalProfile.fields";
|
||||||
|
static const String basalProfile_fields_name = "$basalProfile_fields.name";
|
||||||
|
static const String basalProfile_fields_notes = "$basalProfile_fields.notes";
|
||||||
|
static const String basalProfile_fields_active = "$basalProfile_fields.active";
|
||||||
|
static const String basalProfile_fields_validators = "$basalProfile_fields.validators";
|
||||||
|
static const String basalProfile_fields_validators_name = "$basalProfile_fields_validators.name";
|
||||||
|
static const String basalProfile_title = "$basalProfile.title";
|
||||||
|
static const String basalProfile_detail = "$basalProfile.detail";
|
||||||
|
static const String basalProfile_detail_title = "$basalProfile_detail.title";
|
||||||
|
static const String basalProfile_detail_tabs = "$basalProfile_detail.tabs";
|
||||||
|
static const String basalProfile_detail_tabs_profile = "$basalProfile_detail_tabs.profile";
|
||||||
|
static const String basalProfile_detail_tabs_rates = "$basalProfile_detail_tabs.rates";
|
||||||
|
|
||||||
|
static const String bolus = "bolus";
|
||||||
|
static const String bolus_empty = "$bolus.empty";
|
||||||
|
static const String bolus_warnings = "$bolus.warnings";
|
||||||
|
static const String bolus_warnings_duplicate = "$bolus_warnings.duplicate";
|
||||||
|
static const String bolus_warnings_overlap = "$bolus_warnings.overlap";
|
||||||
|
static const String bolus_warnings_startTimeFirst = "$bolus_warnings.startTimeFirst";
|
||||||
|
static const String bolus_warnings_gap = "$bolus_warnings.gap";
|
||||||
|
static const String bolus_warnings_endTimeLast = "$bolus_warnings.endTimeLast";
|
||||||
|
static const String bolus_saved = "$bolus.saved";
|
||||||
|
static const String bolus_saved_1 = "$bolus_saved.1";
|
||||||
|
static const String bolus_saved_else = "$bolus_saved.else";
|
||||||
|
static const String bolus_deleted = "$bolus.deleted";
|
||||||
|
static const String bolus_confirmDelete = "$bolus.confirmDelete";
|
||||||
|
static const String bolus_new = "$bolus.new";
|
||||||
|
static const String bolus_fields = "$bolus.fields";
|
||||||
|
static const String bolus_fields_startTime = "$bolus_fields.startTime";
|
||||||
|
static const String bolus_fields_endTime = "$bolus_fields.endTime";
|
||||||
|
static const String bolus_fields_units = "$bolus_fields.units";
|
||||||
|
static const String bolus_fields_perCarbs = "$bolus_fields.perCarbs";
|
||||||
|
static const String bolus_fields_perGlucose = "$bolus_fields.perGlucose";
|
||||||
|
static const String bolus_title = "$bolus.title";
|
||||||
|
|
||||||
|
static const String bolusProfile = "bolusProfile";
|
||||||
|
static const String bolusProfile_empty = "$bolusProfile.empty";
|
||||||
|
static const String bolusProfile_warnings = "$bolusProfile.warnings";
|
||||||
|
static const String bolusProfile_warnings_noActive = "$bolusProfile_warnings.noActive";
|
||||||
|
static const String bolusProfile_warnings_noActiveOnCreate = "$bolusProfile_warnings.noActiveOnCreate";
|
||||||
|
static const String bolusProfile_warnings_multipleActive = "$bolusProfile_warnings.multipleActive";
|
||||||
|
static const String bolusProfile_warnings_activeAlreadySet = "$bolusProfile_warnings.activeAlreadySet";
|
||||||
|
static const String bolusProfile_warnings_resolve = "$bolusProfile_warnings.resolve";
|
||||||
|
static const String bolusProfile_warnings_resolve_activate = "$bolusProfile_warnings_resolve.activate";
|
||||||
|
static const String bolusProfile_warnings_resolve_activateCurrent = "$bolusProfile_warnings_resolve.activateCurrent";
|
||||||
|
static const String bolusProfile_warnings_resolve_create = "$bolusProfile_warnings_resolve.create";
|
||||||
|
static const String bolusProfile_warnings_resolve_createInstead = "$bolusProfile_warnings_resolve.createInstead";
|
||||||
|
static const String bolusProfile_warnings_resolve_pick = "$bolusProfile_warnings_resolve.pick";
|
||||||
|
static const String bolusProfile_warnings_resolve_ignore = "$bolusProfile_warnings_resolve.ignore";
|
||||||
|
static const String bolusProfile_warnings_resolve_deactivateProfile = "$bolusProfile_warnings_resolve.deactivateProfile";
|
||||||
|
static const String bolusProfile_warnings_resolve_deactivateOthers = "$bolusProfile_warnings_resolve.deactivateOthers";
|
||||||
|
static const String bolusProfile_saved = "$bolusProfile.saved";
|
||||||
|
static const String bolusProfile_default = "$bolusProfile.default";
|
||||||
|
static const String bolusProfile_active = "$bolusProfile.active";
|
||||||
|
static const String bolusProfile_copied = "$bolusProfile.copied";
|
||||||
|
static const String bolusProfile_copyOf = "$bolusProfile.copyOf";
|
||||||
|
static const String bolusProfile_deleted = "$bolusProfile.deleted";
|
||||||
|
static const String bolusProfile_confirmDelete = "$bolusProfile.confirmDelete";
|
||||||
|
static const String bolusProfile_activated = "$bolusProfile.activated";
|
||||||
|
static const String bolusProfile_new = "$bolusProfile.new";
|
||||||
|
static const String bolusProfile_fields = "$bolusProfile.fields";
|
||||||
|
static const String bolusProfile_fields_name = "$bolusProfile_fields.name";
|
||||||
|
static const String bolusProfile_fields_notes = "$bolusProfile_fields.notes";
|
||||||
|
static const String bolusProfile_fields_active = "$bolusProfile_fields.active";
|
||||||
|
static const String bolusProfile_fields_validators = "$bolusProfile_fields.validators";
|
||||||
|
static const String bolusProfile_fields_validators_name = "$bolusProfile_fields_validators.name";
|
||||||
|
static const String bolusProfile_title = "$bolusProfile.title";
|
||||||
|
static const String bolusProfile_detail = "$bolusProfile.detail";
|
||||||
|
static const String bolusProfile_detail_title = "$bolusProfile_detail.title";
|
||||||
|
static const String bolusProfile_detail_tabs = "$bolusProfile_detail.tabs";
|
||||||
|
static const String bolusProfile_detail_tabs_profile = "$bolusProfile_detail_tabs.profile";
|
||||||
|
static const String bolusProfile_detail_tabs_rates = "$bolusProfile_detail_tabs.rates";
|
||||||
|
|
||||||
|
static const String categories = "categories";
|
||||||
|
|
||||||
|
static const String log = "log";
|
||||||
|
static const String log_title = "$log.title";
|
||||||
|
static const String log_empty = "$log.empty";
|
||||||
|
static const String log_confirmDelete = "$log.confirmDelete";
|
||||||
|
static const String log_saved = "$log.saved";
|
||||||
|
static const String log_deleted = "$log.deleted";
|
||||||
|
static const String log_new = "$log.new";
|
||||||
|
static const String log_fields = "$log.fields";
|
||||||
|
static const String log_fields_date = "$log_fields.date";
|
||||||
|
static const String log_fields_time = "$log_fields.time";
|
||||||
|
static const String log_fields_glucose = "$log_fields.glucose";
|
||||||
|
static const String log_fields_notes = "$log_fields.notes";
|
||||||
|
static const String log_filter = "$log.filter";
|
||||||
|
static const String log_filter_startDate = "$log_filter.startDate";
|
||||||
|
static const String log_filter_endDate = "$log_filter.endDate";
|
||||||
|
static const String log_filter_minGlucose = "$log_filter.minGlucose";
|
||||||
|
static const String log_filter_maxGlucose = "$log_filter.maxGlucose";
|
||||||
|
static const String log_filter_meal = "$log_filter.meal";
|
||||||
|
static const String log_filter_mealNameContains = "$log_filter.mealNameContains";
|
||||||
|
static const String log_filter_noteContains = "$log_filter.noteContains";
|
||||||
|
static const String log_detail = "$log.detail";
|
||||||
|
static const String log_detail_title = "$log_detail.title";
|
||||||
|
static const String log_detail_tabs = "$log_detail.tabs";
|
||||||
|
static const String log_detail_tabs_general = "$log_detail_tabs.general";
|
||||||
|
static const String log_detail_tabs_meal = "$log_detail_tabs.meal";
|
||||||
|
static const String log_detail_tabs_meal_title = "$log_detail_tabs_meal.title";
|
||||||
|
static const String log_detail_tabs_meal_saved = "$log_detail_tabs_meal.saved";
|
||||||
|
static const String log_detail_tabs_meal_new = "$log_detail_tabs_meal.new";
|
||||||
|
static const String log_detail_tabs_meal_empty = "$log_detail_tabs_meal.empty";
|
||||||
|
static const String log_detail_tabs_meal_confirmDelete = "$log_detail_tabs_meal.confirmDelete";
|
||||||
|
static const String log_detail_tabs_meal_deleted = "$log_detail_tabs_meal.deleted";
|
||||||
|
static const String log_detail_tabs_meal_detail = "$log_detail_tabs_meal.detail";
|
||||||
|
static const String log_detail_tabs_meal_detail_title = "$log_detail_tabs_meal_detail.title";
|
||||||
|
static const String log_detail_tabs_meal_detail_additionalFields = "$log_detail_tabs_meal_detail.additionalFields";
|
||||||
|
static const String log_detail_tabs_meal_detail_fields = "$log_detail_tabs_meal_detail.fields";
|
||||||
|
static const String log_detail_tabs_meal_detail_fields_meal = "$log_detail_tabs_meal_detail_fields.meal";
|
||||||
|
static const String log_detail_tabs_meal_detail_fields_name = "$log_detail_tabs_meal_detail_fields.name";
|
||||||
|
static const String log_detail_tabs_meal_detail_fields_amount = "$log_detail_tabs_meal_detail_fields.amount";
|
||||||
|
static const String log_detail_tabs_meal_detail_fields_portionSize = "$log_detail_tabs_meal_detail_fields.portionSize";
|
||||||
|
static const String log_detail_tabs_meal_detail_fields_carbsRatio = "$log_detail_tabs_meal_detail_fields.carbsRatio";
|
||||||
|
static const String log_detail_tabs_meal_detail_fields_totalCarbs = "$log_detail_tabs_meal_detail_fields.totalCarbs";
|
||||||
|
static const String log_detail_tabs_meal_detail_fields_setManually = "$log_detail_tabs_meal_detail_fields.setManually";
|
||||||
|
static const String log_detail_tabs_meal_detail_fields_notes = "$log_detail_tabs_meal_detail_fields.notes";
|
||||||
|
static const String log_detail_tabs_meal_detail_fields_mealSource = "$log_detail_tabs_meal_detail_fields.mealSource";
|
||||||
|
static const String log_detail_tabs_meal_detail_fields_mealCategory = "$log_detail_tabs_meal_detail_fields.mealCategory";
|
||||||
|
static const String log_detail_tabs_meal_detail_fields_mealPortionType = "$log_detail_tabs_meal_detail_fields.mealPortionType";
|
||||||
|
static const String log_detail_tabs_meal_detail_fields_portionSizeAccuracy = "$log_detail_tabs_meal_detail_fields.portionSizeAccuracy";
|
||||||
|
static const String log_detail_tabs_meal_detail_fields_carbsRatioAccuracy = "$log_detail_tabs_meal_detail_fields.carbsRatioAccuracy";
|
||||||
|
static const String log_detail_tabs_meal_detail_fields_validators = "$log_detail_tabs_meal_detail_fields.validators";
|
||||||
|
static const String log_detail_tabs_meal_detail_fields_validators_name = "$log_detail_tabs_meal_detail_fields_validators.name";
|
||||||
|
static const String log_detail_tabs_bolus = "$log_detail_tabs.bolus";
|
||||||
|
static const String log_detail_tabs_bolus_title = "$log_detail_tabs_bolus.title";
|
||||||
|
static const String log_detail_tabs_bolus_saved = "$log_detail_tabs_bolus.saved";
|
||||||
|
static const String log_detail_tabs_bolus_new = "$log_detail_tabs_bolus.new";
|
||||||
|
static const String log_detail_tabs_bolus_deleted = "$log_detail_tabs_bolus.deleted";
|
||||||
|
static const String log_detail_tabs_bolus_confirmDelete = "$log_detail_tabs_bolus.confirmDelete";
|
||||||
|
static const String log_detail_tabs_bolus_delayedBy = "$log_detail_tabs_bolus.delayedBy";
|
||||||
|
static const String log_detail_tabs_bolus_forMeal = "$log_detail_tabs_bolus.forMeal";
|
||||||
|
static const String log_detail_tabs_bolus_toCorrect = "$log_detail_tabs_bolus.toCorrect";
|
||||||
|
static const String log_detail_tabs_bolus_empty = "$log_detail_tabs_bolus.empty";
|
||||||
|
static const String log_detail_tabs_bolus_detail = "$log_detail_tabs_bolus.detail";
|
||||||
|
static const String log_detail_tabs_bolus_detail_title = "$log_detail_tabs_bolus_detail.title";
|
||||||
|
static const String log_detail_tabs_bolus_detail_fields = "$log_detail_tabs_bolus_detail.fields";
|
||||||
|
static const String log_detail_tabs_bolus_detail_fields_units = "$log_detail_tabs_bolus_detail_fields.units";
|
||||||
|
static const String log_detail_tabs_bolus_detail_fields_setManually = "$log_detail_tabs_bolus_detail_fields.setManually";
|
||||||
|
static const String log_detail_tabs_bolus_detail_fields_forGlucose = "$log_detail_tabs_bolus_detail_fields.forGlucose";
|
||||||
|
static const String log_detail_tabs_bolus_detail_fields_forMeal = "$log_detail_tabs_bolus_detail_fields.forMeal";
|
||||||
|
static const String log_detail_tabs_bolus_detail_fields_current = "$log_detail_tabs_bolus_detail_fields.current";
|
||||||
|
static const String log_detail_tabs_bolus_detail_fields_target = "$log_detail_tabs_bolus_detail_fields.target";
|
||||||
|
static const String log_detail_tabs_bolus_detail_fields_correction = "$log_detail_tabs_bolus_detail_fields.correction";
|
||||||
|
static const String log_detail_tabs_bolus_detail_fields_meal = "$log_detail_tabs_bolus_detail_fields.meal";
|
||||||
|
static const String log_detail_tabs_bolus_detail_fields_carbs = "$log_detail_tabs_bolus_detail_fields.carbs";
|
||||||
|
static const String log_detail_tabs_bolus_detail_fields_delayedBolusDuration = "$log_detail_tabs_bolus_detail_fields.delayedBolusDuration";
|
||||||
|
static const String log_detail_tabs_bolus_detail_fields_immediateBolus = "$log_detail_tabs_bolus_detail_fields.immediateBolus";
|
||||||
|
static const String log_detail_tabs_bolus_detail_fields_delayedBolus = "$log_detail_tabs_bolus_detail_fields.delayedBolus";
|
||||||
|
|
||||||
|
static const String meal = "meal";
|
||||||
|
static const String meal_title = "$meal.title";
|
||||||
|
static const String meal_empty = "$meal.empty";
|
||||||
|
static const String meal_confirmDelete = "$meal.confirmDelete";
|
||||||
|
static const String meal_saved = "$meal.saved";
|
||||||
|
static const String meal_deleted = "$meal.deleted";
|
||||||
|
static const String meal_new = "$meal.new";
|
||||||
|
static const String meal_fields = "$meal.fields";
|
||||||
|
static const String meal_fields_name = "$meal_fields.name";
|
||||||
|
static const String meal_fields_mealSource = "$meal_fields.mealSource";
|
||||||
|
static const String meal_fields_mealPortionType = "$meal_fields.mealPortionType";
|
||||||
|
static const String meal_fields_notes = "$meal_fields.notes";
|
||||||
|
static const String meal_fields_carbsRatio = "$meal_fields.carbsRatio";
|
||||||
|
static const String meal_fields_setManually = "$meal_fields.setManually";
|
||||||
|
static const String meal_fields_portionSize = "$meal_fields.portionSize";
|
||||||
|
static const String meal_fields_carbsPerPortion = "$meal_fields.carbsPerPortion";
|
||||||
|
static const String meal_fields_delay = "$meal_fields.delay";
|
||||||
|
static const String meal_fields_delay_title = "$meal_fields_delay.title";
|
||||||
|
static const String meal_fields_delay_duration = "$meal_fields_delay.duration";
|
||||||
|
static const String meal_fields_additional = "$meal_fields.additional";
|
||||||
|
static const String meal_fields_additional_title = "$meal_fields_additional.title";
|
||||||
|
static const String meal_fields_additional_mealCategory = "$meal_fields_additional.mealCategory";
|
||||||
|
static const String meal_fields_additional_portionSizeAccuracy = "$meal_fields_additional.portionSizeAccuracy";
|
||||||
|
static const String meal_fields_additional_carbsRatioAccuracy = "$meal_fields_additional.carbsRatioAccuracy";
|
||||||
|
static const String meal_fields_validators = "$meal_fields.validators";
|
||||||
|
static const String meal_fields_validators_name = "$meal_fields_validators.name";
|
||||||
|
static const String meal_detail = "$meal.detail";
|
||||||
|
static const String meal_detail_title = "$meal_detail.title";
|
||||||
|
|
||||||
|
static const String mealSource = "mealSource";
|
||||||
|
static const String mealSource_title = "$mealSource.title";
|
||||||
|
static const String mealSource_empty = "$mealSource.empty";
|
||||||
|
static const String mealSource_confirmDelete = "$mealSource.confirmDelete";
|
||||||
|
static const String mealSource_saved = "$mealSource.saved";
|
||||||
|
static const String mealSource_deleted = "$mealSource.deleted";
|
||||||
|
static const String mealSource_new = "$mealSource.new";
|
||||||
|
static const String mealSource_fields = "$mealSource.fields";
|
||||||
|
static const String mealSource_fields_name = "$mealSource_fields.name";
|
||||||
|
static const String mealSource_fields_notes = "$mealSource_fields.notes";
|
||||||
|
static const String mealSource_fields_defaultCarbsRatioAccuracy = "$mealSource_fields.defaultCarbsRatioAccuracy";
|
||||||
|
static const String mealSource_fields_defaultPortionSizeAccuracy = "$mealSource_fields.defaultPortionSizeAccuracy";
|
||||||
|
static const String mealSource_fields_defaultMealCategory = "$mealSource_fields.defaultMealCategory";
|
||||||
|
static const String mealSource_fields_defaultMealPortionType = "$mealSource_fields.defaultMealPortionType";
|
||||||
|
static const String mealSource_fields_validators = "$mealSource_fields.validators";
|
||||||
|
static const String mealSource_fields_validators_name = "$mealSource_fields_validators.name";
|
||||||
|
static const String mealSource_detail = "$mealSource.detail";
|
||||||
|
static const String mealSource_detail_title = "$mealSource_detail.title";
|
||||||
|
|
||||||
|
static const String mealCategory = "mealCategory";
|
||||||
|
static const String mealCategory_title = "$mealCategory.title";
|
||||||
|
static const String mealCategory_empty = "$mealCategory.empty";
|
||||||
|
static const String mealCategory_confirmDelete = "$mealCategory.confirmDelete";
|
||||||
|
static const String mealCategory_saved = "$mealCategory.saved";
|
||||||
|
static const String mealCategory_deleted = "$mealCategory.deleted";
|
||||||
|
static const String mealCategory_new = "$mealCategory.new";
|
||||||
|
static const String mealCategory_fields = "$mealCategory.fields";
|
||||||
|
static const String mealCategory_fields_name = "$mealCategory_fields.name";
|
||||||
|
static const String mealCategory_fields_notes = "$mealCategory_fields.notes";
|
||||||
|
static const String mealCategory_fields_validators = "$mealCategory_fields.validators";
|
||||||
|
static const String mealCategory_fields_validators_name = "$mealCategory_fields_validators.name";
|
||||||
|
static const String mealCategory_detail = "$mealCategory.detail";
|
||||||
|
static const String mealCategory_detail_title = "$mealCategory_detail.title";
|
||||||
|
|
||||||
|
static const String portionType = "portionType";
|
||||||
|
static const String portionType_title = "$portionType.title";
|
||||||
|
static const String portionType_empty = "$portionType.empty";
|
||||||
|
static const String portionType_confirmDelete = "$portionType.confirmDelete";
|
||||||
|
static const String portionType_saved = "$portionType.saved";
|
||||||
|
static const String portionType_deleted = "$portionType.deleted";
|
||||||
|
static const String portionType_new = "$portionType.new";
|
||||||
|
static const String portionType_fields = "$portionType.fields";
|
||||||
|
static const String portionType_fields_name = "$portionType_fields.name";
|
||||||
|
static const String portionType_fields_notes = "$portionType_fields.notes";
|
||||||
|
static const String portionType_fields_validators = "$portionType_fields.validators";
|
||||||
|
static const String portionType_fields_validators_name = "$portionType_fields_validators.name";
|
||||||
|
static const String portionType_detail = "$portionType.detail";
|
||||||
|
static const String portionType_detail_title = "$portionType_detail.title";
|
||||||
|
|
||||||
|
static const String eventType = "eventType";
|
||||||
|
static const String eventType_title = "$eventType.title";
|
||||||
|
static const String eventType_empty = "$eventType.empty";
|
||||||
|
static const String eventType_saved = "$eventType.saved";
|
||||||
|
static const String eventType_deleted = "$eventType.deleted";
|
||||||
|
static const String eventType_new = "$eventType.new";
|
||||||
|
static const String eventType_fields = "$eventType.fields";
|
||||||
|
static const String eventType_fields_name = "$eventType_fields.name";
|
||||||
|
static const String eventType_fields_notes = "$eventType_fields.notes";
|
||||||
|
static const String eventType_fields_hasEndTime = "$eventType_fields.hasEndTime";
|
||||||
|
static const String eventType_fields_defaultReminderDuration = "$eventType_fields.defaultReminderDuration";
|
||||||
|
static const String eventType_fields_bolusProfile = "$eventType_fields.bolusProfile";
|
||||||
|
static const String eventType_fields_basalProfile = "$eventType_fields.basalProfile";
|
||||||
|
static const String eventType_fields_validators = "$eventType_fields.validators";
|
||||||
|
static const String eventType_fields_validators_name = "$eventType_fields_validators.name";
|
||||||
|
static const String eventType_detail = "$eventType.detail";
|
||||||
|
static const String eventType_detail_title = "$eventType_detail.title";
|
||||||
|
|
||||||
|
static const String event = "event";
|
||||||
|
static const String event_warnings = "$event.warnings";
|
||||||
|
static const String event_warnings_duplicate = "$event_warnings.duplicate";
|
||||||
|
static const String event_title = "$event.title";
|
||||||
|
static const String event_titleActive = "$event.titleAcive";
|
||||||
|
static const String event_empty = "$event.empty";
|
||||||
|
static const String event_emptyActive = "$event.emptyActive";
|
||||||
|
static const String event_saved = "$event.saved";
|
||||||
|
static const String event_deleted = "$event.deleted";
|
||||||
|
static const String event_confirmDelete = "$event.confirmDelete";
|
||||||
|
static const String event_end = "$event.end";
|
||||||
|
static const String event_ended = "$event.ended";
|
||||||
|
static const String event_confirmEnd = "$event.confirmEnd";
|
||||||
|
static const String event_new = "$event.new";
|
||||||
|
static const String event_fields = "$event.fields";
|
||||||
|
static const String event_fields_eventType = "$event_fields.eventType";
|
||||||
|
static const String event_fields_startDate = "$event_fields.startDate";
|
||||||
|
static const String event_fields_endDate = "$event_fields.endDate";
|
||||||
|
static const String event_fields_date = "$event_fields.date";
|
||||||
|
static const String event_fields_startTime = "$event_fields.startTime";
|
||||||
|
static const String event_fields_endTime = "$event_fields.endTime";
|
||||||
|
static const String event_fields_time = "$event_fields.time";
|
||||||
|
static const String event_fields_notes = "$event_fields.notes";
|
||||||
|
static const String event_fields_hasEndTime = "$event_fields.hasEndTime";
|
||||||
|
static const String event_fields_reminderDuration = "$event_fields.reminderDuration";
|
||||||
|
static const String event_fields_bolusProfile = "$event_fields.bolusProfile";
|
||||||
|
static const String event_fields_basalProfile = "$event_fields.basalProfile";
|
||||||
|
static const String event_detail = "$event.detail";
|
||||||
|
static const String event_detail_title = "$event_detail.title";
|
||||||
|
|
||||||
|
static const String settings = "settings";
|
||||||
|
static const String settings_title = "$settings.title";
|
||||||
|
static const String settings_reset = "$settings.reset";
|
||||||
|
static const String settings_resetAll = "$settings.resetAll";
|
||||||
|
static const String settings_confirmReset = "$settings.confirmReset";
|
||||||
|
static const String settings_updated = "$settings.updated";
|
||||||
|
static const String settings_sections = "$settings.sections";
|
||||||
|
static const String settings_sections_measurements = "$settings_sections.measurements";
|
||||||
|
static const String settings_sections_confirmation = "$settings_sections.confirmation";
|
||||||
|
static const String settings_sections_dateTimeFormat = "$settings_sections.dateTimeFormat";
|
||||||
|
static const String settings_fields = "$settings.fields";
|
||||||
|
static const String settings_fields_nutritionMeasurement = "$settings_fields.nutritionMeasurement";
|
||||||
|
static const String settings_fields_glucoseMeasurement = "$settings_fields.glucoseMeasurement";
|
||||||
|
static const String settings_fields_targetGlucose = "$settings_fields.targetGlucose";
|
||||||
|
static const String settings_fields_insulinIncrement = "$settings_fields.insulinIncrement";
|
||||||
|
static const String settings_fields_nutritionIncrement = "$settings_fields.nutritionIncrement";
|
||||||
|
static const String settings_fields_mmolLIncrement = "$settings_fields.mmolLIncrement";
|
||||||
|
static const String settings_fields_onlyDisplayActive = "$settings_fields.onlyDisplayActive";
|
||||||
|
static const String settings_fields_displayBothDetail = "$settings_fields.displayBothDetail";
|
||||||
|
static const String settings_fields_displayBothList = "$settings_fields.displayBothList";
|
||||||
|
static const String settings_fields_confirmOnCancel = "$settings_fields.confirmOnCancel";
|
||||||
|
static const String settings_fields_confirmOnDelete = "$settings_fields.confirmOnDelete";
|
||||||
|
static const String settings_fields_confirmOnEndEvent = "$settings_fields.confirmOnEndEvent";
|
||||||
|
static const String settings_fields_dateFormat = "$settings_fields.dateFormat";
|
||||||
|
static const String settings_fields_longDateFormat = "$settings_fields.longDateFormat";
|
||||||
|
static const String settings_fields_timeFormat = "$settings_fields.timeFormat";
|
||||||
|
static const String settings_fields_longTimeFormat = "$settings_fields.longTimeFormat";
|
||||||
|
|
||||||
|
static const String reports = "reports";
|
||||||
|
static const String reports_title = "$reports.title";
|
||||||
|
static const String reports_ids = "$reports.ids";
|
||||||
|
static const String reports_ids_glucose = "$reports_ids.glucose";
|
||||||
|
static const String reports_ids_carbs = "$reports_ids.carbs";
|
||||||
|
static const String reports_ids_basal = "$reports_ids.basal";
|
||||||
|
static const String reports_ids_bolus = "$reports_ids.bolus";
|
||||||
|
static const String reports_dailyCharts = "$reports.dailyCharts";
|
||||||
|
static const String reports_dailyCharts_showChart = "$reports_dailyCharts.showChart";
|
||||||
|
static const String reports_dailyCharts_showBolus = "$reports_dailyCharts.showBolus";
|
||||||
|
static const String reports_dailyCharts_showBasal = "$reports_dailyCharts.showBasal";
|
||||||
|
static const String reports_dailyCharts_showMeals = "$reports_dailyCharts.showMeals";
|
||||||
|
static const String reports_dailyCharts_empty = "$reports_dailyCharts.empty";
|
||||||
|
static const String reports_sections = "$reports.sections";
|
||||||
|
static const String reports_sections_dailyReport = "$reports_sections.dailyReport";
|
||||||
|
static const String reports_sections_pdfReport = "$reports_sections.pdfReport";
|
||||||
|
static const String reports_export = "$reports.export";
|
||||||
|
static const String reports_export_title = "$reports_export.title";
|
||||||
|
static const String reports_export_singleDate = "$reports_export.singleDate";
|
||||||
|
static const String reports_export_range = "$reports_export.range";
|
||||||
|
static const String reports_export_date = "$reports_export.date";
|
||||||
|
static const String reports_export_endDate = "$reports_export.endDate";
|
||||||
|
static const String reports_export_showChart = "$reports_export.showChart";
|
||||||
|
static const String reports_export_showBolus = "$reports_export.showBolus";
|
||||||
|
static const String reports_export_showBasal = "$reports_export.showBasal";
|
||||||
|
static const String reports_export_showMeals = "$reports_export.showMeals";
|
||||||
|
static const String reports_export_showTable = "$reports_export.showTable";
|
||||||
|
static const String reports_export_export = "$reports_export.export";
|
||||||
|
static const String reports_export_tableHeaders = "$reports_export.tableHeaders";
|
||||||
|
static const String reports_export_tableHeaders_time = "$reports_export_tableHeaders.time";
|
||||||
|
static const String reports_export_tableHeaders_glucose = "$reports_export_tableHeaders.glucose";
|
||||||
|
static const String reports_export_tableHeaders_bolus = "$reports_export_tableHeaders.bolus";
|
||||||
|
static const String reports_export_tableHeaders_notes = "$reports_export_tableHeaders.notes";
|
||||||
|
static const String reports_export_tableHeaders_meals = "$reports_export_tableHeaders.meals";
|
||||||
|
static const String reports_export_tableHeaders_portionSize = "$reports_export_tableHeaders.portionSize";
|
||||||
|
static const String reports_export_tableHeaders_carbs = "$reports_export_tableHeaders.carbs";
|
||||||
|
static const String reports_export_tableHeaders_mealBolus = "$reports_export_tableHeaders.mealBolus";
|
||||||
|
static const String reports_export_tableHeaders_mealNotes = "$reports_export_tableHeaders.mealNotes";
|
||||||
|
|
||||||
|
static const String export = "export";
|
||||||
|
static const String export_error = "$export.error";
|
||||||
|
|
||||||
|
}
|
@ -25,30 +25,62 @@ import 'package:diameter/screens/meal/meal_list.dart';
|
|||||||
import 'package:diameter/screens/reports/export.dart';
|
import 'package:diameter/screens/reports/export.dart';
|
||||||
import 'package:diameter/screens/reports/reports.dart';
|
import 'package:diameter/screens/reports/reports.dart';
|
||||||
import 'package:diameter/settings.dart';
|
import 'package:diameter/settings.dart';
|
||||||
|
import 'package:diameter/data_export.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:diameter/screens/basal/basal_profile_list.dart';
|
import 'package:diameter/screens/basal/basal_profile_list.dart';
|
||||||
import 'package:diameter/screens/bolus/bolus_profile_list.dart';
|
import 'package:diameter/screens/bolus/bolus_profile_list.dart';
|
||||||
import 'package:diameter/navigation.dart';
|
import 'package:diameter/navigation.dart';
|
||||||
import 'package:objectbox/objectbox.dart';
|
import 'package:objectbox/objectbox.dart';
|
||||||
|
import 'package:flutter_translate/flutter_translate.dart';
|
||||||
|
|
||||||
late ObjectBox objectBox;
|
late ObjectBox objectBox;
|
||||||
|
|
||||||
Future<void> main() async {
|
Future<void> main() async {
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
|
DataExport.exportToGoogleDrive();
|
||||||
|
|
||||||
objectBox = await ObjectBox.create();
|
objectBox = await ObjectBox.create();
|
||||||
|
|
||||||
Sync.isAvailable();
|
Sync.isAvailable();
|
||||||
SyncClient syncClient = Sync.client(
|
SyncClient syncClient = Sync.client(objectBox.store,
|
||||||
objectBox.store,
|
'ws://192.168.1.184:9999', SyncCredentials.sharedSecretString(secret));
|
||||||
'ws://192.168.1.184:9999',
|
|
||||||
SyncCredentials.sharedSecretString(secret)
|
|
||||||
);
|
|
||||||
syncClient.start();
|
syncClient.start();
|
||||||
syncClient.requestUpdates(subscribeForFuturePushes: false);
|
syncClient.requestUpdates(subscribeForFuturePushes: false);
|
||||||
|
|
||||||
|
DataExport.exportToGoogleDrive();
|
||||||
|
|
||||||
|
var delegate = await LocalizationDelegate.create(
|
||||||
|
fallbackLocale: 'en_US',
|
||||||
|
supportedLocales: ['en_US', 'de'],
|
||||||
|
);
|
||||||
|
|
||||||
runApp(
|
runApp(
|
||||||
GestureDetector(
|
LocalizedApp(delegate, const App()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class App extends StatelessWidget {
|
||||||
|
const App({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
var localizationDelegate = LocalizedApp.of(context).delegate;
|
||||||
|
|
||||||
|
return LocalizationProvider(
|
||||||
|
state: LocalizationProvider.of(context).state,
|
||||||
|
child: GestureDetector(
|
||||||
onTap: () => FocusManager.instance.primaryFocus?.unfocus(),
|
onTap: () => FocusManager.instance.primaryFocus?.unfocus(),
|
||||||
child: MaterialApp(
|
child: MaterialApp(
|
||||||
|
localizationsDelegates: [
|
||||||
|
localizationDelegate,
|
||||||
|
],
|
||||||
|
supportedLocales: const [
|
||||||
|
Locale('en', 'US'),
|
||||||
|
Locale('de', 'DE'),
|
||||||
|
],
|
||||||
|
// localizationDelegate.supportedLocales,
|
||||||
|
locale: localizationDelegate.currentLocale,
|
||||||
theme: AppTheme.makeTheme(AppTheme.lightTheme),
|
theme: AppTheme.makeTheme(AppTheme.lightTheme),
|
||||||
darkTheme: AppTheme.makeTheme(AppTheme.darkTheme),
|
darkTheme: AppTheme.makeTheme(AppTheme.darkTheme),
|
||||||
themeMode: Settings.themeMode,
|
themeMode: Settings.themeMode,
|
||||||
@ -87,3 +119,4 @@ Future<void> main() async {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@ -10,11 +10,13 @@ class Accuracy {
|
|||||||
// properties
|
// properties
|
||||||
int id;
|
int id;
|
||||||
bool deleted;
|
bool deleted;
|
||||||
|
@Unique()
|
||||||
String value;
|
String value;
|
||||||
bool forCarbsRatio;
|
bool forCarbsRatio;
|
||||||
bool forPortionSize;
|
bool forPortionSize;
|
||||||
int? confidenceRating;
|
int? confidenceRating;
|
||||||
String? notes;
|
String? notes;
|
||||||
|
String? source;
|
||||||
|
|
||||||
// constructor
|
// constructor
|
||||||
Accuracy({
|
Accuracy({
|
||||||
@ -25,6 +27,7 @@ class Accuracy {
|
|||||||
this.forPortionSize = false,
|
this.forPortionSize = false,
|
||||||
this.confidenceRating,
|
this.confidenceRating,
|
||||||
this.notes,
|
this.notes,
|
||||||
|
this.source,
|
||||||
});
|
});
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
@ -60,10 +63,14 @@ class Accuracy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void reorder(Accuracy accuracy, int? newPosition) {
|
static void reorder(Accuracy accuracy, int? newPosition) {
|
||||||
QueryBuilder<Accuracy> all = box.query(Accuracy_.deleted.equals(false).and(Accuracy_.id.notEquals(accuracy.id)))
|
QueryBuilder<Accuracy> all = box.query(Accuracy_.deleted
|
||||||
|
.equals(false)
|
||||||
|
.and(Accuracy_.id.notEquals(accuracy.id)))
|
||||||
..order(Accuracy_.confidenceRating);
|
..order(Accuracy_.confidenceRating);
|
||||||
List<Accuracy> accuracies = all.build().find();
|
List<Accuracy> accuracies = all.build().find();
|
||||||
newPosition == null || newPosition >= accuracies.length ? accuracies.add(accuracy) : accuracies.insert(newPosition, accuracy);
|
newPosition == null || newPosition >= accuracies.length
|
||||||
|
? accuracies.add(accuracy)
|
||||||
|
: accuracies.insert(newPosition, accuracy);
|
||||||
box.putMany(accuracies.map((item) {
|
box.putMany(accuracies.map((item) {
|
||||||
item.confidenceRating = accuracies.indexOf(item);
|
item.confidenceRating = accuracies.indexOf(item);
|
||||||
return item;
|
return item;
|
||||||
@ -74,4 +81,31 @@ class Accuracy {
|
|||||||
String toString() {
|
String toString() {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = <String, dynamic>{};
|
||||||
|
data['id'] = id;
|
||||||
|
data['deleted'] = deleted;
|
||||||
|
data['value'] = value;
|
||||||
|
data['forCarbsRatio'] = forCarbsRatio;
|
||||||
|
data['forPortionSize'] = forPortionSize;
|
||||||
|
data['confidenceRating'] = confidenceRating;
|
||||||
|
data['notes'] = notes;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static String? putFromJson(Map<String, dynamic> json, bool overrideExisting, String? source) {
|
||||||
|
final accuracy = Accuracy(
|
||||||
|
id: overrideExisting ? json['id'] : 0,
|
||||||
|
deleted: json['deleted'],
|
||||||
|
value: json['value'],
|
||||||
|
forCarbsRatio: json['forCarbsRatio'],
|
||||||
|
forPortionSize: json['forPortionSize'],
|
||||||
|
confidenceRating: json['confidenceRating'],
|
||||||
|
notes: json['notes'],
|
||||||
|
source: source,
|
||||||
|
);
|
||||||
|
Accuracy.put(accuracy);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ class Basal {
|
|||||||
@Property(type: PropertyType.date)
|
@Property(type: PropertyType.date)
|
||||||
DateTime endTime;
|
DateTime endTime;
|
||||||
double units;
|
double units;
|
||||||
|
String? source;
|
||||||
|
|
||||||
// relations
|
// relations
|
||||||
final basalProfile = ToOne<BasalProfile>();
|
final basalProfile = ToOne<BasalProfile>();
|
||||||
@ -29,6 +30,7 @@ class Basal {
|
|||||||
required this.startTime,
|
required this.startTime,
|
||||||
required this.endTime,
|
required this.endTime,
|
||||||
this.units = 0,
|
this.units = 0,
|
||||||
|
this.source,
|
||||||
});
|
});
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
@ -43,6 +45,13 @@ class Basal {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void removeAllForProfile(int id) {
|
||||||
|
box.putMany(getAllForProfile(id).map((item) {
|
||||||
|
item.deleted = true;
|
||||||
|
return item;
|
||||||
|
}).toList());
|
||||||
|
}
|
||||||
|
|
||||||
static List<Basal> getAllForProfile(int id) {
|
static List<Basal> getAllForProfile(int id) {
|
||||||
QueryBuilder<Basal> builder = box.query(Basal_.deleted.equals(false))
|
QueryBuilder<Basal> builder = box.query(Basal_.deleted.equals(false))
|
||||||
..order(Basal_.startTime);
|
..order(Basal_.startTime);
|
||||||
@ -94,4 +103,42 @@ class Basal {
|
|||||||
String toString() {
|
String toString() {
|
||||||
return DateTimeUtils.displayTime(startTime);
|
return DateTimeUtils.displayTime(startTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = <String, dynamic>{};
|
||||||
|
data['id'] = id;
|
||||||
|
data['deleted'] = deleted;
|
||||||
|
data['startTime'] = startTime.toIso8601String();
|
||||||
|
data['endTime'] = endTime.toIso8601String();
|
||||||
|
data['units'] = units;
|
||||||
|
data['basalProfile'] = basalProfile.targetId;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static String? putFromJson(Map<String, dynamic> json, bool overrideExisting, String? source) {
|
||||||
|
DateTime? startTime = DateTime.tryParse(json['startTime']);
|
||||||
|
DateTime? endTime = DateTime.tryParse(json['endTime']);
|
||||||
|
|
||||||
|
if (startTime == null || endTime == null) {
|
||||||
|
return startTime == null
|
||||||
|
? endTime == null
|
||||||
|
? 'start and end time are missing'
|
||||||
|
: 'start time is missing'
|
||||||
|
: 'end time is missing';
|
||||||
|
}
|
||||||
|
|
||||||
|
final basal = Basal(
|
||||||
|
id: overrideExisting ? json['id'] : 0,
|
||||||
|
deleted: json['deleted'],
|
||||||
|
startTime: startTime,
|
||||||
|
endTime: endTime,
|
||||||
|
units: json['units'],
|
||||||
|
source: source,
|
||||||
|
);
|
||||||
|
|
||||||
|
basal.basalProfile.targetId = json['basalProfile'];
|
||||||
|
Basal.put(basal);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import 'package:diameter/main.dart';
|
import 'package:diameter/main.dart';
|
||||||
|
import 'package:diameter/models/basal.dart';
|
||||||
import 'package:diameter/models/log_event.dart';
|
import 'package:diameter/models/log_event.dart';
|
||||||
import 'package:objectbox/objectbox.dart';
|
import 'package:objectbox/objectbox.dart';
|
||||||
import 'package:diameter/objectbox.g.dart' show BasalProfile_;
|
import 'package:diameter/objectbox.g.dart' show BasalProfile_;
|
||||||
@ -11,9 +12,11 @@ class BasalProfile {
|
|||||||
// properties
|
// properties
|
||||||
int id;
|
int id;
|
||||||
bool deleted;
|
bool deleted;
|
||||||
|
@Unique()
|
||||||
String name;
|
String name;
|
||||||
bool active;
|
bool active;
|
||||||
String? notes;
|
String? notes;
|
||||||
|
String? source;
|
||||||
|
|
||||||
// constructor
|
// constructor
|
||||||
BasalProfile({
|
BasalProfile({
|
||||||
@ -22,6 +25,7 @@ class BasalProfile {
|
|||||||
this.name = '',
|
this.name = '',
|
||||||
this.active = false,
|
this.active = false,
|
||||||
this.notes,
|
this.notes,
|
||||||
|
this.source,
|
||||||
});
|
});
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
@ -29,7 +33,8 @@ class BasalProfile {
|
|||||||
static void put(BasalProfile basalProfile) => box.put(basalProfile);
|
static void put(BasalProfile basalProfile) => box.put(basalProfile);
|
||||||
|
|
||||||
static List<BasalProfile> getAll() {
|
static List<BasalProfile> getAll() {
|
||||||
QueryBuilder<BasalProfile> all = box.query(BasalProfile_.deleted.equals(false))
|
QueryBuilder<BasalProfile> all = box
|
||||||
|
.query(BasalProfile_.deleted.equals(false))
|
||||||
..order(BasalProfile_.name);
|
..order(BasalProfile_.name);
|
||||||
return all.build().find();
|
return all.build().find();
|
||||||
}
|
}
|
||||||
@ -38,13 +43,16 @@ class BasalProfile {
|
|||||||
final item = box.get(id);
|
final item = box.get(id);
|
||||||
if (item != null) {
|
if (item != null) {
|
||||||
item.deleted = true;
|
item.deleted = true;
|
||||||
|
Basal.removeAllForProfile(id);
|
||||||
box.put(item);
|
box.put(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int activeCount() {
|
static int activeCount() {
|
||||||
Query<BasalProfile> query = box
|
Query<BasalProfile> query = box
|
||||||
.query(BasalProfile_.active.equals(true) & BasalProfile_.deleted.equals(false)).build();
|
.query(BasalProfile_.active.equals(true) &
|
||||||
|
BasalProfile_.deleted.equals(false))
|
||||||
|
.build();
|
||||||
return query.find().length;
|
return query.find().length;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,13 +66,15 @@ class BasalProfile {
|
|||||||
static BasalProfile? getActive(DateTime? dateTime) {
|
static BasalProfile? getActive(DateTime? dateTime) {
|
||||||
if (dateTime != null) {
|
if (dateTime != null) {
|
||||||
List<LogEvent> activeEvents = LogEvent.getAllActiveForTime(dateTime)
|
List<LogEvent> activeEvents = LogEvent.getAllActiveForTime(dateTime)
|
||||||
.where((event) => event.basalProfile.target != null).toList();
|
.where((event) => event.basalProfile.target != null)
|
||||||
|
.toList();
|
||||||
if (activeEvents.length > 1) {
|
if (activeEvents.length > 1) {
|
||||||
final now = DateTime.now();
|
final now = DateTime.now();
|
||||||
activeEvents =
|
activeEvents = activeEvents
|
||||||
activeEvents.where((item) => !activeEvents.any((other) =>
|
.where((item) => !activeEvents.any((other) =>
|
||||||
item.time.isBefore(other.time) || (item.endTime ?? now).isAfter(other.endTime ?? now)
|
item.time.isBefore(other.time) ||
|
||||||
)).toList();
|
(item.endTime ?? now).isAfter(other.endTime ?? now)))
|
||||||
|
.toList();
|
||||||
}
|
}
|
||||||
if (activeEvents.length == 1) {
|
if (activeEvents.length == 1) {
|
||||||
return activeEvents.single.basalProfile.target;
|
return activeEvents.single.basalProfile.target;
|
||||||
@ -84,4 +94,28 @@ class BasalProfile {
|
|||||||
String toString() {
|
String toString() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = <String, dynamic>{};
|
||||||
|
data['id'] = id;
|
||||||
|
data['deleted'] = deleted;
|
||||||
|
data['name'] = name;
|
||||||
|
data['active'] = active;
|
||||||
|
data['notes'] = notes;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static String? putFromJson(
|
||||||
|
Map<String, dynamic> json, bool overrideExisting, String? source) {
|
||||||
|
final basalProfile = BasalProfile(
|
||||||
|
id: overrideExisting ? json['id'] : 0,
|
||||||
|
deleted: json['deleted'] == 'true',
|
||||||
|
name: json['name'],
|
||||||
|
active: json['active'] == 'true',
|
||||||
|
notes: json['notes'],
|
||||||
|
source: source,
|
||||||
|
);
|
||||||
|
BasalProfile.put(basalProfile);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ class Bolus {
|
|||||||
double carbs;
|
double carbs;
|
||||||
int? mgPerDl;
|
int? mgPerDl;
|
||||||
double? mmolPerL;
|
double? mmolPerL;
|
||||||
|
String? source;
|
||||||
|
|
||||||
// relations
|
// relations
|
||||||
final bolusProfile = ToOne<BolusProfile>();
|
final bolusProfile = ToOne<BolusProfile>();
|
||||||
@ -35,6 +36,7 @@ class Bolus {
|
|||||||
this.carbs = 0,
|
this.carbs = 0,
|
||||||
this.mgPerDl,
|
this.mgPerDl,
|
||||||
this.mmolPerL,
|
this.mmolPerL,
|
||||||
|
this.source,
|
||||||
});
|
});
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
@ -56,6 +58,13 @@ class Bolus {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void removeAllForProfile(int id) {
|
||||||
|
box.putMany(getAllForProfile(id).map((item) {
|
||||||
|
item.deleted = true;
|
||||||
|
return item;
|
||||||
|
}).toList());
|
||||||
|
}
|
||||||
|
|
||||||
static Bolus? getRateForTime(DateTime? dateTime) {
|
static Bolus? getRateForTime(DateTime? dateTime) {
|
||||||
if (dateTime != null) {
|
if (dateTime != null) {
|
||||||
final bolusProfile = BolusProfile.getActive(dateTime);
|
final bolusProfile = BolusProfile.getActive(dateTime);
|
||||||
@ -81,4 +90,48 @@ class Bolus {
|
|||||||
String toString() {
|
String toString() {
|
||||||
return DateTimeUtils.displayTime(startTime);
|
return DateTimeUtils.displayTime(startTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = <String, dynamic>{};
|
||||||
|
data['id'] = id;
|
||||||
|
data['deleted'] = deleted;
|
||||||
|
data['startTime'] = startTime.toIso8601String();
|
||||||
|
data['endTime'] = endTime.toIso8601String();
|
||||||
|
data['units'] = units;
|
||||||
|
data['carbs'] = carbs;
|
||||||
|
data['mgPerDl'] = mgPerDl;
|
||||||
|
data['mmolPerL'] = mmolPerL;
|
||||||
|
data['bolusProfile'] = bolusProfile.targetId;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static String? putFromJson(Map<String, dynamic> json, bool overrideExisting, String? source) {
|
||||||
|
DateTime? startTime = DateTime.tryParse(json['startTime']);
|
||||||
|
DateTime? endTime = DateTime.tryParse(json['endTime']);
|
||||||
|
|
||||||
|
if (startTime == null || endTime == null) {
|
||||||
|
return startTime == null
|
||||||
|
? endTime == null
|
||||||
|
? 'start and end time are missing'
|
||||||
|
: 'start time is missing'
|
||||||
|
: 'end time is missing';
|
||||||
|
}
|
||||||
|
|
||||||
|
final bolus = Bolus(
|
||||||
|
id: overrideExisting ? json['id'] : 0,
|
||||||
|
deleted: json['deleted'],
|
||||||
|
startTime: startTime,
|
||||||
|
endTime: endTime,
|
||||||
|
units: json['units'],
|
||||||
|
carbs: json['carbs'],
|
||||||
|
mgPerDl: json['mgPerDl'],
|
||||||
|
mmolPerL: json['mmolPerL'],
|
||||||
|
source: source,
|
||||||
|
);
|
||||||
|
|
||||||
|
bolus.bolusProfile.targetId = json['bolusProfile'];
|
||||||
|
Bolus.put(bolus);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import 'package:diameter/main.dart';
|
import 'package:diameter/main.dart';
|
||||||
|
import 'package:diameter/models/bolus.dart';
|
||||||
import 'package:diameter/models/log_event.dart';
|
import 'package:diameter/models/log_event.dart';
|
||||||
import 'package:objectbox/objectbox.dart';
|
import 'package:objectbox/objectbox.dart';
|
||||||
import 'package:diameter/objectbox.g.dart' show BolusProfile_;
|
import 'package:diameter/objectbox.g.dart' show BolusProfile_;
|
||||||
@ -11,9 +12,11 @@ class BolusProfile {
|
|||||||
// properties
|
// properties
|
||||||
int id;
|
int id;
|
||||||
bool deleted;
|
bool deleted;
|
||||||
|
@Unique()
|
||||||
String name;
|
String name;
|
||||||
bool active;
|
bool active;
|
||||||
String? notes;
|
String? notes;
|
||||||
|
String? source;
|
||||||
|
|
||||||
// constructor
|
// constructor
|
||||||
BolusProfile({
|
BolusProfile({
|
||||||
@ -22,6 +25,7 @@ class BolusProfile {
|
|||||||
this.name = '',
|
this.name = '',
|
||||||
this.active = false,
|
this.active = false,
|
||||||
this.notes,
|
this.notes,
|
||||||
|
this.source,
|
||||||
});
|
});
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
@ -38,6 +42,7 @@ class BolusProfile {
|
|||||||
final item = box.get(id);
|
final item = box.get(id);
|
||||||
if (item != null) {
|
if (item != null) {
|
||||||
item.deleted = true;
|
item.deleted = true;
|
||||||
|
Bolus.removeAllForProfile(id);
|
||||||
box.put(item);
|
box.put(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -87,4 +92,29 @@ class BolusProfile {
|
|||||||
String toString() {
|
String toString() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = <String, dynamic>{};
|
||||||
|
data['id'] = id;
|
||||||
|
data['deleted'] = deleted;
|
||||||
|
data['name'] = name;
|
||||||
|
data['active'] = active;
|
||||||
|
data['notes'] = notes;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static String? putFromJson(
|
||||||
|
Map<String, dynamic> json, bool overrideExisting, String? source) {
|
||||||
|
final bolusProfile = BolusProfile(
|
||||||
|
id: overrideExisting ? json['id'] : 0,
|
||||||
|
deleted: json['deleted'] == 'true',
|
||||||
|
name: json['name'],
|
||||||
|
active: json['active'],
|
||||||
|
notes: json['notes'],
|
||||||
|
source: source,
|
||||||
|
);
|
||||||
|
|
||||||
|
BolusProfile.put(bolusProfile);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ class GlucoseTarget {
|
|||||||
double fromMmolPerL;
|
double fromMmolPerL;
|
||||||
double toMmolPerL;
|
double toMmolPerL;
|
||||||
int color;
|
int color;
|
||||||
|
String? source;
|
||||||
|
|
||||||
// constructor
|
// constructor
|
||||||
GlucoseTarget({
|
GlucoseTarget({
|
||||||
@ -27,6 +28,7 @@ class GlucoseTarget {
|
|||||||
required this.fromMmolPerL,
|
required this.fromMmolPerL,
|
||||||
required this.toMmolPerL,
|
required this.toMmolPerL,
|
||||||
required this.color,
|
required this.color,
|
||||||
|
this.source,
|
||||||
});
|
});
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
@ -49,11 +51,15 @@ class GlucoseTarget {
|
|||||||
if (mgPerDl > 0 &&
|
if (mgPerDl > 0 &&
|
||||||
(mmolPerL == 0 ||
|
(mmolPerL == 0 ||
|
||||||
Settings.glucoseMeasurement == GlucoseMeasurement.mgPerDl)) {
|
Settings.glucoseMeasurement == GlucoseMeasurement.mgPerDl)) {
|
||||||
condition = GlucoseTarget_.fromMgPerDL.lessOrEqual(mgPerDl).and(GlucoseTarget_.toMgPerDl.greaterOrEqual(mgPerDl));
|
condition = GlucoseTarget_.fromMgPerDL
|
||||||
|
.lessOrEqual(mgPerDl)
|
||||||
|
.and(GlucoseTarget_.toMgPerDl.greaterOrEqual(mgPerDl));
|
||||||
} else if (mmolPerL > 0 &&
|
} else if (mmolPerL > 0 &&
|
||||||
(mgPerDl == 0 ||
|
(mgPerDl == 0 ||
|
||||||
Settings.glucoseMeasurement == GlucoseMeasurement.mmolPerL)) {
|
Settings.glucoseMeasurement == GlucoseMeasurement.mmolPerL)) {
|
||||||
condition = GlucoseTarget_.fromMmolPerL.lessOrEqual(mmolPerL).and(GlucoseTarget_.toMmolPerL.greaterOrEqual(mmolPerL));
|
condition = GlucoseTarget_.fromMmolPerL
|
||||||
|
.lessOrEqual(mmolPerL)
|
||||||
|
.and(GlucoseTarget_.toMmolPerL.greaterOrEqual(mmolPerL));
|
||||||
} else {
|
} else {
|
||||||
return Colors.black;
|
return Colors.black;
|
||||||
}
|
}
|
||||||
@ -119,4 +125,33 @@ class GlucoseTarget {
|
|||||||
];
|
];
|
||||||
box.putMany(defaultTargets);
|
box.putMany(defaultTargets);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = <String, dynamic>{};
|
||||||
|
data['id'] = id;
|
||||||
|
data['deleted'] = deleted;
|
||||||
|
data['fromMgPerDL'] = fromMgPerDL;
|
||||||
|
data['toMgPerDl'] = toMgPerDl;
|
||||||
|
data['fromMmolPerL'] = fromMmolPerL;
|
||||||
|
data['toMmolPerL'] = toMmolPerL;
|
||||||
|
data['color'] = color;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static String? putFromJson(Map<String, dynamic> json, bool overrideExisting, String? source) {
|
||||||
|
final glucoseTarget = GlucoseTarget(
|
||||||
|
id: overrideExisting ? json['id'] : 0,
|
||||||
|
deleted: json['deleted'],
|
||||||
|
fromMgPerDL: json['fromMgPerDL'],
|
||||||
|
toMgPerDl: json['toMgPerDl'],
|
||||||
|
fromMmolPerL: json['fromMmolPerL'],
|
||||||
|
toMmolPerL: json['toMmolPerL'],
|
||||||
|
color: json['color'],
|
||||||
|
source: source,
|
||||||
|
);
|
||||||
|
|
||||||
|
GlucoseTarget.put(glucoseTarget);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ class LogBolus {
|
|||||||
double? mmolPerLCorrection;
|
double? mmolPerLCorrection;
|
||||||
bool setManually;
|
bool setManually;
|
||||||
String? notes;
|
String? notes;
|
||||||
|
String? source;
|
||||||
|
|
||||||
// relations
|
// relations
|
||||||
final logEntry = ToOne<LogEntry>();
|
final logEntry = ToOne<LogEntry>();
|
||||||
@ -45,6 +46,7 @@ class LogBolus {
|
|||||||
this.mmolPerLCorrection,
|
this.mmolPerLCorrection,
|
||||||
this.setManually = false,
|
this.setManually = false,
|
||||||
this.notes,
|
this.notes,
|
||||||
|
this.source,
|
||||||
});
|
});
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
@ -72,8 +74,7 @@ class LogBolus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool bolusForMealExists(int id) {
|
static bool bolusForMealExists(int id) {
|
||||||
QueryBuilder<LogBolus> builder = box.query(LogBolus_.deleted
|
QueryBuilder<LogBolus> builder = box.query(LogBolus_.deleted.equals(false));
|
||||||
.equals(false));
|
|
||||||
builder.link(LogBolus_.meal, LogMeal_.id.equals(id));
|
builder.link(LogBolus_.meal, LogMeal_.id.equals(id));
|
||||||
return builder.build().find().isNotEmpty;
|
return builder.build().find().isNotEmpty;
|
||||||
}
|
}
|
||||||
@ -86,8 +87,63 @@ class LogBolus {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void removeAllForEntry(int id) {
|
||||||
|
box.putMany(getAllForEntry(id).map((item) {
|
||||||
|
item.deleted = true;
|
||||||
|
return item;
|
||||||
|
}).toList());
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return units.toString();
|
return units.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = <String, dynamic>{};
|
||||||
|
data['id'] = id;
|
||||||
|
data['deleted'] = deleted;
|
||||||
|
data['units'] = units;
|
||||||
|
data['carbs'] = carbs;
|
||||||
|
data['delay'] = delay;
|
||||||
|
data['mgPerDlCurrent'] = mgPerDlCurrent;
|
||||||
|
data['mgPerDlTarget'] = mgPerDlTarget;
|
||||||
|
data['mgPerDlCorrection'] = mgPerDlCorrection;
|
||||||
|
data['mmolPerLCurrent'] = mmolPerLCurrent;
|
||||||
|
data['mmolPerLTarget'] = mmolPerLTarget;
|
||||||
|
data['mmolPerLCorrection'] = mmolPerLCorrection;
|
||||||
|
data['setManually'] = setManually;
|
||||||
|
data['notes'] = notes;
|
||||||
|
data['logEntry'] = logEntry.targetId;
|
||||||
|
data['rate'] = rate.targetId;
|
||||||
|
data['meal'] = meal.targetId;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static String? putFromJson(Map<String, dynamic> json, bool overrideExisting, String? source) {
|
||||||
|
final logBolus = LogBolus(
|
||||||
|
id: overrideExisting ? json['id'] : 0,
|
||||||
|
deleted: json['deleted'],
|
||||||
|
units: json['units'],
|
||||||
|
carbs: json['carbs'],
|
||||||
|
delay: json['delay'],
|
||||||
|
mgPerDlCurrent: json['mgPerDlCurrent'],
|
||||||
|
mgPerDlTarget: json['mgPerDlTarget'],
|
||||||
|
mgPerDlCorrection: json['mgPerDlCorrection'],
|
||||||
|
mmolPerLCurrent: json['mmolPerLCurrent'],
|
||||||
|
mmolPerLTarget: json['mmolPerLTarget'],
|
||||||
|
mmolPerLCorrection: json['mmolPerLCorrection'],
|
||||||
|
setManually: json['setManually'],
|
||||||
|
notes: json['notes'],
|
||||||
|
source: source,
|
||||||
|
);
|
||||||
|
|
||||||
|
logBolus.logEntry.targetId = json['logEntry'];
|
||||||
|
logBolus.rate.targetId = json['rate'];
|
||||||
|
logBolus.meal.targetId = json['meal'];
|
||||||
|
|
||||||
|
LogBolus.put(logBolus);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import 'package:diameter/main.dart';
|
import 'package:diameter/main.dart';
|
||||||
import 'package:diameter/models/log_bolus.dart';
|
import 'package:diameter/models/log_bolus.dart';
|
||||||
|
import 'package:diameter/models/log_meal.dart';
|
||||||
import 'package:diameter/models/settings.dart';
|
import 'package:diameter/models/settings.dart';
|
||||||
import 'package:diameter/utils/date_time_utils.dart';
|
import 'package:diameter/utils/date_time_utils.dart';
|
||||||
import 'package:objectbox/objectbox.dart';
|
import 'package:objectbox/objectbox.dart';
|
||||||
@ -19,6 +20,7 @@ class LogEntry {
|
|||||||
double? mmolPerL;
|
double? mmolPerL;
|
||||||
double? glucoseTrend;
|
double? glucoseTrend;
|
||||||
String? notes;
|
String? notes;
|
||||||
|
String? source;
|
||||||
|
|
||||||
// constructor
|
// constructor
|
||||||
LogEntry({
|
LogEntry({
|
||||||
@ -29,6 +31,7 @@ class LogEntry {
|
|||||||
this.mmolPerL,
|
this.mmolPerL,
|
||||||
this.glucoseTrend,
|
this.glucoseTrend,
|
||||||
this.notes,
|
this.notes,
|
||||||
|
this.source,
|
||||||
});
|
});
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
@ -40,6 +43,8 @@ class LogEntry {
|
|||||||
final item = box.get(id);
|
final item = box.get(id);
|
||||||
if (item != null) {
|
if (item != null) {
|
||||||
item.deleted = true;
|
item.deleted = true;
|
||||||
|
LogMeal.removeAllForEntry(id);
|
||||||
|
LogBolus.removeAllForEntry(id);
|
||||||
box.put(item);
|
box.put(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -64,8 +69,77 @@ class LogEntry {
|
|||||||
}).toList();
|
}).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static List<LogEntry> getAllByFilter({
|
||||||
|
DateTime? startDate,
|
||||||
|
DateTime? endDate,
|
||||||
|
int? minMgPerDl,
|
||||||
|
int? maxMgPerDl,
|
||||||
|
double? minMmolPerL,
|
||||||
|
double? maxMmolPerL,
|
||||||
|
int? mealId,
|
||||||
|
String? mealName,
|
||||||
|
String? note,
|
||||||
|
}) {
|
||||||
|
DateTime start = startDate ?? DateTime(2000, 1, 1);
|
||||||
|
DateTime end = endDate ?? DateTime.now();
|
||||||
|
QueryBuilder<LogEntry> builder = box.query(LogEntry_.deleted.equals(false) &
|
||||||
|
(Settings.glucoseMeasurement == GlucoseMeasurement.mgPerDl
|
||||||
|
? LogEntry_.mgPerDl.between(
|
||||||
|
minMgPerDl ?? 0, maxMgPerDl ?? double.maxFinite.toInt())
|
||||||
|
: LogEntry_.mmolPerL
|
||||||
|
.between(minMmolPerL ?? 0, maxMmolPerL ?? double.maxFinite)))
|
||||||
|
..order(LogEntry_.time, flags: Order.descending);
|
||||||
|
|
||||||
|
return builder.build().find().where((entry) {
|
||||||
|
return (note == null || (entry.notes ?? '').contains(note)) &&
|
||||||
|
(mealId == null ||
|
||||||
|
LogMeal.getAllForEntry(entry.id)
|
||||||
|
.any((LogMeal logMeal) => logMeal.meal.targetId == mealId)) &&
|
||||||
|
(mealName == null ||
|
||||||
|
LogMeal.getAllForEntry(entry.id).any(
|
||||||
|
(LogMeal logMeal) => logMeal.value.contains(mealName))) &&
|
||||||
|
(entry.time.compareTo(start) >= 0 && entry.time.isBefore(end));
|
||||||
|
}).toList();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return DateTimeUtils.displayDateTime(time);
|
return DateTimeUtils.displayDateTime(time);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = <String, dynamic>{};
|
||||||
|
data['id'] = id;
|
||||||
|
data['deleted'] = deleted;
|
||||||
|
data['time'] = time.toIso8601String();
|
||||||
|
data['mgPerDl'] = mgPerDl;
|
||||||
|
data['mmolPerL'] = mmolPerL;
|
||||||
|
data['glucoseTrend'] = glucoseTrend;
|
||||||
|
data['notes'] = notes;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static String? putFromJson(
|
||||||
|
Map<String, dynamic> json, bool overrideExisting, String? source) {
|
||||||
|
DateTime? time = DateTime.tryParse(json['time']);
|
||||||
|
|
||||||
|
if (time == null) {
|
||||||
|
return 'time is missing';
|
||||||
|
}
|
||||||
|
|
||||||
|
final logEntry = LogEntry(
|
||||||
|
id: overrideExisting ? json['id'] : 0,
|
||||||
|
deleted: json['deleted'],
|
||||||
|
time: time,
|
||||||
|
mgPerDl: json['mgPerDl'],
|
||||||
|
mmolPerL: json['mmolPerL'],
|
||||||
|
glucoseTrend: json['glucoseTrend'],
|
||||||
|
notes: json['notes'],
|
||||||
|
source: source,
|
||||||
|
);
|
||||||
|
|
||||||
|
LogEntry.put(logEntry);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ class LogEvent {
|
|||||||
bool hasEndTime;
|
bool hasEndTime;
|
||||||
int? reminderDuration;
|
int? reminderDuration;
|
||||||
String? notes;
|
String? notes;
|
||||||
|
String? source;
|
||||||
|
|
||||||
@Transient()
|
@Transient()
|
||||||
String? title;
|
String? title;
|
||||||
@ -40,6 +41,7 @@ class LogEvent {
|
|||||||
this.hasEndTime = false,
|
this.hasEndTime = false,
|
||||||
this.reminderDuration,
|
this.reminderDuration,
|
||||||
this.notes,
|
this.notes,
|
||||||
|
this.source,
|
||||||
});
|
});
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
@ -143,4 +145,46 @@ class LogEvent {
|
|||||||
String toString() {
|
String toString() {
|
||||||
return eventType.target?.value ?? '';
|
return eventType.target?.value ?? '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = <String, dynamic>{};
|
||||||
|
data['id'] = id;
|
||||||
|
data['deleted'] = deleted;
|
||||||
|
data['time'] = time.toIso8601String();
|
||||||
|
data['endTime'] = endTime?.toIso8601String();
|
||||||
|
data['hasEndTime'] = hasEndTime;
|
||||||
|
data['reminderDuration'] = reminderDuration;
|
||||||
|
data['notes'] = notes;
|
||||||
|
data['eventType'] = eventType.targetId;
|
||||||
|
data['bolusProfile'] = bolusProfile.targetId;
|
||||||
|
data['basalProfile'] = basalProfile.targetId;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static String? putFromJson(Map<String, dynamic> json, bool overrideExisting, String? source) {
|
||||||
|
DateTime? time = DateTime.tryParse(json['time']);
|
||||||
|
|
||||||
|
if (time == null) {
|
||||||
|
return 'time is missing';
|
||||||
|
}
|
||||||
|
|
||||||
|
final logEvent = LogEvent(
|
||||||
|
id: overrideExisting ? json['id'] : 0,
|
||||||
|
deleted: json['deleted'],
|
||||||
|
time: time,
|
||||||
|
endTime: DateTime.tryParse(json['endTime']),
|
||||||
|
hasEndTime: json['hasEndTime'],
|
||||||
|
reminderDuration: json['reminderDuration'],
|
||||||
|
notes: json['notes'],
|
||||||
|
source: source,
|
||||||
|
);
|
||||||
|
|
||||||
|
logEvent.eventType.targetId = json['eventType'];
|
||||||
|
logEvent.bolusProfile.targetId = json['bolusProfile'];
|
||||||
|
logEvent.basalProfile.targetId = json['basalProfile'];
|
||||||
|
|
||||||
|
LogEvent.put(logEvent);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,10 +12,12 @@ class LogEventType {
|
|||||||
// properties
|
// properties
|
||||||
int id;
|
int id;
|
||||||
bool deleted;
|
bool deleted;
|
||||||
|
@Unique()
|
||||||
String value;
|
String value;
|
||||||
bool hasEndTime;
|
bool hasEndTime;
|
||||||
int? defaultReminderDuration;
|
int? defaultReminderDuration;
|
||||||
String? notes;
|
String? notes;
|
||||||
|
String? source;
|
||||||
|
|
||||||
// constructor
|
// constructor
|
||||||
LogEventType({
|
LogEventType({
|
||||||
@ -25,6 +27,7 @@ class LogEventType {
|
|||||||
this.hasEndTime = false,
|
this.hasEndTime = false,
|
||||||
this.defaultReminderDuration,
|
this.defaultReminderDuration,
|
||||||
this.notes,
|
this.notes,
|
||||||
|
this.source,
|
||||||
});
|
});
|
||||||
|
|
||||||
// relations
|
// relations
|
||||||
@ -52,4 +55,32 @@ class LogEventType {
|
|||||||
String toString() {
|
String toString() {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = <String, dynamic>{};
|
||||||
|
data['id'] = id;
|
||||||
|
data['deleted'] = deleted;
|
||||||
|
data['value'] = value;
|
||||||
|
data['hasEndTime'] = hasEndTime;
|
||||||
|
data['defaultReminderDuration'] = defaultReminderDuration;
|
||||||
|
data['notes'] = notes;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static String? putFromJson(Map<String, dynamic> json, bool overrideExisting, String? source) {
|
||||||
|
final logEventType = LogEventType(
|
||||||
|
id: overrideExisting ? json['id'] : 0,
|
||||||
|
deleted: json['deleted'],
|
||||||
|
value: json['value'],
|
||||||
|
hasEndTime: json['hasEndTime'],
|
||||||
|
defaultReminderDuration: json['defaultReminderDuration'],
|
||||||
|
notes: json['notes'],
|
||||||
|
source: source,
|
||||||
|
);
|
||||||
|
|
||||||
|
LogEventType.put(logEventType);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,8 +22,8 @@ class LogMeal {
|
|||||||
double? portionSize;
|
double? portionSize;
|
||||||
double? totalCarbs;
|
double? totalCarbs;
|
||||||
String? notes;
|
String? notes;
|
||||||
double? bolus;
|
|
||||||
double amount;
|
double amount;
|
||||||
|
String? source;
|
||||||
|
|
||||||
// relations
|
// relations
|
||||||
final logEntry = ToOne<LogEntry>();
|
final logEntry = ToOne<LogEntry>();
|
||||||
@ -44,6 +44,7 @@ class LogMeal {
|
|||||||
this.portionSize,
|
this.portionSize,
|
||||||
this.totalCarbs,
|
this.totalCarbs,
|
||||||
this.notes,
|
this.notes,
|
||||||
|
this.source,
|
||||||
});
|
});
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
@ -57,6 +58,13 @@ class LogMeal {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void removeAllForEntry(int id) {
|
||||||
|
box.putMany(getAllForEntry(id).map((item) {
|
||||||
|
item.deleted = true;
|
||||||
|
return item;
|
||||||
|
}).toList());
|
||||||
|
}
|
||||||
|
|
||||||
static List<LogMeal> getAllForEntry(int id) {
|
static List<LogMeal> getAllForEntry(int id) {
|
||||||
QueryBuilder<LogMeal> builder = box.query(LogMeal_.deleted.equals(false));
|
QueryBuilder<LogMeal> builder = box.query(LogMeal_.deleted.equals(false));
|
||||||
builder.link(LogMeal_.logEntry, LogEntry_.id.equals(id));
|
builder.link(LogMeal_.logEntry, LogEntry_.id.equals(id));
|
||||||
@ -86,4 +94,50 @@ class LogMeal {
|
|||||||
String toString() {
|
String toString() {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = <String, dynamic>{};
|
||||||
|
data['id'] = id;
|
||||||
|
data['deleted'] = deleted;
|
||||||
|
data['value'] = value;
|
||||||
|
data['carbsRatio'] = carbsRatio;
|
||||||
|
data['portionSize'] = portionSize;
|
||||||
|
data['totalCarbs'] = totalCarbs;
|
||||||
|
data['notes'] = notes;
|
||||||
|
data['amount'] = amount;
|
||||||
|
data['logEntry'] = logEntry.targetId;
|
||||||
|
data['meal'] = meal.targetId;
|
||||||
|
data['mealSource'] = mealSource.targetId;
|
||||||
|
data['mealCategory'] = mealCategory.targetId;
|
||||||
|
data['mealPortionType'] = mealPortionType.targetId;
|
||||||
|
data['portionSizeAccuracy'] = portionSizeAccuracy.targetId;
|
||||||
|
data['carbsRatioAccuracy'] = carbsRatioAccuracy.targetId;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static String? putFromJson(
|
||||||
|
Map<String, dynamic> json, bool overrideExisting, String? source) {
|
||||||
|
final logMeal = LogMeal(
|
||||||
|
id: overrideExisting ? json['id'] : 0,
|
||||||
|
deleted: json['deleted'] == 'true',
|
||||||
|
value: json['value'],
|
||||||
|
carbsRatio: json['carbsRatio'],
|
||||||
|
portionSize: json['portionSize'],
|
||||||
|
totalCarbs: json['totalCarbs'],
|
||||||
|
amount: json['amount'],
|
||||||
|
notes: json['notes'],
|
||||||
|
source: source,
|
||||||
|
);
|
||||||
|
|
||||||
|
logMeal.logEntry.targetId = json['logEntry'];
|
||||||
|
logMeal.meal.targetId = json['meal'];
|
||||||
|
logMeal.mealSource.targetId = json['mealSource'];
|
||||||
|
logMeal.mealCategory.targetId = json['mealCategory'];
|
||||||
|
logMeal.mealPortionType.targetId = json['mealPortionType'];
|
||||||
|
logMeal.portionSizeAccuracy.targetId = json['portionSizeAccuracy'];
|
||||||
|
logMeal.carbsRatioAccuracy.targetId = json['carbsRatioAccuracy'];
|
||||||
|
|
||||||
|
LogMeal.put(logMeal);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ class Meal {
|
|||||||
// properties
|
// properties
|
||||||
int id;
|
int id;
|
||||||
bool deleted;
|
bool deleted;
|
||||||
|
@Unique()
|
||||||
String value;
|
String value;
|
||||||
double? carbsRatio;
|
double? carbsRatio;
|
||||||
double? portionSize;
|
double? portionSize;
|
||||||
@ -23,6 +24,7 @@ class Meal {
|
|||||||
int? delayedBolusDuration;
|
int? delayedBolusDuration;
|
||||||
double? delayedBolusPercentage;
|
double? delayedBolusPercentage;
|
||||||
String? notes;
|
String? notes;
|
||||||
|
String? source;
|
||||||
|
|
||||||
// relations
|
// relations
|
||||||
final mealSource = ToOne<MealSource>();
|
final mealSource = ToOne<MealSource>();
|
||||||
@ -42,6 +44,7 @@ class Meal {
|
|||||||
this.delayedBolusDuration,
|
this.delayedBolusDuration,
|
||||||
this.delayedBolusPercentage,
|
this.delayedBolusPercentage,
|
||||||
this.notes,
|
this.notes,
|
||||||
|
this.source,
|
||||||
});
|
});
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
@ -65,4 +68,48 @@ class Meal {
|
|||||||
String toString() {
|
String toString() {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = <String, dynamic>{};
|
||||||
|
data['id'] = id;
|
||||||
|
data['deleted'] = deleted;
|
||||||
|
data['value'] = value;
|
||||||
|
data['carbsRatio'] = carbsRatio;
|
||||||
|
data['portionSize'] = portionSize;
|
||||||
|
data['carbsPerPortion'] = carbsPerPortion;
|
||||||
|
data['delayedBolusDuration'] = delayedBolusDuration;
|
||||||
|
data['delayedBolusPercentage'] = delayedBolusPercentage;
|
||||||
|
data['notes'] = notes;
|
||||||
|
data['mealSource'] = mealSource.targetId;
|
||||||
|
data['mealCategory'] = mealCategory.targetId;
|
||||||
|
data['mealPortionType'] = mealPortionType.targetId;
|
||||||
|
data['portionSizeAccuracy'] = portionSizeAccuracy.targetId;
|
||||||
|
data['carbsRatioAccuracy'] = carbsRatioAccuracy.targetId;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static String? putFromJson(
|
||||||
|
Map<String, dynamic> json, bool overrideExisting, String? source) {
|
||||||
|
final meal = Meal(
|
||||||
|
id: overrideExisting ? json['id'] : 0,
|
||||||
|
deleted: json['deleted'] == 'true',
|
||||||
|
value: json['value'],
|
||||||
|
carbsRatio: json['carbsRatio'],
|
||||||
|
portionSize: json['portionSize'],
|
||||||
|
carbsPerPortion: json['carbsPerPortion'],
|
||||||
|
delayedBolusDuration: json['delayedBolusDuration'],
|
||||||
|
delayedBolusPercentage: json['delayedBolusPercentage'],
|
||||||
|
notes: json['notes'],
|
||||||
|
source: source,
|
||||||
|
);
|
||||||
|
|
||||||
|
meal.mealSource.targetId = json['mealSource'];
|
||||||
|
meal.mealCategory.targetId = json['mealCategory'];
|
||||||
|
meal.mealPortionType.targetId = json['mealPortionType'];
|
||||||
|
meal.portionSizeAccuracy.targetId = json['portionSizeAccuracy'];
|
||||||
|
meal.carbsRatioAccuracy.targetId = json['carbsRatioAccuracy'];
|
||||||
|
|
||||||
|
Meal.put(meal);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,8 +10,10 @@ class MealCategory {
|
|||||||
// properties
|
// properties
|
||||||
int id;
|
int id;
|
||||||
bool deleted;
|
bool deleted;
|
||||||
|
@Unique()
|
||||||
String value;
|
String value;
|
||||||
String? notes;
|
String? notes;
|
||||||
|
String? source;
|
||||||
|
|
||||||
// constructor
|
// constructor
|
||||||
MealCategory({
|
MealCategory({
|
||||||
@ -19,6 +21,7 @@ class MealCategory {
|
|||||||
this.deleted = false,
|
this.deleted = false,
|
||||||
this.value = '',
|
this.value = '',
|
||||||
this.notes,
|
this.notes,
|
||||||
|
this.source,
|
||||||
});
|
});
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
@ -42,4 +45,27 @@ class MealCategory {
|
|||||||
String toString() {
|
String toString() {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = <String, dynamic>{};
|
||||||
|
data['id'] = id;
|
||||||
|
data['deleted'] = deleted;
|
||||||
|
data['value'] = value;
|
||||||
|
data['notes'] = notes;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static String? putFromJson(
|
||||||
|
Map<String, dynamic> json, bool overrideExisting, String? source) {
|
||||||
|
final mealCategory = MealCategory(
|
||||||
|
id: overrideExisting ? json['id'] : 0,
|
||||||
|
deleted: json['deleted'] == 'true',
|
||||||
|
value: json['value'],
|
||||||
|
notes: json['notes'],
|
||||||
|
source: source,
|
||||||
|
);
|
||||||
|
|
||||||
|
MealCategory.put(mealCategory);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,13 +5,16 @@ import 'package:diameter/objectbox.g.dart' show MealPortionType_;
|
|||||||
@Entity(uid: 2111511899235985637)
|
@Entity(uid: 2111511899235985637)
|
||||||
@Sync()
|
@Sync()
|
||||||
class MealPortionType {
|
class MealPortionType {
|
||||||
static final Box<MealPortionType> box = objectBox.store.box<MealPortionType>();
|
static final Box<MealPortionType> box =
|
||||||
|
objectBox.store.box<MealPortionType>();
|
||||||
|
|
||||||
// properties
|
// properties
|
||||||
int id;
|
int id;
|
||||||
bool deleted;
|
bool deleted;
|
||||||
|
@Unique()
|
||||||
String value;
|
String value;
|
||||||
String? notes;
|
String? notes;
|
||||||
|
String? source;
|
||||||
|
|
||||||
// constructor
|
// constructor
|
||||||
MealPortionType({
|
MealPortionType({
|
||||||
@ -19,6 +22,7 @@ class MealPortionType {
|
|||||||
this.deleted = false,
|
this.deleted = false,
|
||||||
this.value = '',
|
this.value = '',
|
||||||
this.notes,
|
this.notes,
|
||||||
|
this.source,
|
||||||
});
|
});
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
@ -26,7 +30,9 @@ class MealPortionType {
|
|||||||
static void put(MealPortionType mealPortionType) => box.put(mealPortionType);
|
static void put(MealPortionType mealPortionType) => box.put(mealPortionType);
|
||||||
|
|
||||||
static List<MealPortionType> getAll() {
|
static List<MealPortionType> getAll() {
|
||||||
QueryBuilder<MealPortionType> builder = box.query(MealPortionType_.deleted.equals(false))..order(MealPortionType_.value);
|
QueryBuilder<MealPortionType> builder = box
|
||||||
|
.query(MealPortionType_.deleted.equals(false))
|
||||||
|
..order(MealPortionType_.value);
|
||||||
return builder.build().find();
|
return builder.build().find();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,4 +48,27 @@ class MealPortionType {
|
|||||||
String toString() {
|
String toString() {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = <String, dynamic>{};
|
||||||
|
data['id'] = id;
|
||||||
|
data['deleted'] = deleted;
|
||||||
|
data['value'] = value;
|
||||||
|
data['notes'] = notes;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static String? putFromJson(
|
||||||
|
Map<String, dynamic> json, bool overrideExisting, String? source) {
|
||||||
|
final mealPortionType = MealPortionType(
|
||||||
|
id: overrideExisting ? json['id'] : 0,
|
||||||
|
deleted: json['deleted'] == 'true',
|
||||||
|
value: json['value'],
|
||||||
|
notes: json['notes'],
|
||||||
|
source: source,
|
||||||
|
);
|
||||||
|
|
||||||
|
MealPortionType.put(mealPortionType);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,8 +13,10 @@ class MealSource {
|
|||||||
// properties
|
// properties
|
||||||
int id;
|
int id;
|
||||||
bool deleted;
|
bool deleted;
|
||||||
|
@Unique()
|
||||||
String value;
|
String value;
|
||||||
String? notes;
|
String? notes;
|
||||||
|
String? source;
|
||||||
|
|
||||||
// relations
|
// relations
|
||||||
final defaultMealCategory = ToOne<MealCategory>();
|
final defaultMealCategory = ToOne<MealCategory>();
|
||||||
@ -28,6 +30,7 @@ class MealSource {
|
|||||||
this.deleted = false,
|
this.deleted = false,
|
||||||
this.value = '',
|
this.value = '',
|
||||||
this.notes,
|
this.notes,
|
||||||
|
this.source,
|
||||||
});
|
});
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
@ -35,7 +38,8 @@ class MealSource {
|
|||||||
static void put(MealSource mealSource) => box.put(mealSource);
|
static void put(MealSource mealSource) => box.put(mealSource);
|
||||||
|
|
||||||
static List<MealSource> getAll() {
|
static List<MealSource> getAll() {
|
||||||
QueryBuilder<MealSource> builder = box.query(MealSource_.deleted.equals(false))..order(MealSource_.value);
|
QueryBuilder<MealSource> builder =
|
||||||
|
box.query(MealSource_.deleted.equals(false))..order(MealSource_.value);
|
||||||
return builder.build().find();
|
return builder.build().find();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,4 +55,36 @@ class MealSource {
|
|||||||
String toString() {
|
String toString() {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = <String, dynamic>{};
|
||||||
|
data['id'] = id;
|
||||||
|
data['deleted'] = deleted;
|
||||||
|
data['value'] = value;
|
||||||
|
data['notes'] = notes;
|
||||||
|
data['defaultMealCategory'] = defaultMealCategory.targetId;
|
||||||
|
data['defaultMealPortionType'] = defaultMealPortionType.targetId;
|
||||||
|
data['defaultCarbsRatioAccuracy'] = defaultCarbsRatioAccuracy.targetId;
|
||||||
|
data['defaultPortionSizeAccuracy'] = defaultPortionSizeAccuracy.targetId;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static String? putFromJson(
|
||||||
|
Map<String, dynamic> json, bool overrideExisting, String? source) {
|
||||||
|
final mealSource = MealSource(
|
||||||
|
id: overrideExisting ? json['id'] : 0,
|
||||||
|
deleted: json['deleted'] == 'true',
|
||||||
|
value: json['value'],
|
||||||
|
notes: json['notes'],
|
||||||
|
source: source,
|
||||||
|
);
|
||||||
|
|
||||||
|
mealSource.defaultMealCategory.targetId = json['defaultMealCategory'];
|
||||||
|
mealSource.defaultMealPortionType.targetId = json['defaultMealPortionType'];
|
||||||
|
mealSource.defaultCarbsRatioAccuracy.targetId = json['defaultCarbsRatioAccuracy'];
|
||||||
|
mealSource.defaultPortionSizeAccuracy.targetId = json['defaultPortionSizeAccuracy'];
|
||||||
|
|
||||||
|
MealSource.put(mealSource);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -69,6 +69,8 @@ class Settings {
|
|||||||
|
|
||||||
bool useDarkTheme;
|
bool useDarkTheme;
|
||||||
|
|
||||||
|
DateTime? lastExportTimestamp;
|
||||||
|
|
||||||
// constructor
|
// constructor
|
||||||
Settings({
|
Settings({
|
||||||
this.id = 0,
|
this.id = 0,
|
||||||
@ -89,6 +91,7 @@ class Settings {
|
|||||||
this.targetGlucoseMgPerDl = 100,
|
this.targetGlucoseMgPerDl = 100,
|
||||||
this.targetGlucoseMmolPerL = 5.5,
|
this.targetGlucoseMmolPerL = 5.5,
|
||||||
this.useDarkTheme = false,
|
this.useDarkTheme = false,
|
||||||
|
this.lastExportTimestamp,
|
||||||
});
|
});
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
@ -101,7 +104,8 @@ class Settings {
|
|||||||
|
|
||||||
static NutritionMeasurement get nutritionMeasurement =>
|
static NutritionMeasurement get nutritionMeasurement =>
|
||||||
NutritionMeasurement.values[get().nutritionMeasurementIndex];
|
NutritionMeasurement.values[get().nutritionMeasurementIndex];
|
||||||
static GlucoseMeasurement get glucoseMeasurement => GlucoseMeasurement.values[get().glucoseMeasurementIndex];
|
static GlucoseMeasurement get glucoseMeasurement =>
|
||||||
|
GlucoseMeasurement.values[get().glucoseMeasurementIndex];
|
||||||
static GlucoseDisplayMode get glucoseDisplayMode =>
|
static GlucoseDisplayMode get glucoseDisplayMode =>
|
||||||
GlucoseDisplayMode.values[get().glucoseDisplayModeIndex];
|
GlucoseDisplayMode.values[get().glucoseDisplayModeIndex];
|
||||||
|
|
||||||
@ -120,10 +124,39 @@ class Settings {
|
|||||||
static ThemeMode get themeMode =>
|
static ThemeMode get themeMode =>
|
||||||
get().useDarkTheme ? ThemeMode.dark : ThemeMode.light;
|
get().useDarkTheme ? ThemeMode.dark : ThemeMode.light;
|
||||||
|
|
||||||
|
static DateTime? get lastExportTimeStamp => get().lastExportTimestamp;
|
||||||
|
|
||||||
static void put(Settings settings) => box.put(settings);
|
static void put(Settings settings) => box.put(settings);
|
||||||
|
|
||||||
static void reset() {
|
static void reset() {
|
||||||
box.removeAll();
|
box.removeAll();
|
||||||
box.put(Settings(useDarkTheme: ThemeMode.system == ThemeMode.dark));
|
box.put(Settings(useDarkTheme: ThemeMode.system == ThemeMode.dark));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Map<String, dynamic> toJson() {
|
||||||
|
Settings settings = get();
|
||||||
|
final Map<String, dynamic> data = <String, dynamic>{};
|
||||||
|
data['id'] = settings.id;
|
||||||
|
data['nutritionMeasurementIndex'] = settings.nutritionMeasurementIndex;
|
||||||
|
data['glucoseDisplayModeIndex'] = settings.glucoseDisplayModeIndex;
|
||||||
|
data['glucoseMeasurementIndex'] = settings.glucoseMeasurementIndex;
|
||||||
|
data['targetGlucoseMgPerDl'] = settings.targetGlucoseMgPerDl;
|
||||||
|
data['targetGlucoseMmolPerL'] = settings.targetGlucoseMmolPerL;
|
||||||
|
data['insulinIncrements'] = settings.insulinIncrements;
|
||||||
|
data['nutritionIncrements'] = settings.nutritionIncrements;
|
||||||
|
data['mmolPerLIncrements'] = settings.mmolPerLIncrements;
|
||||||
|
data['amountIncrements'] = settings.amountIncrements;
|
||||||
|
data['dateFormat'] = settings.dateFormat;
|
||||||
|
data['longDateFormat'] = settings.longDateFormat;
|
||||||
|
data['timeFormat'] = settings.timeFormat;
|
||||||
|
data['longTimeFormat'] = settings.longTimeFormat;
|
||||||
|
data['showConfirmationDialogOnCancel'] =
|
||||||
|
settings.showConfirmationDialogOnCancel;
|
||||||
|
data['showConfirmationDialogOnDelete'] =
|
||||||
|
settings.showConfirmationDialogOnDelete;
|
||||||
|
data['showConfirmationDialogOnStopEvent'] =
|
||||||
|
settings.showConfirmationDialogOnStopEvent;
|
||||||
|
data['useDarkTheme'] = settings.useDarkTheme;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import 'package:diameter/main.dart';
|
import 'package:diameter/main.dart';
|
||||||
import 'package:diameter/models/meal.dart';
|
import 'package:diameter/models/meal.dart';
|
||||||
import 'package:diameter/models/recipe.dart';
|
import 'package:diameter/models/x_recipe.dart';
|
||||||
import 'package:diameter/utils/utils.dart';
|
import 'package:diameter/utils/utils.dart';
|
||||||
import 'package:objectbox/objectbox.dart';
|
import 'package:objectbox/objectbox.dart';
|
||||||
import 'package:diameter/objectbox.g.dart' show Ingredient_, Recipe_;
|
import 'package:diameter/objectbox.g.dart' show Ingredient_, Recipe_;
|
||||||
|
|
||||||
@Entity(uid: 6950311793136068892)
|
// @Entity(uid: 6950311793136068892)
|
||||||
@Sync()
|
// @Sync()
|
||||||
class Ingredient {
|
class Ingredient {
|
||||||
static final Box<Ingredient> box = objectBox.store.box<Ingredient>();
|
static final Box<Ingredient> box = objectBox.store.box<Ingredient>();
|
||||||
|
|
@ -1,12 +1,12 @@
|
|||||||
import 'package:diameter/main.dart';
|
import 'package:diameter/main.dart';
|
||||||
import 'package:diameter/models/ingredient.dart';
|
import 'package:diameter/models/x_ingredient.dart';
|
||||||
import 'package:diameter/models/meal.dart';
|
import 'package:diameter/models/meal.dart';
|
||||||
import 'package:diameter/utils/utils.dart';
|
import 'package:diameter/utils/utils.dart';
|
||||||
import 'package:objectbox/objectbox.dart';
|
import 'package:objectbox/objectbox.dart';
|
||||||
import 'package:diameter/objectbox.g.dart' show Recipe_;
|
import 'package:diameter/objectbox.g.dart' show Recipe_;
|
||||||
|
|
||||||
@Entity(uid: 6497942314956341514)
|
// @Entity(uid: 6497942314956341514)
|
||||||
@Sync()
|
// @Sync()
|
||||||
class Recipe {
|
class Recipe {
|
||||||
static final Box<Recipe> box = objectBox.store.box<Recipe>();
|
static final Box<Recipe> box = objectBox.store.box<Recipe>();
|
||||||
|
|
@ -1,8 +1,8 @@
|
|||||||
import 'package:diameter/main.dart';
|
import 'package:diameter/main.dart';
|
||||||
import 'package:objectbox/objectbox.dart';
|
import 'package:objectbox/objectbox.dart';
|
||||||
|
|
||||||
@Entity()
|
// @Entity()
|
||||||
@Sync()
|
// @Sync()
|
||||||
class User {
|
class User {
|
||||||
static final Box<User> box = objectBox.store.box<User>();
|
static final Box<User> box = objectBox.store.box<User>();
|
||||||
// properties
|
// properties
|
@ -1,3 +1,4 @@
|
|||||||
|
import 'package:diameter/localization_keys.dart';
|
||||||
import 'package:diameter/screens/category/categories.dart';
|
import 'package:diameter/screens/category/categories.dart';
|
||||||
import 'package:diameter/screens/category/accuracy_detail.dart';
|
import 'package:diameter/screens/category/accuracy_detail.dart';
|
||||||
import 'package:diameter/screens/category/accuracy_list.dart';
|
import 'package:diameter/screens/category/accuracy_list.dart';
|
||||||
@ -28,6 +29,7 @@ import 'package:diameter/screens/reports/export.dart';
|
|||||||
import 'package:diameter/screens/reports/reports.dart';
|
import 'package:diameter/screens/reports/reports.dart';
|
||||||
import 'package:diameter/settings.dart';
|
import 'package:diameter/settings.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_translate/flutter_translate.dart';
|
||||||
|
|
||||||
class Routes {
|
class Routes {
|
||||||
static const String basal = BasalDetailScreen.routeName;
|
static const String basal = BasalDetailScreen.routeName;
|
||||||
@ -119,7 +121,7 @@ class _NavigationState extends State<Navigation> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
title: const Text('Log'),
|
title: Text(translate(LocalizationKeys.navigation_log)),
|
||||||
leading: const Icon(Icons.dashboard),
|
leading: const Icon(Icons.dashboard),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
selectDestination(Routes.log);
|
selectDestination(Routes.log);
|
||||||
@ -127,7 +129,7 @@ class _NavigationState extends State<Navigation> {
|
|||||||
selected: widget.currentLocation == Routes.log,
|
selected: widget.currentLocation == Routes.log,
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
title: const Text('Log Events'),
|
title: Text(translate(LocalizationKeys.navigation_logEvents)),
|
||||||
leading: const Icon(Icons.event),
|
leading: const Icon(Icons.event),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
selectDestination(Routes.logEvents);
|
selectDestination(Routes.logEvents);
|
||||||
@ -135,7 +137,7 @@ class _NavigationState extends State<Navigation> {
|
|||||||
selected: widget.currentLocation == Routes.logEvents,
|
selected: widget.currentLocation == Routes.logEvents,
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
title: const Text('Reports'),
|
title: Text(translate(LocalizationKeys.navigation_reports)),
|
||||||
leading: const Icon(Icons.show_chart),
|
leading: const Icon(Icons.show_chart),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
selectDestination(Routes.reports);
|
selectDestination(Routes.reports);
|
||||||
@ -143,7 +145,7 @@ class _NavigationState extends State<Navigation> {
|
|||||||
selected: Routes.reportRoutes.contains(widget.currentLocation),
|
selected: Routes.reportRoutes.contains(widget.currentLocation),
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
title: const Text('Meals'),
|
title: Text(translate(LocalizationKeys.navigation_meals)),
|
||||||
leading: const Icon(Icons.dinner_dining),
|
leading: const Icon(Icons.dinner_dining),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
selectDestination(Routes.meals);
|
selectDestination(Routes.meals);
|
||||||
@ -151,7 +153,7 @@ class _NavigationState extends State<Navigation> {
|
|||||||
selected: Routes.mealRoutes.contains(widget.currentLocation),
|
selected: Routes.mealRoutes.contains(widget.currentLocation),
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
title: const Text('Basal Profiles'),
|
title: Text(translate(LocalizationKeys.navigation_basalProfiles)),
|
||||||
leading: const Icon(Icons.access_time),
|
leading: const Icon(Icons.access_time),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
selectDestination(Routes.basalProfiles);
|
selectDestination(Routes.basalProfiles);
|
||||||
@ -159,7 +161,7 @@ class _NavigationState extends State<Navigation> {
|
|||||||
selected: Routes.basalRoutes.contains(widget.currentLocation),
|
selected: Routes.basalRoutes.contains(widget.currentLocation),
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
title: const Text('Bolus Profiles'),
|
title: Text(translate(LocalizationKeys.navigation_bolusProfiles)),
|
||||||
leading: const Icon(Icons.medication),
|
leading: const Icon(Icons.medication),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
selectDestination(Routes.bolusProfiles);
|
selectDestination(Routes.bolusProfiles);
|
||||||
@ -167,7 +169,7 @@ class _NavigationState extends State<Navigation> {
|
|||||||
selected: Routes.bolusRoutes.contains(widget.currentLocation),
|
selected: Routes.bolusRoutes.contains(widget.currentLocation),
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
title: const Text('Categorization'),
|
title: Text(translate(LocalizationKeys.navigation_categorization)),
|
||||||
leading: const Icon(Icons.category),
|
leading: const Icon(Icons.category),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
selectDestination(Routes.category);
|
selectDestination(Routes.category);
|
||||||
@ -175,7 +177,7 @@ class _NavigationState extends State<Navigation> {
|
|||||||
selected: Routes.categoryRoutes.contains(widget.currentLocation),
|
selected: Routes.categoryRoutes.contains(widget.currentLocation),
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
title: const Text('Settings'),
|
title: Text(translate(LocalizationKeys.navigation_settings)),
|
||||||
leading: const Icon(Icons.settings),
|
leading: const Icon(Icons.settings),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
selectDestination(Routes.settings);
|
selectDestination(Routes.settings);
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
"entities": [
|
"entities": [
|
||||||
{
|
{
|
||||||
"id": "2:1467758525778521891",
|
"id": "2:1467758525778521891",
|
||||||
"lastPropertyId": "6:3409466778841164684",
|
"lastPropertyId": "7:3194552447464951410",
|
||||||
"name": "Basal",
|
"name": "Basal",
|
||||||
"flags": 2,
|
"flags": 2,
|
||||||
"properties": [
|
"properties": [
|
||||||
@ -42,13 +42,18 @@
|
|||||||
"id": "6:3409466778841164684",
|
"id": "6:3409466778841164684",
|
||||||
"name": "deleted",
|
"name": "deleted",
|
||||||
"type": 1
|
"type": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "7:3194552447464951410",
|
||||||
|
"name": "source",
|
||||||
|
"type": 9
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"relations": []
|
"relations": []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "3:3613736032926903785",
|
"id": "3:3613736032926903785",
|
||||||
"lastPropertyId": "5:8140071977687660397",
|
"lastPropertyId": "6:3153627070507809184",
|
||||||
"name": "BasalProfile",
|
"name": "BasalProfile",
|
||||||
"flags": 2,
|
"flags": 2,
|
||||||
"properties": [
|
"properties": [
|
||||||
@ -77,13 +82,18 @@
|
|||||||
"id": "5:8140071977687660397",
|
"id": "5:8140071977687660397",
|
||||||
"name": "deleted",
|
"name": "deleted",
|
||||||
"type": 1
|
"type": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "6:3153627070507809184",
|
||||||
|
"name": "source",
|
||||||
|
"type": 9
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"relations": []
|
"relations": []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "4:3417770529060202389",
|
"id": "4:3417770529060202389",
|
||||||
"lastPropertyId": "9:7440090146687096977",
|
"lastPropertyId": "10:6138236789530596038",
|
||||||
"name": "Bolus",
|
"name": "Bolus",
|
||||||
"flags": 2,
|
"flags": 2,
|
||||||
"properties": [
|
"properties": [
|
||||||
@ -135,13 +145,18 @@
|
|||||||
"id": "9:7440090146687096977",
|
"id": "9:7440090146687096977",
|
||||||
"name": "deleted",
|
"name": "deleted",
|
||||||
"type": 1
|
"type": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "10:6138236789530596038",
|
||||||
|
"name": "source",
|
||||||
|
"type": 9
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"relations": []
|
"relations": []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "5:8812452529027052317",
|
"id": "5:8812452529027052317",
|
||||||
"lastPropertyId": "5:8082994824481464395",
|
"lastPropertyId": "6:8746199841403936632",
|
||||||
"name": "BolusProfile",
|
"name": "BolusProfile",
|
||||||
"flags": 2,
|
"flags": 2,
|
||||||
"properties": [
|
"properties": [
|
||||||
@ -170,13 +185,18 @@
|
|||||||
"id": "5:8082994824481464395",
|
"id": "5:8082994824481464395",
|
||||||
"name": "deleted",
|
"name": "deleted",
|
||||||
"type": 1
|
"type": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "6:8746199841403936632",
|
||||||
|
"name": "source",
|
||||||
|
"type": 9
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"relations": []
|
"relations": []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "6:752131069307970560",
|
"id": "6:752131069307970560",
|
||||||
"lastPropertyId": "10:2505303363495348118",
|
"lastPropertyId": "11:8454251731096762477",
|
||||||
"name": "LogEntry",
|
"name": "LogEntry",
|
||||||
"flags": 2,
|
"flags": 2,
|
||||||
"properties": [
|
"properties": [
|
||||||
@ -215,13 +235,18 @@
|
|||||||
"id": "10:2505303363495348118",
|
"id": "10:2505303363495348118",
|
||||||
"name": "glucoseTrend",
|
"name": "glucoseTrend",
|
||||||
"type": 8
|
"type": 8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "11:8454251731096762477",
|
||||||
|
"name": "source",
|
||||||
|
"type": 9
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"relations": []
|
"relations": []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "7:4303325892753185970",
|
"id": "7:4303325892753185970",
|
||||||
"lastPropertyId": "12:3041952167628926163",
|
"lastPropertyId": "13:9206766629540069341",
|
||||||
"name": "LogEvent",
|
"name": "LogEvent",
|
||||||
"flags": 2,
|
"flags": 2,
|
||||||
"properties": [
|
"properties": [
|
||||||
@ -284,13 +309,18 @@
|
|||||||
"id": "12:3041952167628926163",
|
"id": "12:3041952167628926163",
|
||||||
"name": "reminderDuration",
|
"name": "reminderDuration",
|
||||||
"type": 6
|
"type": 6
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "13:9206766629540069341",
|
||||||
|
"name": "source",
|
||||||
|
"type": 9
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"relations": []
|
"relations": []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "8:8362795406595606110",
|
"id": "8:8362795406595606110",
|
||||||
"lastPropertyId": "8:1869014400856897151",
|
"lastPropertyId": "9:7377683740652293217",
|
||||||
"name": "LogEventType",
|
"name": "LogEventType",
|
||||||
"flags": 2,
|
"flags": 2,
|
||||||
"properties": [
|
"properties": [
|
||||||
@ -340,13 +370,18 @@
|
|||||||
"flags": 520,
|
"flags": 520,
|
||||||
"indexId": "28:4563029809754152081",
|
"indexId": "28:4563029809754152081",
|
||||||
"relationTarget": "BasalProfile"
|
"relationTarget": "BasalProfile"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "9:7377683740652293217",
|
||||||
|
"name": "source",
|
||||||
|
"type": 9
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"relations": []
|
"relations": []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "9:411177866700467286",
|
"id": "9:411177866700467286",
|
||||||
"lastPropertyId": "19:8965198821438347033",
|
"lastPropertyId": "20:3296734778930341954",
|
||||||
"name": "LogMeal",
|
"name": "LogMeal",
|
||||||
"flags": 2,
|
"flags": 2,
|
||||||
"properties": [
|
"properties": [
|
||||||
@ -371,11 +406,6 @@
|
|||||||
"name": "portionSize",
|
"name": "portionSize",
|
||||||
"type": 8
|
"type": 8
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"id": "6:8074052538574863399",
|
|
||||||
"name": "bolus",
|
|
||||||
"type": 8
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"id": "9:1920579694098037947",
|
"id": "9:1920579694098037947",
|
||||||
"name": "notes",
|
"name": "notes",
|
||||||
@ -451,13 +481,18 @@
|
|||||||
"id": "19:8965198821438347033",
|
"id": "19:8965198821438347033",
|
||||||
"name": "totalCarbs",
|
"name": "totalCarbs",
|
||||||
"type": 8
|
"type": 8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "20:3296734778930341954",
|
||||||
|
"name": "source",
|
||||||
|
"type": 9
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"relations": []
|
"relations": []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "10:382130101578692012",
|
"id": "10:382130101578692012",
|
||||||
"lastPropertyId": "15:8283810711091063880",
|
"lastPropertyId": "16:8612850434699732822",
|
||||||
"name": "Meal",
|
"name": "Meal",
|
||||||
"flags": 2,
|
"flags": 2,
|
||||||
"properties": [
|
"properties": [
|
||||||
@ -546,13 +581,18 @@
|
|||||||
"id": "15:8283810711091063880",
|
"id": "15:8283810711091063880",
|
||||||
"name": "delayedBolusPercentage",
|
"name": "delayedBolusPercentage",
|
||||||
"type": 8
|
"type": 8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "16:8612850434699732822",
|
||||||
|
"name": "source",
|
||||||
|
"type": 9
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"relations": []
|
"relations": []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "11:3158200688796904913",
|
"id": "11:3158200688796904913",
|
||||||
"lastPropertyId": "4:824435977543069541",
|
"lastPropertyId": "5:2221810999445049020",
|
||||||
"name": "MealCategory",
|
"name": "MealCategory",
|
||||||
"flags": 2,
|
"flags": 2,
|
||||||
"properties": [
|
"properties": [
|
||||||
@ -576,13 +616,18 @@
|
|||||||
"id": "4:824435977543069541",
|
"id": "4:824435977543069541",
|
||||||
"name": "deleted",
|
"name": "deleted",
|
||||||
"type": 1
|
"type": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "5:2221810999445049020",
|
||||||
|
"name": "source",
|
||||||
|
"type": 9
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"relations": []
|
"relations": []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "12:2111511899235985637",
|
"id": "12:2111511899235985637",
|
||||||
"lastPropertyId": "4:5680236937391945907",
|
"lastPropertyId": "5:6807468448392267469",
|
||||||
"name": "MealPortionType",
|
"name": "MealPortionType",
|
||||||
"flags": 2,
|
"flags": 2,
|
||||||
"properties": [
|
"properties": [
|
||||||
@ -606,13 +651,18 @@
|
|||||||
"id": "4:5680236937391945907",
|
"id": "4:5680236937391945907",
|
||||||
"name": "deleted",
|
"name": "deleted",
|
||||||
"type": 1
|
"type": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "5:6807468448392267469",
|
||||||
|
"name": "source",
|
||||||
|
"type": 9
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"relations": []
|
"relations": []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "13:1283034494527412242",
|
"id": "13:1283034494527412242",
|
||||||
"lastPropertyId": "8:4547899751779962180",
|
"lastPropertyId": "9:6873017370661053783",
|
||||||
"name": "MealSource",
|
"name": "MealSource",
|
||||||
"flags": 2,
|
"flags": 2,
|
||||||
"properties": [
|
"properties": [
|
||||||
@ -668,13 +718,18 @@
|
|||||||
"id": "8:4547899751779962180",
|
"id": "8:4547899751779962180",
|
||||||
"name": "deleted",
|
"name": "deleted",
|
||||||
"type": 1
|
"type": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "9:6873017370661053783",
|
||||||
|
"name": "source",
|
||||||
|
"type": 9
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"relations": []
|
"relations": []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "14:8033487006694871160",
|
"id": "14:8033487006694871160",
|
||||||
"lastPropertyId": "18:7503231998671134983",
|
"lastPropertyId": "19:3683854670538916324",
|
||||||
"name": "LogBolus",
|
"name": "LogBolus",
|
||||||
"flags": 2,
|
"flags": 2,
|
||||||
"properties": [
|
"properties": [
|
||||||
@ -767,13 +822,18 @@
|
|||||||
"id": "18:7503231998671134983",
|
"id": "18:7503231998671134983",
|
||||||
"name": "mmolPerLCorrection",
|
"name": "mmolPerLCorrection",
|
||||||
"type": 8
|
"type": 8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "19:3683854670538916324",
|
||||||
|
"name": "source",
|
||||||
|
"type": 9
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"relations": []
|
"relations": []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "15:291512798403320400",
|
"id": "15:291512798403320400",
|
||||||
"lastPropertyId": "7:6675647182186603076",
|
"lastPropertyId": "8:1800866627092978542",
|
||||||
"name": "Accuracy",
|
"name": "Accuracy",
|
||||||
"flags": 2,
|
"flags": 2,
|
||||||
"properties": [
|
"properties": [
|
||||||
@ -812,13 +872,18 @@
|
|||||||
"id": "7:6675647182186603076",
|
"id": "7:6675647182186603076",
|
||||||
"name": "deleted",
|
"name": "deleted",
|
||||||
"type": 1
|
"type": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8:1800866627092978542",
|
||||||
|
"name": "source",
|
||||||
|
"type": 9
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"relations": []
|
"relations": []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "16:3989341091218179227",
|
"id": "16:3989341091218179227",
|
||||||
"lastPropertyId": "27:3553639710779248831",
|
"lastPropertyId": "28:7196743106880728684",
|
||||||
"name": "Settings",
|
"name": "Settings",
|
||||||
"flags": 2,
|
"flags": 2,
|
||||||
"properties": [
|
"properties": [
|
||||||
@ -912,13 +977,18 @@
|
|||||||
"id": "27:3553639710779248831",
|
"id": "27:3553639710779248831",
|
||||||
"name": "amountIncrements",
|
"name": "amountIncrements",
|
||||||
"type": 8
|
"type": 8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "28:7196743106880728684",
|
||||||
|
"name": "lastExportTimestamp",
|
||||||
|
"type": 10
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"relations": []
|
"relations": []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "17:5041265995704044399",
|
"id": "17:5041265995704044399",
|
||||||
"lastPropertyId": "7:1333487551279074696",
|
"lastPropertyId": "8:1091046738846336945",
|
||||||
"name": "GlucoseTarget",
|
"name": "GlucoseTarget",
|
||||||
"flags": 2,
|
"flags": 2,
|
||||||
"properties": [
|
"properties": [
|
||||||
@ -957,6 +1027,11 @@
|
|||||||
"id": "7:1333487551279074696",
|
"id": "7:1333487551279074696",
|
||||||
"name": "color",
|
"name": "color",
|
||||||
"type": 6
|
"type": 6
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8:1091046738846336945",
|
||||||
|
"name": "source",
|
||||||
|
"type": 9
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"relations": []
|
"relations": []
|
||||||
@ -1125,7 +1200,8 @@
|
|||||||
4678123663117222609,
|
4678123663117222609,
|
||||||
780211923138281722,
|
780211923138281722,
|
||||||
763575433624979013,
|
763575433624979013,
|
||||||
1225271130099322691
|
1225271130099322691,
|
||||||
|
8074052538574863399
|
||||||
],
|
],
|
||||||
"retiredRelationUids": [],
|
"retiredRelationUids": [],
|
||||||
"version": 1
|
"version": 1
|
||||||
|
@ -19,7 +19,7 @@ import 'models/basal_profile.dart';
|
|||||||
import 'models/bolus.dart';
|
import 'models/bolus.dart';
|
||||||
import 'models/bolus_profile.dart';
|
import 'models/bolus_profile.dart';
|
||||||
import 'models/glucose_target.dart';
|
import 'models/glucose_target.dart';
|
||||||
import 'models/ingredient.dart';
|
import 'models/x_ingredient.dart';
|
||||||
import 'models/log_bolus.dart';
|
import 'models/log_bolus.dart';
|
||||||
import 'models/log_entry.dart';
|
import 'models/log_entry.dart';
|
||||||
import 'models/log_event.dart';
|
import 'models/log_event.dart';
|
||||||
@ -29,9 +29,9 @@ import 'models/meal.dart';
|
|||||||
import 'models/meal_category.dart';
|
import 'models/meal_category.dart';
|
||||||
import 'models/meal_portion_type.dart';
|
import 'models/meal_portion_type.dart';
|
||||||
import 'models/meal_source.dart';
|
import 'models/meal_source.dart';
|
||||||
import 'models/recipe.dart';
|
import 'models/x_recipe.dart';
|
||||||
import 'models/settings.dart';
|
import 'models/settings.dart';
|
||||||
import 'models/user.dart';
|
import 'models/x_user.dart';
|
||||||
|
|
||||||
export 'package:objectbox/objectbox.dart'; // so that callers only have to import this file
|
export 'package:objectbox/objectbox.dart'; // so that callers only have to import this file
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ final _entities = <ModelEntity>[
|
|||||||
ModelEntity(
|
ModelEntity(
|
||||||
id: const IdUid(2, 1467758525778521891),
|
id: const IdUid(2, 1467758525778521891),
|
||||||
name: 'Basal',
|
name: 'Basal',
|
||||||
lastPropertyId: const IdUid(6, 3409466778841164684),
|
lastPropertyId: const IdUid(7, 3194552447464951410),
|
||||||
flags: 2,
|
flags: 2,
|
||||||
properties: <ModelProperty>[
|
properties: <ModelProperty>[
|
||||||
ModelProperty(
|
ModelProperty(
|
||||||
@ -73,6 +73,11 @@ final _entities = <ModelEntity>[
|
|||||||
id: const IdUid(6, 3409466778841164684),
|
id: const IdUid(6, 3409466778841164684),
|
||||||
name: 'deleted',
|
name: 'deleted',
|
||||||
type: 1,
|
type: 1,
|
||||||
|
flags: 0),
|
||||||
|
ModelProperty(
|
||||||
|
id: const IdUid(7, 3194552447464951410),
|
||||||
|
name: 'source',
|
||||||
|
type: 9,
|
||||||
flags: 0)
|
flags: 0)
|
||||||
],
|
],
|
||||||
relations: <ModelRelation>[],
|
relations: <ModelRelation>[],
|
||||||
@ -80,7 +85,7 @@ final _entities = <ModelEntity>[
|
|||||||
ModelEntity(
|
ModelEntity(
|
||||||
id: const IdUid(3, 3613736032926903785),
|
id: const IdUid(3, 3613736032926903785),
|
||||||
name: 'BasalProfile',
|
name: 'BasalProfile',
|
||||||
lastPropertyId: const IdUid(5, 8140071977687660397),
|
lastPropertyId: const IdUid(6, 3153627070507809184),
|
||||||
flags: 2,
|
flags: 2,
|
||||||
properties: <ModelProperty>[
|
properties: <ModelProperty>[
|
||||||
ModelProperty(
|
ModelProperty(
|
||||||
@ -107,6 +112,11 @@ final _entities = <ModelEntity>[
|
|||||||
id: const IdUid(5, 8140071977687660397),
|
id: const IdUid(5, 8140071977687660397),
|
||||||
name: 'deleted',
|
name: 'deleted',
|
||||||
type: 1,
|
type: 1,
|
||||||
|
flags: 0),
|
||||||
|
ModelProperty(
|
||||||
|
id: const IdUid(6, 3153627070507809184),
|
||||||
|
name: 'source',
|
||||||
|
type: 9,
|
||||||
flags: 0)
|
flags: 0)
|
||||||
],
|
],
|
||||||
relations: <ModelRelation>[],
|
relations: <ModelRelation>[],
|
||||||
@ -114,7 +124,7 @@ final _entities = <ModelEntity>[
|
|||||||
ModelEntity(
|
ModelEntity(
|
||||||
id: const IdUid(4, 3417770529060202389),
|
id: const IdUid(4, 3417770529060202389),
|
||||||
name: 'Bolus',
|
name: 'Bolus',
|
||||||
lastPropertyId: const IdUid(9, 7440090146687096977),
|
lastPropertyId: const IdUid(10, 6138236789530596038),
|
||||||
flags: 2,
|
flags: 2,
|
||||||
properties: <ModelProperty>[
|
properties: <ModelProperty>[
|
||||||
ModelProperty(
|
ModelProperty(
|
||||||
@ -163,6 +173,11 @@ final _entities = <ModelEntity>[
|
|||||||
id: const IdUid(9, 7440090146687096977),
|
id: const IdUid(9, 7440090146687096977),
|
||||||
name: 'deleted',
|
name: 'deleted',
|
||||||
type: 1,
|
type: 1,
|
||||||
|
flags: 0),
|
||||||
|
ModelProperty(
|
||||||
|
id: const IdUid(10, 6138236789530596038),
|
||||||
|
name: 'source',
|
||||||
|
type: 9,
|
||||||
flags: 0)
|
flags: 0)
|
||||||
],
|
],
|
||||||
relations: <ModelRelation>[],
|
relations: <ModelRelation>[],
|
||||||
@ -170,7 +185,7 @@ final _entities = <ModelEntity>[
|
|||||||
ModelEntity(
|
ModelEntity(
|
||||||
id: const IdUid(5, 8812452529027052317),
|
id: const IdUid(5, 8812452529027052317),
|
||||||
name: 'BolusProfile',
|
name: 'BolusProfile',
|
||||||
lastPropertyId: const IdUid(5, 8082994824481464395),
|
lastPropertyId: const IdUid(6, 8746199841403936632),
|
||||||
flags: 2,
|
flags: 2,
|
||||||
properties: <ModelProperty>[
|
properties: <ModelProperty>[
|
||||||
ModelProperty(
|
ModelProperty(
|
||||||
@ -197,6 +212,11 @@ final _entities = <ModelEntity>[
|
|||||||
id: const IdUid(5, 8082994824481464395),
|
id: const IdUid(5, 8082994824481464395),
|
||||||
name: 'deleted',
|
name: 'deleted',
|
||||||
type: 1,
|
type: 1,
|
||||||
|
flags: 0),
|
||||||
|
ModelProperty(
|
||||||
|
id: const IdUid(6, 8746199841403936632),
|
||||||
|
name: 'source',
|
||||||
|
type: 9,
|
||||||
flags: 0)
|
flags: 0)
|
||||||
],
|
],
|
||||||
relations: <ModelRelation>[],
|
relations: <ModelRelation>[],
|
||||||
@ -204,7 +224,7 @@ final _entities = <ModelEntity>[
|
|||||||
ModelEntity(
|
ModelEntity(
|
||||||
id: const IdUid(6, 752131069307970560),
|
id: const IdUid(6, 752131069307970560),
|
||||||
name: 'LogEntry',
|
name: 'LogEntry',
|
||||||
lastPropertyId: const IdUid(10, 2505303363495348118),
|
lastPropertyId: const IdUid(11, 8454251731096762477),
|
||||||
flags: 2,
|
flags: 2,
|
||||||
properties: <ModelProperty>[
|
properties: <ModelProperty>[
|
||||||
ModelProperty(
|
ModelProperty(
|
||||||
@ -241,6 +261,11 @@ final _entities = <ModelEntity>[
|
|||||||
id: const IdUid(10, 2505303363495348118),
|
id: const IdUid(10, 2505303363495348118),
|
||||||
name: 'glucoseTrend',
|
name: 'glucoseTrend',
|
||||||
type: 8,
|
type: 8,
|
||||||
|
flags: 0),
|
||||||
|
ModelProperty(
|
||||||
|
id: const IdUid(11, 8454251731096762477),
|
||||||
|
name: 'source',
|
||||||
|
type: 9,
|
||||||
flags: 0)
|
flags: 0)
|
||||||
],
|
],
|
||||||
relations: <ModelRelation>[],
|
relations: <ModelRelation>[],
|
||||||
@ -248,7 +273,7 @@ final _entities = <ModelEntity>[
|
|||||||
ModelEntity(
|
ModelEntity(
|
||||||
id: const IdUid(7, 4303325892753185970),
|
id: const IdUid(7, 4303325892753185970),
|
||||||
name: 'LogEvent',
|
name: 'LogEvent',
|
||||||
lastPropertyId: const IdUid(12, 3041952167628926163),
|
lastPropertyId: const IdUid(13, 9206766629540069341),
|
||||||
flags: 2,
|
flags: 2,
|
||||||
properties: <ModelProperty>[
|
properties: <ModelProperty>[
|
||||||
ModelProperty(
|
ModelProperty(
|
||||||
@ -306,6 +331,11 @@ final _entities = <ModelEntity>[
|
|||||||
id: const IdUid(12, 3041952167628926163),
|
id: const IdUid(12, 3041952167628926163),
|
||||||
name: 'reminderDuration',
|
name: 'reminderDuration',
|
||||||
type: 6,
|
type: 6,
|
||||||
|
flags: 0),
|
||||||
|
ModelProperty(
|
||||||
|
id: const IdUid(13, 9206766629540069341),
|
||||||
|
name: 'source',
|
||||||
|
type: 9,
|
||||||
flags: 0)
|
flags: 0)
|
||||||
],
|
],
|
||||||
relations: <ModelRelation>[],
|
relations: <ModelRelation>[],
|
||||||
@ -313,7 +343,7 @@ final _entities = <ModelEntity>[
|
|||||||
ModelEntity(
|
ModelEntity(
|
||||||
id: const IdUid(8, 8362795406595606110),
|
id: const IdUid(8, 8362795406595606110),
|
||||||
name: 'LogEventType',
|
name: 'LogEventType',
|
||||||
lastPropertyId: const IdUid(8, 1869014400856897151),
|
lastPropertyId: const IdUid(9, 7377683740652293217),
|
||||||
flags: 2,
|
flags: 2,
|
||||||
properties: <ModelProperty>[
|
properties: <ModelProperty>[
|
||||||
ModelProperty(
|
ModelProperty(
|
||||||
@ -359,14 +389,19 @@ final _entities = <ModelEntity>[
|
|||||||
type: 11,
|
type: 11,
|
||||||
flags: 520,
|
flags: 520,
|
||||||
indexId: const IdUid(28, 4563029809754152081),
|
indexId: const IdUid(28, 4563029809754152081),
|
||||||
relationTarget: 'BasalProfile')
|
relationTarget: 'BasalProfile'),
|
||||||
|
ModelProperty(
|
||||||
|
id: const IdUid(9, 7377683740652293217),
|
||||||
|
name: 'source',
|
||||||
|
type: 9,
|
||||||
|
flags: 0)
|
||||||
],
|
],
|
||||||
relations: <ModelRelation>[],
|
relations: <ModelRelation>[],
|
||||||
backlinks: <ModelBacklink>[]),
|
backlinks: <ModelBacklink>[]),
|
||||||
ModelEntity(
|
ModelEntity(
|
||||||
id: const IdUid(9, 411177866700467286),
|
id: const IdUid(9, 411177866700467286),
|
||||||
name: 'LogMeal',
|
name: 'LogMeal',
|
||||||
lastPropertyId: const IdUid(19, 8965198821438347033),
|
lastPropertyId: const IdUid(20, 3296734778930341954),
|
||||||
flags: 2,
|
flags: 2,
|
||||||
properties: <ModelProperty>[
|
properties: <ModelProperty>[
|
||||||
ModelProperty(
|
ModelProperty(
|
||||||
@ -389,11 +424,6 @@ final _entities = <ModelEntity>[
|
|||||||
name: 'portionSize',
|
name: 'portionSize',
|
||||||
type: 8,
|
type: 8,
|
||||||
flags: 0),
|
flags: 0),
|
||||||
ModelProperty(
|
|
||||||
id: const IdUid(6, 8074052538574863399),
|
|
||||||
name: 'bolus',
|
|
||||||
type: 8,
|
|
||||||
flags: 0),
|
|
||||||
ModelProperty(
|
ModelProperty(
|
||||||
id: const IdUid(9, 1920579694098037947),
|
id: const IdUid(9, 1920579694098037947),
|
||||||
name: 'notes',
|
name: 'notes',
|
||||||
@ -462,6 +492,11 @@ final _entities = <ModelEntity>[
|
|||||||
id: const IdUid(19, 8965198821438347033),
|
id: const IdUid(19, 8965198821438347033),
|
||||||
name: 'totalCarbs',
|
name: 'totalCarbs',
|
||||||
type: 8,
|
type: 8,
|
||||||
|
flags: 0),
|
||||||
|
ModelProperty(
|
||||||
|
id: const IdUid(20, 3296734778930341954),
|
||||||
|
name: 'source',
|
||||||
|
type: 9,
|
||||||
flags: 0)
|
flags: 0)
|
||||||
],
|
],
|
||||||
relations: <ModelRelation>[],
|
relations: <ModelRelation>[],
|
||||||
@ -469,7 +504,7 @@ final _entities = <ModelEntity>[
|
|||||||
ModelEntity(
|
ModelEntity(
|
||||||
id: const IdUid(10, 382130101578692012),
|
id: const IdUid(10, 382130101578692012),
|
||||||
name: 'Meal',
|
name: 'Meal',
|
||||||
lastPropertyId: const IdUid(15, 8283810711091063880),
|
lastPropertyId: const IdUid(16, 8612850434699732822),
|
||||||
flags: 2,
|
flags: 2,
|
||||||
properties: <ModelProperty>[
|
properties: <ModelProperty>[
|
||||||
ModelProperty(
|
ModelProperty(
|
||||||
@ -551,6 +586,11 @@ final _entities = <ModelEntity>[
|
|||||||
id: const IdUid(15, 8283810711091063880),
|
id: const IdUid(15, 8283810711091063880),
|
||||||
name: 'delayedBolusPercentage',
|
name: 'delayedBolusPercentage',
|
||||||
type: 8,
|
type: 8,
|
||||||
|
flags: 0),
|
||||||
|
ModelProperty(
|
||||||
|
id: const IdUid(16, 8612850434699732822),
|
||||||
|
name: 'source',
|
||||||
|
type: 9,
|
||||||
flags: 0)
|
flags: 0)
|
||||||
],
|
],
|
||||||
relations: <ModelRelation>[],
|
relations: <ModelRelation>[],
|
||||||
@ -558,7 +598,7 @@ final _entities = <ModelEntity>[
|
|||||||
ModelEntity(
|
ModelEntity(
|
||||||
id: const IdUid(11, 3158200688796904913),
|
id: const IdUid(11, 3158200688796904913),
|
||||||
name: 'MealCategory',
|
name: 'MealCategory',
|
||||||
lastPropertyId: const IdUid(4, 824435977543069541),
|
lastPropertyId: const IdUid(5, 2221810999445049020),
|
||||||
flags: 2,
|
flags: 2,
|
||||||
properties: <ModelProperty>[
|
properties: <ModelProperty>[
|
||||||
ModelProperty(
|
ModelProperty(
|
||||||
@ -580,6 +620,11 @@ final _entities = <ModelEntity>[
|
|||||||
id: const IdUid(4, 824435977543069541),
|
id: const IdUid(4, 824435977543069541),
|
||||||
name: 'deleted',
|
name: 'deleted',
|
||||||
type: 1,
|
type: 1,
|
||||||
|
flags: 0),
|
||||||
|
ModelProperty(
|
||||||
|
id: const IdUid(5, 2221810999445049020),
|
||||||
|
name: 'source',
|
||||||
|
type: 9,
|
||||||
flags: 0)
|
flags: 0)
|
||||||
],
|
],
|
||||||
relations: <ModelRelation>[],
|
relations: <ModelRelation>[],
|
||||||
@ -587,7 +632,7 @@ final _entities = <ModelEntity>[
|
|||||||
ModelEntity(
|
ModelEntity(
|
||||||
id: const IdUid(12, 2111511899235985637),
|
id: const IdUid(12, 2111511899235985637),
|
||||||
name: 'MealPortionType',
|
name: 'MealPortionType',
|
||||||
lastPropertyId: const IdUid(4, 5680236937391945907),
|
lastPropertyId: const IdUid(5, 6807468448392267469),
|
||||||
flags: 2,
|
flags: 2,
|
||||||
properties: <ModelProperty>[
|
properties: <ModelProperty>[
|
||||||
ModelProperty(
|
ModelProperty(
|
||||||
@ -609,6 +654,11 @@ final _entities = <ModelEntity>[
|
|||||||
id: const IdUid(4, 5680236937391945907),
|
id: const IdUid(4, 5680236937391945907),
|
||||||
name: 'deleted',
|
name: 'deleted',
|
||||||
type: 1,
|
type: 1,
|
||||||
|
flags: 0),
|
||||||
|
ModelProperty(
|
||||||
|
id: const IdUid(5, 6807468448392267469),
|
||||||
|
name: 'source',
|
||||||
|
type: 9,
|
||||||
flags: 0)
|
flags: 0)
|
||||||
],
|
],
|
||||||
relations: <ModelRelation>[],
|
relations: <ModelRelation>[],
|
||||||
@ -616,7 +666,7 @@ final _entities = <ModelEntity>[
|
|||||||
ModelEntity(
|
ModelEntity(
|
||||||
id: const IdUid(13, 1283034494527412242),
|
id: const IdUid(13, 1283034494527412242),
|
||||||
name: 'MealSource',
|
name: 'MealSource',
|
||||||
lastPropertyId: const IdUid(8, 4547899751779962180),
|
lastPropertyId: const IdUid(9, 6873017370661053783),
|
||||||
flags: 2,
|
flags: 2,
|
||||||
properties: <ModelProperty>[
|
properties: <ModelProperty>[
|
||||||
ModelProperty(
|
ModelProperty(
|
||||||
@ -666,6 +716,11 @@ final _entities = <ModelEntity>[
|
|||||||
id: const IdUid(8, 4547899751779962180),
|
id: const IdUid(8, 4547899751779962180),
|
||||||
name: 'deleted',
|
name: 'deleted',
|
||||||
type: 1,
|
type: 1,
|
||||||
|
flags: 0),
|
||||||
|
ModelProperty(
|
||||||
|
id: const IdUid(9, 6873017370661053783),
|
||||||
|
name: 'source',
|
||||||
|
type: 9,
|
||||||
flags: 0)
|
flags: 0)
|
||||||
],
|
],
|
||||||
relations: <ModelRelation>[],
|
relations: <ModelRelation>[],
|
||||||
@ -673,7 +728,7 @@ final _entities = <ModelEntity>[
|
|||||||
ModelEntity(
|
ModelEntity(
|
||||||
id: const IdUid(14, 8033487006694871160),
|
id: const IdUid(14, 8033487006694871160),
|
||||||
name: 'LogBolus',
|
name: 'LogBolus',
|
||||||
lastPropertyId: const IdUid(18, 7503231998671134983),
|
lastPropertyId: const IdUid(19, 3683854670538916324),
|
||||||
flags: 2,
|
flags: 2,
|
||||||
properties: <ModelProperty>[
|
properties: <ModelProperty>[
|
||||||
ModelProperty(
|
ModelProperty(
|
||||||
@ -761,6 +816,11 @@ final _entities = <ModelEntity>[
|
|||||||
id: const IdUid(18, 7503231998671134983),
|
id: const IdUid(18, 7503231998671134983),
|
||||||
name: 'mmolPerLCorrection',
|
name: 'mmolPerLCorrection',
|
||||||
type: 8,
|
type: 8,
|
||||||
|
flags: 0),
|
||||||
|
ModelProperty(
|
||||||
|
id: const IdUid(19, 3683854670538916324),
|
||||||
|
name: 'source',
|
||||||
|
type: 9,
|
||||||
flags: 0)
|
flags: 0)
|
||||||
],
|
],
|
||||||
relations: <ModelRelation>[],
|
relations: <ModelRelation>[],
|
||||||
@ -768,7 +828,7 @@ final _entities = <ModelEntity>[
|
|||||||
ModelEntity(
|
ModelEntity(
|
||||||
id: const IdUid(15, 291512798403320400),
|
id: const IdUid(15, 291512798403320400),
|
||||||
name: 'Accuracy',
|
name: 'Accuracy',
|
||||||
lastPropertyId: const IdUid(7, 6675647182186603076),
|
lastPropertyId: const IdUid(8, 1800866627092978542),
|
||||||
flags: 2,
|
flags: 2,
|
||||||
properties: <ModelProperty>[
|
properties: <ModelProperty>[
|
||||||
ModelProperty(
|
ModelProperty(
|
||||||
@ -805,6 +865,11 @@ final _entities = <ModelEntity>[
|
|||||||
id: const IdUid(7, 6675647182186603076),
|
id: const IdUid(7, 6675647182186603076),
|
||||||
name: 'deleted',
|
name: 'deleted',
|
||||||
type: 1,
|
type: 1,
|
||||||
|
flags: 0),
|
||||||
|
ModelProperty(
|
||||||
|
id: const IdUid(8, 1800866627092978542),
|
||||||
|
name: 'source',
|
||||||
|
type: 9,
|
||||||
flags: 0)
|
flags: 0)
|
||||||
],
|
],
|
||||||
relations: <ModelRelation>[],
|
relations: <ModelRelation>[],
|
||||||
@ -812,7 +877,7 @@ final _entities = <ModelEntity>[
|
|||||||
ModelEntity(
|
ModelEntity(
|
||||||
id: const IdUid(16, 3989341091218179227),
|
id: const IdUid(16, 3989341091218179227),
|
||||||
name: 'Settings',
|
name: 'Settings',
|
||||||
lastPropertyId: const IdUid(27, 3553639710779248831),
|
lastPropertyId: const IdUid(28, 7196743106880728684),
|
||||||
flags: 2,
|
flags: 2,
|
||||||
properties: <ModelProperty>[
|
properties: <ModelProperty>[
|
||||||
ModelProperty(
|
ModelProperty(
|
||||||
@ -904,6 +969,11 @@ final _entities = <ModelEntity>[
|
|||||||
id: const IdUid(27, 3553639710779248831),
|
id: const IdUid(27, 3553639710779248831),
|
||||||
name: 'amountIncrements',
|
name: 'amountIncrements',
|
||||||
type: 8,
|
type: 8,
|
||||||
|
flags: 0),
|
||||||
|
ModelProperty(
|
||||||
|
id: const IdUid(28, 7196743106880728684),
|
||||||
|
name: 'lastExportTimestamp',
|
||||||
|
type: 10,
|
||||||
flags: 0)
|
flags: 0)
|
||||||
],
|
],
|
||||||
relations: <ModelRelation>[],
|
relations: <ModelRelation>[],
|
||||||
@ -911,7 +981,7 @@ final _entities = <ModelEntity>[
|
|||||||
ModelEntity(
|
ModelEntity(
|
||||||
id: const IdUid(17, 5041265995704044399),
|
id: const IdUid(17, 5041265995704044399),
|
||||||
name: 'GlucoseTarget',
|
name: 'GlucoseTarget',
|
||||||
lastPropertyId: const IdUid(7, 1333487551279074696),
|
lastPropertyId: const IdUid(8, 1091046738846336945),
|
||||||
flags: 2,
|
flags: 2,
|
||||||
properties: <ModelProperty>[
|
properties: <ModelProperty>[
|
||||||
ModelProperty(
|
ModelProperty(
|
||||||
@ -948,6 +1018,11 @@ final _entities = <ModelEntity>[
|
|||||||
id: const IdUid(7, 1333487551279074696),
|
id: const IdUid(7, 1333487551279074696),
|
||||||
name: 'color',
|
name: 'color',
|
||||||
type: 6,
|
type: 6,
|
||||||
|
flags: 0),
|
||||||
|
ModelProperty(
|
||||||
|
id: const IdUid(8, 1091046738846336945),
|
||||||
|
name: 'source',
|
||||||
|
type: 9,
|
||||||
flags: 0)
|
flags: 0)
|
||||||
],
|
],
|
||||||
relations: <ModelRelation>[],
|
relations: <ModelRelation>[],
|
||||||
@ -1124,7 +1199,8 @@ ModelDefinition getObjectBoxModel() {
|
|||||||
4678123663117222609,
|
4678123663117222609,
|
||||||
780211923138281722,
|
780211923138281722,
|
||||||
763575433624979013,
|
763575433624979013,
|
||||||
1225271130099322691
|
1225271130099322691,
|
||||||
|
8074052538574863399
|
||||||
],
|
],
|
||||||
retiredRelationUids: const [],
|
retiredRelationUids: const [],
|
||||||
modelVersion: 5,
|
modelVersion: 5,
|
||||||
@ -1141,13 +1217,16 @@ ModelDefinition getObjectBoxModel() {
|
|||||||
object.id = id;
|
object.id = id;
|
||||||
},
|
},
|
||||||
objectToFB: (Basal object, fb.Builder fbb) {
|
objectToFB: (Basal object, fb.Builder fbb) {
|
||||||
fbb.startTable(7);
|
final sourceOffset =
|
||||||
|
object.source == null ? null : fbb.writeString(object.source!);
|
||||||
|
fbb.startTable(8);
|
||||||
fbb.addInt64(0, object.id);
|
fbb.addInt64(0, object.id);
|
||||||
fbb.addInt64(1, object.startTime.millisecondsSinceEpoch);
|
fbb.addInt64(1, object.startTime.millisecondsSinceEpoch);
|
||||||
fbb.addInt64(2, object.endTime.millisecondsSinceEpoch);
|
fbb.addInt64(2, object.endTime.millisecondsSinceEpoch);
|
||||||
fbb.addFloat64(3, object.units);
|
fbb.addFloat64(3, object.units);
|
||||||
fbb.addInt64(4, object.basalProfile.targetId);
|
fbb.addInt64(4, object.basalProfile.targetId);
|
||||||
fbb.addBool(5, object.deleted);
|
fbb.addBool(5, object.deleted);
|
||||||
|
fbb.addOffset(6, sourceOffset);
|
||||||
fbb.finish(fbb.endTable());
|
fbb.finish(fbb.endTable());
|
||||||
return object.id;
|
return object.id;
|
||||||
},
|
},
|
||||||
@ -1163,8 +1242,10 @@ ModelDefinition getObjectBoxModel() {
|
|||||||
const fb.Int64Reader().vTableGet(buffer, rootOffset, 6, 0)),
|
const fb.Int64Reader().vTableGet(buffer, rootOffset, 6, 0)),
|
||||||
endTime: DateTime.fromMillisecondsSinceEpoch(
|
endTime: DateTime.fromMillisecondsSinceEpoch(
|
||||||
const fb.Int64Reader().vTableGet(buffer, rootOffset, 8, 0)),
|
const fb.Int64Reader().vTableGet(buffer, rootOffset, 8, 0)),
|
||||||
units: const fb.Float64Reader()
|
units:
|
||||||
.vTableGet(buffer, rootOffset, 10, 0));
|
const fb.Float64Reader().vTableGet(buffer, rootOffset, 10, 0),
|
||||||
|
source: const fb.StringReader(asciiOptimization: true)
|
||||||
|
.vTableGetNullable(buffer, rootOffset, 16));
|
||||||
object.basalProfile.targetId =
|
object.basalProfile.targetId =
|
||||||
const fb.Int64Reader().vTableGet(buffer, rootOffset, 12, 0);
|
const fb.Int64Reader().vTableGet(buffer, rootOffset, 12, 0);
|
||||||
object.basalProfile.attach(store);
|
object.basalProfile.attach(store);
|
||||||
@ -1182,12 +1263,15 @@ ModelDefinition getObjectBoxModel() {
|
|||||||
final nameOffset = fbb.writeString(object.name);
|
final nameOffset = fbb.writeString(object.name);
|
||||||
final notesOffset =
|
final notesOffset =
|
||||||
object.notes == null ? null : fbb.writeString(object.notes!);
|
object.notes == null ? null : fbb.writeString(object.notes!);
|
||||||
fbb.startTable(6);
|
final sourceOffset =
|
||||||
|
object.source == null ? null : fbb.writeString(object.source!);
|
||||||
|
fbb.startTable(7);
|
||||||
fbb.addInt64(0, object.id);
|
fbb.addInt64(0, object.id);
|
||||||
fbb.addOffset(1, nameOffset);
|
fbb.addOffset(1, nameOffset);
|
||||||
fbb.addBool(2, object.active);
|
fbb.addBool(2, object.active);
|
||||||
fbb.addOffset(3, notesOffset);
|
fbb.addOffset(3, notesOffset);
|
||||||
fbb.addBool(4, object.deleted);
|
fbb.addBool(4, object.deleted);
|
||||||
|
fbb.addOffset(5, sourceOffset);
|
||||||
fbb.finish(fbb.endTable());
|
fbb.finish(fbb.endTable());
|
||||||
return object.id;
|
return object.id;
|
||||||
},
|
},
|
||||||
@ -1204,7 +1288,9 @@ ModelDefinition getObjectBoxModel() {
|
|||||||
active:
|
active:
|
||||||
const fb.BoolReader().vTableGet(buffer, rootOffset, 8, false),
|
const fb.BoolReader().vTableGet(buffer, rootOffset, 8, false),
|
||||||
notes: const fb.StringReader(asciiOptimization: true)
|
notes: const fb.StringReader(asciiOptimization: true)
|
||||||
.vTableGetNullable(buffer, rootOffset, 10));
|
.vTableGetNullable(buffer, rootOffset, 10),
|
||||||
|
source: const fb.StringReader(asciiOptimization: true)
|
||||||
|
.vTableGetNullable(buffer, rootOffset, 14));
|
||||||
|
|
||||||
return object;
|
return object;
|
||||||
}),
|
}),
|
||||||
@ -1217,7 +1303,9 @@ ModelDefinition getObjectBoxModel() {
|
|||||||
object.id = id;
|
object.id = id;
|
||||||
},
|
},
|
||||||
objectToFB: (Bolus object, fb.Builder fbb) {
|
objectToFB: (Bolus object, fb.Builder fbb) {
|
||||||
fbb.startTable(10);
|
final sourceOffset =
|
||||||
|
object.source == null ? null : fbb.writeString(object.source!);
|
||||||
|
fbb.startTable(11);
|
||||||
fbb.addInt64(0, object.id);
|
fbb.addInt64(0, object.id);
|
||||||
fbb.addInt64(1, object.startTime.millisecondsSinceEpoch);
|
fbb.addInt64(1, object.startTime.millisecondsSinceEpoch);
|
||||||
fbb.addInt64(2, object.endTime.millisecondsSinceEpoch);
|
fbb.addInt64(2, object.endTime.millisecondsSinceEpoch);
|
||||||
@ -1227,6 +1315,7 @@ ModelDefinition getObjectBoxModel() {
|
|||||||
fbb.addFloat64(6, object.mmolPerL);
|
fbb.addFloat64(6, object.mmolPerL);
|
||||||
fbb.addInt64(7, object.bolusProfile.targetId);
|
fbb.addInt64(7, object.bolusProfile.targetId);
|
||||||
fbb.addBool(8, object.deleted);
|
fbb.addBool(8, object.deleted);
|
||||||
|
fbb.addOffset(9, sourceOffset);
|
||||||
fbb.finish(fbb.endTable());
|
fbb.finish(fbb.endTable());
|
||||||
return object.id;
|
return object.id;
|
||||||
},
|
},
|
||||||
@ -1249,7 +1338,9 @@ ModelDefinition getObjectBoxModel() {
|
|||||||
mgPerDl: const fb.Int64Reader()
|
mgPerDl: const fb.Int64Reader()
|
||||||
.vTableGetNullable(buffer, rootOffset, 14),
|
.vTableGetNullable(buffer, rootOffset, 14),
|
||||||
mmolPerL: const fb.Float64Reader()
|
mmolPerL: const fb.Float64Reader()
|
||||||
.vTableGetNullable(buffer, rootOffset, 16));
|
.vTableGetNullable(buffer, rootOffset, 16),
|
||||||
|
source: const fb.StringReader(asciiOptimization: true)
|
||||||
|
.vTableGetNullable(buffer, rootOffset, 22));
|
||||||
object.bolusProfile.targetId =
|
object.bolusProfile.targetId =
|
||||||
const fb.Int64Reader().vTableGet(buffer, rootOffset, 18, 0);
|
const fb.Int64Reader().vTableGet(buffer, rootOffset, 18, 0);
|
||||||
object.bolusProfile.attach(store);
|
object.bolusProfile.attach(store);
|
||||||
@ -1267,12 +1358,15 @@ ModelDefinition getObjectBoxModel() {
|
|||||||
final nameOffset = fbb.writeString(object.name);
|
final nameOffset = fbb.writeString(object.name);
|
||||||
final notesOffset =
|
final notesOffset =
|
||||||
object.notes == null ? null : fbb.writeString(object.notes!);
|
object.notes == null ? null : fbb.writeString(object.notes!);
|
||||||
fbb.startTable(6);
|
final sourceOffset =
|
||||||
|
object.source == null ? null : fbb.writeString(object.source!);
|
||||||
|
fbb.startTable(7);
|
||||||
fbb.addInt64(0, object.id);
|
fbb.addInt64(0, object.id);
|
||||||
fbb.addOffset(1, nameOffset);
|
fbb.addOffset(1, nameOffset);
|
||||||
fbb.addBool(2, object.active);
|
fbb.addBool(2, object.active);
|
||||||
fbb.addOffset(3, notesOffset);
|
fbb.addOffset(3, notesOffset);
|
||||||
fbb.addBool(4, object.deleted);
|
fbb.addBool(4, object.deleted);
|
||||||
|
fbb.addOffset(5, sourceOffset);
|
||||||
fbb.finish(fbb.endTable());
|
fbb.finish(fbb.endTable());
|
||||||
return object.id;
|
return object.id;
|
||||||
},
|
},
|
||||||
@ -1289,7 +1383,9 @@ ModelDefinition getObjectBoxModel() {
|
|||||||
active:
|
active:
|
||||||
const fb.BoolReader().vTableGet(buffer, rootOffset, 8, false),
|
const fb.BoolReader().vTableGet(buffer, rootOffset, 8, false),
|
||||||
notes: const fb.StringReader(asciiOptimization: true)
|
notes: const fb.StringReader(asciiOptimization: true)
|
||||||
.vTableGetNullable(buffer, rootOffset, 10));
|
.vTableGetNullable(buffer, rootOffset, 10),
|
||||||
|
source: const fb.StringReader(asciiOptimization: true)
|
||||||
|
.vTableGetNullable(buffer, rootOffset, 14));
|
||||||
|
|
||||||
return object;
|
return object;
|
||||||
}),
|
}),
|
||||||
@ -1304,7 +1400,9 @@ ModelDefinition getObjectBoxModel() {
|
|||||||
objectToFB: (LogEntry object, fb.Builder fbb) {
|
objectToFB: (LogEntry object, fb.Builder fbb) {
|
||||||
final notesOffset =
|
final notesOffset =
|
||||||
object.notes == null ? null : fbb.writeString(object.notes!);
|
object.notes == null ? null : fbb.writeString(object.notes!);
|
||||||
fbb.startTable(11);
|
final sourceOffset =
|
||||||
|
object.source == null ? null : fbb.writeString(object.source!);
|
||||||
|
fbb.startTable(12);
|
||||||
fbb.addInt64(0, object.id);
|
fbb.addInt64(0, object.id);
|
||||||
fbb.addInt64(1, object.time.millisecondsSinceEpoch);
|
fbb.addInt64(1, object.time.millisecondsSinceEpoch);
|
||||||
fbb.addInt64(2, object.mgPerDl);
|
fbb.addInt64(2, object.mgPerDl);
|
||||||
@ -1312,6 +1410,7 @@ ModelDefinition getObjectBoxModel() {
|
|||||||
fbb.addOffset(7, notesOffset);
|
fbb.addOffset(7, notesOffset);
|
||||||
fbb.addBool(8, object.deleted);
|
fbb.addBool(8, object.deleted);
|
||||||
fbb.addFloat64(9, object.glucoseTrend);
|
fbb.addFloat64(9, object.glucoseTrend);
|
||||||
|
fbb.addOffset(10, sourceOffset);
|
||||||
fbb.finish(fbb.endTable());
|
fbb.finish(fbb.endTable());
|
||||||
return object.id;
|
return object.id;
|
||||||
},
|
},
|
||||||
@ -1332,7 +1431,9 @@ ModelDefinition getObjectBoxModel() {
|
|||||||
glucoseTrend: const fb.Float64Reader()
|
glucoseTrend: const fb.Float64Reader()
|
||||||
.vTableGetNullable(buffer, rootOffset, 22),
|
.vTableGetNullable(buffer, rootOffset, 22),
|
||||||
notes: const fb.StringReader(asciiOptimization: true)
|
notes: const fb.StringReader(asciiOptimization: true)
|
||||||
.vTableGetNullable(buffer, rootOffset, 18));
|
.vTableGetNullable(buffer, rootOffset, 18),
|
||||||
|
source: const fb.StringReader(asciiOptimization: true)
|
||||||
|
.vTableGetNullable(buffer, rootOffset, 24));
|
||||||
|
|
||||||
return object;
|
return object;
|
||||||
}),
|
}),
|
||||||
@ -1348,7 +1449,9 @@ ModelDefinition getObjectBoxModel() {
|
|||||||
objectToFB: (LogEvent object, fb.Builder fbb) {
|
objectToFB: (LogEvent object, fb.Builder fbb) {
|
||||||
final notesOffset =
|
final notesOffset =
|
||||||
object.notes == null ? null : fbb.writeString(object.notes!);
|
object.notes == null ? null : fbb.writeString(object.notes!);
|
||||||
fbb.startTable(13);
|
final sourceOffset =
|
||||||
|
object.source == null ? null : fbb.writeString(object.source!);
|
||||||
|
fbb.startTable(14);
|
||||||
fbb.addInt64(0, object.id);
|
fbb.addInt64(0, object.id);
|
||||||
fbb.addInt64(1, object.time.millisecondsSinceEpoch);
|
fbb.addInt64(1, object.time.millisecondsSinceEpoch);
|
||||||
fbb.addInt64(2, object.endTime?.millisecondsSinceEpoch);
|
fbb.addInt64(2, object.endTime?.millisecondsSinceEpoch);
|
||||||
@ -1359,6 +1462,7 @@ ModelDefinition getObjectBoxModel() {
|
|||||||
fbb.addInt64(9, object.bolusProfile.targetId);
|
fbb.addInt64(9, object.bolusProfile.targetId);
|
||||||
fbb.addInt64(10, object.basalProfile.targetId);
|
fbb.addInt64(10, object.basalProfile.targetId);
|
||||||
fbb.addInt64(11, object.reminderDuration);
|
fbb.addInt64(11, object.reminderDuration);
|
||||||
|
fbb.addOffset(12, sourceOffset);
|
||||||
fbb.finish(fbb.endTable());
|
fbb.finish(fbb.endTable());
|
||||||
return object.id;
|
return object.id;
|
||||||
},
|
},
|
||||||
@ -1381,7 +1485,9 @@ ModelDefinition getObjectBoxModel() {
|
|||||||
reminderDuration: const fb.Int64Reader()
|
reminderDuration: const fb.Int64Reader()
|
||||||
.vTableGetNullable(buffer, rootOffset, 26),
|
.vTableGetNullable(buffer, rootOffset, 26),
|
||||||
notes: const fb.StringReader(asciiOptimization: true)
|
notes: const fb.StringReader(asciiOptimization: true)
|
||||||
.vTableGetNullable(buffer, rootOffset, 12));
|
.vTableGetNullable(buffer, rootOffset, 12),
|
||||||
|
source: const fb.StringReader(asciiOptimization: true)
|
||||||
|
.vTableGetNullable(buffer, rootOffset, 28));
|
||||||
object.eventType.targetId =
|
object.eventType.targetId =
|
||||||
const fb.Int64Reader().vTableGet(buffer, rootOffset, 18, 0);
|
const fb.Int64Reader().vTableGet(buffer, rootOffset, 18, 0);
|
||||||
object.eventType.attach(store);
|
object.eventType.attach(store);
|
||||||
@ -1406,7 +1512,9 @@ ModelDefinition getObjectBoxModel() {
|
|||||||
final valueOffset = fbb.writeString(object.value);
|
final valueOffset = fbb.writeString(object.value);
|
||||||
final notesOffset =
|
final notesOffset =
|
||||||
object.notes == null ? null : fbb.writeString(object.notes!);
|
object.notes == null ? null : fbb.writeString(object.notes!);
|
||||||
fbb.startTable(9);
|
final sourceOffset =
|
||||||
|
object.source == null ? null : fbb.writeString(object.source!);
|
||||||
|
fbb.startTable(10);
|
||||||
fbb.addInt64(0, object.id);
|
fbb.addInt64(0, object.id);
|
||||||
fbb.addOffset(1, valueOffset);
|
fbb.addOffset(1, valueOffset);
|
||||||
fbb.addBool(2, object.hasEndTime);
|
fbb.addBool(2, object.hasEndTime);
|
||||||
@ -1415,6 +1523,7 @@ ModelDefinition getObjectBoxModel() {
|
|||||||
fbb.addBool(5, object.deleted);
|
fbb.addBool(5, object.deleted);
|
||||||
fbb.addInt64(6, object.bolusProfile.targetId);
|
fbb.addInt64(6, object.bolusProfile.targetId);
|
||||||
fbb.addInt64(7, object.basalProfile.targetId);
|
fbb.addInt64(7, object.basalProfile.targetId);
|
||||||
|
fbb.addOffset(8, sourceOffset);
|
||||||
fbb.finish(fbb.endTable());
|
fbb.finish(fbb.endTable());
|
||||||
return object.id;
|
return object.id;
|
||||||
},
|
},
|
||||||
@ -1433,7 +1542,9 @@ ModelDefinition getObjectBoxModel() {
|
|||||||
defaultReminderDuration: const fb.Int64Reader()
|
defaultReminderDuration: const fb.Int64Reader()
|
||||||
.vTableGetNullable(buffer, rootOffset, 10),
|
.vTableGetNullable(buffer, rootOffset, 10),
|
||||||
notes: const fb.StringReader(asciiOptimization: true)
|
notes: const fb.StringReader(asciiOptimization: true)
|
||||||
.vTableGetNullable(buffer, rootOffset, 12));
|
.vTableGetNullable(buffer, rootOffset, 12),
|
||||||
|
source: const fb.StringReader(asciiOptimization: true)
|
||||||
|
.vTableGetNullable(buffer, rootOffset, 20));
|
||||||
object.bolusProfile.targetId =
|
object.bolusProfile.targetId =
|
||||||
const fb.Int64Reader().vTableGet(buffer, rootOffset, 16, 0);
|
const fb.Int64Reader().vTableGet(buffer, rootOffset, 16, 0);
|
||||||
object.bolusProfile.attach(store);
|
object.bolusProfile.attach(store);
|
||||||
@ -1462,12 +1573,13 @@ ModelDefinition getObjectBoxModel() {
|
|||||||
final valueOffset = fbb.writeString(object.value);
|
final valueOffset = fbb.writeString(object.value);
|
||||||
final notesOffset =
|
final notesOffset =
|
||||||
object.notes == null ? null : fbb.writeString(object.notes!);
|
object.notes == null ? null : fbb.writeString(object.notes!);
|
||||||
fbb.startTable(20);
|
final sourceOffset =
|
||||||
|
object.source == null ? null : fbb.writeString(object.source!);
|
||||||
|
fbb.startTable(21);
|
||||||
fbb.addInt64(0, object.id);
|
fbb.addInt64(0, object.id);
|
||||||
fbb.addOffset(1, valueOffset);
|
fbb.addOffset(1, valueOffset);
|
||||||
fbb.addFloat64(2, object.carbsRatio);
|
fbb.addFloat64(2, object.carbsRatio);
|
||||||
fbb.addFloat64(3, object.portionSize);
|
fbb.addFloat64(3, object.portionSize);
|
||||||
fbb.addFloat64(5, object.bolus);
|
|
||||||
fbb.addOffset(8, notesOffset);
|
fbb.addOffset(8, notesOffset);
|
||||||
fbb.addInt64(9, object.logEntry.targetId);
|
fbb.addInt64(9, object.logEntry.targetId);
|
||||||
fbb.addInt64(10, object.meal.targetId);
|
fbb.addInt64(10, object.meal.targetId);
|
||||||
@ -1479,6 +1591,7 @@ ModelDefinition getObjectBoxModel() {
|
|||||||
fbb.addBool(16, object.deleted);
|
fbb.addBool(16, object.deleted);
|
||||||
fbb.addFloat64(17, object.amount);
|
fbb.addFloat64(17, object.amount);
|
||||||
fbb.addFloat64(18, object.totalCarbs);
|
fbb.addFloat64(18, object.totalCarbs);
|
||||||
|
fbb.addOffset(19, sourceOffset);
|
||||||
fbb.finish(fbb.endTable());
|
fbb.finish(fbb.endTable());
|
||||||
return object.id;
|
return object.id;
|
||||||
},
|
},
|
||||||
@ -1501,9 +1614,9 @@ ModelDefinition getObjectBoxModel() {
|
|||||||
totalCarbs: const fb.Float64Reader()
|
totalCarbs: const fb.Float64Reader()
|
||||||
.vTableGetNullable(buffer, rootOffset, 40),
|
.vTableGetNullable(buffer, rootOffset, 40),
|
||||||
notes: const fb.StringReader(asciiOptimization: true)
|
notes: const fb.StringReader(asciiOptimization: true)
|
||||||
.vTableGetNullable(buffer, rootOffset, 20))
|
.vTableGetNullable(buffer, rootOffset, 20),
|
||||||
..bolus = const fb.Float64Reader()
|
source: const fb.StringReader(asciiOptimization: true)
|
||||||
.vTableGetNullable(buffer, rootOffset, 14);
|
.vTableGetNullable(buffer, rootOffset, 42));
|
||||||
object.logEntry.targetId =
|
object.logEntry.targetId =
|
||||||
const fb.Int64Reader().vTableGet(buffer, rootOffset, 22, 0);
|
const fb.Int64Reader().vTableGet(buffer, rootOffset, 22, 0);
|
||||||
object.logEntry.attach(store);
|
object.logEntry.attach(store);
|
||||||
@ -1545,7 +1658,9 @@ ModelDefinition getObjectBoxModel() {
|
|||||||
final valueOffset = fbb.writeString(object.value);
|
final valueOffset = fbb.writeString(object.value);
|
||||||
final notesOffset =
|
final notesOffset =
|
||||||
object.notes == null ? null : fbb.writeString(object.notes!);
|
object.notes == null ? null : fbb.writeString(object.notes!);
|
||||||
fbb.startTable(16);
|
final sourceOffset =
|
||||||
|
object.source == null ? null : fbb.writeString(object.source!);
|
||||||
|
fbb.startTable(17);
|
||||||
fbb.addInt64(0, object.id);
|
fbb.addInt64(0, object.id);
|
||||||
fbb.addOffset(1, valueOffset);
|
fbb.addOffset(1, valueOffset);
|
||||||
fbb.addFloat64(2, object.carbsRatio);
|
fbb.addFloat64(2, object.carbsRatio);
|
||||||
@ -1560,6 +1675,7 @@ ModelDefinition getObjectBoxModel() {
|
|||||||
fbb.addInt64(12, object.carbsRatioAccuracy.targetId);
|
fbb.addInt64(12, object.carbsRatioAccuracy.targetId);
|
||||||
fbb.addBool(13, object.deleted);
|
fbb.addBool(13, object.deleted);
|
||||||
fbb.addFloat64(14, object.delayedBolusPercentage);
|
fbb.addFloat64(14, object.delayedBolusPercentage);
|
||||||
|
fbb.addOffset(15, sourceOffset);
|
||||||
fbb.finish(fbb.endTable());
|
fbb.finish(fbb.endTable());
|
||||||
return object.id;
|
return object.id;
|
||||||
},
|
},
|
||||||
@ -1584,7 +1700,9 @@ ModelDefinition getObjectBoxModel() {
|
|||||||
delayedBolusPercentage: const fb.Float64Reader()
|
delayedBolusPercentage: const fb.Float64Reader()
|
||||||
.vTableGetNullable(buffer, rootOffset, 32),
|
.vTableGetNullable(buffer, rootOffset, 32),
|
||||||
notes: const fb.StringReader(asciiOptimization: true)
|
notes: const fb.StringReader(asciiOptimization: true)
|
||||||
.vTableGetNullable(buffer, rootOffset, 18));
|
.vTableGetNullable(buffer, rootOffset, 18),
|
||||||
|
source: const fb.StringReader(asciiOptimization: true)
|
||||||
|
.vTableGetNullable(buffer, rootOffset, 34));
|
||||||
object.mealSource.targetId =
|
object.mealSource.targetId =
|
||||||
const fb.Int64Reader().vTableGet(buffer, rootOffset, 20, 0);
|
const fb.Int64Reader().vTableGet(buffer, rootOffset, 20, 0);
|
||||||
object.mealSource.attach(store);
|
object.mealSource.attach(store);
|
||||||
@ -1614,11 +1732,14 @@ ModelDefinition getObjectBoxModel() {
|
|||||||
final valueOffset = fbb.writeString(object.value);
|
final valueOffset = fbb.writeString(object.value);
|
||||||
final notesOffset =
|
final notesOffset =
|
||||||
object.notes == null ? null : fbb.writeString(object.notes!);
|
object.notes == null ? null : fbb.writeString(object.notes!);
|
||||||
fbb.startTable(5);
|
final sourceOffset =
|
||||||
|
object.source == null ? null : fbb.writeString(object.source!);
|
||||||
|
fbb.startTable(6);
|
||||||
fbb.addInt64(0, object.id);
|
fbb.addInt64(0, object.id);
|
||||||
fbb.addOffset(1, valueOffset);
|
fbb.addOffset(1, valueOffset);
|
||||||
fbb.addOffset(2, notesOffset);
|
fbb.addOffset(2, notesOffset);
|
||||||
fbb.addBool(3, object.deleted);
|
fbb.addBool(3, object.deleted);
|
||||||
|
fbb.addOffset(4, sourceOffset);
|
||||||
fbb.finish(fbb.endTable());
|
fbb.finish(fbb.endTable());
|
||||||
return object.id;
|
return object.id;
|
||||||
},
|
},
|
||||||
@ -1633,7 +1754,9 @@ ModelDefinition getObjectBoxModel() {
|
|||||||
value: const fb.StringReader(asciiOptimization: true)
|
value: const fb.StringReader(asciiOptimization: true)
|
||||||
.vTableGet(buffer, rootOffset, 6, ''),
|
.vTableGet(buffer, rootOffset, 6, ''),
|
||||||
notes: const fb.StringReader(asciiOptimization: true)
|
notes: const fb.StringReader(asciiOptimization: true)
|
||||||
.vTableGetNullable(buffer, rootOffset, 8));
|
.vTableGetNullable(buffer, rootOffset, 8),
|
||||||
|
source: const fb.StringReader(asciiOptimization: true)
|
||||||
|
.vTableGetNullable(buffer, rootOffset, 12));
|
||||||
|
|
||||||
return object;
|
return object;
|
||||||
}),
|
}),
|
||||||
@ -1649,11 +1772,14 @@ ModelDefinition getObjectBoxModel() {
|
|||||||
final valueOffset = fbb.writeString(object.value);
|
final valueOffset = fbb.writeString(object.value);
|
||||||
final notesOffset =
|
final notesOffset =
|
||||||
object.notes == null ? null : fbb.writeString(object.notes!);
|
object.notes == null ? null : fbb.writeString(object.notes!);
|
||||||
fbb.startTable(5);
|
final sourceOffset =
|
||||||
|
object.source == null ? null : fbb.writeString(object.source!);
|
||||||
|
fbb.startTable(6);
|
||||||
fbb.addInt64(0, object.id);
|
fbb.addInt64(0, object.id);
|
||||||
fbb.addOffset(1, valueOffset);
|
fbb.addOffset(1, valueOffset);
|
||||||
fbb.addOffset(2, notesOffset);
|
fbb.addOffset(2, notesOffset);
|
||||||
fbb.addBool(3, object.deleted);
|
fbb.addBool(3, object.deleted);
|
||||||
|
fbb.addOffset(4, sourceOffset);
|
||||||
fbb.finish(fbb.endTable());
|
fbb.finish(fbb.endTable());
|
||||||
return object.id;
|
return object.id;
|
||||||
},
|
},
|
||||||
@ -1668,7 +1794,9 @@ ModelDefinition getObjectBoxModel() {
|
|||||||
value: const fb.StringReader(asciiOptimization: true)
|
value: const fb.StringReader(asciiOptimization: true)
|
||||||
.vTableGet(buffer, rootOffset, 6, ''),
|
.vTableGet(buffer, rootOffset, 6, ''),
|
||||||
notes: const fb.StringReader(asciiOptimization: true)
|
notes: const fb.StringReader(asciiOptimization: true)
|
||||||
.vTableGetNullable(buffer, rootOffset, 8));
|
.vTableGetNullable(buffer, rootOffset, 8),
|
||||||
|
source: const fb.StringReader(asciiOptimization: true)
|
||||||
|
.vTableGetNullable(buffer, rootOffset, 12));
|
||||||
|
|
||||||
return object;
|
return object;
|
||||||
}),
|
}),
|
||||||
@ -1689,7 +1817,9 @@ ModelDefinition getObjectBoxModel() {
|
|||||||
final valueOffset = fbb.writeString(object.value);
|
final valueOffset = fbb.writeString(object.value);
|
||||||
final notesOffset =
|
final notesOffset =
|
||||||
object.notes == null ? null : fbb.writeString(object.notes!);
|
object.notes == null ? null : fbb.writeString(object.notes!);
|
||||||
fbb.startTable(9);
|
final sourceOffset =
|
||||||
|
object.source == null ? null : fbb.writeString(object.source!);
|
||||||
|
fbb.startTable(10);
|
||||||
fbb.addInt64(0, object.id);
|
fbb.addInt64(0, object.id);
|
||||||
fbb.addOffset(1, valueOffset);
|
fbb.addOffset(1, valueOffset);
|
||||||
fbb.addOffset(2, notesOffset);
|
fbb.addOffset(2, notesOffset);
|
||||||
@ -1698,6 +1828,7 @@ ModelDefinition getObjectBoxModel() {
|
|||||||
fbb.addInt64(5, object.defaultCarbsRatioAccuracy.targetId);
|
fbb.addInt64(5, object.defaultCarbsRatioAccuracy.targetId);
|
||||||
fbb.addInt64(6, object.defaultPortionSizeAccuracy.targetId);
|
fbb.addInt64(6, object.defaultPortionSizeAccuracy.targetId);
|
||||||
fbb.addBool(7, object.deleted);
|
fbb.addBool(7, object.deleted);
|
||||||
|
fbb.addOffset(8, sourceOffset);
|
||||||
fbb.finish(fbb.endTable());
|
fbb.finish(fbb.endTable());
|
||||||
return object.id;
|
return object.id;
|
||||||
},
|
},
|
||||||
@ -1712,7 +1843,9 @@ ModelDefinition getObjectBoxModel() {
|
|||||||
value: const fb.StringReader(asciiOptimization: true)
|
value: const fb.StringReader(asciiOptimization: true)
|
||||||
.vTableGet(buffer, rootOffset, 6, ''),
|
.vTableGet(buffer, rootOffset, 6, ''),
|
||||||
notes: const fb.StringReader(asciiOptimization: true)
|
notes: const fb.StringReader(asciiOptimization: true)
|
||||||
.vTableGetNullable(buffer, rootOffset, 8));
|
.vTableGetNullable(buffer, rootOffset, 8),
|
||||||
|
source: const fb.StringReader(asciiOptimization: true)
|
||||||
|
.vTableGetNullable(buffer, rootOffset, 20));
|
||||||
object.defaultMealCategory.targetId =
|
object.defaultMealCategory.targetId =
|
||||||
const fb.Int64Reader().vTableGet(buffer, rootOffset, 10, 0);
|
const fb.Int64Reader().vTableGet(buffer, rootOffset, 10, 0);
|
||||||
object.defaultMealCategory.attach(store);
|
object.defaultMealCategory.attach(store);
|
||||||
@ -1739,7 +1872,9 @@ ModelDefinition getObjectBoxModel() {
|
|||||||
objectToFB: (LogBolus object, fb.Builder fbb) {
|
objectToFB: (LogBolus object, fb.Builder fbb) {
|
||||||
final notesOffset =
|
final notesOffset =
|
||||||
object.notes == null ? null : fbb.writeString(object.notes!);
|
object.notes == null ? null : fbb.writeString(object.notes!);
|
||||||
fbb.startTable(19);
|
final sourceOffset =
|
||||||
|
object.source == null ? null : fbb.writeString(object.source!);
|
||||||
|
fbb.startTable(20);
|
||||||
fbb.addInt64(0, object.id);
|
fbb.addInt64(0, object.id);
|
||||||
fbb.addFloat64(1, object.units);
|
fbb.addFloat64(1, object.units);
|
||||||
fbb.addFloat64(2, object.carbs);
|
fbb.addFloat64(2, object.carbs);
|
||||||
@ -1756,6 +1891,7 @@ ModelDefinition getObjectBoxModel() {
|
|||||||
fbb.addFloat64(15, object.mmolPerLCurrent);
|
fbb.addFloat64(15, object.mmolPerLCurrent);
|
||||||
fbb.addFloat64(16, object.mmolPerLTarget);
|
fbb.addFloat64(16, object.mmolPerLTarget);
|
||||||
fbb.addFloat64(17, object.mmolPerLCorrection);
|
fbb.addFloat64(17, object.mmolPerLCorrection);
|
||||||
|
fbb.addOffset(18, sourceOffset);
|
||||||
fbb.finish(fbb.endTable());
|
fbb.finish(fbb.endTable());
|
||||||
return object.id;
|
return object.id;
|
||||||
},
|
},
|
||||||
@ -1788,7 +1924,9 @@ ModelDefinition getObjectBoxModel() {
|
|||||||
setManually: const fb.BoolReader()
|
setManually: const fb.BoolReader()
|
||||||
.vTableGet(buffer, rootOffset, 16, false),
|
.vTableGet(buffer, rootOffset, 16, false),
|
||||||
notes: const fb.StringReader(asciiOptimization: true)
|
notes: const fb.StringReader(asciiOptimization: true)
|
||||||
.vTableGetNullable(buffer, rootOffset, 18));
|
.vTableGetNullable(buffer, rootOffset, 18),
|
||||||
|
source:
|
||||||
|
const fb.StringReader(asciiOptimization: true).vTableGetNullable(buffer, rootOffset, 40));
|
||||||
object.logEntry.targetId =
|
object.logEntry.targetId =
|
||||||
const fb.Int64Reader().vTableGet(buffer, rootOffset, 20, 0);
|
const fb.Int64Reader().vTableGet(buffer, rootOffset, 20, 0);
|
||||||
object.logEntry.attach(store);
|
object.logEntry.attach(store);
|
||||||
@ -1812,7 +1950,9 @@ ModelDefinition getObjectBoxModel() {
|
|||||||
final valueOffset = fbb.writeString(object.value);
|
final valueOffset = fbb.writeString(object.value);
|
||||||
final notesOffset =
|
final notesOffset =
|
||||||
object.notes == null ? null : fbb.writeString(object.notes!);
|
object.notes == null ? null : fbb.writeString(object.notes!);
|
||||||
fbb.startTable(8);
|
final sourceOffset =
|
||||||
|
object.source == null ? null : fbb.writeString(object.source!);
|
||||||
|
fbb.startTable(9);
|
||||||
fbb.addInt64(0, object.id);
|
fbb.addInt64(0, object.id);
|
||||||
fbb.addOffset(1, valueOffset);
|
fbb.addOffset(1, valueOffset);
|
||||||
fbb.addBool(2, object.forCarbsRatio);
|
fbb.addBool(2, object.forCarbsRatio);
|
||||||
@ -1820,6 +1960,7 @@ ModelDefinition getObjectBoxModel() {
|
|||||||
fbb.addInt64(4, object.confidenceRating);
|
fbb.addInt64(4, object.confidenceRating);
|
||||||
fbb.addOffset(5, notesOffset);
|
fbb.addOffset(5, notesOffset);
|
||||||
fbb.addBool(6, object.deleted);
|
fbb.addBool(6, object.deleted);
|
||||||
|
fbb.addOffset(7, sourceOffset);
|
||||||
fbb.finish(fbb.endTable());
|
fbb.finish(fbb.endTable());
|
||||||
return object.id;
|
return object.id;
|
||||||
},
|
},
|
||||||
@ -1840,7 +1981,9 @@ ModelDefinition getObjectBoxModel() {
|
|||||||
confidenceRating: const fb.Int64Reader()
|
confidenceRating: const fb.Int64Reader()
|
||||||
.vTableGetNullable(buffer, rootOffset, 12),
|
.vTableGetNullable(buffer, rootOffset, 12),
|
||||||
notes: const fb.StringReader(asciiOptimization: true)
|
notes: const fb.StringReader(asciiOptimization: true)
|
||||||
.vTableGetNullable(buffer, rootOffset, 14));
|
.vTableGetNullable(buffer, rootOffset, 14),
|
||||||
|
source: const fb.StringReader(asciiOptimization: true)
|
||||||
|
.vTableGetNullable(buffer, rootOffset, 18));
|
||||||
|
|
||||||
return object;
|
return object;
|
||||||
}),
|
}),
|
||||||
@ -1861,7 +2004,7 @@ ModelDefinition getObjectBoxModel() {
|
|||||||
final longTimeFormatOffset = object.longTimeFormat == null
|
final longTimeFormatOffset = object.longTimeFormat == null
|
||||||
? null
|
? null
|
||||||
: fbb.writeString(object.longTimeFormat!);
|
: fbb.writeString(object.longTimeFormat!);
|
||||||
fbb.startTable(28);
|
fbb.startTable(29);
|
||||||
fbb.addInt64(0, object.id);
|
fbb.addInt64(0, object.id);
|
||||||
fbb.addOffset(1, dateFormatOffset);
|
fbb.addOffset(1, dateFormatOffset);
|
||||||
fbb.addOffset(2, longDateFormatOffset);
|
fbb.addOffset(2, longDateFormatOffset);
|
||||||
@ -1880,13 +2023,15 @@ ModelDefinition getObjectBoxModel() {
|
|||||||
fbb.addFloat64(24, object.nutritionIncrements);
|
fbb.addFloat64(24, object.nutritionIncrements);
|
||||||
fbb.addFloat64(25, object.mmolPerLIncrements);
|
fbb.addFloat64(25, object.mmolPerLIncrements);
|
||||||
fbb.addFloat64(26, object.amountIncrements);
|
fbb.addFloat64(26, object.amountIncrements);
|
||||||
|
fbb.addInt64(27, object.lastExportTimestamp?.millisecondsSinceEpoch);
|
||||||
fbb.finish(fbb.endTable());
|
fbb.finish(fbb.endTable());
|
||||||
return object.id;
|
return object.id;
|
||||||
},
|
},
|
||||||
objectFromFB: (Store store, ByteData fbData) {
|
objectFromFB: (Store store, ByteData fbData) {
|
||||||
final buffer = fb.BufferContext(fbData);
|
final buffer = fb.BufferContext(fbData);
|
||||||
final rootOffset = buffer.derefObject(0);
|
final rootOffset = buffer.derefObject(0);
|
||||||
|
final lastExportTimestampValue =
|
||||||
|
const fb.Int64Reader().vTableGetNullable(buffer, rootOffset, 58);
|
||||||
final object = Settings(
|
final object = Settings(
|
||||||
id: const fb.Int64Reader().vTableGet(buffer, rootOffset, 4, 0),
|
id: const fb.Int64Reader().vTableGet(buffer, rootOffset, 4, 0),
|
||||||
nutritionMeasurementIndex:
|
nutritionMeasurementIndex:
|
||||||
@ -1916,7 +2061,8 @@ ModelDefinition getObjectBoxModel() {
|
|||||||
showConfirmationDialogOnStopEvent: const fb.BoolReader().vTableGet(buffer, rootOffset, 18, false),
|
showConfirmationDialogOnStopEvent: const fb.BoolReader().vTableGet(buffer, rootOffset, 18, false),
|
||||||
targetGlucoseMgPerDl: const fb.Int64Reader().vTableGet(buffer, rootOffset, 44, 0),
|
targetGlucoseMgPerDl: const fb.Int64Reader().vTableGet(buffer, rootOffset, 44, 0),
|
||||||
targetGlucoseMmolPerL: const fb.Float64Reader().vTableGet(buffer, rootOffset, 46, 0),
|
targetGlucoseMmolPerL: const fb.Float64Reader().vTableGet(buffer, rootOffset, 46, 0),
|
||||||
useDarkTheme: const fb.BoolReader().vTableGet(buffer, rootOffset, 48, false));
|
useDarkTheme: const fb.BoolReader().vTableGet(buffer, rootOffset, 48, false),
|
||||||
|
lastExportTimestamp: lastExportTimestampValue == null ? null : DateTime.fromMillisecondsSinceEpoch(lastExportTimestampValue));
|
||||||
|
|
||||||
return object;
|
return object;
|
||||||
}),
|
}),
|
||||||
@ -1929,7 +2075,9 @@ ModelDefinition getObjectBoxModel() {
|
|||||||
object.id = id;
|
object.id = id;
|
||||||
},
|
},
|
||||||
objectToFB: (GlucoseTarget object, fb.Builder fbb) {
|
objectToFB: (GlucoseTarget object, fb.Builder fbb) {
|
||||||
fbb.startTable(8);
|
final sourceOffset =
|
||||||
|
object.source == null ? null : fbb.writeString(object.source!);
|
||||||
|
fbb.startTable(9);
|
||||||
fbb.addInt64(0, object.id);
|
fbb.addInt64(0, object.id);
|
||||||
fbb.addBool(1, object.deleted);
|
fbb.addBool(1, object.deleted);
|
||||||
fbb.addInt64(2, object.fromMgPerDL);
|
fbb.addInt64(2, object.fromMgPerDL);
|
||||||
@ -1937,6 +2085,7 @@ ModelDefinition getObjectBoxModel() {
|
|||||||
fbb.addFloat64(4, object.fromMmolPerL);
|
fbb.addFloat64(4, object.fromMmolPerL);
|
||||||
fbb.addFloat64(5, object.toMmolPerL);
|
fbb.addFloat64(5, object.toMmolPerL);
|
||||||
fbb.addInt64(6, object.color);
|
fbb.addInt64(6, object.color);
|
||||||
|
fbb.addOffset(7, sourceOffset);
|
||||||
fbb.finish(fbb.endTable());
|
fbb.finish(fbb.endTable());
|
||||||
return object.id;
|
return object.id;
|
||||||
},
|
},
|
||||||
@ -1957,7 +2106,9 @@ ModelDefinition getObjectBoxModel() {
|
|||||||
toMmolPerL:
|
toMmolPerL:
|
||||||
const fb.Float64Reader().vTableGet(buffer, rootOffset, 14, 0),
|
const fb.Float64Reader().vTableGet(buffer, rootOffset, 14, 0),
|
||||||
color:
|
color:
|
||||||
const fb.Int64Reader().vTableGet(buffer, rootOffset, 16, 0));
|
const fb.Int64Reader().vTableGet(buffer, rootOffset, 16, 0),
|
||||||
|
source: const fb.StringReader(asciiOptimization: true)
|
||||||
|
.vTableGetNullable(buffer, rootOffset, 18));
|
||||||
|
|
||||||
return object;
|
return object;
|
||||||
}),
|
}),
|
||||||
@ -2105,6 +2256,9 @@ class Basal_ {
|
|||||||
/// see [Basal.deleted]
|
/// see [Basal.deleted]
|
||||||
static final deleted =
|
static final deleted =
|
||||||
QueryBooleanProperty<Basal>(_entities[0].properties[5]);
|
QueryBooleanProperty<Basal>(_entities[0].properties[5]);
|
||||||
|
|
||||||
|
/// see [Basal.source]
|
||||||
|
static final source = QueryStringProperty<Basal>(_entities[0].properties[6]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [BasalProfile] entity fields to define ObjectBox queries.
|
/// [BasalProfile] entity fields to define ObjectBox queries.
|
||||||
@ -2128,6 +2282,10 @@ class BasalProfile_ {
|
|||||||
/// see [BasalProfile.deleted]
|
/// see [BasalProfile.deleted]
|
||||||
static final deleted =
|
static final deleted =
|
||||||
QueryBooleanProperty<BasalProfile>(_entities[1].properties[4]);
|
QueryBooleanProperty<BasalProfile>(_entities[1].properties[4]);
|
||||||
|
|
||||||
|
/// see [BasalProfile.source]
|
||||||
|
static final source =
|
||||||
|
QueryStringProperty<BasalProfile>(_entities[1].properties[5]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [Bolus] entity fields to define ObjectBox queries.
|
/// [Bolus] entity fields to define ObjectBox queries.
|
||||||
@ -2164,6 +2322,9 @@ class Bolus_ {
|
|||||||
/// see [Bolus.deleted]
|
/// see [Bolus.deleted]
|
||||||
static final deleted =
|
static final deleted =
|
||||||
QueryBooleanProperty<Bolus>(_entities[2].properties[8]);
|
QueryBooleanProperty<Bolus>(_entities[2].properties[8]);
|
||||||
|
|
||||||
|
/// see [Bolus.source]
|
||||||
|
static final source = QueryStringProperty<Bolus>(_entities[2].properties[9]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [BolusProfile] entity fields to define ObjectBox queries.
|
/// [BolusProfile] entity fields to define ObjectBox queries.
|
||||||
@ -2187,6 +2348,10 @@ class BolusProfile_ {
|
|||||||
/// see [BolusProfile.deleted]
|
/// see [BolusProfile.deleted]
|
||||||
static final deleted =
|
static final deleted =
|
||||||
QueryBooleanProperty<BolusProfile>(_entities[3].properties[4]);
|
QueryBooleanProperty<BolusProfile>(_entities[3].properties[4]);
|
||||||
|
|
||||||
|
/// see [BolusProfile.source]
|
||||||
|
static final source =
|
||||||
|
QueryStringProperty<BolusProfile>(_entities[3].properties[5]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [LogEntry] entity fields to define ObjectBox queries.
|
/// [LogEntry] entity fields to define ObjectBox queries.
|
||||||
@ -2217,6 +2382,10 @@ class LogEntry_ {
|
|||||||
/// see [LogEntry.glucoseTrend]
|
/// see [LogEntry.glucoseTrend]
|
||||||
static final glucoseTrend =
|
static final glucoseTrend =
|
||||||
QueryDoubleProperty<LogEntry>(_entities[4].properties[6]);
|
QueryDoubleProperty<LogEntry>(_entities[4].properties[6]);
|
||||||
|
|
||||||
|
/// see [LogEntry.source]
|
||||||
|
static final source =
|
||||||
|
QueryStringProperty<LogEntry>(_entities[4].properties[7]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [LogEvent] entity fields to define ObjectBox queries.
|
/// [LogEvent] entity fields to define ObjectBox queries.
|
||||||
@ -2259,6 +2428,10 @@ class LogEvent_ {
|
|||||||
/// see [LogEvent.reminderDuration]
|
/// see [LogEvent.reminderDuration]
|
||||||
static final reminderDuration =
|
static final reminderDuration =
|
||||||
QueryIntegerProperty<LogEvent>(_entities[5].properties[9]);
|
QueryIntegerProperty<LogEvent>(_entities[5].properties[9]);
|
||||||
|
|
||||||
|
/// see [LogEvent.source]
|
||||||
|
static final source =
|
||||||
|
QueryStringProperty<LogEvent>(_entities[5].properties[10]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [LogEventType] entity fields to define ObjectBox queries.
|
/// [LogEventType] entity fields to define ObjectBox queries.
|
||||||
@ -2294,6 +2467,10 @@ class LogEventType_ {
|
|||||||
/// see [LogEventType.basalProfile]
|
/// see [LogEventType.basalProfile]
|
||||||
static final basalProfile = QueryRelationToOne<LogEventType, BasalProfile>(
|
static final basalProfile = QueryRelationToOne<LogEventType, BasalProfile>(
|
||||||
_entities[6].properties[7]);
|
_entities[6].properties[7]);
|
||||||
|
|
||||||
|
/// see [LogEventType.source]
|
||||||
|
static final source =
|
||||||
|
QueryStringProperty<LogEventType>(_entities[6].properties[8]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [LogMeal] entity fields to define ObjectBox queries.
|
/// [LogMeal] entity fields to define ObjectBox queries.
|
||||||
@ -2312,51 +2489,52 @@ class LogMeal_ {
|
|||||||
static final portionSize =
|
static final portionSize =
|
||||||
QueryDoubleProperty<LogMeal>(_entities[7].properties[3]);
|
QueryDoubleProperty<LogMeal>(_entities[7].properties[3]);
|
||||||
|
|
||||||
/// see [LogMeal.bolus]
|
|
||||||
static final bolus = QueryDoubleProperty<LogMeal>(_entities[7].properties[4]);
|
|
||||||
|
|
||||||
/// see [LogMeal.notes]
|
/// see [LogMeal.notes]
|
||||||
static final notes = QueryStringProperty<LogMeal>(_entities[7].properties[5]);
|
static final notes = QueryStringProperty<LogMeal>(_entities[7].properties[4]);
|
||||||
|
|
||||||
/// see [LogMeal.logEntry]
|
/// see [LogMeal.logEntry]
|
||||||
static final logEntry =
|
static final logEntry =
|
||||||
QueryRelationToOne<LogMeal, LogEntry>(_entities[7].properties[6]);
|
QueryRelationToOne<LogMeal, LogEntry>(_entities[7].properties[5]);
|
||||||
|
|
||||||
/// see [LogMeal.meal]
|
/// see [LogMeal.meal]
|
||||||
static final meal =
|
static final meal =
|
||||||
QueryRelationToOne<LogMeal, Meal>(_entities[7].properties[7]);
|
QueryRelationToOne<LogMeal, Meal>(_entities[7].properties[6]);
|
||||||
|
|
||||||
/// see [LogMeal.mealSource]
|
/// see [LogMeal.mealSource]
|
||||||
static final mealSource =
|
static final mealSource =
|
||||||
QueryRelationToOne<LogMeal, MealSource>(_entities[7].properties[8]);
|
QueryRelationToOne<LogMeal, MealSource>(_entities[7].properties[7]);
|
||||||
|
|
||||||
/// see [LogMeal.mealCategory]
|
/// see [LogMeal.mealCategory]
|
||||||
static final mealCategory =
|
static final mealCategory =
|
||||||
QueryRelationToOne<LogMeal, MealCategory>(_entities[7].properties[9]);
|
QueryRelationToOne<LogMeal, MealCategory>(_entities[7].properties[8]);
|
||||||
|
|
||||||
/// see [LogMeal.mealPortionType]
|
/// see [LogMeal.mealPortionType]
|
||||||
static final mealPortionType =
|
static final mealPortionType =
|
||||||
QueryRelationToOne<LogMeal, MealPortionType>(_entities[7].properties[10]);
|
QueryRelationToOne<LogMeal, MealPortionType>(_entities[7].properties[9]);
|
||||||
|
|
||||||
/// see [LogMeal.portionSizeAccuracy]
|
/// see [LogMeal.portionSizeAccuracy]
|
||||||
static final portionSizeAccuracy =
|
static final portionSizeAccuracy =
|
||||||
QueryRelationToOne<LogMeal, Accuracy>(_entities[7].properties[11]);
|
QueryRelationToOne<LogMeal, Accuracy>(_entities[7].properties[10]);
|
||||||
|
|
||||||
/// see [LogMeal.carbsRatioAccuracy]
|
/// see [LogMeal.carbsRatioAccuracy]
|
||||||
static final carbsRatioAccuracy =
|
static final carbsRatioAccuracy =
|
||||||
QueryRelationToOne<LogMeal, Accuracy>(_entities[7].properties[12]);
|
QueryRelationToOne<LogMeal, Accuracy>(_entities[7].properties[11]);
|
||||||
|
|
||||||
/// see [LogMeal.deleted]
|
/// see [LogMeal.deleted]
|
||||||
static final deleted =
|
static final deleted =
|
||||||
QueryBooleanProperty<LogMeal>(_entities[7].properties[13]);
|
QueryBooleanProperty<LogMeal>(_entities[7].properties[12]);
|
||||||
|
|
||||||
/// see [LogMeal.amount]
|
/// see [LogMeal.amount]
|
||||||
static final amount =
|
static final amount =
|
||||||
QueryDoubleProperty<LogMeal>(_entities[7].properties[14]);
|
QueryDoubleProperty<LogMeal>(_entities[7].properties[13]);
|
||||||
|
|
||||||
/// see [LogMeal.totalCarbs]
|
/// see [LogMeal.totalCarbs]
|
||||||
static final totalCarbs =
|
static final totalCarbs =
|
||||||
QueryDoubleProperty<LogMeal>(_entities[7].properties[15]);
|
QueryDoubleProperty<LogMeal>(_entities[7].properties[14]);
|
||||||
|
|
||||||
|
/// see [LogMeal.source]
|
||||||
|
static final source =
|
||||||
|
QueryStringProperty<LogMeal>(_entities[7].properties[15]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [Meal] entity fields to define ObjectBox queries.
|
/// [Meal] entity fields to define ObjectBox queries.
|
||||||
@ -2413,6 +2591,9 @@ class Meal_ {
|
|||||||
/// see [Meal.delayedBolusPercentage]
|
/// see [Meal.delayedBolusPercentage]
|
||||||
static final delayedBolusPercentage =
|
static final delayedBolusPercentage =
|
||||||
QueryDoubleProperty<Meal>(_entities[8].properties[13]);
|
QueryDoubleProperty<Meal>(_entities[8].properties[13]);
|
||||||
|
|
||||||
|
/// see [Meal.source]
|
||||||
|
static final source = QueryStringProperty<Meal>(_entities[8].properties[14]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [MealCategory] entity fields to define ObjectBox queries.
|
/// [MealCategory] entity fields to define ObjectBox queries.
|
||||||
@ -2432,6 +2613,10 @@ class MealCategory_ {
|
|||||||
/// see [MealCategory.deleted]
|
/// see [MealCategory.deleted]
|
||||||
static final deleted =
|
static final deleted =
|
||||||
QueryBooleanProperty<MealCategory>(_entities[9].properties[3]);
|
QueryBooleanProperty<MealCategory>(_entities[9].properties[3]);
|
||||||
|
|
||||||
|
/// see [MealCategory.source]
|
||||||
|
static final source =
|
||||||
|
QueryStringProperty<MealCategory>(_entities[9].properties[4]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [MealPortionType] entity fields to define ObjectBox queries.
|
/// [MealPortionType] entity fields to define ObjectBox queries.
|
||||||
@ -2451,6 +2636,10 @@ class MealPortionType_ {
|
|||||||
/// see [MealPortionType.deleted]
|
/// see [MealPortionType.deleted]
|
||||||
static final deleted =
|
static final deleted =
|
||||||
QueryBooleanProperty<MealPortionType>(_entities[10].properties[3]);
|
QueryBooleanProperty<MealPortionType>(_entities[10].properties[3]);
|
||||||
|
|
||||||
|
/// see [MealPortionType.source]
|
||||||
|
static final source =
|
||||||
|
QueryStringProperty<MealPortionType>(_entities[10].properties[4]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [MealSource] entity fields to define ObjectBox queries.
|
/// [MealSource] entity fields to define ObjectBox queries.
|
||||||
@ -2487,6 +2676,10 @@ class MealSource_ {
|
|||||||
/// see [MealSource.deleted]
|
/// see [MealSource.deleted]
|
||||||
static final deleted =
|
static final deleted =
|
||||||
QueryBooleanProperty<MealSource>(_entities[11].properties[7]);
|
QueryBooleanProperty<MealSource>(_entities[11].properties[7]);
|
||||||
|
|
||||||
|
/// see [MealSource.source]
|
||||||
|
static final source =
|
||||||
|
QueryStringProperty<MealSource>(_entities[11].properties[8]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [LogBolus] entity fields to define ObjectBox queries.
|
/// [LogBolus] entity fields to define ObjectBox queries.
|
||||||
@ -2553,6 +2746,10 @@ class LogBolus_ {
|
|||||||
/// see [LogBolus.mmolPerLCorrection]
|
/// see [LogBolus.mmolPerLCorrection]
|
||||||
static final mmolPerLCorrection =
|
static final mmolPerLCorrection =
|
||||||
QueryDoubleProperty<LogBolus>(_entities[12].properties[15]);
|
QueryDoubleProperty<LogBolus>(_entities[12].properties[15]);
|
||||||
|
|
||||||
|
/// see [LogBolus.source]
|
||||||
|
static final source =
|
||||||
|
QueryStringProperty<LogBolus>(_entities[12].properties[16]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [Accuracy] entity fields to define ObjectBox queries.
|
/// [Accuracy] entity fields to define ObjectBox queries.
|
||||||
@ -2583,6 +2780,10 @@ class Accuracy_ {
|
|||||||
/// see [Accuracy.deleted]
|
/// see [Accuracy.deleted]
|
||||||
static final deleted =
|
static final deleted =
|
||||||
QueryBooleanProperty<Accuracy>(_entities[13].properties[6]);
|
QueryBooleanProperty<Accuracy>(_entities[13].properties[6]);
|
||||||
|
|
||||||
|
/// see [Accuracy.source]
|
||||||
|
static final source =
|
||||||
|
QueryStringProperty<Accuracy>(_entities[13].properties[7]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [Settings] entity fields to define ObjectBox queries.
|
/// [Settings] entity fields to define ObjectBox queries.
|
||||||
@ -2657,6 +2858,10 @@ class Settings_ {
|
|||||||
/// see [Settings.amountIncrements]
|
/// see [Settings.amountIncrements]
|
||||||
static final amountIncrements =
|
static final amountIncrements =
|
||||||
QueryDoubleProperty<Settings>(_entities[14].properties[17]);
|
QueryDoubleProperty<Settings>(_entities[14].properties[17]);
|
||||||
|
|
||||||
|
/// see [Settings.lastExportTimestamp]
|
||||||
|
static final lastExportTimestamp =
|
||||||
|
QueryIntegerProperty<Settings>(_entities[14].properties[18]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [GlucoseTarget] entity fields to define ObjectBox queries.
|
/// [GlucoseTarget] entity fields to define ObjectBox queries.
|
||||||
@ -2688,6 +2893,10 @@ class GlucoseTarget_ {
|
|||||||
/// see [GlucoseTarget.color]
|
/// see [GlucoseTarget.color]
|
||||||
static final color =
|
static final color =
|
||||||
QueryIntegerProperty<GlucoseTarget>(_entities[15].properties[6]);
|
QueryIntegerProperty<GlucoseTarget>(_entities[15].properties[6]);
|
||||||
|
|
||||||
|
/// see [GlucoseTarget.source]
|
||||||
|
static final source =
|
||||||
|
QueryStringProperty<GlucoseTarget>(_entities[15].properties[7]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [Recipe] entity fields to define ObjectBox queries.
|
/// [Recipe] entity fields to define ObjectBox queries.
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import 'package:diameter/components/detail.dart';
|
import 'package:diameter/components/detail.dart';
|
||||||
import 'package:diameter/components/forms/number_form_field.dart';
|
import 'package:diameter/components/forms/number_form_field.dart';
|
||||||
import 'package:diameter/components/forms/time_of_day_form_field.dart';
|
import 'package:diameter/components/forms/time_of_day_form_field.dart';
|
||||||
|
import 'package:diameter/localization_keys.dart';
|
||||||
import 'package:diameter/utils/dialog_utils.dart';
|
import 'package:diameter/utils/dialog_utils.dart';
|
||||||
import 'package:diameter/models/settings.dart';
|
import 'package:diameter/models/settings.dart';
|
||||||
import 'package:diameter/navigation.dart';
|
import 'package:diameter/navigation.dart';
|
||||||
@ -10,6 +11,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:diameter/components/forms/form_wrapper.dart';
|
import 'package:diameter/components/forms/form_wrapper.dart';
|
||||||
import 'package:diameter/models/basal.dart';
|
import 'package:diameter/models/basal.dart';
|
||||||
import 'package:diameter/models/basal_profile.dart';
|
import 'package:diameter/models/basal_profile.dart';
|
||||||
|
import 'package:flutter_translate/flutter_translate.dart';
|
||||||
|
|
||||||
class BasalDetailScreen extends StatefulWidget {
|
class BasalDetailScreen extends StatefulWidget {
|
||||||
static const String routeName = '/basal';
|
static const String routeName = '/basal';
|
||||||
@ -130,7 +132,7 @@ class _BasalDetailScreenState extends State<BasalDetailScreen> {
|
|||||||
_startTime.hour == other.startTime.hour &&
|
_startTime.hour == other.startTime.hour &&
|
||||||
_startTime.minute == other.startTime.minute)
|
_startTime.minute == other.startTime.minute)
|
||||||
.isNotEmpty) {
|
.isNotEmpty) {
|
||||||
error = 'There\'s already a rate with this start time.';
|
error = translate(LocalizationKeys.basal_warnings_duplicate);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (basalRates
|
if (basalRates
|
||||||
@ -141,7 +143,7 @@ class _BasalDetailScreenState extends State<BasalDetailScreen> {
|
|||||||
DateTimeUtils.convertTimeOfDayToDateTime(_endTime)
|
DateTimeUtils.convertTimeOfDayToDateTime(_endTime)
|
||||||
.isAfter(other.startTime))
|
.isAfter(other.startTime))
|
||||||
.isNotEmpty) {
|
.isNotEmpty) {
|
||||||
error = 'This rate\'s time period overlaps with another one.';
|
error = translate(LocalizationKeys.basal_warnings_overlap);
|
||||||
}
|
}
|
||||||
|
|
||||||
return error == null
|
return error == null
|
||||||
@ -154,11 +156,11 @@ class _BasalDetailScreenState extends State<BasalDetailScreen> {
|
|||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.pop(context, 'CANCEL'),
|
onPressed: () => Navigator.pop(context, 'CANCEL'),
|
||||||
child: const Text('GO BACK TO EDITING'),
|
child: Text(translate(LocalizationKeys.general_keepEditing).toUpperCase()),
|
||||||
),
|
),
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: () => Navigator.pop(context, 'CONFIRM'),
|
onPressed: () => Navigator.pop(context, 'CONFIRM'),
|
||||||
child: const Text('SAVE AS IS'),
|
child: Text(translate(LocalizationKeys.general_saveAsIs).toUpperCase()),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@ -196,13 +198,26 @@ class _BasalDetailScreenState extends State<BasalDetailScreen> {
|
|||||||
).then((result) {
|
).then((result) {
|
||||||
Navigator.pop(
|
Navigator.pop(
|
||||||
context,
|
context,
|
||||||
['New Basal Rate${result[1] != null ? 's' : ''} saved', basal] +
|
[
|
||||||
[result[1]],
|
translatePlural(
|
||||||
|
LocalizationKeys.basal_saved,
|
||||||
|
result.length,
|
||||||
|
args: {
|
||||||
|
"status": _isNew ? '${LocalizationKeys.basal_new} ' : ''
|
||||||
|
},
|
||||||
|
),
|
||||||
|
basal] + [result[1]],
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
Navigator.pop(
|
Navigator.pop(
|
||||||
context, ['${_isNew ? 'New' : ''} Basal Rate saved', basal]);
|
context, [translatePlural(
|
||||||
|
LocalizationKeys.basal_saved,
|
||||||
|
1,
|
||||||
|
args: {
|
||||||
|
"status": _isNew ? '${LocalizationKeys.basal_new} ' : ''
|
||||||
|
},
|
||||||
|
), basal]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -241,7 +256,14 @@ class _BasalDetailScreenState extends State<BasalDetailScreen> {
|
|||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(
|
title: Text(
|
||||||
'${_isNew ? 'New' : 'Edit'} Basal Rate for ${BasalProfile.get(widget.basalProfileId)?.name}'),
|
translate(
|
||||||
|
LocalizationKeys.basal_title,
|
||||||
|
args: {
|
||||||
|
"status": _isNew ? LocalizationKeys.basal_new : LocalizationKeys.general_edit,
|
||||||
|
"profileName": BasalProfile.get(widget.basalProfileId)?.name,
|
||||||
|
}
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
drawer: const Navigation(currentLocation: BasalDetailScreen.routeName),
|
drawer: const Navigation(currentLocation: BasalDetailScreen.routeName),
|
||||||
body: Scrollbar(
|
body: Scrollbar(
|
||||||
@ -259,7 +281,7 @@ class _BasalDetailScreenState extends State<BasalDetailScreen> {
|
|||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(right: 5),
|
padding: const EdgeInsets.only(right: 5),
|
||||||
child: TimeOfDayFormField(
|
child: TimeOfDayFormField(
|
||||||
label: 'Start Time',
|
label: translate(LocalizationKeys.basal_fields_startTime),
|
||||||
controller: _startTimeController,
|
controller: _startTimeController,
|
||||||
time: _startTime,
|
time: _startTime,
|
||||||
onChanged: updateStartTime,
|
onChanged: updateStartTime,
|
||||||
@ -270,7 +292,7 @@ class _BasalDetailScreenState extends State<BasalDetailScreen> {
|
|||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(left: 5),
|
padding: const EdgeInsets.only(left: 5),
|
||||||
child: TimeOfDayFormField(
|
child: TimeOfDayFormField(
|
||||||
label: 'End Time',
|
label: translate(LocalizationKeys.basal_fields_endTime),
|
||||||
controller: _endTimeController,
|
controller: _endTimeController,
|
||||||
time: _endTime,
|
time: _endTime,
|
||||||
onChanged: updateEndTime,
|
onChanged: updateEndTime,
|
||||||
@ -281,8 +303,8 @@ class _BasalDetailScreenState extends State<BasalDetailScreen> {
|
|||||||
),
|
),
|
||||||
NumberFormField(
|
NumberFormField(
|
||||||
controller: _unitsController,
|
controller: _unitsController,
|
||||||
label: 'Units',
|
label: translate(LocalizationKeys.basal_fields_units),
|
||||||
suffix: 'U',
|
suffix: translate(LocalizationKeys.general_suffixes_units),
|
||||||
autoRoundToMultipleOfStep: true,
|
autoRoundToMultipleOfStep: true,
|
||||||
step: Settings.insulinSteps,
|
step: Settings.insulinSteps,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
@ -291,7 +313,7 @@ class _BasalDetailScreenState extends State<BasalDetailScreen> {
|
|||||||
Utils.toStringMatchingTemplateFractionPrecision(
|
Utils.toStringMatchingTemplateFractionPrecision(
|
||||||
value, Settings.insulinSteps);
|
value, Settings.insulinSteps);
|
||||||
}
|
}
|
||||||
}),
|
})
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -305,8 +327,8 @@ class _BasalDetailScreenState extends State<BasalDetailScreen> {
|
|||||||
onMiddleAction: _isSaving || _isFinalRate
|
onMiddleAction: _isSaving || _isFinalRate
|
||||||
? null
|
? null
|
||||||
: () => handleSaveAction(next: false),
|
: () => handleSaveAction(next: false),
|
||||||
actionText: _isFinalRate ? 'SAVE & CLOSE' : 'NEXT',
|
actionTextKey: translate(_isFinalRate ? LocalizationKeys.general_saveAndClose : LocalizationKeys.general_next).toUpperCase(),
|
||||||
middleActionText: 'SAVE & CLOSE',
|
middleActionTextKey: translate(LocalizationKeys.general_saveAndClose).toUpperCase(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import 'package:diameter/localization_keys.dart';
|
||||||
import 'package:diameter/utils/dialog_utils.dart';
|
import 'package:diameter/utils/dialog_utils.dart';
|
||||||
import 'package:diameter/models/settings.dart';
|
import 'package:diameter/models/settings.dart';
|
||||||
import 'package:diameter/utils/date_time_utils.dart';
|
import 'package:diameter/utils/date_time_utils.dart';
|
||||||
@ -5,6 +6,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:diameter/models/basal.dart';
|
import 'package:diameter/models/basal.dart';
|
||||||
import 'package:diameter/models/basal_profile.dart';
|
import 'package:diameter/models/basal_profile.dart';
|
||||||
import 'package:diameter/screens/basal/basal_detail.dart';
|
import 'package:diameter/screens/basal/basal_detail.dart';
|
||||||
|
import 'package:flutter_translate/flutter_translate.dart';
|
||||||
|
|
||||||
class BasalListScreen extends StatefulWidget {
|
class BasalListScreen extends StatefulWidget {
|
||||||
final BasalProfile basalProfile;
|
final BasalProfile basalProfile;
|
||||||
@ -61,7 +63,7 @@ class _BasalListScreenState extends State<BasalListScreen> {
|
|||||||
|
|
||||||
void onDelete(Basal basal) {
|
void onDelete(Basal basal) {
|
||||||
Basal.remove(basal.id);
|
Basal.remove(basal.id);
|
||||||
reload(message: 'Basal Rate deleted');
|
reload(message: translate(LocalizationKeys.basal_deleted));
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleDeleteAction(Basal basal) async {
|
void handleDeleteAction(Basal basal) async {
|
||||||
@ -69,7 +71,7 @@ class _BasalListScreenState extends State<BasalListScreen> {
|
|||||||
DialogUtils.showConfirmationDialog(
|
DialogUtils.showConfirmationDialog(
|
||||||
context: context,
|
context: context,
|
||||||
onConfirm: () => onDelete(basal),
|
onConfirm: () => onDelete(basal),
|
||||||
message: 'Are you sure you want to delete this Basal Rate?',
|
message: translate(LocalizationKeys.basal_confirmDelete),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
onDelete(basal);
|
onDelete(basal);
|
||||||
@ -83,26 +85,26 @@ class _BasalListScreenState extends State<BasalListScreen> {
|
|||||||
// check for gaps
|
// check for gaps
|
||||||
if (index == 0 &&
|
if (index == 0 &&
|
||||||
(basal.startTime.hour != 0 || basal.startTime.minute != 0)) {
|
(basal.startTime.hour != 0 || basal.startTime.minute != 0)) {
|
||||||
return 'First Basal of the day needs to start at 00:00';
|
return translate(LocalizationKeys.basal_warnings_startTimeFirst);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (index > 0) {
|
if (index > 0) {
|
||||||
var lastEndTime = basalRates[index - 1].endTime;
|
var lastEndTime = basalRates[index - 1].endTime;
|
||||||
if (basal.startTime.isAfter(lastEndTime)) {
|
if (basal.startTime.isAfter(lastEndTime)) {
|
||||||
return 'There\'s a time gap between this and the previous rate';
|
return translate(LocalizationKeys.basal_warnings_gap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (index == basalRates.length - 1 &&
|
if (index == basalRates.length - 1 &&
|
||||||
(basal.endTime.hour != 0 || basal.endTime.minute != 0)) {
|
(basal.endTime.hour != 0 || basal.endTime.minute != 0)) {
|
||||||
return 'Last Basal of the day needs to end at 00:00';
|
return translate(LocalizationKeys.basal_warnings_endTimeLast);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for duplicates
|
// check for duplicates
|
||||||
if (basalRates
|
if (basalRates
|
||||||
.where((other) => basal != other && basal.startTime == other.startTime)
|
.where((other) => basal != other && basal.startTime == other.startTime)
|
||||||
.isNotEmpty) {
|
.isNotEmpty) {
|
||||||
return 'There are multiple rates with this start time';
|
return translate(LocalizationKeys.basal_warnings_duplicate);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (basalRates
|
if (basalRates
|
||||||
@ -110,7 +112,7 @@ class _BasalListScreenState extends State<BasalListScreen> {
|
|||||||
basal.startTime.isBefore(other.startTime) &&
|
basal.startTime.isBefore(other.startTime) &&
|
||||||
basal.endTime.isAfter(other.startTime))
|
basal.endTime.isAfter(other.startTime))
|
||||||
.isNotEmpty) {
|
.isNotEmpty) {
|
||||||
return 'This rate\'s time period overlaps with another one';
|
return translate(LocalizationKeys.basal_warnings_overlap);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@ -158,7 +160,7 @@ class _BasalListScreenState extends State<BasalListScreen> {
|
|||||||
child: Text(
|
child: Text(
|
||||||
'${DateTimeUtils.displayTime(basal.startTime)} - ${DateTimeUtils.displayTime(basal.endTime)}')),
|
'${DateTimeUtils.displayTime(basal.startTime)} - ${DateTimeUtils.displayTime(basal.endTime)}')),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
Expanded(child: Text('${basal.units} U')),
|
Expanded(child: Text('${basal.units} ${translate(LocalizationKeys.general_suffixes_units)}')),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
trailing: Row(
|
trailing: Row(
|
||||||
@ -180,8 +182,8 @@ class _BasalListScreenState extends State<BasalListScreen> {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: const Center(
|
: Center(
|
||||||
child: Text('You have not created any Basal Rates yet!'),
|
child: Text(translate(LocalizationKeys.basal_empty)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import 'package:diameter/components/detail.dart';
|
import 'package:diameter/components/detail.dart';
|
||||||
import 'package:diameter/components/forms/boolean_form_field.dart';
|
import 'package:diameter/components/forms/boolean_form_field.dart';
|
||||||
|
import 'package:diameter/localization_keys.dart';
|
||||||
import 'package:diameter/utils/dialog_utils.dart';
|
import 'package:diameter/utils/dialog_utils.dart';
|
||||||
import 'package:diameter/models/basal.dart';
|
import 'package:diameter/models/basal.dart';
|
||||||
import 'package:diameter/models/settings.dart';
|
import 'package:diameter/models/settings.dart';
|
||||||
@ -9,6 +10,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:diameter/components/forms/form_wrapper.dart';
|
import 'package:diameter/components/forms/form_wrapper.dart';
|
||||||
import 'package:diameter/models/basal_profile.dart';
|
import 'package:diameter/models/basal_profile.dart';
|
||||||
import 'package:diameter/screens/basal/basal_list.dart';
|
import 'package:diameter/screens/basal/basal_list.dart';
|
||||||
|
import 'package:flutter_translate/flutter_translate.dart';
|
||||||
|
|
||||||
class BasalProfileDetailScreen extends StatefulWidget {
|
class BasalProfileDetailScreen extends StatefulWidget {
|
||||||
static const String routeName = '/basal-profile';
|
static const String routeName = '/basal-profile';
|
||||||
@ -133,21 +135,30 @@ class _BasalProfileDetailScreenState extends State<BasalProfileDetailScreen> {
|
|||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
content: const Text(
|
content: Text(translate(LocalizationKeys.basalProfile_warnings_activeAlreadySet)),
|
||||||
'There are already one or more active profiles. What would you like to do?'),
|
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.pop(context, 0),
|
onPressed: () => Navigator.pop(context, 0),
|
||||||
child: const Text('IGNORE'),
|
child: Text(translate(LocalizationKeys.basalProfile_warnings_resolve_ignore).toUpperCase()),
|
||||||
),
|
),
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.pop(context, 1),
|
onPressed: () => Navigator.pop(context, 1),
|
||||||
child:
|
child:
|
||||||
Text('DEACTIVATE ${_nameController.text.toUpperCase()}'),
|
Text(
|
||||||
|
translate(
|
||||||
|
LocalizationKeys.basalProfile_warnings_resolve_deactivateProfile,
|
||||||
|
args: {
|
||||||
|
"profileName": _nameController.text,
|
||||||
|
}
|
||||||
|
).toUpperCase()
|
||||||
|
),
|
||||||
),
|
),
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: () => Navigator.pop(context, 2),
|
onPressed: () => Navigator.pop(context, 2),
|
||||||
child: const Text('DEACTIVATE ALL OTHERS'),
|
child: Text(
|
||||||
|
translate(
|
||||||
|
LocalizationKeys.basalProfile_warnings_resolve_deactivateOthers,
|
||||||
|
).toUpperCase()),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@ -167,16 +178,25 @@ class _BasalProfileDetailScreenState extends State<BasalProfileDetailScreen> {
|
|||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
content: const Text(
|
content: Text(
|
||||||
'There is currently no active profile. Would you like to set this one as active?'),
|
translate(
|
||||||
|
LocalizationKeys.basalProfile_warnings_noActiveOnCreate,
|
||||||
|
).toUpperCase()),
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.pop(context, 0),
|
onPressed: () => Navigator.pop(context, 0),
|
||||||
child: const Text('IGNORE'),
|
child: Text(
|
||||||
|
translate(
|
||||||
|
LocalizationKeys.basalProfile_warnings_resolve_ignore,
|
||||||
|
).toUpperCase()),
|
||||||
),
|
),
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.pop(context, 1),
|
onPressed: () => Navigator.pop(context, 1),
|
||||||
child: const Text('ACTIVATE THIS PROFILE'),
|
child: Text(
|
||||||
|
translate(
|
||||||
|
LocalizationKeys.basalProfile_warnings_resolve_activateCurrent,
|
||||||
|
).toUpperCase()
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@ -249,7 +269,11 @@ class _BasalProfileDetailScreenState extends State<BasalProfileDetailScreen> {
|
|||||||
|
|
||||||
if (close) {
|
if (close) {
|
||||||
Navigator.pop(context,
|
Navigator.pop(context,
|
||||||
['${_isNew ? 'New' : ''} Basal Profile saved', basalProfile]);
|
[
|
||||||
|
translate(LocalizationKeys.basalProfile_saved, args: {
|
||||||
|
"status": _isNew ? '${translate(LocalizationKeys.basalProfile_new)} ' : ''
|
||||||
|
}),
|
||||||
|
]);
|
||||||
} else {
|
} else {
|
||||||
if (_isNew) {
|
if (_isNew) {
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
@ -260,7 +284,7 @@ class _BasalProfileDetailScreenState extends State<BasalProfileDetailScreen> {
|
|||||||
),
|
),
|
||||||
).then((result) => Navigator.pop(context, result));
|
).then((result) => Navigator.pop(context, result));
|
||||||
} else {
|
} else {
|
||||||
reload(message: 'Basal Profile saved');
|
reload(message: translate(LocalizationKeys.basalProfile_saved));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -329,12 +353,12 @@ class _BasalProfileDetailScreenState extends State<BasalProfileDetailScreen> {
|
|||||||
fields: [
|
fields: [
|
||||||
TextFormField(
|
TextFormField(
|
||||||
controller: _nameController,
|
controller: _nameController,
|
||||||
decoration: const InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: 'Name',
|
labelText: translate(LocalizationKeys.basalProfile_fields_name),
|
||||||
),
|
),
|
||||||
validator: (value) {
|
validator: (value) {
|
||||||
if (value!.trim().isEmpty) {
|
if (value!.trim().isEmpty) {
|
||||||
return 'Empty title';
|
return translate(LocalizationKeys.basalProfile_fields_validators_name);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
@ -342,8 +366,8 @@ class _BasalProfileDetailScreenState extends State<BasalProfileDetailScreen> {
|
|||||||
TextFormField(
|
TextFormField(
|
||||||
keyboardType: TextInputType.multiline,
|
keyboardType: TextInputType.multiline,
|
||||||
controller: _notesController,
|
controller: _notesController,
|
||||||
decoration: const InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: 'Notes',
|
labelText: translate(LocalizationKeys.basalProfile_fields_notes),
|
||||||
),
|
),
|
||||||
minLines: 2,
|
minLines: 2,
|
||||||
maxLines: 5,
|
maxLines: 5,
|
||||||
@ -355,7 +379,7 @@ class _BasalProfileDetailScreenState extends State<BasalProfileDetailScreen> {
|
|||||||
_active = value;
|
_active = value;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
label: 'active',
|
label: translate(LocalizationKeys.basalProfile_fields_active),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -374,13 +398,24 @@ class _BasalProfileDetailScreenState extends State<BasalProfileDetailScreen> {
|
|||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(_isNew ? 'New Basal Profile' : _basalProfile!.name),
|
title: Text(translate(LocalizationKeys.basalProfile_detail_title, args: {
|
||||||
|
"status": _isNew ? '${translate(LocalizationKeys.basalProfile_new)} ' : '',
|
||||||
|
"profileName": _basalProfile!.name,
|
||||||
|
})),
|
||||||
bottom: _isNew
|
bottom: _isNew
|
||||||
? PreferredSize(child: Container(), preferredSize: Size.zero)
|
? PreferredSize(child: Container(), preferredSize: Size.zero)
|
||||||
: const TabBar(
|
: TabBar(
|
||||||
tabs: [
|
tabs: [
|
||||||
Tab(text: 'PROFILE'),
|
Tab(
|
||||||
Tab(text: 'RATES'),
|
text: translate(
|
||||||
|
LocalizationKeys.basalProfile_detail_tabs_profile,
|
||||||
|
).toUpperCase(),
|
||||||
|
),
|
||||||
|
Tab(
|
||||||
|
text: translate(
|
||||||
|
LocalizationKeys.basalProfile_detail_tabs_rates,
|
||||||
|
).toUpperCase(),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
actions: appBarActions,
|
actions: appBarActions,
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import 'package:diameter/localization_keys.dart';
|
||||||
import 'package:diameter/utils/dialog_utils.dart';
|
import 'package:diameter/utils/dialog_utils.dart';
|
||||||
import 'package:diameter/components/forms/auto_complete_dropdown_button.dart';
|
import 'package:diameter/components/forms/auto_complete_dropdown_button.dart';
|
||||||
import 'package:diameter/models/basal.dart';
|
import 'package:diameter/models/basal.dart';
|
||||||
@ -6,6 +7,7 @@ import 'package:diameter/navigation.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:diameter/models/basal_profile.dart';
|
import 'package:diameter/models/basal_profile.dart';
|
||||||
import 'package:diameter/screens/basal/basal_profile_detail.dart';
|
import 'package:diameter/screens/basal/basal_profile_detail.dart';
|
||||||
|
import 'package:flutter_translate/flutter_translate.dart';
|
||||||
|
|
||||||
class BasalProfileListScreen extends StatefulWidget {
|
class BasalProfileListScreen extends StatefulWidget {
|
||||||
static const String routeName = '/basal-profiles';
|
static const String routeName = '/basal-profiles';
|
||||||
@ -59,26 +61,33 @@ class _BasalProfileListScreenState extends State<BasalProfileListScreen> {
|
|||||||
banner = activeProfileCount != 1
|
banner = activeProfileCount != 1
|
||||||
? MaterialBanner(
|
? MaterialBanner(
|
||||||
content: Text(activeProfileCount == 0
|
content: Text(activeProfileCount == 0
|
||||||
? 'You currently do not have an active Basal Profile.'
|
? translate(LocalizationKeys.basalProfile_warnings_noActive)
|
||||||
: 'More than one active Basal Profile has been found.'),
|
: translate(
|
||||||
|
LocalizationKeys.basalProfile_warnings_multipleActive)),
|
||||||
leading: const CircleAvatar(child: Icon(Icons.warning)),
|
leading: const CircleAvatar(child: Icon(Icons.warning)),
|
||||||
forceActionsBelow: true,
|
forceActionsBelow: true,
|
||||||
actions: activeProfileCount == 0
|
actions: activeProfileCount == 0
|
||||||
? [
|
? [
|
||||||
_basalProfiles.isNotEmpty
|
_basalProfiles.isNotEmpty
|
||||||
? TextButton(
|
? TextButton(
|
||||||
child: const Text('ACTIVATE A PROFILE'),
|
child: Text(translate(LocalizationKeys
|
||||||
|
.basalProfile_warnings_resolve_activate)
|
||||||
|
.toUpperCase()),
|
||||||
onPressed: handlePickActiveProfileAction,
|
onPressed: handlePickActiveProfileAction,
|
||||||
)
|
)
|
||||||
: Container(),
|
: Container(),
|
||||||
TextButton(
|
TextButton(
|
||||||
child: const Text('CREATE A NEW PROFILE'),
|
child: Text(translate(LocalizationKeys
|
||||||
|
.basalProfile_warnings_resolve_create)
|
||||||
|
.toUpperCase()),
|
||||||
onPressed: () => onNew(true),
|
onPressed: () => onNew(true),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
: [
|
: [
|
||||||
TextButton(
|
TextButton(
|
||||||
child: const Text('PICK A PROFILE'),
|
child: Text(translate(LocalizationKeys
|
||||||
|
.basalProfile_warnings_resolve_pick)
|
||||||
|
.toUpperCase()),
|
||||||
onPressed: handlePickActiveProfileAction,
|
onPressed: handlePickActiveProfileAction,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -90,8 +99,9 @@ class _BasalProfileListScreenState extends State<BasalProfileListScreen> {
|
|||||||
void handleDuplicateAction(BasalProfile basalProfile) async {
|
void handleDuplicateAction(BasalProfile basalProfile) async {
|
||||||
final copy = BasalProfile(
|
final copy = BasalProfile(
|
||||||
active: false,
|
active: false,
|
||||||
name: 'Copy of ${basalProfile.name}',
|
name: translate(LocalizationKeys.basalProfile_copyOf, args: {
|
||||||
);
|
"profileName": basalProfile.name,
|
||||||
|
}));
|
||||||
BasalProfile.put(copy);
|
BasalProfile.put(copy);
|
||||||
|
|
||||||
final rates = Basal.getAllForProfile(basalProfile.id);
|
final rates = Basal.getAllForProfile(basalProfile.id);
|
||||||
@ -105,12 +115,19 @@ class _BasalProfileListScreenState extends State<BasalProfileListScreen> {
|
|||||||
Basal.put(basal);
|
Basal.put(basal);
|
||||||
}
|
}
|
||||||
|
|
||||||
reload(message: 'Added copy of ${basalProfile.name}');
|
reload(
|
||||||
|
message: translate(
|
||||||
|
LocalizationKeys.basalProfile_warnings_resolve_ignore,
|
||||||
|
args: {"profileName": basalProfile.name},
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
void onDelete(BasalProfile basalProfile) {
|
void onDelete(BasalProfile basalProfile) {
|
||||||
BasalProfile.remove(basalProfile.id);
|
BasalProfile.remove(basalProfile.id);
|
||||||
reload(message: 'Basal Profile deleted');
|
reload(
|
||||||
|
message: translate(
|
||||||
|
LocalizationKeys.basalProfile_deleted,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleDeleteAction(BasalProfile basalProfile) async {
|
void handleDeleteAction(BasalProfile basalProfile) async {
|
||||||
@ -118,7 +135,7 @@ class _BasalProfileListScreenState extends State<BasalProfileListScreen> {
|
|||||||
DialogUtils.showConfirmationDialog(
|
DialogUtils.showConfirmationDialog(
|
||||||
context: context,
|
context: context,
|
||||||
onConfirm: () => onDelete(basalProfile),
|
onConfirm: () => onDelete(basalProfile),
|
||||||
message: 'Are you sure you want to delete this Basal Profile?',
|
message: translate(LocalizationKeys.basalProfile_confirmDelete),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
onDelete(basalProfile);
|
onDelete(basalProfile);
|
||||||
@ -131,7 +148,8 @@ class _BasalProfileListScreenState extends State<BasalProfileListScreen> {
|
|||||||
basalProfile.active = true;
|
basalProfile.active = true;
|
||||||
BasalProfile.put(basalProfile);
|
BasalProfile.put(basalProfile);
|
||||||
reload(
|
reload(
|
||||||
message: '${basalProfile.name} has been set as your active Profile');
|
message: translate(LocalizationKeys.basalProfile_activated,
|
||||||
|
args: {"profileName": basalProfile.name}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,14 +159,16 @@ class _BasalProfileListScreenState extends State<BasalProfileListScreen> {
|
|||||||
content: AutoCompleteDropdownButton(
|
content: AutoCompleteDropdownButton(
|
||||||
controller: TextEditingController(text: ''),
|
controller: TextEditingController(text: ''),
|
||||||
items: _basalProfiles,
|
items: _basalProfiles,
|
||||||
label: 'Default Basal Profile',
|
label: translate(LocalizationKeys.basalProfile_default),
|
||||||
onChanged: onPickActive,
|
onChanged: onPickActive,
|
||||||
),
|
),
|
||||||
leading: const CircleAvatar(child: Icon(Icons.info)),
|
leading: const CircleAvatar(child: Icon(Icons.info)),
|
||||||
forceActionsBelow: true,
|
forceActionsBelow: true,
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
TextButton(
|
||||||
child: const Text('CREATE A NEW PROFILE INSTEAD'),
|
child: Text(translate(LocalizationKeys
|
||||||
|
.basalProfile_warnings_resolve_createInstead)
|
||||||
|
.toUpperCase()),
|
||||||
onPressed: () => onNew(true),
|
onPressed: () => onNew(true),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -178,7 +198,7 @@ class _BasalProfileListScreenState extends State<BasalProfileListScreen> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: const Text('Basal Profiles'),
|
title: Text(translate(LocalizationKeys.basalProfile_title)),
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
IconButton(onPressed: reload, icon: const Icon(Icons.refresh))
|
IconButton(onPressed: reload, icon: const Icon(Icons.refresh))
|
||||||
],
|
],
|
||||||
@ -202,9 +222,9 @@ class _BasalProfileListScreenState extends State<BasalProfileListScreen> {
|
|||||||
double dailyTotal =
|
double dailyTotal =
|
||||||
Basal.getDailyTotalForProfile(basalProfile.id);
|
Basal.getDailyTotalForProfile(basalProfile.id);
|
||||||
String activeProfileText = basalProfile.active
|
String activeProfileText = basalProfile.active
|
||||||
? ' (Default Profile)'
|
? '(${translate(LocalizationKeys.basalProfile_default)})'
|
||||||
: basalProfile.id == _activeProfile?.id
|
: basalProfile.id == _activeProfile?.id
|
||||||
? ' (Current Active Profile)'
|
? ' (${translate(LocalizationKeys.basalProfile_active)})'
|
||||||
: '';
|
: '';
|
||||||
return Card(
|
return Card(
|
||||||
child: ListTile(
|
child: ListTile(
|
||||||
@ -228,7 +248,9 @@ class _BasalProfileListScreenState extends State<BasalProfileListScreen> {
|
|||||||
? [
|
? [
|
||||||
Text(dailyTotal
|
Text(dailyTotal
|
||||||
.toStringAsPrecision(3)),
|
.toStringAsPrecision(3)),
|
||||||
const Text('U/day',
|
Text(
|
||||||
|
translate(LocalizationKeys
|
||||||
|
.general_suffixes_perDay),
|
||||||
textScaleFactor: 0.75),
|
textScaleFactor: 0.75),
|
||||||
]
|
]
|
||||||
: [],
|
: [],
|
||||||
@ -263,8 +285,8 @@ class _BasalProfileListScreenState extends State<BasalProfileListScreen> {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: const Center(
|
: Center(
|
||||||
child: Text('You have not created any Basal Profiles yet!'),
|
child: Text(translate(LocalizationKeys.basalProfile_empty)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import 'package:diameter/components/detail.dart';
|
import 'package:diameter/components/detail.dart';
|
||||||
import 'package:diameter/components/forms/number_form_field.dart';
|
import 'package:diameter/components/forms/number_form_field.dart';
|
||||||
import 'package:diameter/components/forms/time_of_day_form_field.dart';
|
import 'package:diameter/components/forms/time_of_day_form_field.dart';
|
||||||
|
import 'package:diameter/localization_keys.dart';
|
||||||
import 'package:diameter/utils/dialog_utils.dart';
|
import 'package:diameter/utils/dialog_utils.dart';
|
||||||
import 'package:diameter/models/settings.dart';
|
import 'package:diameter/models/settings.dart';
|
||||||
import 'package:diameter/navigation.dart';
|
import 'package:diameter/navigation.dart';
|
||||||
@ -10,6 +11,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:diameter/components/forms/form_wrapper.dart';
|
import 'package:diameter/components/forms/form_wrapper.dart';
|
||||||
import 'package:diameter/models/bolus.dart';
|
import 'package:diameter/models/bolus.dart';
|
||||||
import 'package:diameter/models/bolus_profile.dart';
|
import 'package:diameter/models/bolus_profile.dart';
|
||||||
|
import 'package:flutter_translate/flutter_translate.dart';
|
||||||
|
|
||||||
class BolusDetailScreen extends StatefulWidget {
|
class BolusDetailScreen extends StatefulWidget {
|
||||||
static const String routeName = '/bolus';
|
static const String routeName = '/bolus';
|
||||||
@ -140,7 +142,7 @@ class _BolusDetailScreenState extends State<BolusDetailScreen> {
|
|||||||
_startTime.hour == other.startTime.hour &&
|
_startTime.hour == other.startTime.hour &&
|
||||||
_startTime.minute == other.startTime.minute)
|
_startTime.minute == other.startTime.minute)
|
||||||
.isNotEmpty) {
|
.isNotEmpty) {
|
||||||
error = 'There\'s already a rate with this start time.';
|
error = translate(LocalizationKeys.bolus_warnings_duplicate);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bolusRates
|
if (bolusRates
|
||||||
@ -151,7 +153,7 @@ class _BolusDetailScreenState extends State<BolusDetailScreen> {
|
|||||||
DateTimeUtils.convertTimeOfDayToDateTime(_endTime)
|
DateTimeUtils.convertTimeOfDayToDateTime(_endTime)
|
||||||
.isAfter(other.startTime))
|
.isAfter(other.startTime))
|
||||||
.isNotEmpty) {
|
.isNotEmpty) {
|
||||||
error = 'This rate\'s time period overlaps with another one.';
|
error = translate(LocalizationKeys.bolus_warnings_overlap);
|
||||||
}
|
}
|
||||||
|
|
||||||
return error == null
|
return error == null
|
||||||
@ -164,11 +166,11 @@ class _BolusDetailScreenState extends State<BolusDetailScreen> {
|
|||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.pop(context, 'CANCEL'),
|
onPressed: () => Navigator.pop(context, 'CANCEL'),
|
||||||
child: const Text('GO BACK TO EDITING'),
|
child: Text(translate(LocalizationKeys.general_keepEditing).toUpperCase()),
|
||||||
),
|
),
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: () => Navigator.pop(context, 'CONFIRM'),
|
onPressed: () => Navigator.pop(context, 'CONFIRM'),
|
||||||
child: const Text('SAVE AS IS'),
|
child: Text(translate(LocalizationKeys.general_saveAsIs).toUpperCase()),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@ -210,13 +212,27 @@ class _BolusDetailScreenState extends State<BolusDetailScreen> {
|
|||||||
).then((result) {
|
).then((result) {
|
||||||
Navigator.pop(
|
Navigator.pop(
|
||||||
context,
|
context,
|
||||||
['New Bolus Rate${result[1] != null ? 's' : ''} saved', bolus] +
|
[
|
||||||
|
translatePlural(
|
||||||
|
LocalizationKeys.bolus_saved,
|
||||||
|
result.length,
|
||||||
|
args: {
|
||||||
|
"status": _isNew ? '${LocalizationKeys.bolus_new} ' : ''
|
||||||
|
},
|
||||||
|
),
|
||||||
|
bolus] +
|
||||||
[result[1]],
|
[result[1]],
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
Navigator.pop(
|
Navigator.pop(
|
||||||
context, ['${_isNew ? 'New' : ''} Bolus Rate saved', bolus]);
|
context, [translatePlural(
|
||||||
|
LocalizationKeys.bolus_saved,
|
||||||
|
1,
|
||||||
|
args: {
|
||||||
|
"status": _isNew ? '${LocalizationKeys.bolus_new} ' : ''
|
||||||
|
},
|
||||||
|
), bolus]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -288,7 +304,14 @@ class _BolusDetailScreenState extends State<BolusDetailScreen> {
|
|||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(
|
title: Text(
|
||||||
'${_isNew ? 'New' : 'Edit'} Bolus Rate for ${BolusProfile.get(widget.bolusProfileId)?.name}'),
|
translate(
|
||||||
|
LocalizationKeys.basal_title,
|
||||||
|
args: {
|
||||||
|
"status": _isNew ? LocalizationKeys.bolus_new : LocalizationKeys.general_edit,
|
||||||
|
"profileName": BolusProfile.get(widget.bolusProfileId)?.name,
|
||||||
|
}
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
drawer: const Navigation(currentLocation: BolusDetailScreen.routeName),
|
drawer: const Navigation(currentLocation: BolusDetailScreen.routeName),
|
||||||
body: Scrollbar(
|
body: Scrollbar(
|
||||||
@ -306,7 +329,7 @@ class _BolusDetailScreenState extends State<BolusDetailScreen> {
|
|||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(right: 5),
|
padding: const EdgeInsets.only(right: 5),
|
||||||
child: TimeOfDayFormField(
|
child: TimeOfDayFormField(
|
||||||
label: 'Start Time',
|
label: translate(LocalizationKeys.bolus_fields_startTime),
|
||||||
controller: _startTimeController,
|
controller: _startTimeController,
|
||||||
time: _startTime,
|
time: _startTime,
|
||||||
onChanged: updateStartTime,
|
onChanged: updateStartTime,
|
||||||
@ -317,7 +340,7 @@ class _BolusDetailScreenState extends State<BolusDetailScreen> {
|
|||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(left: 5),
|
padding: const EdgeInsets.only(left: 5),
|
||||||
child: TimeOfDayFormField(
|
child: TimeOfDayFormField(
|
||||||
label: 'End Time',
|
label: translate(LocalizationKeys.bolus_fields_endTime),
|
||||||
controller: _endTimeController,
|
controller: _endTimeController,
|
||||||
time: _endTime,
|
time: _endTime,
|
||||||
onChanged: updateEndTime,
|
onChanged: updateEndTime,
|
||||||
@ -328,8 +351,8 @@ class _BolusDetailScreenState extends State<BolusDetailScreen> {
|
|||||||
),
|
),
|
||||||
NumberFormField(
|
NumberFormField(
|
||||||
controller: _unitsController,
|
controller: _unitsController,
|
||||||
label: 'Units',
|
label: translate(LocalizationKeys.bolus_fields_units),
|
||||||
suffix: 'U',
|
suffix: translate(LocalizationKeys.general_suffixes_units),
|
||||||
autoRoundToMultipleOfStep: true,
|
autoRoundToMultipleOfStep: true,
|
||||||
step: Settings.insulinSteps,
|
step: Settings.insulinSteps,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
@ -342,7 +365,7 @@ class _BolusDetailScreenState extends State<BolusDetailScreen> {
|
|||||||
),
|
),
|
||||||
NumberFormField(
|
NumberFormField(
|
||||||
controller: _carbsController,
|
controller: _carbsController,
|
||||||
label: 'per carbs',
|
label: translate(LocalizationKeys.bolus_fields_perCarbs),
|
||||||
suffix: Settings.nutritionMeasurementSuffix,
|
suffix: Settings.nutritionMeasurementSuffix,
|
||||||
autoRoundToMultipleOfStep: true,
|
autoRoundToMultipleOfStep: true,
|
||||||
step: Settings.nutritionSteps,
|
step: Settings.nutritionSteps,
|
||||||
@ -365,8 +388,10 @@ class _BolusDetailScreenState extends State<BolusDetailScreen> {
|
|||||||
? Expanded(
|
? Expanded(
|
||||||
flex: Settings.glucoseMeasurement == GlucoseMeasurement.mgPerDl ? 2 : 1,
|
flex: Settings.glucoseMeasurement == GlucoseMeasurement.mgPerDl ? 2 : 1,
|
||||||
child: NumberFormField(
|
child: NumberFormField(
|
||||||
label: 'per mg/dl',
|
label: translate(LocalizationKeys.bolus_fields_perGlucose, args: {
|
||||||
suffix: 'mg/dl',
|
"glucoseMeasurement": Settings.glucoseMeasurementSuffix
|
||||||
|
}),
|
||||||
|
suffix: Settings.glucoseMeasurementSuffix,
|
||||||
readOnly: Settings.glucoseMeasurement ==
|
readOnly: Settings.glucoseMeasurement ==
|
||||||
GlucoseMeasurement.mmolPerL,
|
GlucoseMeasurement.mmolPerL,
|
||||||
showSteppers: Settings.glucoseMeasurement == GlucoseMeasurement.mgPerDl,
|
showSteppers: Settings.glucoseMeasurement == GlucoseMeasurement.mgPerDl,
|
||||||
@ -384,8 +409,10 @@ class _BolusDetailScreenState extends State<BolusDetailScreen> {
|
|||||||
? Expanded(
|
? Expanded(
|
||||||
flex: Settings.glucoseMeasurement == GlucoseMeasurement.mmolPerL ? 2 : 1,
|
flex: Settings.glucoseMeasurement == GlucoseMeasurement.mmolPerL ? 2 : 1,
|
||||||
child: NumberFormField(
|
child: NumberFormField(
|
||||||
label: 'per mmol/l',
|
label: translate(LocalizationKeys.bolus_fields_perGlucose, args: {
|
||||||
suffix: 'mmol/l',
|
"glucoseMeasurement": Settings.glucoseMeasurementSuffix
|
||||||
|
}),
|
||||||
|
suffix: Settings.glucoseMeasurementSuffix,
|
||||||
readOnly: Settings.glucoseMeasurement ==
|
readOnly: Settings.glucoseMeasurement ==
|
||||||
GlucoseMeasurement.mgPerDl,
|
GlucoseMeasurement.mgPerDl,
|
||||||
showSteppers: Settings.glucoseMeasurement == GlucoseMeasurement.mmolPerL,
|
showSteppers: Settings.glucoseMeasurement == GlucoseMeasurement.mmolPerL,
|
||||||
@ -410,8 +437,8 @@ class _BolusDetailScreenState extends State<BolusDetailScreen> {
|
|||||||
onMiddleAction: _isSaving || _isFinalRate
|
onMiddleAction: _isSaving || _isFinalRate
|
||||||
? null
|
? null
|
||||||
: () => handleSaveAction(next: false),
|
: () => handleSaveAction(next: false),
|
||||||
actionText: _isFinalRate ? 'SAVE & CLOSE' : 'NEXT',
|
actionTextKey: _isFinalRate ? translate(LocalizationKeys.general_saveAndClose) : translate(LocalizationKeys.general_next),
|
||||||
middleActionText: 'SAVE & CLOSE',
|
middleActionTextKey: translate(LocalizationKeys.general_saveAndClose),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import 'package:diameter/localization_keys.dart';
|
||||||
import 'package:diameter/utils/dialog_utils.dart';
|
import 'package:diameter/utils/dialog_utils.dart';
|
||||||
import 'package:diameter/models/settings.dart';
|
import 'package:diameter/models/settings.dart';
|
||||||
import 'package:diameter/utils/date_time_utils.dart';
|
import 'package:diameter/utils/date_time_utils.dart';
|
||||||
@ -5,6 +6,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:diameter/models/bolus.dart';
|
import 'package:diameter/models/bolus.dart';
|
||||||
import 'package:diameter/models/bolus_profile.dart';
|
import 'package:diameter/models/bolus_profile.dart';
|
||||||
import 'package:diameter/screens/bolus/bolus_detail.dart';
|
import 'package:diameter/screens/bolus/bolus_detail.dart';
|
||||||
|
import 'package:flutter_translate/flutter_translate.dart';
|
||||||
|
|
||||||
class BolusListScreen extends StatefulWidget {
|
class BolusListScreen extends StatefulWidget {
|
||||||
final BolusProfile bolusProfile;
|
final BolusProfile bolusProfile;
|
||||||
@ -61,7 +63,7 @@ class _BolusListScreenState extends State<BolusListScreen> {
|
|||||||
|
|
||||||
void onDelete(Bolus bolus) {
|
void onDelete(Bolus bolus) {
|
||||||
Bolus.remove(bolus.id);
|
Bolus.remove(bolus.id);
|
||||||
reload(message: 'Bolus Rate deleted');
|
reload(message: translate(LocalizationKeys.bolus_deleted));
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleDeleteAction(Bolus bolus) async {
|
void handleDeleteAction(Bolus bolus) async {
|
||||||
@ -69,7 +71,7 @@ class _BolusListScreenState extends State<BolusListScreen> {
|
|||||||
DialogUtils.showConfirmationDialog(
|
DialogUtils.showConfirmationDialog(
|
||||||
context: context,
|
context: context,
|
||||||
onConfirm: () => onDelete(bolus),
|
onConfirm: () => onDelete(bolus),
|
||||||
message: 'Are you sure you want to delete this Bolus Rate?',
|
message: translate(LocalizationKeys.bolus_confirmDelete),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
onDelete(bolus);
|
onDelete(bolus);
|
||||||
@ -82,26 +84,26 @@ class _BolusListScreenState extends State<BolusListScreen> {
|
|||||||
|
|
||||||
if (index == 0 &&
|
if (index == 0 &&
|
||||||
(bolus.startTime.toLocal().hour != 0 || bolus.startTime.minute != 0)) {
|
(bolus.startTime.toLocal().hour != 0 || bolus.startTime.minute != 0)) {
|
||||||
return 'First Bolus of the day needs to start at 00:00';
|
return translate(LocalizationKeys.bolus_warnings_startTimeFirst);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (index > 0) {
|
if (index > 0) {
|
||||||
var lastEndTime = bolusRates[index - 1].endTime;
|
var lastEndTime = bolusRates[index - 1].endTime;
|
||||||
if (bolus.startTime.isAfter(lastEndTime)) {
|
if (bolus.startTime.isAfter(lastEndTime)) {
|
||||||
return 'There\'s a time gap between this and the previous rate';
|
return translate(LocalizationKeys.bolus_warnings_gap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (index == bolusRates.length - 1 &&
|
if (index == bolusRates.length - 1 &&
|
||||||
(bolus.endTime.toLocal().hour != 0 || bolus.endTime.minute != 0)) {
|
(bolus.endTime.toLocal().hour != 0 || bolus.endTime.minute != 0)) {
|
||||||
return 'Last Bolus of the day needs to end at 00:00';
|
return translate(LocalizationKeys.bolus_warnings_endTimeLast);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for duplicates
|
// check for duplicates
|
||||||
if (bolusRates
|
if (bolusRates
|
||||||
.where((other) => bolus != other && bolus.startTime == other.startTime)
|
.where((other) => bolus != other && bolus.startTime == other.startTime)
|
||||||
.isNotEmpty) {
|
.isNotEmpty) {
|
||||||
return 'There are multiple rates with this start time';
|
return translate(LocalizationKeys.bolus_warnings_duplicate);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bolusRates
|
if (bolusRates
|
||||||
@ -109,7 +111,7 @@ class _BolusListScreenState extends State<BolusListScreen> {
|
|||||||
bolus.startTime.isBefore(other.startTime) &&
|
bolus.startTime.isBefore(other.startTime) &&
|
||||||
bolus.endTime.isAfter(other.startTime))
|
bolus.endTime.isAfter(other.startTime))
|
||||||
.isNotEmpty) {
|
.isNotEmpty) {
|
||||||
return 'This rate\'s time period overlaps with another one';
|
return translate(LocalizationKeys.bolus_warnings_overlap);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@ -162,8 +164,9 @@ class _BolusListScreenState extends State<BolusListScreen> {
|
|||||||
? [
|
? [
|
||||||
Text((bolus.carbs / bolus.units)
|
Text((bolus.carbs / bolus.units)
|
||||||
.toStringAsPrecision(2)),
|
.toStringAsPrecision(2)),
|
||||||
Text(
|
Text(translate(LocalizationKeys.general_suffixes_carbsPerU, args: {
|
||||||
'${Settings.nutritionMeasurementSuffix} carbs per U',
|
"nutritionMeasurementSuffix": Settings.nutritionMeasurementSuffix
|
||||||
|
}),
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
textScaleFactor: 0.75),
|
textScaleFactor: 0.75),
|
||||||
]
|
]
|
||||||
@ -176,7 +179,7 @@ class _BolusListScreenState extends State<BolusListScreen> {
|
|||||||
? [
|
? [
|
||||||
Text((bolus.units / bolus.carbs * 12)
|
Text((bolus.units / bolus.carbs * 12)
|
||||||
.toStringAsPrecision(2)),
|
.toStringAsPrecision(2)),
|
||||||
const Text('U per bread unit',
|
Text(translate(LocalizationKeys.general_suffixes_uPerBreadUnit),
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
textScaleFactor: 0.75),
|
textScaleFactor: 0.75),
|
||||||
]
|
]
|
||||||
@ -196,8 +199,9 @@ class _BolusListScreenState extends State<BolusListScreen> {
|
|||||||
: bolus.mmolPerL ?? 0)! /
|
: bolus.mmolPerL ?? 0)! /
|
||||||
bolus.units))
|
bolus.units))
|
||||||
.toString()),
|
.toString()),
|
||||||
Text(
|
Text(translate(LocalizationKeys.general_suffixes_uPerGlucose, args: {
|
||||||
'${Settings.glucoseMeasurementSuffix} per unit',
|
"glucoseMeasurementSuffix": Settings.glucoseMeasurementSuffix
|
||||||
|
}),
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
textScaleFactor: 0.75),
|
textScaleFactor: 0.75),
|
||||||
]
|
]
|
||||||
@ -225,8 +229,8 @@ class _BolusListScreenState extends State<BolusListScreen> {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: const Center(
|
: Center(
|
||||||
child: Text('You have not created any Bolus Rates yet!'),
|
child: Text(translate(LocalizationKeys.bolus_title)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import 'package:diameter/components/detail.dart';
|
import 'package:diameter/components/detail.dart';
|
||||||
import 'package:diameter/components/forms/boolean_form_field.dart';
|
import 'package:diameter/components/forms/boolean_form_field.dart';
|
||||||
|
import 'package:diameter/localization_keys.dart';
|
||||||
import 'package:diameter/utils/dialog_utils.dart';
|
import 'package:diameter/utils/dialog_utils.dart';
|
||||||
import 'package:diameter/models/bolus.dart';
|
import 'package:diameter/models/bolus.dart';
|
||||||
import 'package:diameter/models/settings.dart';
|
import 'package:diameter/models/settings.dart';
|
||||||
@ -9,6 +10,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:diameter/components/forms/form_wrapper.dart';
|
import 'package:diameter/components/forms/form_wrapper.dart';
|
||||||
import 'package:diameter/models/bolus_profile.dart';
|
import 'package:diameter/models/bolus_profile.dart';
|
||||||
import 'package:diameter/screens/bolus/bolus_list.dart';
|
import 'package:diameter/screens/bolus/bolus_list.dart';
|
||||||
|
import 'package:flutter_translate/flutter_translate.dart';
|
||||||
|
|
||||||
class BolusProfileDetailScreen extends StatefulWidget {
|
class BolusProfileDetailScreen extends StatefulWidget {
|
||||||
static const String routeName = '/bolus-profile';
|
static const String routeName = '/bolus-profile';
|
||||||
@ -131,20 +133,19 @@ class _BolusProfileDetailScreenState extends State<BolusProfileDetailScreen> {
|
|||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
content: const Text(
|
content: Text(translate(LocalizationKeys.bolusProfile_warnings_activeAlreadySet)),
|
||||||
'There are already one or more active profiles. What would you like to do?'),
|
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.pop(context, 0),
|
onPressed: () => Navigator.pop(context, 0),
|
||||||
child: const Text('IGNORE'),
|
child: Text(translate(LocalizationKeys.bolusProfile_warnings_resolve_ignore).toUpperCase()),
|
||||||
),
|
),
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.pop(context, 1),
|
onPressed: () => Navigator.pop(context, 1),
|
||||||
child: const Text('DEACTIVATE THIS PROFILE'),
|
child: Text(translate(LocalizationKeys.bolusProfile_warnings_resolve_deactivateProfile).toUpperCase()),
|
||||||
),
|
),
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: () => Navigator.pop(context, 2),
|
onPressed: () => Navigator.pop(context, 2),
|
||||||
child: const Text('DEACTIVATE ALL OTHERS'),
|
child: Text(translate(LocalizationKeys.bolusProfile_warnings_resolve_deactivateOthers).toUpperCase()),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@ -164,16 +165,15 @@ class _BolusProfileDetailScreenState extends State<BolusProfileDetailScreen> {
|
|||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
content: const Text(
|
content: Text(translate(LocalizationKeys.bolusProfile_warnings_noActiveOnCreate)),
|
||||||
'There is currently no active profile. Would you like to set this one as active?'),
|
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.pop(context, 0),
|
onPressed: () => Navigator.pop(context, 0),
|
||||||
child: const Text('IGNORE'),
|
child: Text(translate(LocalizationKeys.bolusProfile_warnings_resolve_ignore).toUpperCase()),
|
||||||
),
|
),
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.pop(context, 1),
|
onPressed: () => Navigator.pop(context, 1),
|
||||||
child: const Text('ACTIVATE THIS PROFILE'),
|
child: Text(translate(LocalizationKeys.bolusProfile_warnings_resolve_activateCurrent).toUpperCase()),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@ -246,8 +246,15 @@ class _BolusProfileDetailScreenState extends State<BolusProfileDetailScreen> {
|
|||||||
BolusProfile.put(bolusProfile);
|
BolusProfile.put(bolusProfile);
|
||||||
|
|
||||||
if (close) {
|
if (close) {
|
||||||
Navigator.pop(context,
|
Navigator.pop(context, [
|
||||||
['${_isNew ? 'New' : ''} Bolus Profile saved', bolusProfile]);
|
translate(
|
||||||
|
LocalizationKeys.bolusProfile_saved,
|
||||||
|
args: {
|
||||||
|
"status": _isNew ? '${translate(LocalizationKeys.bolusProfile_new)} ' : ''
|
||||||
|
},
|
||||||
|
), bolusProfile
|
||||||
|
],
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
if (_isNew) {
|
if (_isNew) {
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
@ -258,7 +265,7 @@ class _BolusProfileDetailScreenState extends State<BolusProfileDetailScreen> {
|
|||||||
),
|
),
|
||||||
).then((result) => Navigator.pop(context, result));
|
).then((result) => Navigator.pop(context, result));
|
||||||
} else {
|
} else {
|
||||||
reload(message: 'Bolus Profile saved');
|
reload(message: translate(LocalizationKeys.bolusProfile_saved));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -329,19 +336,19 @@ class _BolusProfileDetailScreenState extends State<BolusProfileDetailScreen> {
|
|||||||
fields: [
|
fields: [
|
||||||
TextFormField(
|
TextFormField(
|
||||||
controller: _nameController,
|
controller: _nameController,
|
||||||
decoration: const InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: 'Name',
|
labelText: translate(LocalizationKeys.bolusProfile_fields_name),
|
||||||
),
|
),
|
||||||
validator: (value) {
|
validator: (value) {
|
||||||
if (value!.trim().isEmpty) {
|
if (value!.trim().isEmpty) {
|
||||||
return 'Empty title';
|
return translate(LocalizationKeys.bolusProfile_fields_validators_name);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
TextFormField(
|
TextFormField(
|
||||||
decoration: const InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: 'Notes',
|
labelText: translate(LocalizationKeys.bolusProfile_fields_notes),
|
||||||
),
|
),
|
||||||
controller: _notesController,
|
controller: _notesController,
|
||||||
keyboardType: TextInputType.multiline,
|
keyboardType: TextInputType.multiline,
|
||||||
@ -355,7 +362,7 @@ class _BolusProfileDetailScreenState extends State<BolusProfileDetailScreen> {
|
|||||||
_active = value;
|
_active = value;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
label: 'active',
|
label: translate(LocalizationKeys.bolusProfile_fields_active),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -374,13 +381,16 @@ class _BolusProfileDetailScreenState extends State<BolusProfileDetailScreen> {
|
|||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(_isNew ? 'New Bolus Profile' : _bolusProfile!.name),
|
title: Text(translate(LocalizationKeys.bolusProfile_detail_title, args: {
|
||||||
|
"status": _isNew ? '${translate(LocalizationKeys.bolusProfile_new)} ' : '',
|
||||||
|
"profileName": _bolusProfile!.name,
|
||||||
|
})),
|
||||||
bottom: _isNew
|
bottom: _isNew
|
||||||
? PreferredSize(child: Container(), preferredSize: Size.zero)
|
? PreferredSize(child: Container(), preferredSize: Size.zero)
|
||||||
: const TabBar(
|
: TabBar(
|
||||||
tabs: [
|
tabs: [
|
||||||
Tab(text: 'PROFILE'),
|
Tab(text: translate(LocalizationKeys.bolusProfile_detail_tabs_profile).toUpperCase()),
|
||||||
Tab(text: 'RATES'),
|
Tab(text: translate(LocalizationKeys.bolusProfile_detail_tabs_rates).toUpperCase()),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
actions: appBarActions,
|
actions: appBarActions,
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import 'package:diameter/localization_keys.dart';
|
||||||
import 'package:diameter/utils/dialog_utils.dart';
|
import 'package:diameter/utils/dialog_utils.dart';
|
||||||
import 'package:diameter/components/forms/auto_complete_dropdown_button.dart';
|
import 'package:diameter/components/forms/auto_complete_dropdown_button.dart';
|
||||||
import 'package:diameter/models/bolus.dart';
|
import 'package:diameter/models/bolus.dart';
|
||||||
@ -6,6 +7,7 @@ import 'package:diameter/navigation.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:diameter/models/bolus_profile.dart';
|
import 'package:diameter/models/bolus_profile.dart';
|
||||||
import 'package:diameter/screens/bolus/bolus_profile_detail.dart';
|
import 'package:diameter/screens/bolus/bolus_profile_detail.dart';
|
||||||
|
import 'package:flutter_translate/flutter_translate.dart';
|
||||||
|
|
||||||
class BolusProfileListScreen extends StatefulWidget {
|
class BolusProfileListScreen extends StatefulWidget {
|
||||||
static const String routeName = '/bolus-profiles';
|
static const String routeName = '/bolus-profiles';
|
||||||
@ -62,26 +64,26 @@ class _BolusProfileListScreenState extends State<BolusProfileListScreen> {
|
|||||||
banner = activeProfileCount != 1
|
banner = activeProfileCount != 1
|
||||||
? MaterialBanner(
|
? MaterialBanner(
|
||||||
content: Text(activeProfileCount == 0
|
content: Text(activeProfileCount == 0
|
||||||
? 'You currently do not have an active Bolus Profile.'
|
? translate(LocalizationKeys.bolusProfile_warnings_noActive)
|
||||||
: 'More than one active Bolus Profile has been found.'),
|
: translate(LocalizationKeys.bolusProfile_warnings_multipleActive)),
|
||||||
leading: const CircleAvatar(child: Icon(Icons.warning)),
|
leading: const CircleAvatar(child: Icon(Icons.warning)),
|
||||||
forceActionsBelow: true,
|
forceActionsBelow: true,
|
||||||
actions: activeProfileCount == 0
|
actions: activeProfileCount == 0
|
||||||
? [
|
? [
|
||||||
_bolusProfiles.isNotEmpty
|
_bolusProfiles.isNotEmpty
|
||||||
? TextButton(
|
? TextButton(
|
||||||
child: const Text('ACTIVATE A PROFILE'),
|
child: Text(translate(LocalizationKeys.bolusProfile_warnings_resolve_activate).toUpperCase()),
|
||||||
onPressed: handlePickActiveProfileAction,
|
onPressed: handlePickActiveProfileAction,
|
||||||
)
|
)
|
||||||
: Container(),
|
: Container(),
|
||||||
TextButton(
|
TextButton(
|
||||||
child: const Text('CREATE A NEW PROFILE'),
|
child: Text(translate(LocalizationKeys.bolusProfile_warnings_resolve_create).toUpperCase()),
|
||||||
onPressed: () => onNew(true),
|
onPressed: () => onNew(true),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
: [
|
: [
|
||||||
TextButton(
|
TextButton(
|
||||||
child: const Text('PICK A PROFILE'),
|
child: Text(translate(LocalizationKeys.bolusProfile_warnings_resolve_pick).toUpperCase()),
|
||||||
onPressed: handlePickActiveProfileAction,
|
onPressed: handlePickActiveProfileAction,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -93,7 +95,12 @@ class _BolusProfileListScreenState extends State<BolusProfileListScreen> {
|
|||||||
void handleDuplicateAction(BolusProfile bolusProfile) async {
|
void handleDuplicateAction(BolusProfile bolusProfile) async {
|
||||||
final copy = BolusProfile(
|
final copy = BolusProfile(
|
||||||
active: false,
|
active: false,
|
||||||
name: 'Copy of ${bolusProfile.name}',
|
name: translate(
|
||||||
|
LocalizationKeys.bolusProfile_copyOf,
|
||||||
|
args: {
|
||||||
|
"profileName": bolusProfile.name
|
||||||
|
},
|
||||||
|
),
|
||||||
);
|
);
|
||||||
BolusProfile.put(copy);
|
BolusProfile.put(copy);
|
||||||
|
|
||||||
@ -111,12 +118,19 @@ class _BolusProfileListScreenState extends State<BolusProfileListScreen> {
|
|||||||
Bolus.put(bolus);
|
Bolus.put(bolus);
|
||||||
}
|
}
|
||||||
|
|
||||||
reload(message: 'Added copy of ${bolusProfile.name}');
|
reload(
|
||||||
|
message: translate(
|
||||||
|
LocalizationKeys.bolusProfile_copied,
|
||||||
|
args: {
|
||||||
|
"profileName": bolusProfile.name
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void onDelete(BolusProfile bolusProfile) {
|
void onDelete(BolusProfile bolusProfile) {
|
||||||
BolusProfile.remove(bolusProfile.id);
|
BolusProfile.remove(bolusProfile.id);
|
||||||
reload(message: 'Bolus Profile deleted');
|
reload(message: translate(LocalizationKeys.bolusProfile_deleted));
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleDeleteAction(BolusProfile bolusProfile) async {
|
void handleDeleteAction(BolusProfile bolusProfile) async {
|
||||||
@ -124,7 +138,7 @@ class _BolusProfileListScreenState extends State<BolusProfileListScreen> {
|
|||||||
DialogUtils.showConfirmationDialog(
|
DialogUtils.showConfirmationDialog(
|
||||||
context: context,
|
context: context,
|
||||||
onConfirm: () => onDelete(bolusProfile),
|
onConfirm: () => onDelete(bolusProfile),
|
||||||
message: 'Are you sure you want to delete this Bolus Profile?',
|
message: translate(LocalizationKeys.bolusProfile_confirmDelete),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
onDelete(bolusProfile);
|
onDelete(bolusProfile);
|
||||||
@ -137,7 +151,13 @@ class _BolusProfileListScreenState extends State<BolusProfileListScreen> {
|
|||||||
bolusProfile.active = true;
|
bolusProfile.active = true;
|
||||||
BolusProfile.put(bolusProfile);
|
BolusProfile.put(bolusProfile);
|
||||||
reload(
|
reload(
|
||||||
message: '${bolusProfile.name} has been set as your active Profile');
|
message: translate(
|
||||||
|
LocalizationKeys.bolusProfile_activated,
|
||||||
|
args: {
|
||||||
|
"profileName": bolusProfile.name
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,14 +167,14 @@ class _BolusProfileListScreenState extends State<BolusProfileListScreen> {
|
|||||||
content: AutoCompleteDropdownButton(
|
content: AutoCompleteDropdownButton(
|
||||||
controller: TextEditingController(text: ''),
|
controller: TextEditingController(text: ''),
|
||||||
items: _bolusProfiles,
|
items: _bolusProfiles,
|
||||||
label: 'Default Basal Profile',
|
label: translate(LocalizationKeys.bolusProfile_default),
|
||||||
onChanged: onPickActive,
|
onChanged: onPickActive,
|
||||||
),
|
),
|
||||||
leading: const CircleAvatar(child: Icon(Icons.info)),
|
leading: const CircleAvatar(child: Icon(Icons.info)),
|
||||||
forceActionsBelow: true,
|
forceActionsBelow: true,
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
TextButton(
|
||||||
child: const Text('CREATE A NEW PROFILE INSTEAD'),
|
child: Text(translate(LocalizationKeys.bolusProfile_warnings_resolve_createInstead).toUpperCase()),
|
||||||
onPressed: () => onNew(true),
|
onPressed: () => onNew(true),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -184,7 +204,7 @@ class _BolusProfileListScreenState extends State<BolusProfileListScreen> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: const Text('Bolus Profiles'),
|
title: Text(translate(LocalizationKeys.bolusProfile_title)),
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
IconButton(onPressed: reload, icon: const Icon(Icons.refresh))
|
IconButton(onPressed: reload, icon: const Icon(Icons.refresh))
|
||||||
],
|
],
|
||||||
@ -206,9 +226,9 @@ class _BolusProfileListScreenState extends State<BolusProfileListScreen> {
|
|||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
final bolusProfile = _bolusProfiles[index];
|
final bolusProfile = _bolusProfiles[index];
|
||||||
String activeProfileText = bolusProfile.active
|
String activeProfileText = bolusProfile.active
|
||||||
? ' (Default Profile)'
|
? ' (${translate(LocalizationKeys.bolusProfile_default)})'
|
||||||
: bolusProfile.id == _activeProfile?.id
|
: bolusProfile.id == _activeProfile?.id
|
||||||
? ' (Current Active Profile)'
|
? ' (${translate(LocalizationKeys.bolusProfile_active)})'
|
||||||
: '';
|
: '';
|
||||||
return Card(
|
return Card(
|
||||||
child: ListTile(
|
child: ListTile(
|
||||||
@ -250,8 +270,8 @@ class _BolusProfileListScreenState extends State<BolusProfileListScreen> {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: const Center(
|
: Center(
|
||||||
child: Text('You have not created any Bolus Profiles yet!'),
|
child: Text(translate(LocalizationKeys.bolusProfile_empty)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
import 'package:diameter/components/detail.dart';
|
import 'package:diameter/components/detail.dart';
|
||||||
import 'package:diameter/components/forms/boolean_form_field.dart';
|
import 'package:diameter/components/forms/boolean_form_field.dart';
|
||||||
import 'package:diameter/components/forms/number_form_field.dart';
|
import 'package:diameter/components/forms/number_form_field.dart';
|
||||||
|
import 'package:diameter/localization_keys.dart';
|
||||||
import 'package:diameter/utils/dialog_utils.dart';
|
import 'package:diameter/utils/dialog_utils.dart';
|
||||||
import 'package:diameter/models/settings.dart';
|
import 'package:diameter/models/settings.dart';
|
||||||
import 'package:diameter/navigation.dart';
|
import 'package:diameter/navigation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:diameter/components/forms/form_wrapper.dart';
|
import 'package:diameter/components/forms/form_wrapper.dart';
|
||||||
import 'package:diameter/models/accuracy.dart';
|
import 'package:diameter/models/accuracy.dart';
|
||||||
|
import 'package:flutter_translate/flutter_translate.dart';
|
||||||
|
|
||||||
class AccuracyDetailScreen extends StatefulWidget {
|
class AccuracyDetailScreen extends StatefulWidget {
|
||||||
static const String routeName = '/accuracy';
|
static const String routeName = '/accuracy';
|
||||||
@ -93,7 +95,12 @@ class _AccuracyDetailScreenState extends State<AccuracyDetailScreen> {
|
|||||||
Accuracy.reorder(
|
Accuracy.reorder(
|
||||||
accuracy, int.tryParse(_confidenceRatingController.text));
|
accuracy, int.tryParse(_confidenceRatingController.text));
|
||||||
Navigator.pop(
|
Navigator.pop(
|
||||||
context, ['${_isNew ? 'New' : ''} Accuracy saved', accuracy]);
|
context, [translate(
|
||||||
|
LocalizationKeys.accuracy_saved,
|
||||||
|
args: {
|
||||||
|
"status": _isNew ? '${translate(LocalizationKeys.accuracy_new)} ' : ''
|
||||||
|
},
|
||||||
|
), accuracy]);
|
||||||
}
|
}
|
||||||
setState(() {
|
setState(() {
|
||||||
_isSaving = false;
|
_isSaving = false;
|
||||||
@ -130,7 +137,9 @@ class _AccuracyDetailScreenState extends State<AccuracyDetailScreen> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(_isNew ? 'New Accuracy' : _accuracy!.value),
|
title: Text(translate(LocalizationKeys.accuracy_detail_title, args: {
|
||||||
|
"status": _isNew ? '${translate(LocalizationKeys.accuracy_new)} ' : '',
|
||||||
|
})),
|
||||||
),
|
),
|
||||||
drawer: const Navigation(currentLocation: AccuracyDetailScreen.routeName),
|
drawer: const Navigation(currentLocation: AccuracyDetailScreen.routeName),
|
||||||
body: Scrollbar(
|
body: Scrollbar(
|
||||||
@ -145,12 +154,12 @@ class _AccuracyDetailScreenState extends State<AccuracyDetailScreen> {
|
|||||||
fields: [
|
fields: [
|
||||||
TextFormField(
|
TextFormField(
|
||||||
controller: _valueController,
|
controller: _valueController,
|
||||||
decoration: const InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: 'Name',
|
labelText: translate(LocalizationKeys.accuracy_fields_name),
|
||||||
),
|
),
|
||||||
validator: (value) {
|
validator: (value) {
|
||||||
if (value!.trim().isEmpty) {
|
if (value!.trim().isEmpty) {
|
||||||
return 'Empty name';
|
return translate(LocalizationKeys.accuracy_fields_validators_name);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
@ -158,7 +167,7 @@ class _AccuracyDetailScreenState extends State<AccuracyDetailScreen> {
|
|||||||
BooleanFormField(
|
BooleanFormField(
|
||||||
icon: const Icon(Icons.square_foot),
|
icon: const Icon(Icons.square_foot),
|
||||||
value: _forPortionSize,
|
value: _forPortionSize,
|
||||||
label: 'for portion size',
|
label: translate(LocalizationKeys.accuracy_fields_forPortionSize),
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_forPortionSize = value;
|
_forPortionSize = value;
|
||||||
@ -168,7 +177,7 @@ class _AccuracyDetailScreenState extends State<AccuracyDetailScreen> {
|
|||||||
BooleanFormField(
|
BooleanFormField(
|
||||||
icon: const Icon(Icons.pie_chart),
|
icon: const Icon(Icons.pie_chart),
|
||||||
value: _forCarbsRatio,
|
value: _forCarbsRatio,
|
||||||
label: 'for carbs ratio',
|
label: translate(LocalizationKeys.accuracy_fields_forCarbsRatio),
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_forCarbsRatio = value;
|
_forCarbsRatio = value;
|
||||||
@ -177,7 +186,7 @@ class _AccuracyDetailScreenState extends State<AccuracyDetailScreen> {
|
|||||||
),
|
),
|
||||||
NumberFormField(
|
NumberFormField(
|
||||||
controller: _confidenceRatingController,
|
controller: _confidenceRatingController,
|
||||||
label: 'Confidence Rating',
|
label: translate(LocalizationKeys.accuracy_fields_confidenceRating),
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_confidenceRatingController.text =
|
_confidenceRatingController.text =
|
||||||
@ -188,8 +197,8 @@ class _AccuracyDetailScreenState extends State<AccuracyDetailScreen> {
|
|||||||
TextFormField(
|
TextFormField(
|
||||||
controller: _notesController,
|
controller: _notesController,
|
||||||
keyboardType: TextInputType.multiline,
|
keyboardType: TextInputType.multiline,
|
||||||
decoration: const InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: 'Notes',
|
labelText: translate(LocalizationKeys.accuracy_fields_notes),
|
||||||
),
|
),
|
||||||
minLines: 2,
|
minLines: 2,
|
||||||
maxLines: 5,
|
maxLines: 5,
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
|
import 'package:diameter/localization_keys.dart';
|
||||||
import 'package:diameter/utils/dialog_utils.dart';
|
import 'package:diameter/utils/dialog_utils.dart';
|
||||||
import 'package:diameter/models/settings.dart';
|
import 'package:diameter/models/settings.dart';
|
||||||
import 'package:diameter/navigation.dart';
|
import 'package:diameter/navigation.dart';
|
||||||
import 'package:diameter/screens/category/accuracy_detail.dart';
|
import 'package:diameter/screens/category/accuracy_detail.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:diameter/models/accuracy.dart';
|
import 'package:diameter/models/accuracy.dart';
|
||||||
|
import 'package:flutter_translate/flutter_translate.dart';
|
||||||
|
|
||||||
class AccuracyListScreen extends StatefulWidget {
|
class AccuracyListScreen extends StatefulWidget {
|
||||||
static const String routeName = '/accuracies';
|
static const String routeName = '/accuracies';
|
||||||
@ -58,7 +60,7 @@ class _AccuracyListScreenState extends State<AccuracyListScreen> {
|
|||||||
DialogUtils.showConfirmationDialog(
|
DialogUtils.showConfirmationDialog(
|
||||||
context: context,
|
context: context,
|
||||||
onConfirm: () => onDelete(accuracy),
|
onConfirm: () => onDelete(accuracy),
|
||||||
message: 'Are you sure you want to delete this Accuracy?',
|
message: translate(LocalizationKeys.accuracy_confirmDelete),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
onDelete(accuracy);
|
onDelete(accuracy);
|
||||||
@ -81,7 +83,7 @@ class _AccuracyListScreenState extends State<AccuracyListScreen> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: const Text('Accuracies'),
|
title: Text(translate(LocalizationKeys.accuracy_detail)),
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
IconButton(onPressed: reload, icon: const Icon(Icons.refresh))
|
IconButton(onPressed: reload, icon: const Icon(Icons.refresh))
|
||||||
],
|
],
|
||||||
@ -164,8 +166,8 @@ class _AccuracyListScreenState extends State<AccuracyListScreen> {
|
|||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
: const Center(
|
: Center(
|
||||||
child: Text('You have not created any Accuracies yet!'),
|
child: Text(translate(LocalizationKeys.accuracy_empty)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
|
import 'package:diameter/localization_keys.dart';
|
||||||
import 'package:diameter/navigation.dart';
|
import 'package:diameter/navigation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_translate/flutter_translate.dart';
|
||||||
|
|
||||||
class CategoryOverviewScreen extends StatefulWidget {
|
class CategoryOverviewScreen extends StatefulWidget {
|
||||||
static const String routeName = '/category';
|
static const String routeName = '/category';
|
||||||
@ -22,7 +24,7 @@ class _CategoryOverviewScreenState extends State<CategoryOverviewScreen> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: const Text('Reports'),
|
title: Text(translate(LocalizationKeys.categories)),
|
||||||
),
|
),
|
||||||
drawer:
|
drawer:
|
||||||
const Navigation(currentLocation: CategoryOverviewScreen.routeName),
|
const Navigation(currentLocation: CategoryOverviewScreen.routeName),
|
||||||
@ -45,7 +47,7 @@ class _CategoryOverviewScreenState extends State<CategoryOverviewScreen> {
|
|||||||
child: Icon(Icons.local_grocery_store, size: 50, color: Theme.of(context).textTheme.subtitle2?.color),
|
child: Icon(Icons.local_grocery_store, size: 50, color: Theme.of(context).textTheme.subtitle2?.color),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
'MEAL SOURCES',
|
translate(LocalizationKeys.mealSource_title).toUpperCase(),
|
||||||
style: Theme.of(context).textTheme.subtitle2,
|
style: Theme.of(context).textTheme.subtitle2,
|
||||||
textAlign: TextAlign.center
|
textAlign: TextAlign.center
|
||||||
),
|
),
|
||||||
@ -66,7 +68,7 @@ class _CategoryOverviewScreenState extends State<CategoryOverviewScreen> {
|
|||||||
child: Icon(Icons.category, size: 50, color: Theme.of(context).textTheme.subtitle2?.color),
|
child: Icon(Icons.category, size: 50, color: Theme.of(context).textTheme.subtitle2?.color),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
'MEAL CATEGORIES',
|
translate(LocalizationKeys.mealCategory_title).toUpperCase(),
|
||||||
style: Theme.of(context).textTheme.subtitle2,
|
style: Theme.of(context).textTheme.subtitle2,
|
||||||
textAlign: TextAlign.center
|
textAlign: TextAlign.center
|
||||||
),
|
),
|
||||||
@ -86,7 +88,7 @@ class _CategoryOverviewScreenState extends State<CategoryOverviewScreen> {
|
|||||||
child: Icon(Icons.pie_chart, size: 50, color: Theme.of(context).textTheme.subtitle2?.color),
|
child: Icon(Icons.pie_chart, size: 50, color: Theme.of(context).textTheme.subtitle2?.color),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
'PORTION TYPES',
|
translate(LocalizationKeys.portionType_title).toUpperCase(),
|
||||||
style: Theme.of(context).textTheme.subtitle2,
|
style: Theme.of(context).textTheme.subtitle2,
|
||||||
textAlign: TextAlign.center
|
textAlign: TextAlign.center
|
||||||
),
|
),
|
||||||
@ -107,7 +109,7 @@ class _CategoryOverviewScreenState extends State<CategoryOverviewScreen> {
|
|||||||
child: Icon(Icons.architecture, size: 50, color: Theme.of(context).textTheme.subtitle2?.color),
|
child: Icon(Icons.architecture, size: 50, color: Theme.of(context).textTheme.subtitle2?.color),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
'ACCURACIES',
|
translate(LocalizationKeys.accuracy_title).toUpperCase(),
|
||||||
style: Theme.of(context).textTheme.subtitle2,
|
style: Theme.of(context).textTheme.subtitle2,
|
||||||
textAlign: TextAlign.center
|
textAlign: TextAlign.center
|
||||||
),
|
),
|
||||||
@ -127,7 +129,7 @@ class _CategoryOverviewScreenState extends State<CategoryOverviewScreen> {
|
|||||||
child: Icon(Icons.event, size: 50, color: Theme.of(context).textTheme.subtitle2?.color),
|
child: Icon(Icons.event, size: 50, color: Theme.of(context).textTheme.subtitle2?.color),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
'EVENT TYPES',
|
translate(LocalizationKeys.eventType_title).toUpperCase(),
|
||||||
style: Theme.of(context).textTheme.subtitle2,
|
style: Theme.of(context).textTheme.subtitle2,
|
||||||
textAlign: TextAlign.center
|
textAlign: TextAlign.center
|
||||||
),
|
),
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import 'package:diameter/components/detail.dart';
|
import 'package:diameter/components/detail.dart';
|
||||||
import 'package:diameter/components/forms/boolean_form_field.dart';
|
import 'package:diameter/components/forms/boolean_form_field.dart';
|
||||||
import 'package:diameter/components/forms/duration_form_field.dart';
|
import 'package:diameter/components/forms/duration_form_field.dart';
|
||||||
|
import 'package:diameter/localization_keys.dart';
|
||||||
import 'package:diameter/utils/dialog_utils.dart';
|
import 'package:diameter/utils/dialog_utils.dart';
|
||||||
import 'package:diameter/components/forms/auto_complete_dropdown_button.dart';
|
import 'package:diameter/components/forms/auto_complete_dropdown_button.dart';
|
||||||
import 'package:diameter/components/forms/form_wrapper.dart';
|
import 'package:diameter/components/forms/form_wrapper.dart';
|
||||||
@ -12,6 +13,7 @@ import 'package:diameter/navigation.dart';
|
|||||||
import 'package:diameter/screens/basal/basal_profile_detail.dart';
|
import 'package:diameter/screens/basal/basal_profile_detail.dart';
|
||||||
import 'package:diameter/screens/bolus/bolus_profile_detail.dart';
|
import 'package:diameter/screens/bolus/bolus_profile_detail.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_translate/flutter_translate.dart';
|
||||||
|
|
||||||
class EventTypeDetailScreen extends StatefulWidget {
|
class EventTypeDetailScreen extends StatefulWidget {
|
||||||
static const String routeName = '/log-event-type';
|
static const String routeName = '/log-event-type';
|
||||||
@ -126,7 +128,9 @@ class _EventTypeDetailScreenState extends State<EventTypeDetailScreen> {
|
|||||||
eventType.bolusProfile.target = _bolusProfile;
|
eventType.bolusProfile.target = _bolusProfile;
|
||||||
LogEventType.put(eventType);
|
LogEventType.put(eventType);
|
||||||
Navigator.pop(
|
Navigator.pop(
|
||||||
context, ['${_isNew ? 'New' : ''} Log Event Type Saved', eventType]);
|
context, [translate(LocalizationKeys.eventType_saved, args: {
|
||||||
|
"status": _isNew ? LocalizationKeys.eventType_new : '',
|
||||||
|
}), eventType]);
|
||||||
}
|
}
|
||||||
setState(() {
|
setState(() {
|
||||||
_isSaving = false;
|
_isSaving = false;
|
||||||
@ -161,7 +165,10 @@ class _EventTypeDetailScreenState extends State<EventTypeDetailScreen> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(_isNew ? 'New Log Event Type' : _logEventType!.value),
|
title: Text(translate(LocalizationKeys.eventType_detail_title, args: {
|
||||||
|
"status": _isNew ? LocalizationKeys.eventType_new : LocalizationKeys.general_edit,
|
||||||
|
"name": _isNew ? '' : _logEventType!.value,
|
||||||
|
}))
|
||||||
),
|
),
|
||||||
drawer:
|
drawer:
|
||||||
const Navigation(currentLocation: EventTypeDetailScreen.routeName),
|
const Navigation(currentLocation: EventTypeDetailScreen.routeName),
|
||||||
@ -175,19 +182,19 @@ class _EventTypeDetailScreenState extends State<EventTypeDetailScreen> {
|
|||||||
FormWrapper(formState: _logEventTypeForm, fields: [
|
FormWrapper(formState: _logEventTypeForm, fields: [
|
||||||
TextFormField(
|
TextFormField(
|
||||||
controller: _valueController,
|
controller: _valueController,
|
||||||
decoration: const InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: 'Name',
|
labelText: translate(LocalizationKeys.eventType_fields_name),
|
||||||
),
|
),
|
||||||
validator: (value) {
|
validator: (value) {
|
||||||
if (value!.trim().isEmpty) {
|
if (value!.trim().isEmpty) {
|
||||||
return 'Empty name';
|
return translate(LocalizationKeys.eventType_fields_validators_name);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
BooleanFormField(
|
BooleanFormField(
|
||||||
value: _hasEndTime,
|
value: _hasEndTime,
|
||||||
label: 'has end time',
|
label: translate(LocalizationKeys.eventType_fields_hasEndTime),
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_hasEndTime = value;
|
_hasEndTime = value;
|
||||||
@ -201,7 +208,7 @@ class _EventTypeDetailScreenState extends State<EventTypeDetailScreen> {
|
|||||||
padding: const EdgeInsets.only(bottom: 10.0),
|
padding: const EdgeInsets.only(bottom: 10.0),
|
||||||
child: DurationFormField(
|
child: DurationFormField(
|
||||||
minutes: _defaultReminderDuration,
|
minutes: _defaultReminderDuration,
|
||||||
label: 'Default Reminder Duration',
|
label: translate(LocalizationKeys.eventType_fields_defaultReminderDuration),
|
||||||
onChanged: (value) => _defaultReminderDuration = value ?? 0,
|
onChanged: (value) => _defaultReminderDuration = value ?? 0,
|
||||||
showSteppers: true,
|
showSteppers: true,
|
||||||
),
|
),
|
||||||
@ -215,7 +222,7 @@ class _EventTypeDetailScreenState extends State<EventTypeDetailScreen> {
|
|||||||
BolusProfile>(
|
BolusProfile>(
|
||||||
selectedItem: _bolusProfile,
|
selectedItem: _bolusProfile,
|
||||||
controller: _bolusProfileController,
|
controller: _bolusProfileController,
|
||||||
label: 'Bolus Profile',
|
label: translate(LocalizationKeys.eventType_fields_bolusProfile),
|
||||||
items: _bolusProfiles,
|
items: _bolusProfiles,
|
||||||
onChanged: updateBolusProfile,
|
onChanged: updateBolusProfile,
|
||||||
),
|
),
|
||||||
@ -252,7 +259,7 @@ class _EventTypeDetailScreenState extends State<EventTypeDetailScreen> {
|
|||||||
AutoCompleteDropdownButton<BasalProfile>(
|
AutoCompleteDropdownButton<BasalProfile>(
|
||||||
controller: _basalProfileController,
|
controller: _basalProfileController,
|
||||||
selectedItem: _basalProfile,
|
selectedItem: _basalProfile,
|
||||||
label: 'Basal Profile',
|
label: translate(LocalizationKeys.eventType_fields_basalProfile),
|
||||||
items: _basalProfiles,
|
items: _basalProfiles,
|
||||||
onChanged: updateBasalProfile,
|
onChanged: updateBasalProfile,
|
||||||
),
|
),
|
||||||
@ -283,8 +290,8 @@ class _EventTypeDetailScreenState extends State<EventTypeDetailScreen> {
|
|||||||
: []),
|
: []),
|
||||||
TextFormField(
|
TextFormField(
|
||||||
controller: _notesController,
|
controller: _notesController,
|
||||||
decoration: const InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: 'Notes',
|
labelText: translate(LocalizationKeys.eventType_fields_notes),
|
||||||
),
|
),
|
||||||
keyboardType: TextInputType.multiline,
|
keyboardType: TextInputType.multiline,
|
||||||
minLines: 2,
|
minLines: 2,
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
|
import 'package:diameter/localization_keys.dart';
|
||||||
import 'package:diameter/models/log_event_type.dart';
|
import 'package:diameter/models/log_event_type.dart';
|
||||||
import 'package:diameter/navigation.dart';
|
import 'package:diameter/navigation.dart';
|
||||||
import 'package:diameter/screens/category/event_type_detail.dart';
|
import 'package:diameter/screens/category/event_type_detail.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_translate/flutter_translate.dart';
|
||||||
|
|
||||||
class EventTypeListScreen extends StatefulWidget {
|
class EventTypeListScreen extends StatefulWidget {
|
||||||
static const String routeName = '/log-event-types';
|
static const String routeName = '/log-event-types';
|
||||||
@ -48,7 +50,7 @@ class _EventTypeListScreenState extends State<EventTypeListScreen> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(title: const Text('Log Event Types'), actions: <Widget>[
|
appBar: AppBar(title: Text(translate(LocalizationKeys.eventType_title)), actions: <Widget>[
|
||||||
IconButton(onPressed: reload, icon: const Icon(Icons.refresh))
|
IconButton(onPressed: reload, icon: const Icon(Icons.refresh))
|
||||||
]),
|
]),
|
||||||
drawer:
|
drawer:
|
||||||
@ -88,7 +90,7 @@ class _EventTypeListScreenState extends State<EventTypeListScreen> {
|
|||||||
IconButton(
|
IconButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
LogEventType.remove(logEventType.id);
|
LogEventType.remove(logEventType.id);
|
||||||
reload(message: 'Log Event Type deleted');
|
reload(message: translate(LocalizationKeys.eventType_deleted));
|
||||||
},
|
},
|
||||||
icon: const Icon(Icons.delete,
|
icon: const Icon(Icons.delete,
|
||||||
color: Colors.blue),
|
color: Colors.blue),
|
||||||
@ -100,9 +102,9 @@ class _EventTypeListScreenState extends State<EventTypeListScreen> {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: const Center(
|
: Center(
|
||||||
child:
|
child:
|
||||||
Text('You have not created any Log Event Types yet!'),
|
Text(translate(LocalizationKeys.eventType_empty)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
import 'package:diameter/components/detail.dart';
|
import 'package:diameter/components/detail.dart';
|
||||||
|
import 'package:diameter/localization_keys.dart';
|
||||||
import 'package:diameter/utils/dialog_utils.dart';
|
import 'package:diameter/utils/dialog_utils.dart';
|
||||||
import 'package:diameter/components/forms/form_wrapper.dart';
|
import 'package:diameter/components/forms/form_wrapper.dart';
|
||||||
import 'package:diameter/models/settings.dart';
|
import 'package:diameter/models/settings.dart';
|
||||||
import 'package:diameter/navigation.dart';
|
import 'package:diameter/navigation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:diameter/models/meal_category.dart';
|
import 'package:diameter/models/meal_category.dart';
|
||||||
|
import 'package:flutter_translate/flutter_translate.dart';
|
||||||
|
|
||||||
class MealCategoryDetailScreen extends StatefulWidget {
|
class MealCategoryDetailScreen extends StatefulWidget {
|
||||||
static const String routeName = '/meal-category';
|
static const String routeName = '/meal-category';
|
||||||
@ -76,7 +78,9 @@ class _MealCategoryDetailScreenState extends State<MealCategoryDetailScreen> {
|
|||||||
);
|
);
|
||||||
MealCategory.put(mealCategory);
|
MealCategory.put(mealCategory);
|
||||||
Navigator.pop(context, [
|
Navigator.pop(context, [
|
||||||
'${_isNew ? 'New' : ''} Meal Category saved', mealCategory
|
translate(LocalizationKeys.mealCategory_saved, args: {
|
||||||
|
"status": _isNew ? LocalizationKeys.mealCategory_new : '',
|
||||||
|
}), mealCategory
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -102,7 +106,11 @@ class _MealCategoryDetailScreenState extends State<MealCategoryDetailScreen> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(_isNew ? 'New Meal Category' : _mealCategory!.value),
|
title: Text(translate(LocalizationKeys.mealCategory_detail_title, args: {
|
||||||
|
"status": _isNew ? LocalizationKeys.mealCategory_new : '',
|
||||||
|
"name": _mealCategory!.value
|
||||||
|
}),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
drawer:
|
drawer:
|
||||||
const Navigation(currentLocation: MealCategoryDetailScreen.routeName),
|
const Navigation(currentLocation: MealCategoryDetailScreen.routeName),
|
||||||
@ -118,20 +126,20 @@ class _MealCategoryDetailScreenState extends State<MealCategoryDetailScreen> {
|
|||||||
fields: [
|
fields: [
|
||||||
TextFormField(
|
TextFormField(
|
||||||
controller: _valueController,
|
controller: _valueController,
|
||||||
decoration: const InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: 'Name',
|
labelText: translate(LocalizationKeys.mealCategory_fields_name),
|
||||||
),
|
),
|
||||||
validator: (value) {
|
validator: (value) {
|
||||||
if (value!.trim().isEmpty) {
|
if (value!.trim().isEmpty) {
|
||||||
return 'Empty name';
|
return translate(LocalizationKeys.mealCategory_fields_validators_name);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
TextFormField(
|
TextFormField(
|
||||||
controller: _notesController,
|
controller: _notesController,
|
||||||
decoration: const InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: 'Notes',
|
labelText: translate(LocalizationKeys.mealCategory_fields_notes),
|
||||||
),
|
),
|
||||||
keyboardType: TextInputType.multiline,
|
keyboardType: TextInputType.multiline,
|
||||||
minLines: 2,
|
minLines: 2,
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
|
import 'package:diameter/localization_keys.dart';
|
||||||
import 'package:diameter/utils/dialog_utils.dart';
|
import 'package:diameter/utils/dialog_utils.dart';
|
||||||
import 'package:diameter/models/settings.dart';
|
import 'package:diameter/models/settings.dart';
|
||||||
import 'package:diameter/navigation.dart';
|
import 'package:diameter/navigation.dart';
|
||||||
import 'package:diameter/screens/category/meal_category_detail.dart';
|
import 'package:diameter/screens/category/meal_category_detail.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:diameter/models/meal_category.dart';
|
import 'package:diameter/models/meal_category.dart';
|
||||||
|
import 'package:flutter_translate/flutter_translate.dart';
|
||||||
|
|
||||||
class MealCategoryListScreen extends StatefulWidget {
|
class MealCategoryListScreen extends StatefulWidget {
|
||||||
static const String routeName = '/meal-categories';
|
static const String routeName = '/meal-categories';
|
||||||
@ -50,7 +52,7 @@ class _MealCategoryListScreenState extends State<MealCategoryListScreen> {
|
|||||||
|
|
||||||
void onDelete(MealCategory mealCategory) {
|
void onDelete(MealCategory mealCategory) {
|
||||||
MealCategory.remove(mealCategory.id);
|
MealCategory.remove(mealCategory.id);
|
||||||
reload(message: 'Meal Category deleted');
|
reload(message: translate(LocalizationKeys.mealCategory_deleted));
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleDeleteAction(MealCategory mealCategory) async {
|
void handleDeleteAction(MealCategory mealCategory) async {
|
||||||
@ -58,7 +60,7 @@ class _MealCategoryListScreenState extends State<MealCategoryListScreen> {
|
|||||||
DialogUtils.showConfirmationDialog(
|
DialogUtils.showConfirmationDialog(
|
||||||
context: context,
|
context: context,
|
||||||
onConfirm: () => onDelete(mealCategory),
|
onConfirm: () => onDelete(mealCategory),
|
||||||
message: 'Are you sure you want to delete this Meal Category?',
|
message: translate(LocalizationKeys.mealCategory_confirmDelete),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
onDelete(mealCategory);
|
onDelete(mealCategory);
|
||||||
@ -69,7 +71,7 @@ class _MealCategoryListScreenState extends State<MealCategoryListScreen> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: const Text('Meal Categories'),
|
title: Text(translate(LocalizationKeys.mealCategory_title)),
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: reload,
|
onPressed: reload,
|
||||||
@ -125,8 +127,8 @@ class _MealCategoryListScreenState extends State<MealCategoryListScreen> {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
): const Center(
|
): Center(
|
||||||
child: Text('You have not created any Meal Categories yet!'),
|
child: Text(translate(LocalizationKeys.mealCategory_empty)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
import 'package:diameter/components/detail.dart';
|
import 'package:diameter/components/detail.dart';
|
||||||
|
import 'package:diameter/localization_keys.dart';
|
||||||
import 'package:diameter/utils/dialog_utils.dart';
|
import 'package:diameter/utils/dialog_utils.dart';
|
||||||
import 'package:diameter/components/forms/form_wrapper.dart';
|
import 'package:diameter/components/forms/form_wrapper.dart';
|
||||||
import 'package:diameter/models/settings.dart';
|
import 'package:diameter/models/settings.dart';
|
||||||
import 'package:diameter/navigation.dart';
|
import 'package:diameter/navigation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:diameter/models/meal_portion_type.dart';
|
import 'package:diameter/models/meal_portion_type.dart';
|
||||||
|
import 'package:flutter_translate/flutter_translate.dart';
|
||||||
|
|
||||||
class MealPortionTypeDetailScreen extends StatefulWidget {
|
class MealPortionTypeDetailScreen extends StatefulWidget {
|
||||||
static const String routeName = '/meal-portion-type';
|
static const String routeName = '/meal-portion-type';
|
||||||
@ -78,7 +80,9 @@ class _MealPortionTypeDetailScreenState
|
|||||||
);
|
);
|
||||||
MealPortionType.put(mealPortionType);
|
MealPortionType.put(mealPortionType);
|
||||||
Navigator.pop(context,
|
Navigator.pop(context,
|
||||||
['${_isNew ? 'New' : ''} Meal Portion Type saved', mealPortionType]);
|
[translate(LocalizationKeys.portionType_saved, args: {
|
||||||
|
"status": _isNew ? LocalizationKeys.portionType_new : '',
|
||||||
|
}), mealPortionType]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,10 +106,12 @@ class _MealPortionTypeDetailScreenState
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
bool isNew = _mealPortionType == null;
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(isNew ? 'New Meal Portion Type' : _mealPortionType!.value),
|
title: Text(translate(LocalizationKeys.portionType_detail_title, args: {
|
||||||
|
"status": translate(_isNew ? LocalizationKeys.portionType_new : LocalizationKeys.general_edit),
|
||||||
|
"name": _mealPortionType!.value,
|
||||||
|
})),
|
||||||
),
|
),
|
||||||
drawer: const Navigation(
|
drawer: const Navigation(
|
||||||
currentLocation: MealPortionTypeDetailScreen.routeName),
|
currentLocation: MealPortionTypeDetailScreen.routeName),
|
||||||
@ -121,20 +127,20 @@ class _MealPortionTypeDetailScreenState
|
|||||||
fields: [
|
fields: [
|
||||||
TextFormField(
|
TextFormField(
|
||||||
controller: _valueController,
|
controller: _valueController,
|
||||||
decoration: const InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: 'Name',
|
labelText: translate(LocalizationKeys.portionType_fields_name),
|
||||||
),
|
),
|
||||||
validator: (value) {
|
validator: (value) {
|
||||||
if (value!.trim().isEmpty) {
|
if (value!.trim().isEmpty) {
|
||||||
return 'Empty name';
|
return translate(LocalizationKeys.portionType_fields_validators_name);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
TextFormField(
|
TextFormField(
|
||||||
controller: _notesController,
|
controller: _notesController,
|
||||||
decoration: const InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: 'Notes',
|
labelText: translate(LocalizationKeys.portionType_fields_notes),
|
||||||
),
|
),
|
||||||
keyboardType: TextInputType.multiline,
|
keyboardType: TextInputType.multiline,
|
||||||
minLines: 2,
|
minLines: 2,
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
|
import 'package:diameter/localization_keys.dart';
|
||||||
import 'package:diameter/utils/dialog_utils.dart';
|
import 'package:diameter/utils/dialog_utils.dart';
|
||||||
import 'package:diameter/models/settings.dart';
|
import 'package:diameter/models/settings.dart';
|
||||||
import 'package:diameter/navigation.dart';
|
import 'package:diameter/navigation.dart';
|
||||||
import 'package:diameter/screens/category/meal_portion_type_detail.dart';
|
import 'package:diameter/screens/category/meal_portion_type_detail.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:diameter/models/meal_portion_type.dart';
|
import 'package:diameter/models/meal_portion_type.dart';
|
||||||
|
import 'package:flutter_translate/flutter_translate.dart';
|
||||||
|
|
||||||
class MealPortionTypeListScreen extends StatefulWidget {
|
class MealPortionTypeListScreen extends StatefulWidget {
|
||||||
static const String routeName = '/meal-portion-types';
|
static const String routeName = '/meal-portion-types';
|
||||||
@ -51,7 +53,7 @@ class _MealPortionTypeListScreenState extends State<MealPortionTypeListScreen> {
|
|||||||
|
|
||||||
void onDelete(MealPortionType mealPortionType) {
|
void onDelete(MealPortionType mealPortionType) {
|
||||||
MealPortionType.remove(mealPortionType.id);
|
MealPortionType.remove(mealPortionType.id);
|
||||||
reload(message: 'Meal Portion Type deleted');
|
reload(message: translate(LocalizationKeys.portionType_deleted));
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleDeleteAction(MealPortionType mealPortionType) async {
|
void handleDeleteAction(MealPortionType mealPortionType) async {
|
||||||
@ -59,7 +61,7 @@ class _MealPortionTypeListScreenState extends State<MealPortionTypeListScreen> {
|
|||||||
DialogUtils.showConfirmationDialog(
|
DialogUtils.showConfirmationDialog(
|
||||||
context: context,
|
context: context,
|
||||||
onConfirm: () => onDelete(mealPortionType),
|
onConfirm: () => onDelete(mealPortionType),
|
||||||
message: 'Are you sure you want to delete this Meal Portion Type?',
|
message: translate(LocalizationKeys.portionType_confirmDelete),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
onDelete(mealPortionType);
|
onDelete(mealPortionType);
|
||||||
@ -70,7 +72,7 @@ class _MealPortionTypeListScreenState extends State<MealPortionTypeListScreen> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: const Text('Meal Portion Types'),
|
title: Text(translate(LocalizationKeys.portionType_title)),
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
IconButton(onPressed: reload, icon: const Icon(Icons.refresh))
|
IconButton(onPressed: reload, icon: const Icon(Icons.refresh))
|
||||||
],
|
],
|
||||||
@ -124,8 +126,8 @@ class _MealPortionTypeListScreenState extends State<MealPortionTypeListScreen> {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
) : const Center(
|
) : Center(
|
||||||
child: Text('You have not created any Meal Portion Types yet!'),
|
child: Text(translate(LocalizationKeys.portionType_empty)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import 'package:diameter/components/detail.dart';
|
import 'package:diameter/components/detail.dart';
|
||||||
|
import 'package:diameter/localization_keys.dart';
|
||||||
import 'package:diameter/utils/dialog_utils.dart';
|
import 'package:diameter/utils/dialog_utils.dart';
|
||||||
import 'package:diameter/components/forms/auto_complete_dropdown_button.dart';
|
import 'package:diameter/components/forms/auto_complete_dropdown_button.dart';
|
||||||
import 'package:diameter/components/forms/form_wrapper.dart';
|
import 'package:diameter/components/forms/form_wrapper.dart';
|
||||||
@ -12,6 +13,7 @@ import 'package:diameter/screens/category/accuracy_detail.dart';
|
|||||||
import 'package:diameter/screens/category/meal_category_detail.dart';
|
import 'package:diameter/screens/category/meal_category_detail.dart';
|
||||||
import 'package:diameter/screens/category/meal_portion_type_detail.dart';
|
import 'package:diameter/screens/category/meal_portion_type_detail.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_translate/flutter_translate.dart';
|
||||||
|
|
||||||
class MealSourceDetailScreen extends StatefulWidget {
|
class MealSourceDetailScreen extends StatefulWidget {
|
||||||
static const String routeName = '/meal-source';
|
static const String routeName = '/meal-source';
|
||||||
@ -121,7 +123,9 @@ class _MealSourceDetailScreenState extends State<MealSourceDetailScreen> {
|
|||||||
mealSource.defaultMealCategory.target = _defaultMealCategory;
|
mealSource.defaultMealCategory.target = _defaultMealCategory;
|
||||||
mealSource.defaultMealPortionType.target = _defaultMealPortionType;
|
mealSource.defaultMealPortionType.target = _defaultMealPortionType;
|
||||||
MealSource.put(mealSource);
|
MealSource.put(mealSource);
|
||||||
Navigator.pop(context, ['${_isNew ? 'New' : ''} Meal Source saved', mealSource]);
|
Navigator.pop(context, [translate(LocalizationKeys.mealSource_saved, args: {
|
||||||
|
"status": _isNew ? LocalizationKeys.mealSource_new : ''
|
||||||
|
}), mealSource]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleCancelAction() {
|
void handleCancelAction() {
|
||||||
@ -158,7 +162,12 @@ class _MealSourceDetailScreenState extends State<MealSourceDetailScreen> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(_isNew ? 'New Meal Source' : _mealSource!.value),
|
title: Text(
|
||||||
|
translate(LocalizationKeys.mealSource_saved, args: {
|
||||||
|
"status": _isNew ? LocalizationKeys.mealSource_new : LocalizationKeys.general_edit,
|
||||||
|
"name": _mealSource!.value,
|
||||||
|
})
|
||||||
|
),
|
||||||
),
|
),
|
||||||
drawer:
|
drawer:
|
||||||
const Navigation(currentLocation: MealSourceDetailScreen.routeName),
|
const Navigation(currentLocation: MealSourceDetailScreen.routeName),
|
||||||
@ -174,12 +183,12 @@ class _MealSourceDetailScreenState extends State<MealSourceDetailScreen> {
|
|||||||
fields: [
|
fields: [
|
||||||
TextFormField(
|
TextFormField(
|
||||||
controller: _valueController,
|
controller: _valueController,
|
||||||
decoration: const InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: 'Name',
|
labelText: translate(LocalizationKeys.mealSource_fields_name),
|
||||||
),
|
),
|
||||||
validator: (value) {
|
validator: (value) {
|
||||||
if (value!.trim().isEmpty) {
|
if (value!.trim().isEmpty) {
|
||||||
return 'Empty name';
|
return translate(LocalizationKeys.mealSource_fields_validators_name);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
@ -190,7 +199,7 @@ class _MealSourceDetailScreenState extends State<MealSourceDetailScreen> {
|
|||||||
child: AutoCompleteDropdownButton<Accuracy>(
|
child: AutoCompleteDropdownButton<Accuracy>(
|
||||||
selectedItem: _defaultCarbsRatioAccuracy,
|
selectedItem: _defaultCarbsRatioAccuracy,
|
||||||
controller: _defaultCarbsRatioAccuracyController,
|
controller: _defaultCarbsRatioAccuracyController,
|
||||||
label: 'Default Carbs Ratio Accuracy',
|
label: translate(LocalizationKeys.mealSource_fields_defaultCarbsRatioAccuracy),
|
||||||
items: _carbsRatioAccuracies,
|
items: _carbsRatioAccuracies,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
setState(() {
|
setState(() {
|
||||||
@ -233,7 +242,7 @@ class _MealSourceDetailScreenState extends State<MealSourceDetailScreen> {
|
|||||||
child: AutoCompleteDropdownButton<Accuracy>(
|
child: AutoCompleteDropdownButton<Accuracy>(
|
||||||
selectedItem: _defaultPortionSizeAccuracy,
|
selectedItem: _defaultPortionSizeAccuracy,
|
||||||
controller: _defaultPortionSizeAccuracyController,
|
controller: _defaultPortionSizeAccuracyController,
|
||||||
label: 'Default Portion Size Accuracy',
|
label: translate(LocalizationKeys.mealSource_fields_defaultPortionSizeAccuracy),
|
||||||
items: _portionSizeAccuracies,
|
items: _portionSizeAccuracies,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
setState(() {
|
setState(() {
|
||||||
@ -278,7 +287,7 @@ class _MealSourceDetailScreenState extends State<MealSourceDetailScreen> {
|
|||||||
child: AutoCompleteDropdownButton<MealCategory>(
|
child: AutoCompleteDropdownButton<MealCategory>(
|
||||||
selectedItem: _defaultMealCategory,
|
selectedItem: _defaultMealCategory,
|
||||||
controller: _defaultMealCategoryController,
|
controller: _defaultMealCategoryController,
|
||||||
label: 'Default Meal Category',
|
label: translate(LocalizationKeys.mealSource_fields_defaultMealCategory),
|
||||||
items: _mealCategories,
|
items: _mealCategories,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
setState(() {
|
setState(() {
|
||||||
@ -320,7 +329,7 @@ class _MealSourceDetailScreenState extends State<MealSourceDetailScreen> {
|
|||||||
child: AutoCompleteDropdownButton<MealPortionType>(
|
child: AutoCompleteDropdownButton<MealPortionType>(
|
||||||
selectedItem: _defaultMealPortionType,
|
selectedItem: _defaultMealPortionType,
|
||||||
controller: _defaultMealPortionTypeController,
|
controller: _defaultMealPortionTypeController,
|
||||||
label: 'Default Meal Portion Type',
|
label: translate(LocalizationKeys.mealSource_fields_defaultMealPortionType),
|
||||||
items: _mealPortionTypes,
|
items: _mealPortionTypes,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
setState(() {
|
setState(() {
|
||||||
@ -359,8 +368,8 @@ class _MealSourceDetailScreenState extends State<MealSourceDetailScreen> {
|
|||||||
),
|
),
|
||||||
TextFormField(
|
TextFormField(
|
||||||
controller: _notesController,
|
controller: _notesController,
|
||||||
decoration: const InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: 'Notes',
|
labelText: translate(LocalizationKeys.mealSource_fields_notes),
|
||||||
),
|
),
|
||||||
keyboardType: TextInputType.multiline,
|
keyboardType: TextInputType.multiline,
|
||||||
minLines: 2,
|
minLines: 2,
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
|
import 'package:diameter/localization_keys.dart';
|
||||||
import 'package:diameter/utils/dialog_utils.dart';
|
import 'package:diameter/utils/dialog_utils.dart';
|
||||||
import 'package:diameter/models/meal_source.dart';
|
import 'package:diameter/models/meal_source.dart';
|
||||||
import 'package:diameter/models/settings.dart';
|
import 'package:diameter/models/settings.dart';
|
||||||
import 'package:diameter/navigation.dart';
|
import 'package:diameter/navigation.dart';
|
||||||
import 'package:diameter/screens/category/meal_source_detail.dart';
|
import 'package:diameter/screens/category/meal_source_detail.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_translate/flutter_translate.dart';
|
||||||
|
|
||||||
class MealSourceListScreen extends StatefulWidget {
|
class MealSourceListScreen extends StatefulWidget {
|
||||||
static const String routeName = '/meal-sources';
|
static const String routeName = '/meal-sources';
|
||||||
@ -50,7 +52,7 @@ class _MealSourceListScreenState extends State<MealSourceListScreen> {
|
|||||||
|
|
||||||
void onDelete(MealSource mealSource) {
|
void onDelete(MealSource mealSource) {
|
||||||
MealSource.remove(mealSource.id);
|
MealSource.remove(mealSource.id);
|
||||||
reload(message: 'Meal Source deleted');
|
reload(message: translate(LocalizationKeys.mealSource_deleted));
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleDeleteAction(MealSource mealSource) async {
|
void handleDeleteAction(MealSource mealSource) async {
|
||||||
@ -58,7 +60,7 @@ class _MealSourceListScreenState extends State<MealSourceListScreen> {
|
|||||||
DialogUtils.showConfirmationDialog(
|
DialogUtils.showConfirmationDialog(
|
||||||
context: context,
|
context: context,
|
||||||
onConfirm: () => onDelete(mealSource),
|
onConfirm: () => onDelete(mealSource),
|
||||||
message: 'Are you sure you want to delete this Meal Source?',
|
message: translate(LocalizationKeys.mealSource_confirmDelete),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
onDelete(mealSource);
|
onDelete(mealSource);
|
||||||
@ -69,7 +71,7 @@ class _MealSourceListScreenState extends State<MealSourceListScreen> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: const Text('Meal Sources'),
|
title: Text(translate(LocalizationKeys.mealSource_title)),
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
IconButton(onPressed: reload, icon: const Icon(Icons.refresh))
|
IconButton(onPressed: reload, icon: const Icon(Icons.refresh))
|
||||||
],
|
],
|
||||||
@ -122,8 +124,8 @@ class _MealSourceListScreenState extends State<MealSourceListScreen> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
) : const Center(
|
) : Center(
|
||||||
child: Text('You have not created any Meal Sources yet!'),
|
child: Text(translate(LocalizationKeys.mealSource_empty)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -3,6 +3,7 @@ import 'dart:math';
|
|||||||
import 'package:diameter/components/detail.dart';
|
import 'package:diameter/components/detail.dart';
|
||||||
import 'package:diameter/components/forms/boolean_form_field.dart';
|
import 'package:diameter/components/forms/boolean_form_field.dart';
|
||||||
import 'package:diameter/components/forms/number_form_field.dart';
|
import 'package:diameter/components/forms/number_form_field.dart';
|
||||||
|
import 'package:diameter/localization_keys.dart';
|
||||||
import 'package:diameter/utils/dialog_utils.dart';
|
import 'package:diameter/utils/dialog_utils.dart';
|
||||||
import 'package:diameter/components/forms/auto_complete_dropdown_button.dart';
|
import 'package:diameter/components/forms/auto_complete_dropdown_button.dart';
|
||||||
import 'package:diameter/components/forms/form_wrapper.dart';
|
import 'package:diameter/components/forms/form_wrapper.dart';
|
||||||
@ -15,6 +16,7 @@ import 'package:diameter/navigation.dart';
|
|||||||
import 'package:diameter/screens/log/log_entry/log_meal_detail.dart';
|
import 'package:diameter/screens/log/log_entry/log_meal_detail.dart';
|
||||||
import 'package:diameter/utils/utils.dart';
|
import 'package:diameter/utils/utils.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_translate/flutter_translate.dart';
|
||||||
|
|
||||||
enum BolusType {
|
enum BolusType {
|
||||||
meal,
|
meal,
|
||||||
@ -453,7 +455,9 @@ class _LogBolusDetailScreenState extends State<LogBolusDetailScreen> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Navigator.pop(context,
|
Navigator.pop(context,
|
||||||
['${_isNew ? 'New' : ''} Bolus Saved', logBolus, delayedBolus]);
|
[translate(LocalizationKeys.log_detail_tabs_bolus_saved, args: {
|
||||||
|
"status": _isNew ? LocalizationKeys.log_detail_tabs_bolus_new : ''
|
||||||
|
}), logBolus, delayedBolus]);
|
||||||
}
|
}
|
||||||
setState(() {
|
setState(() {
|
||||||
_isSaving = false;
|
_isSaving = false;
|
||||||
@ -509,7 +513,9 @@ class _LogBolusDetailScreenState extends State<LogBolusDetailScreen> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(_isNew ? 'New Bolus' : 'Edit Bolus'),
|
title: Text(translate(LocalizationKeys.log_detail_tabs_bolus_detail_title, args: {
|
||||||
|
"status": _isNew ? LocalizationKeys.log_detail_tabs_bolus_new : LocalizationKeys.general_edit
|
||||||
|
})),
|
||||||
),
|
),
|
||||||
drawer: const Navigation(currentLocation: LogBolusDetailScreen.routeName),
|
drawer: const Navigation(currentLocation: LogBolusDetailScreen.routeName),
|
||||||
body: Scrollbar(
|
body: Scrollbar(
|
||||||
@ -544,7 +550,7 @@ class _LogBolusDetailScreenState extends State<LogBolusDetailScreen> {
|
|||||||
contentPadding: const EdgeInsets.only(
|
contentPadding: const EdgeInsets.only(
|
||||||
left: 10.0, right: 10.0, top: 10.0),
|
left: 10.0, right: 10.0, top: 10.0),
|
||||||
value: _setManually,
|
value: _setManually,
|
||||||
label: 'set manually',
|
label: translate(LocalizationKeys.log_detail_tabs_bolus_detail_fields_setManually),
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_setManually = value;
|
_setManually = value;
|
||||||
@ -559,7 +565,7 @@ class _LogBolusDetailScreenState extends State<LogBolusDetailScreen> {
|
|||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: RadioListTile(
|
child: RadioListTile(
|
||||||
title: const Text('for glucose'),
|
title: Text(translate(LocalizationKeys.log_detail_tabs_bolus_detail_fields_forGlucose)),
|
||||||
groupValue: _bolusType,
|
groupValue: _bolusType,
|
||||||
value: BolusType.glucose,
|
value: BolusType.glucose,
|
||||||
onChanged: (_) {
|
onChanged: (_) {
|
||||||
@ -571,7 +577,7 @@ class _LogBolusDetailScreenState extends State<LogBolusDetailScreen> {
|
|||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: RadioListTile(
|
child: RadioListTile(
|
||||||
title: const Text('for meal'),
|
title: Text(translate(LocalizationKeys.log_detail_tabs_bolus_detail_fields_forMeal)),
|
||||||
groupValue: _bolusType,
|
groupValue: _bolusType,
|
||||||
value: BolusType.meal,
|
value: BolusType.meal,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
@ -599,8 +605,8 @@ class _LogBolusDetailScreenState extends State<LogBolusDetailScreen> {
|
|||||||
padding:
|
padding:
|
||||||
const EdgeInsets.only(right: 5.0),
|
const EdgeInsets.only(right: 5.0),
|
||||||
child: NumberFormField(
|
child: NumberFormField(
|
||||||
label: 'Current',
|
label: translate(LocalizationKeys.log_detail_tabs_bolus_detail_fields_current),
|
||||||
suffix: 'mg/dl',
|
suffix: Settings.glucoseMeasurementSuffix,
|
||||||
controller:
|
controller:
|
||||||
_mgPerDlCurrentController,
|
_mgPerDlCurrentController,
|
||||||
onChanged: (_) => onChangeGlucose(),
|
onChanged: (_) => onChangeGlucose(),
|
||||||
@ -613,8 +619,8 @@ class _LogBolusDetailScreenState extends State<LogBolusDetailScreen> {
|
|||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.symmetric(
|
||||||
horizontal: 5.0),
|
horizontal: 5.0),
|
||||||
child: NumberFormField(
|
child: NumberFormField(
|
||||||
label: 'Target',
|
label: translate(LocalizationKeys.log_detail_tabs_bolus_detail_fields_target),
|
||||||
suffix: 'mg/dl',
|
suffix: Settings.glucoseMeasurementSuffix,
|
||||||
controller:
|
controller:
|
||||||
_mgPerDlTargetController,
|
_mgPerDlTargetController,
|
||||||
onChanged: (_) => onChangeGlucose(),
|
onChanged: (_) => onChangeGlucose(),
|
||||||
@ -627,9 +633,9 @@ class _LogBolusDetailScreenState extends State<LogBolusDetailScreen> {
|
|||||||
padding:
|
padding:
|
||||||
const EdgeInsets.only(left: 5.0),
|
const EdgeInsets.only(left: 5.0),
|
||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
decoration: const InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: 'Correction',
|
labelText: translate(LocalizationKeys.log_detail_tabs_bolus_detail_fields_correction),
|
||||||
suffixText: 'mg/dl',
|
suffixText: Settings.glucoseMeasurementSuffix,
|
||||||
),
|
),
|
||||||
controller:
|
controller:
|
||||||
_mgPerDlCorrectionController,
|
_mgPerDlCorrectionController,
|
||||||
@ -661,8 +667,8 @@ class _LogBolusDetailScreenState extends State<LogBolusDetailScreen> {
|
|||||||
padding: const EdgeInsets.only(
|
padding: const EdgeInsets.only(
|
||||||
right: 5.0),
|
right: 5.0),
|
||||||
child: NumberFormField(
|
child: NumberFormField(
|
||||||
label: 'Current',
|
label: translate(LocalizationKeys.log_detail_tabs_bolus_detail_fields_current),
|
||||||
suffix: 'mmol/l',
|
suffix: Settings.glucoseMeasurementSuffix,
|
||||||
controller:
|
controller:
|
||||||
_mmolPerLCurrentController,
|
_mmolPerLCurrentController,
|
||||||
onChanged: (_) =>
|
onChanged: (_) =>
|
||||||
@ -676,8 +682,8 @@ class _LogBolusDetailScreenState extends State<LogBolusDetailScreen> {
|
|||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.symmetric(
|
||||||
horizontal: 5.0),
|
horizontal: 5.0),
|
||||||
child: NumberFormField(
|
child: NumberFormField(
|
||||||
label: 'Target',
|
label: translate(LocalizationKeys.log_detail_tabs_bolus_detail_fields_target),
|
||||||
suffix: 'mmol/l',
|
suffix: Settings.glucoseMeasurementSuffix,
|
||||||
controller:
|
controller:
|
||||||
_mmolPerLTargetController,
|
_mmolPerLTargetController,
|
||||||
onChanged: (_) =>
|
onChanged: (_) =>
|
||||||
@ -691,9 +697,9 @@ class _LogBolusDetailScreenState extends State<LogBolusDetailScreen> {
|
|||||||
padding: const EdgeInsets.only(
|
padding: const EdgeInsets.only(
|
||||||
left: 5.0),
|
left: 5.0),
|
||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
decoration: const InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: 'Correction',
|
labelText: translate(LocalizationKeys.log_detail_tabs_bolus_detail_fields_correction),
|
||||||
suffixText: 'mmol/l',
|
suffixText: Settings.glucoseMeasurementSuffix,
|
||||||
),
|
),
|
||||||
controller:
|
controller:
|
||||||
_mmolPerLCorrectionController,
|
_mmolPerLCorrectionController,
|
||||||
@ -713,7 +719,7 @@ class _LogBolusDetailScreenState extends State<LogBolusDetailScreen> {
|
|||||||
child: AutoCompleteDropdownButton<LogMeal>(
|
child: AutoCompleteDropdownButton<LogMeal>(
|
||||||
controller: _mealController,
|
controller: _mealController,
|
||||||
selectedItem: _meal,
|
selectedItem: _meal,
|
||||||
label: 'Meal',
|
label: translate(LocalizationKeys.log_detail_tabs_bolus_detail_fields_meal),
|
||||||
items: _logMeals,
|
items: _logMeals,
|
||||||
onChanged: onSelectMeal,
|
onChanged: onSelectMeal,
|
||||||
),
|
),
|
||||||
@ -758,9 +764,9 @@ class _LogBolusDetailScreenState extends State<LogBolusDetailScreen> {
|
|||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
decoration: const InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: 'Delayed Bolus Duration',
|
labelText: translate(LocalizationKeys.log_detail_tabs_bolus_detail_fields_delayedBolusDuration),
|
||||||
suffixText: ' min',
|
suffixText: translate(LocalizationKeys.general_suffixes_mins),
|
||||||
),
|
),
|
||||||
controller: _delayController,
|
controller: _delayController,
|
||||||
onChanged: (value) => setState(() {}),
|
onChanged: (value) => setState(() {}),
|
||||||
@ -789,8 +795,8 @@ class _LogBolusDetailScreenState extends State<LogBolusDetailScreen> {
|
|||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(right: 5.0),
|
padding: const EdgeInsets.only(right: 5.0),
|
||||||
child: NumberFormField(
|
child: NumberFormField(
|
||||||
label: 'Immediate Bolus',
|
label: translate(LocalizationKeys.log_detail_tabs_bolus_detail_fields_immediateBolus),
|
||||||
suffix: ' U',
|
suffix: translate(LocalizationKeys.general_suffixes_units),
|
||||||
controller: _immediateUnitsController,
|
controller: _immediateUnitsController,
|
||||||
max: double.tryParse(_unitsController.text),
|
max: double.tryParse(_unitsController.text),
|
||||||
step: Settings.insulinSteps,
|
step: Settings.insulinSteps,
|
||||||
@ -804,8 +810,8 @@ class _LogBolusDetailScreenState extends State<LogBolusDetailScreen> {
|
|||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(left: 5.0),
|
padding: const EdgeInsets.only(left: 5.0),
|
||||||
child: NumberFormField(
|
child: NumberFormField(
|
||||||
label: 'Delayed Bolus',
|
label: translate(LocalizationKeys.log_detail_tabs_bolus_detail_fields_delayedBolus),
|
||||||
suffix: ' U',
|
suffix: translate(LocalizationKeys.general_suffixes_units),
|
||||||
controller: _delayedUnitsController,
|
controller: _delayedUnitsController,
|
||||||
max: double.tryParse(_unitsController.text),
|
max: double.tryParse(_unitsController.text),
|
||||||
step: Settings.insulinSteps,
|
step: Settings.insulinSteps,
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import 'package:diameter/localization_keys.dart';
|
||||||
import 'package:diameter/utils/dialog_utils.dart';
|
import 'package:diameter/utils/dialog_utils.dart';
|
||||||
import 'package:diameter/models/log_bolus.dart';
|
import 'package:diameter/models/log_bolus.dart';
|
||||||
import 'package:diameter/models/log_entry.dart';
|
import 'package:diameter/models/log_entry.dart';
|
||||||
@ -5,6 +6,7 @@ import 'package:diameter/models/settings.dart';
|
|||||||
import 'package:diameter/screens/log/log_entry/log_bolus_detail.dart';
|
import 'package:diameter/screens/log/log_entry/log_bolus_detail.dart';
|
||||||
import 'package:diameter/screens/log/log_entry/log_meal_detail.dart';
|
import 'package:diameter/screens/log/log_entry/log_meal_detail.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_translate/flutter_translate.dart';
|
||||||
|
|
||||||
class LogBolusListScreen extends StatefulWidget {
|
class LogBolusListScreen extends StatefulWidget {
|
||||||
final LogEntry logEntry;
|
final LogEntry logEntry;
|
||||||
@ -61,7 +63,7 @@ class _LogBolusListScreenState extends State<LogBolusListScreen> {
|
|||||||
|
|
||||||
void onDelete(LogBolus logBolus) {
|
void onDelete(LogBolus logBolus) {
|
||||||
LogBolus.remove(logBolus.id);
|
LogBolus.remove(logBolus.id);
|
||||||
reload(message: 'Bolus deleted');
|
reload(message: translate(LocalizationKeys.log_detail_tabs_bolus_deleted));
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleDeleteAction(LogBolus logBolus) async {
|
void handleDeleteAction(LogBolus logBolus) async {
|
||||||
@ -69,7 +71,8 @@ class _LogBolusListScreenState extends State<LogBolusListScreen> {
|
|||||||
DialogUtils.showConfirmationDialog(
|
DialogUtils.showConfirmationDialog(
|
||||||
context: context,
|
context: context,
|
||||||
onConfirm: () => onDelete(logBolus),
|
onConfirm: () => onDelete(logBolus),
|
||||||
message: 'Are you sure you want to delete this Bolus?',
|
message:
|
||||||
|
translate(LocalizationKeys.log_detail_tabs_bolus_confirmDelete),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
onDelete(logBolus);
|
onDelete(logBolus);
|
||||||
@ -100,9 +103,14 @@ class _LogBolusListScreenState extends State<LogBolusListScreen> {
|
|||||||
itemCount: widget.logBoli.length,
|
itemCount: widget.logBoli.length,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
final bolus = widget.logBoli[index];
|
final bolus = widget.logBoli[index];
|
||||||
String titleText = '${bolus.units} U ${(bolus.delay ?? 0) != 0
|
String titleText =
|
||||||
? ' (delayed by ${bolus.delay} min)'
|
'${bolus.units} ${translate(LocalizationKeys.general_suffixes_units)} ${(bolus.delay ?? 0) != 0 ?
|
||||||
: ''}';
|
translate(
|
||||||
|
LocalizationKeys.log_detail_tabs_bolus_delayedBy,
|
||||||
|
args: {
|
||||||
|
"delay": '${bolus.delay} ${translate(LocalizationKeys.general_suffixes_mins)}'
|
||||||
|
}
|
||||||
|
) : ''}';
|
||||||
return Card(
|
return Card(
|
||||||
child: ListTile(
|
child: ListTile(
|
||||||
onTap: () => handleEditAction(bolus),
|
onTap: () => handleEditAction(bolus),
|
||||||
@ -110,8 +118,8 @@ class _LogBolusListScreenState extends State<LogBolusListScreen> {
|
|||||||
titleText.toUpperCase(),
|
titleText.toUpperCase(),
|
||||||
style: Theme.of(context).textTheme.subtitle2,
|
style: Theme.of(context).textTheme.subtitle2,
|
||||||
),
|
),
|
||||||
subtitle: Text(bolus.carbs != null ?
|
subtitle: Text(bolus.carbs != null
|
||||||
'for ${(bolus.meal.target ?? '').toString()} (${bolus.carbs}${Settings.nutritionMeasurementSuffix} carbs)'
|
? 'for ${(bolus.meal.target ?? '').toString()} (${bolus.carbs}${Settings.nutritionMeasurementSuffix} carbs)'
|
||||||
: 'to correct ${Settings.glucoseMeasurement == GlucoseMeasurement.mgPerDl ? bolus.mgPerDlCorrection : bolus.mmolPerLCorrection} ${Settings.glucoseMeasurementSuffix}'),
|
: 'to correct ${Settings.glucoseMeasurement == GlucoseMeasurement.mgPerDl ? bolus.mgPerDlCorrection : bolus.mmolPerLCorrection} ${Settings.glucoseMeasurementSuffix}'),
|
||||||
trailing: Row(
|
trailing: Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
@ -138,9 +146,9 @@ class _LogBolusListScreenState extends State<LogBolusListScreen> {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: const Center(
|
: Center(
|
||||||
child: Text(
|
child:
|
||||||
'You have not added any Boli to this Log Entry yet!'),
|
Text(translate(LocalizationKeys.log_detail_tabs_bolus_empty)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ import 'package:diameter/components/detail.dart';
|
|||||||
import 'package:diameter/components/forms/date_time_form_field.dart';
|
import 'package:diameter/components/forms/date_time_form_field.dart';
|
||||||
import 'package:diameter/components/forms/number_form_field.dart';
|
import 'package:diameter/components/forms/number_form_field.dart';
|
||||||
import 'package:diameter/components/forms/time_of_day_form_field.dart';
|
import 'package:diameter/components/forms/time_of_day_form_field.dart';
|
||||||
|
import 'package:diameter/localization_keys.dart';
|
||||||
import 'package:diameter/utils/dialog_utils.dart';
|
import 'package:diameter/utils/dialog_utils.dart';
|
||||||
import 'package:diameter/components/forms/form_wrapper.dart';
|
import 'package:diameter/components/forms/form_wrapper.dart';
|
||||||
import 'package:diameter/models/log_bolus.dart';
|
import 'package:diameter/models/log_bolus.dart';
|
||||||
@ -18,6 +19,8 @@ import 'package:diameter/utils/utils.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'dart:math' as math;
|
import 'dart:math' as math;
|
||||||
|
|
||||||
|
import 'package:flutter_translate/flutter_translate.dart';
|
||||||
|
|
||||||
class LogEntryScreen extends StatefulWidget {
|
class LogEntryScreen extends StatefulWidget {
|
||||||
static const String routeName = '/log-entry';
|
static const String routeName = '/log-entry';
|
||||||
final int id;
|
final int id;
|
||||||
@ -192,7 +195,9 @@ class _LogEntryScreenState extends State<LogEntryScreen> {
|
|||||||
|
|
||||||
if (close) {
|
if (close) {
|
||||||
Navigator.pop(
|
Navigator.pop(
|
||||||
context, ['${_isNew ? 'New' : ''} Log Entry Saved', logEntry]);
|
context, [translate(LocalizationKeys.log_saved, args: {
|
||||||
|
"status": _isNew ? LocalizationKeys.log_new : ''
|
||||||
|
}), logEntry]);
|
||||||
} else {
|
} else {
|
||||||
if (_isNew) {
|
if (_isNew) {
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
@ -202,7 +207,7 @@ class _LogEntryScreenState extends State<LogEntryScreen> {
|
|||||||
),
|
),
|
||||||
).then((result) => Navigator.pop(context, result));
|
).then((result) => Navigator.pop(context, result));
|
||||||
} else {
|
} else {
|
||||||
reload(message: 'Log Entry Saved');
|
reload(message: translate(LocalizationKeys.log_saved));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -306,7 +311,7 @@ class _LogEntryScreenState extends State<LogEntryScreen> {
|
|||||||
padding: const EdgeInsets.only(right: 5),
|
padding: const EdgeInsets.only(right: 5),
|
||||||
child: DateTimeFormField(
|
child: DateTimeFormField(
|
||||||
date: _time,
|
date: _time,
|
||||||
label: 'Date',
|
label: translate(LocalizationKeys.log_fields_date),
|
||||||
controller: _dateController,
|
controller: _dateController,
|
||||||
onChanged: (newTime) {
|
onChanged: (newTime) {
|
||||||
if (newTime != null) {
|
if (newTime != null) {
|
||||||
@ -329,7 +334,7 @@ class _LogEntryScreenState extends State<LogEntryScreen> {
|
|||||||
padding: const EdgeInsets.only(left: 5),
|
padding: const EdgeInsets.only(left: 5),
|
||||||
child: TimeOfDayFormField(
|
child: TimeOfDayFormField(
|
||||||
time: TimeOfDay.fromDateTime(_time),
|
time: TimeOfDay.fromDateTime(_time),
|
||||||
label: 'Time',
|
label: translate(LocalizationKeys.log_fields_time),
|
||||||
controller: _timeController,
|
controller: _timeController,
|
||||||
onChanged: (newTime) {
|
onChanged: (newTime) {
|
||||||
if (newTime != null) {
|
if (newTime != null) {
|
||||||
@ -363,8 +368,8 @@ class _LogEntryScreenState extends State<LogEntryScreen> {
|
|||||||
? 2
|
? 2
|
||||||
: 1,
|
: 1,
|
||||||
child: NumberFormField(
|
child: NumberFormField(
|
||||||
label: 'Blood Glucose',
|
label: translate(LocalizationKeys.log_fields_glucose),
|
||||||
suffix: 'mg/dl',
|
suffix: Settings.glucoseMeasurementSuffix,
|
||||||
readOnly: Settings.glucoseMeasurement ==
|
readOnly: Settings.glucoseMeasurement ==
|
||||||
GlucoseMeasurement.mmolPerL,
|
GlucoseMeasurement.mmolPerL,
|
||||||
showSteppers:
|
showSteppers:
|
||||||
@ -388,8 +393,8 @@ class _LogEntryScreenState extends State<LogEntryScreen> {
|
|||||||
? 2
|
? 2
|
||||||
: 1,
|
: 1,
|
||||||
child: NumberFormField(
|
child: NumberFormField(
|
||||||
label: 'Blood Glucose',
|
label: translate(LocalizationKeys.log_fields_glucose),
|
||||||
suffix: 'mmol/l',
|
suffix: Settings.glucoseMeasurementSuffix,
|
||||||
readOnly: Settings.glucoseMeasurement ==
|
readOnly: Settings.glucoseMeasurement ==
|
||||||
GlucoseMeasurement.mgPerDl,
|
GlucoseMeasurement.mgPerDl,
|
||||||
showSteppers:
|
showSteppers:
|
||||||
@ -421,8 +426,8 @@ class _LogEntryScreenState extends State<LogEntryScreen> {
|
|||||||
),
|
),
|
||||||
TextFormField(
|
TextFormField(
|
||||||
controller: _notesController,
|
controller: _notesController,
|
||||||
decoration: const InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: 'Notes',
|
labelText: translate(LocalizationKeys.log_fields_notes),
|
||||||
),
|
),
|
||||||
keyboardType: TextInputType.multiline,
|
keyboardType: TextInputType.multiline,
|
||||||
minLines: 2,
|
minLines: 2,
|
||||||
@ -444,14 +449,16 @@ class _LogEntryScreenState extends State<LogEntryScreen> {
|
|||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(_isNew ? 'New Log Entry' : 'Edit Log Entry'),
|
title: Text(translate(LocalizationKeys.log_detail_title, args: {
|
||||||
|
"status": _isNew ? LocalizationKeys.log_new : LocalizationKeys.general_edit
|
||||||
|
})),
|
||||||
bottom: _isNew
|
bottom: _isNew
|
||||||
? PreferredSize(child: Container(), preferredSize: Size.zero)
|
? PreferredSize(child: Container(), preferredSize: Size.zero)
|
||||||
: const TabBar(
|
: TabBar(
|
||||||
tabs: [
|
tabs: [
|
||||||
Tab(text: 'GENERAL'),
|
Tab(text: translate(LocalizationKeys.log_detail_tabs_general).toUpperCase()),
|
||||||
Tab(text: 'MEALS'),
|
Tab(text: translate(LocalizationKeys.log_detail_tabs_meal_title).toUpperCase()),
|
||||||
Tab(text: 'BOLI'),
|
Tab(text: translate(LocalizationKeys.log_detail_tabs_bolus_title).toUpperCase()),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
actions: appBarActions,
|
actions: appBarActions,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import 'package:diameter/components/detail.dart';
|
import 'package:diameter/components/detail.dart';
|
||||||
import 'package:diameter/components/forms/boolean_form_field.dart';
|
import 'package:diameter/components/forms/boolean_form_field.dart';
|
||||||
import 'package:diameter/components/forms/number_form_field.dart';
|
import 'package:diameter/components/forms/number_form_field.dart';
|
||||||
|
import 'package:diameter/localization_keys.dart';
|
||||||
import 'package:diameter/utils/dialog_utils.dart';
|
import 'package:diameter/utils/dialog_utils.dart';
|
||||||
import 'package:diameter/components/forms/auto_complete_dropdown_button.dart';
|
import 'package:diameter/components/forms/auto_complete_dropdown_button.dart';
|
||||||
import 'package:diameter/components/forms/form_wrapper.dart';
|
import 'package:diameter/components/forms/form_wrapper.dart';
|
||||||
@ -19,6 +20,7 @@ import 'package:diameter/screens/category/meal_source_detail.dart';
|
|||||||
import 'package:diameter/screens/meal/meal_detail.dart';
|
import 'package:diameter/screens/meal/meal_detail.dart';
|
||||||
import 'package:diameter/utils/utils.dart';
|
import 'package:diameter/utils/utils.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_translate/flutter_translate.dart';
|
||||||
|
|
||||||
class LogMealDetailScreen extends StatefulWidget {
|
class LogMealDetailScreen extends StatefulWidget {
|
||||||
static const String routeName = '/log-meal';
|
static const String routeName = '/log-meal';
|
||||||
@ -230,7 +232,9 @@ class _LogMealDetailScreenState extends State<LogMealDetailScreen> {
|
|||||||
logMeal.carbsRatioAccuracy.target = _carbsRatioAccuracy;
|
logMeal.carbsRatioAccuracy.target = _carbsRatioAccuracy;
|
||||||
|
|
||||||
LogMeal.put(logMeal);
|
LogMeal.put(logMeal);
|
||||||
Navigator.pop(context, ['${_isNew ? 'New' : ''} Meal Saved', logMeal]);
|
Navigator.pop(context, [translate(LocalizationKeys.log_detail_tabs_meal_saved, args: {
|
||||||
|
"status": _isNew ? translate(LocalizationKeys.log_detail_tabs_bolus_new) : ''
|
||||||
|
}), logMeal]);
|
||||||
}
|
}
|
||||||
setState(() {
|
setState(() {
|
||||||
_isSaving = false;
|
_isSaving = false;
|
||||||
@ -405,7 +409,9 @@ class _LogMealDetailScreenState extends State<LogMealDetailScreen> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(_isNew ? 'New Meal for Log Entry' : _logMeal!.value),
|
title: Text(translate(LocalizationKeys.log_detail_tabs_meal_detail_title, args: {
|
||||||
|
"status": _isNew ? translate(LocalizationKeys.log_detail_tabs_bolus_new) : LocalizationKeys.general_edit
|
||||||
|
})),
|
||||||
),
|
),
|
||||||
drawer: const Navigation(currentLocation: LogMealDetailScreen.routeName),
|
drawer: const Navigation(currentLocation: LogMealDetailScreen.routeName),
|
||||||
body: Scrollbar(
|
body: Scrollbar(
|
||||||
@ -424,7 +430,7 @@ class _LogMealDetailScreenState extends State<LogMealDetailScreen> {
|
|||||||
child: AutoCompleteDropdownButton<Meal>(
|
child: AutoCompleteDropdownButton<Meal>(
|
||||||
controller: _mealController,
|
controller: _mealController,
|
||||||
selectedItem: _meal,
|
selectedItem: _meal,
|
||||||
label: 'Meal',
|
label: translate(LocalizationKeys.log_detail_tabs_meal_detail_fields_meal),
|
||||||
items: _meals,
|
items: _meals,
|
||||||
onChanged: onSelectMeal,
|
onChanged: onSelectMeal,
|
||||||
),
|
),
|
||||||
@ -449,12 +455,12 @@ class _LogMealDetailScreenState extends State<LogMealDetailScreen> {
|
|||||||
),
|
),
|
||||||
TextFormField(
|
TextFormField(
|
||||||
controller: _valueController,
|
controller: _valueController,
|
||||||
decoration: const InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: 'Name',
|
labelText: translate(LocalizationKeys.log_detail_tabs_meal_detail_fields_name),
|
||||||
),
|
),
|
||||||
validator: (value) {
|
validator: (value) {
|
||||||
if (value!.trim().isEmpty) {
|
if (value!.trim().isEmpty) {
|
||||||
return 'Empty name';
|
return translate(LocalizationKeys.log_detail_tabs_meal_detail_fields_validators_name);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
@ -465,7 +471,7 @@ class _LogMealDetailScreenState extends State<LogMealDetailScreen> {
|
|||||||
flex: 10,
|
flex: 10,
|
||||||
child: NumberFormField(
|
child: NumberFormField(
|
||||||
controller: _amountController,
|
controller: _amountController,
|
||||||
label: 'Amount',
|
label: translate(LocalizationKeys.log_detail_tabs_meal_detail_fields_amount),
|
||||||
suffix: _mealPortionType?.value,
|
suffix: _mealPortionType?.value,
|
||||||
onChanged: updateAmount,
|
onChanged: updateAmount,
|
||||||
),
|
),
|
||||||
@ -524,7 +530,7 @@ class _LogMealDetailScreenState extends State<LogMealDetailScreen> {
|
|||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: NumberFormField(
|
child: NumberFormField(
|
||||||
label: 'Portion size',
|
label: translate(LocalizationKeys.log_detail_tabs_meal_detail_fields_portionSize),
|
||||||
suffix: Settings.nutritionMeasurementSuffix,
|
suffix: Settings.nutritionMeasurementSuffix,
|
||||||
controller: _portionSizeController,
|
controller: _portionSizeController,
|
||||||
showSteppers: false,
|
showSteppers: false,
|
||||||
@ -548,7 +554,7 @@ class _LogMealDetailScreenState extends State<LogMealDetailScreen> {
|
|||||||
const SizedBox(width: 10),
|
const SizedBox(width: 10),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: NumberFormField(
|
child: NumberFormField(
|
||||||
label: 'Carbs ratio',
|
label: translate(LocalizationKeys.log_detail_tabs_meal_detail_fields_carbsRatio),
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
controller: _carbsRatioController,
|
controller: _carbsRatioController,
|
||||||
showSteppers: false,
|
showSteppers: false,
|
||||||
@ -570,7 +576,7 @@ class _LogMealDetailScreenState extends State<LogMealDetailScreen> {
|
|||||||
const SizedBox(width: 10),
|
const SizedBox(width: 10),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: NumberFormField(
|
child: NumberFormField(
|
||||||
label: 'Total carbs',
|
label: translate(LocalizationKeys.log_detail_tabs_meal_detail_fields_totalCarbs),
|
||||||
suffix: Settings.nutritionMeasurementSuffix,
|
suffix: Settings.nutritionMeasurementSuffix,
|
||||||
controller: _totalCarbsController,
|
controller: _totalCarbsController,
|
||||||
showSteppers: false,
|
showSteppers: false,
|
||||||
@ -595,7 +601,7 @@ class _LogMealDetailScreenState extends State<LogMealDetailScreen> {
|
|||||||
),
|
),
|
||||||
BooleanFormField(
|
BooleanFormField(
|
||||||
value: _setManually,
|
value: _setManually,
|
||||||
label: 'set carbs ratio manually',
|
label: translate(LocalizationKeys.log_detail_tabs_meal_detail_fields_setManually),
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_setManually = value;
|
_setManually = value;
|
||||||
@ -605,8 +611,8 @@ class _LogMealDetailScreenState extends State<LogMealDetailScreen> {
|
|||||||
),
|
),
|
||||||
TextFormField(
|
TextFormField(
|
||||||
controller: _notesController,
|
controller: _notesController,
|
||||||
decoration: const InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: 'Notes',
|
labelText: translate(LocalizationKeys.log_detail_tabs_meal_detail_fields_notes),
|
||||||
),
|
),
|
||||||
keyboardType: TextInputType.multiline,
|
keyboardType: TextInputType.multiline,
|
||||||
minLines: 2,
|
minLines: 2,
|
||||||
@ -621,7 +627,7 @@ class _LogMealDetailScreenState extends State<LogMealDetailScreen> {
|
|||||||
mainAxisSize: MainAxisSize.max,
|
mainAxisSize: MainAxisSize.max,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'ADDITIONAL FIELDS',
|
translate(LocalizationKeys.log_detail_tabs_meal_detail_additionalFields).toUpperCase(),
|
||||||
style: Theme.of(context).textTheme.subtitle2,
|
style: Theme.of(context).textTheme.subtitle2,
|
||||||
),
|
),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
@ -642,7 +648,7 @@ class _LogMealDetailScreenState extends State<LogMealDetailScreen> {
|
|||||||
AutoCompleteDropdownButton<MealSource>(
|
AutoCompleteDropdownButton<MealSource>(
|
||||||
controller: _mealSourceController,
|
controller: _mealSourceController,
|
||||||
selectedItem: _mealSource,
|
selectedItem: _mealSource,
|
||||||
label: 'Meal Source',
|
label: translate(LocalizationKeys.log_detail_tabs_meal_detail_fields_mealSource),
|
||||||
items: _mealSources,
|
items: _mealSources,
|
||||||
onChanged: updateMealSource,
|
onChanged: updateMealSource,
|
||||||
),
|
),
|
||||||
@ -677,7 +683,7 @@ class _LogMealDetailScreenState extends State<LogMealDetailScreen> {
|
|||||||
AutoCompleteDropdownButton<MealCategory>(
|
AutoCompleteDropdownButton<MealCategory>(
|
||||||
controller: _mealCategoryController,
|
controller: _mealCategoryController,
|
||||||
selectedItem: _mealCategory,
|
selectedItem: _mealCategory,
|
||||||
label: 'Meal Category',
|
label: translate(LocalizationKeys.log_detail_tabs_meal_detail_fields_mealCategory),
|
||||||
items: _mealCategories,
|
items: _mealCategories,
|
||||||
onChanged: updateMealCategory,
|
onChanged: updateMealCategory,
|
||||||
),
|
),
|
||||||
@ -712,7 +718,7 @@ class _LogMealDetailScreenState extends State<LogMealDetailScreen> {
|
|||||||
AutoCompleteDropdownButton<MealPortionType>(
|
AutoCompleteDropdownButton<MealPortionType>(
|
||||||
controller: _mealPortionTypeController,
|
controller: _mealPortionTypeController,
|
||||||
selectedItem: _mealPortionType,
|
selectedItem: _mealPortionType,
|
||||||
label: 'Meal Portion Type',
|
label: translate(LocalizationKeys.log_detail_tabs_meal_detail_fields_mealPortionType),
|
||||||
items: _mealPortionTypes,
|
items: _mealPortionTypes,
|
||||||
onChanged: updateMealPortionType,
|
onChanged: updateMealPortionType,
|
||||||
),
|
),
|
||||||
@ -747,7 +753,7 @@ class _LogMealDetailScreenState extends State<LogMealDetailScreen> {
|
|||||||
AutoCompleteDropdownButton<Accuracy>(
|
AutoCompleteDropdownButton<Accuracy>(
|
||||||
controller: _portionSizeAccuracyController,
|
controller: _portionSizeAccuracyController,
|
||||||
selectedItem: _portionSizeAccuracy,
|
selectedItem: _portionSizeAccuracy,
|
||||||
label: 'Portion Size Accuracy',
|
label: translate(LocalizationKeys.log_detail_tabs_meal_detail_fields_portionSizeAccuracy),
|
||||||
items: _portionSizeAccuracies,
|
items: _portionSizeAccuracies,
|
||||||
onChanged: updatePortionSizeAccuracy,
|
onChanged: updatePortionSizeAccuracy,
|
||||||
),
|
),
|
||||||
@ -783,7 +789,7 @@ class _LogMealDetailScreenState extends State<LogMealDetailScreen> {
|
|||||||
AutoCompleteDropdownButton<Accuracy>(
|
AutoCompleteDropdownButton<Accuracy>(
|
||||||
controller: _carbsRatioAccuracyController,
|
controller: _carbsRatioAccuracyController,
|
||||||
selectedItem: _carbsRatioAccuracy,
|
selectedItem: _carbsRatioAccuracy,
|
||||||
label: 'Carbs Ratio Accuracy',
|
label: translate(LocalizationKeys.log_detail_tabs_meal_detail_fields_carbsRatioAccuracy),
|
||||||
items: _carbsRatioAccuracies,
|
items: _carbsRatioAccuracies,
|
||||||
onChanged: updateCarbsRatioAccuracy,
|
onChanged: updateCarbsRatioAccuracy,
|
||||||
),
|
),
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
|
import 'package:diameter/localization_keys.dart';
|
||||||
import 'package:diameter/utils/dialog_utils.dart';
|
import 'package:diameter/utils/dialog_utils.dart';
|
||||||
import 'package:diameter/models/log_entry.dart';
|
import 'package:diameter/models/log_entry.dart';
|
||||||
import 'package:diameter/models/log_meal.dart';
|
import 'package:diameter/models/log_meal.dart';
|
||||||
import 'package:diameter/models/settings.dart';
|
import 'package:diameter/models/settings.dart';
|
||||||
import 'package:diameter/screens/log/log_entry/log_meal_detail.dart';
|
import 'package:diameter/screens/log/log_entry/log_meal_detail.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_translate/flutter_translate.dart';
|
||||||
|
|
||||||
class LogMealListScreen extends StatefulWidget {
|
class LogMealListScreen extends StatefulWidget {
|
||||||
final LogEntry logEntry;
|
final LogEntry logEntry;
|
||||||
@ -57,7 +59,7 @@ class _LogMealListScreenState extends State<LogMealListScreen> {
|
|||||||
|
|
||||||
void onDelete(LogMeal logMeal) {
|
void onDelete(LogMeal logMeal) {
|
||||||
LogMeal.remove(logMeal.id);
|
LogMeal.remove(logMeal.id);
|
||||||
reload(message: 'Meal deleted');
|
reload(message: translate(LocalizationKeys.log_detail_tabs_meal_deleted));
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleDeleteAction(LogMeal meal) async {
|
void handleDeleteAction(LogMeal meal) async {
|
||||||
@ -65,7 +67,7 @@ class _LogMealListScreenState extends State<LogMealListScreen> {
|
|||||||
DialogUtils.showConfirmationDialog(
|
DialogUtils.showConfirmationDialog(
|
||||||
context: context,
|
context: context,
|
||||||
onConfirm: () => onDelete(meal),
|
onConfirm: () => onDelete(meal),
|
||||||
message: 'Are you sure you want to delete this Meal?',
|
message: translate(LocalizationKeys.log_detail_tabs_meal_confirmDelete),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
onDelete(meal);
|
onDelete(meal);
|
||||||
@ -99,7 +101,7 @@ class _LogMealListScreenState extends State<LogMealListScreen> {
|
|||||||
? [
|
? [
|
||||||
Text(meal.totalCarbs!.toStringAsPrecision(3)),
|
Text(meal.totalCarbs!.toStringAsPrecision(3)),
|
||||||
Text(
|
Text(
|
||||||
'${Settings.nutritionMeasurementSuffix} carbs',
|
'${Settings.nutritionMeasurementSuffix} ${translate(LocalizationKeys.general_suffixes_carbs)}',
|
||||||
textScaleFactor: 0.75),
|
textScaleFactor: 0.75),
|
||||||
]
|
]
|
||||||
: [],
|
: [],
|
||||||
@ -119,9 +121,9 @@ class _LogMealListScreenState extends State<LogMealListScreen> {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: const Center(
|
: Center(
|
||||||
child: Text(
|
child: Text(
|
||||||
'You have not added any Meals to this Log Entry yet!'),
|
translate(LocalizationKeys.log_detail_tabs_meal_empty)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ import 'package:diameter/components/detail.dart';
|
|||||||
import 'package:diameter/components/forms/boolean_form_field.dart';
|
import 'package:diameter/components/forms/boolean_form_field.dart';
|
||||||
import 'package:diameter/components/forms/date_time_form_field.dart';
|
import 'package:diameter/components/forms/date_time_form_field.dart';
|
||||||
import 'package:diameter/components/forms/time_of_day_form_field.dart';
|
import 'package:diameter/components/forms/time_of_day_form_field.dart';
|
||||||
|
import 'package:diameter/localization_keys.dart';
|
||||||
import 'package:diameter/utils/dialog_utils.dart';
|
import 'package:diameter/utils/dialog_utils.dart';
|
||||||
import 'package:diameter/components/forms/auto_complete_dropdown_button.dart';
|
import 'package:diameter/components/forms/auto_complete_dropdown_button.dart';
|
||||||
import 'package:diameter/components/forms/form_wrapper.dart';
|
import 'package:diameter/components/forms/form_wrapper.dart';
|
||||||
@ -15,6 +16,7 @@ import 'package:diameter/screens/basal/basal_profile_detail.dart';
|
|||||||
import 'package:diameter/screens/bolus/bolus_profile_detail.dart';
|
import 'package:diameter/screens/bolus/bolus_profile_detail.dart';
|
||||||
import 'package:diameter/utils/date_time_utils.dart';
|
import 'package:diameter/utils/date_time_utils.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_translate/flutter_translate.dart';
|
||||||
|
|
||||||
class LogEventDetailScreen extends StatefulWidget {
|
class LogEventDetailScreen extends StatefulWidget {
|
||||||
static const String routeName = '/log-event';
|
static const String routeName = '/log-event';
|
||||||
@ -194,20 +196,19 @@ class _LogEventDetailScreenState extends State<LogEventDetailScreen> {
|
|||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
content: const Text(
|
content: Text(translate(LocalizationKeys.event_warnings_duplicate)),
|
||||||
'An Event of this type is already active within the set time frame. What would you like to do?'),
|
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.pop(context, 'DISCARD'),
|
onPressed: () => Navigator.pop(context, 'DISCARD'),
|
||||||
child: const Text('DISCARD'),
|
child: Text(translate(LocalizationKeys.general_discard).toUpperCase()),
|
||||||
),
|
),
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.pop(context, 'EDIT'),
|
onPressed: () => Navigator.pop(context, 'EDIT'),
|
||||||
child: const Text('KEEP EDITING'),
|
child: Text(translate(LocalizationKeys.general_keepEditing).toUpperCase()),
|
||||||
),
|
),
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: () => Navigator.pop(context, 'SAVE'),
|
onPressed: () => Navigator.pop(context, 'SAVE'),
|
||||||
child: const Text('SAVE'),
|
child: Text(translate(LocalizationKeys.general_save).toUpperCase()),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@ -236,7 +237,9 @@ class _LogEventDetailScreenState extends State<LogEventDetailScreen> {
|
|||||||
event.basalProfile.target = _basalProfile;
|
event.basalProfile.target = _basalProfile;
|
||||||
event.bolusProfile.target = _bolusProfile;
|
event.bolusProfile.target = _bolusProfile;
|
||||||
LogEvent.put(event);
|
LogEvent.put(event);
|
||||||
Navigator.pop(context, ['${_isNew ? 'New' : ''} Event Saved', event]);
|
Navigator.pop(context, [translate(LocalizationKeys.event_saved, args: {
|
||||||
|
"status": _isNew ? LocalizationKeys.event_new : "",
|
||||||
|
}), event]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleSaveAction() async {
|
void handleSaveAction() async {
|
||||||
@ -276,7 +279,10 @@ class _LogEventDetailScreenState extends State<LogEventDetailScreen> {
|
|||||||
final now = DateTime.now();
|
final now = DateTime.now();
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(_isNew ? 'New Event' : 'Edit Event'),
|
title: Text(translate(LocalizationKeys.event_saved, args: {
|
||||||
|
"status": _isNew ? LocalizationKeys.event_new : LocalizationKeys.general_edit,
|
||||||
|
"name": _isNew ? '' : _logEvent?.eventType.target?.value
|
||||||
|
})),
|
||||||
),
|
),
|
||||||
drawer: const Navigation(currentLocation: LogEventDetailScreen.routeName),
|
drawer: const Navigation(currentLocation: LogEventDetailScreen.routeName),
|
||||||
body: Scrollbar(
|
body: Scrollbar(
|
||||||
@ -292,7 +298,7 @@ class _LogEventDetailScreenState extends State<LogEventDetailScreen> {
|
|||||||
AutoCompleteDropdownButton<LogEventType>(
|
AutoCompleteDropdownButton<LogEventType>(
|
||||||
controller: _eventTypeController,
|
controller: _eventTypeController,
|
||||||
selectedItem: _eventType,
|
selectedItem: _eventType,
|
||||||
label: 'Event Type',
|
label: translate(LocalizationKeys.event_fields_eventType),
|
||||||
items: _logEventTypes,
|
items: _logEventTypes,
|
||||||
onChanged: onSelectEventType,
|
onChanged: onSelectEventType,
|
||||||
),
|
),
|
||||||
@ -303,7 +309,7 @@ class _LogEventDetailScreenState extends State<LogEventDetailScreen> {
|
|||||||
padding: const EdgeInsets.only(right: 5),
|
padding: const EdgeInsets.only(right: 5),
|
||||||
child: DateTimeFormField(
|
child: DateTimeFormField(
|
||||||
date: _time,
|
date: _time,
|
||||||
label: _hasEndTime ? 'Start Date' : 'Date',
|
label: translate(_hasEndTime ? LocalizationKeys.event_fields_startDate : LocalizationKeys.event_fields_date),
|
||||||
controller: _dateController,
|
controller: _dateController,
|
||||||
onChanged: (newTime) {
|
onChanged: (newTime) {
|
||||||
if (newTime != null) {
|
if (newTime != null) {
|
||||||
@ -322,7 +328,7 @@ class _LogEventDetailScreenState extends State<LogEventDetailScreen> {
|
|||||||
padding: const EdgeInsets.only(left: 5),
|
padding: const EdgeInsets.only(left: 5),
|
||||||
child: TimeOfDayFormField(
|
child: TimeOfDayFormField(
|
||||||
time: TimeOfDay.fromDateTime(_time),
|
time: TimeOfDay.fromDateTime(_time),
|
||||||
label: _hasEndTime ? 'Start Time' : 'Time',
|
label: translate(_hasEndTime ? LocalizationKeys.event_fields_startTime : LocalizationKeys.event_fields_time),
|
||||||
controller: _timeController,
|
controller: _timeController,
|
||||||
onChanged: (newTime) {
|
onChanged: (newTime) {
|
||||||
if (newTime != null) {
|
if (newTime != null) {
|
||||||
@ -345,7 +351,7 @@ class _LogEventDetailScreenState extends State<LogEventDetailScreen> {
|
|||||||
_hasEndTime = value;
|
_hasEndTime = value;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
label: 'has end time',
|
label: translate(LocalizationKeys.event_fields_hasEndTime),
|
||||||
),
|
),
|
||||||
Column(
|
Column(
|
||||||
children: _hasEndTime
|
children: _hasEndTime
|
||||||
@ -357,7 +363,7 @@ class _LogEventDetailScreenState extends State<LogEventDetailScreen> {
|
|||||||
padding: const EdgeInsets.only(right: 5),
|
padding: const EdgeInsets.only(right: 5),
|
||||||
child: DateTimeFormField(
|
child: DateTimeFormField(
|
||||||
date: _endTime ?? now,
|
date: _endTime ?? now,
|
||||||
label: 'End Date',
|
label: translate(LocalizationKeys.event_fields_endDate),
|
||||||
controller: _endDateController,
|
controller: _endDateController,
|
||||||
onChanged: (newTime) {
|
onChanged: (newTime) {
|
||||||
if (newTime != null) {
|
if (newTime != null) {
|
||||||
@ -381,7 +387,7 @@ class _LogEventDetailScreenState extends State<LogEventDetailScreen> {
|
|||||||
child: TimeOfDayFormField(
|
child: TimeOfDayFormField(
|
||||||
time: TimeOfDay.fromDateTime(
|
time: TimeOfDay.fromDateTime(
|
||||||
_endTime ?? now),
|
_endTime ?? now),
|
||||||
label: 'End Time',
|
label: translate(LocalizationKeys.event_fields_endTime),
|
||||||
controller: _endTimeController,
|
controller: _endTimeController,
|
||||||
onChanged: (newTime) {
|
onChanged: (newTime) {
|
||||||
if (newTime != null) {
|
if (newTime != null) {
|
||||||
@ -408,8 +414,8 @@ class _LogEventDetailScreenState extends State<LogEventDetailScreen> {
|
|||||||
keyboardType:
|
keyboardType:
|
||||||
const TextInputType.numberWithOptions(),
|
const TextInputType.numberWithOptions(),
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: 'Default Reminder Duration',
|
labelText: translate(LocalizationKeys.event_fields_reminderDuration),
|
||||||
suffixText: ' min',
|
suffixText: translate(LocalizationKeys.general_suffixes_mins),
|
||||||
enabled: _hasEndTime,
|
enabled: _hasEndTime,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -421,7 +427,7 @@ class _LogEventDetailScreenState extends State<LogEventDetailScreen> {
|
|||||||
BolusProfile>(
|
BolusProfile>(
|
||||||
controller: _bolusProfileController,
|
controller: _bolusProfileController,
|
||||||
selectedItem: _bolusProfile,
|
selectedItem: _bolusProfile,
|
||||||
label: 'Bolus Profile',
|
label: translate(LocalizationKeys.event_fields_bolusProfile),
|
||||||
items: _bolusProfiles,
|
items: _bolusProfiles,
|
||||||
onChanged: updateBolusProfile,
|
onChanged: updateBolusProfile,
|
||||||
),
|
),
|
||||||
@ -457,7 +463,7 @@ class _LogEventDetailScreenState extends State<LogEventDetailScreen> {
|
|||||||
BasalProfile>(
|
BasalProfile>(
|
||||||
controller: _basalProfileController,
|
controller: _basalProfileController,
|
||||||
selectedItem: _basalProfile,
|
selectedItem: _basalProfile,
|
||||||
label: 'Basal Profile',
|
label: translate(LocalizationKeys.event_fields_basalProfile),
|
||||||
items: _basalProfiles,
|
items: _basalProfiles,
|
||||||
onChanged: updateBasalProfile,
|
onChanged: updateBasalProfile,
|
||||||
),
|
),
|
||||||
@ -489,8 +495,8 @@ class _LogEventDetailScreenState extends State<LogEventDetailScreen> {
|
|||||||
: []),
|
: []),
|
||||||
TextFormField(
|
TextFormField(
|
||||||
controller: _notesController,
|
controller: _notesController,
|
||||||
decoration: const InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: 'Notes',
|
labelText: translate(LocalizationKeys.event_fields_notes),
|
||||||
),
|
),
|
||||||
keyboardType: TextInputType.multiline,
|
keyboardType: TextInputType.multiline,
|
||||||
minLines: 2,
|
minLines: 2,
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import 'package:diameter/localization_keys.dart';
|
||||||
import 'package:diameter/utils/dialog_utils.dart';
|
import 'package:diameter/utils/dialog_utils.dart';
|
||||||
import 'package:diameter/models/log_event.dart';
|
import 'package:diameter/models/log_event.dart';
|
||||||
import 'package:diameter/models/settings.dart';
|
import 'package:diameter/models/settings.dart';
|
||||||
@ -5,6 +6,7 @@ import 'package:diameter/screens/log/log_event/log_event_detail.dart';
|
|||||||
import 'package:diameter/utils/date_time_utils.dart';
|
import 'package:diameter/utils/date_time_utils.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:diameter/navigation.dart';
|
import 'package:diameter/navigation.dart';
|
||||||
|
import 'package:flutter_translate/flutter_translate.dart';
|
||||||
|
|
||||||
class LogEventListScreen extends StatefulWidget {
|
class LogEventListScreen extends StatefulWidget {
|
||||||
static const String routeName = '/log-events';
|
static const String routeName = '/log-events';
|
||||||
@ -88,7 +90,7 @@ class _LogEventListScreenState extends State<LogEventListScreen> {
|
|||||||
|
|
||||||
void onDelete(LogEvent logEvent) {
|
void onDelete(LogEvent logEvent) {
|
||||||
LogEvent.remove(logEvent.id);
|
LogEvent.remove(logEvent.id);
|
||||||
reload(message: 'Event deleted');
|
reload(message: translate(LocalizationKeys.event_deleted));
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleDeleteAction(LogEvent logEvent) async {
|
void handleDeleteAction(LogEvent logEvent) async {
|
||||||
@ -96,7 +98,7 @@ class _LogEventListScreenState extends State<LogEventListScreen> {
|
|||||||
DialogUtils.showConfirmationDialog(
|
DialogUtils.showConfirmationDialog(
|
||||||
context: context,
|
context: context,
|
||||||
onConfirm: () => onDelete(logEvent),
|
onConfirm: () => onDelete(logEvent),
|
||||||
message: 'Are you sure you want to delete this Event?',
|
message: translate(LocalizationKeys.event_confirmDelete),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
onDelete(logEvent);
|
onDelete(logEvent);
|
||||||
@ -106,7 +108,7 @@ class _LogEventListScreenState extends State<LogEventListScreen> {
|
|||||||
void onStop(LogEvent event) async {
|
void onStop(LogEvent event) async {
|
||||||
event.endTime = DateTime.now();
|
event.endTime = DateTime.now();
|
||||||
LogEvent.put(event);
|
LogEvent.put(event);
|
||||||
reload(message: 'Event ended');
|
reload(message: translate(LocalizationKeys.event_ended));
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleStopAction(LogEvent event) async {
|
void handleStopAction(LogEvent event) async {
|
||||||
@ -114,8 +116,8 @@ class _LogEventListScreenState extends State<LogEventListScreen> {
|
|||||||
DialogUtils.showConfirmationDialog(
|
DialogUtils.showConfirmationDialog(
|
||||||
context: context,
|
context: context,
|
||||||
onConfirm: () => onStop(event),
|
onConfirm: () => onStop(event),
|
||||||
message: 'Are you sure you want to end this Event?',
|
message: translate(LocalizationKeys.event_confirmEnd),
|
||||||
confirmationLabel: 'END EVENT',
|
confirmationLabel: translate(LocalizationKeys.event_end),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
onStop(event);
|
onStop(event);
|
||||||
@ -136,7 +138,7 @@ class _LogEventListScreenState extends State<LogEventListScreen> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: const Text('Log Events'),
|
title: Text(translate(LocalizationKeys.event_title)),
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: () => onChangeDate(DateTime.now()),
|
onPressed: () => onChangeDate(DateTime.now()),
|
||||||
@ -159,7 +161,7 @@ class _LogEventListScreenState extends State<LogEventListScreen> {
|
|||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Text(
|
child: Text(
|
||||||
'ACTIVE EVENTS',
|
translate(LocalizationKeys.event_titleActive).toUpperCase(),
|
||||||
style: Theme.of(context).textTheme.subtitle2,
|
style: Theme.of(context).textTheme.subtitle2,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
@ -235,8 +237,8 @@ class _LogEventListScreenState extends State<LogEventListScreen> {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
: const Center(
|
: Center(
|
||||||
child: Text('There are no Active Events!'),
|
child: Text(translate(LocalizationKeys.event_emptyActive)),
|
||||||
),
|
),
|
||||||
const Padding(
|
const Padding(
|
||||||
padding: EdgeInsets.all(10.0),
|
padding: EdgeInsets.all(10.0),
|
||||||
@ -351,8 +353,8 @@ class _LogEventListScreenState extends State<LogEventListScreen> {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
: const Center(
|
: Center(
|
||||||
child: Text('There are no Events for that date!'),
|
child: Text(translate(LocalizationKeys.event_empty)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -1,304 +0,0 @@
|
|||||||
import 'package:diameter/components/detail.dart';
|
|
||||||
import 'package:diameter/components/forms/boolean_form_field.dart';
|
|
||||||
import 'package:diameter/components/forms/duration_form_field.dart';
|
|
||||||
import 'package:diameter/utils/dialog_utils.dart';
|
|
||||||
import 'package:diameter/components/forms/auto_complete_dropdown_button.dart';
|
|
||||||
import 'package:diameter/components/forms/form_wrapper.dart';
|
|
||||||
import 'package:diameter/models/basal_profile.dart';
|
|
||||||
import 'package:diameter/models/bolus_profile.dart';
|
|
||||||
import 'package:diameter/models/log_event_type.dart';
|
|
||||||
import 'package:diameter/models/settings.dart';
|
|
||||||
import 'package:diameter/navigation.dart';
|
|
||||||
import 'package:diameter/screens/basal/basal_profile_detail.dart';
|
|
||||||
import 'package:diameter/screens/bolus/bolus_profile_detail.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
class EventTypeDetailScreen extends StatefulWidget {
|
|
||||||
static const String routeName = '/log-event-type';
|
|
||||||
final int id;
|
|
||||||
const EventTypeDetailScreen({Key? key, this.id = 0}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
_EventTypeDetailScreenState createState() => _EventTypeDetailScreenState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _EventTypeDetailScreenState extends State<EventTypeDetailScreen> {
|
|
||||||
LogEventType? _logEventType;
|
|
||||||
bool _isNew = true;
|
|
||||||
bool _isSaving = false;
|
|
||||||
|
|
||||||
List<BolusProfile> _bolusProfiles = [];
|
|
||||||
List<BasalProfile> _basalProfiles = [];
|
|
||||||
|
|
||||||
final GlobalKey<FormState> _logEventTypeForm = GlobalKey<FormState>();
|
|
||||||
final ScrollController _scrollController = ScrollController();
|
|
||||||
|
|
||||||
final _valueController = TextEditingController(text: '');
|
|
||||||
final _notesController = TextEditingController(text: '');
|
|
||||||
|
|
||||||
bool _hasEndTime = false;
|
|
||||||
int _defaultReminderDuration = 0;
|
|
||||||
BolusProfile? _bolusProfile;
|
|
||||||
BasalProfile? _basalProfile;
|
|
||||||
final _bolusProfileController = TextEditingController(text: '');
|
|
||||||
final _basalProfileController = TextEditingController(text: '');
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
|
|
||||||
reload();
|
|
||||||
|
|
||||||
_bolusProfiles = BolusProfile.getAll();
|
|
||||||
_basalProfiles = BasalProfile.getAll();
|
|
||||||
|
|
||||||
if (_logEventType != null) {
|
|
||||||
_valueController.text = _logEventType!.value;
|
|
||||||
_defaultReminderDuration =
|
|
||||||
_logEventType!.defaultReminderDuration ?? 0;
|
|
||||||
_hasEndTime = _logEventType!.hasEndTime;
|
|
||||||
_notesController.text = _logEventType!.notes ?? '';
|
|
||||||
_basalProfile = _logEventType!.basalProfile.target;
|
|
||||||
_basalProfileController.text = (_basalProfile ?? '').toString();
|
|
||||||
_bolusProfile = _logEventType!.bolusProfile.target;
|
|
||||||
_bolusProfileController.text = (_bolusProfile ?? '').toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
_scrollController.dispose();
|
|
||||||
_valueController.dispose();
|
|
||||||
_notesController.dispose();
|
|
||||||
_bolusProfileController.dispose();
|
|
||||||
_basalProfileController.dispose();
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
void reload({String? message}) {
|
|
||||||
if (widget.id != 0) {
|
|
||||||
setState(() {
|
|
||||||
_logEventType = LogEventType.get(widget.id);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
_isNew = _logEventType == null;
|
|
||||||
|
|
||||||
setState(() {
|
|
||||||
if (message != null) {
|
|
||||||
var snackBar = SnackBar(
|
|
||||||
content: Text(message),
|
|
||||||
duration: const Duration(seconds: 2),
|
|
||||||
);
|
|
||||||
ScaffoldMessenger.of(context)
|
|
||||||
..removeCurrentSnackBar()
|
|
||||||
..showSnackBar(snackBar);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void updateBasalProfile(BasalProfile? value) {
|
|
||||||
setState(() {
|
|
||||||
_basalProfile = value;
|
|
||||||
_basalProfileController.text = (_basalProfile ?? '').toString();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void updateBolusProfile(BolusProfile? value) {
|
|
||||||
setState(() {
|
|
||||||
_bolusProfile = value;
|
|
||||||
_bolusProfileController.text = (_bolusProfile ?? '').toString();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void handleSaveAction() async {
|
|
||||||
setState(() {
|
|
||||||
_isSaving = true;
|
|
||||||
});
|
|
||||||
if (_logEventTypeForm.currentState!.validate()) {
|
|
||||||
LogEventType eventType = LogEventType(
|
|
||||||
id: widget.id,
|
|
||||||
value: _valueController.text,
|
|
||||||
notes: _notesController.text,
|
|
||||||
defaultReminderDuration: _defaultReminderDuration,
|
|
||||||
hasEndTime: _hasEndTime,
|
|
||||||
);
|
|
||||||
eventType.basalProfile.target = _basalProfile;
|
|
||||||
eventType.bolusProfile.target = _bolusProfile;
|
|
||||||
LogEventType.put(eventType);
|
|
||||||
Navigator.pop(
|
|
||||||
context, ['${_isNew ? 'New' : ''} Log Event Type Saved', eventType]);
|
|
||||||
}
|
|
||||||
setState(() {
|
|
||||||
_isSaving = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void handleCancelAction() {
|
|
||||||
bool isNew = _logEventType == null;
|
|
||||||
if (Settings.get().showConfirmationDialogOnCancel &&
|
|
||||||
((isNew &&
|
|
||||||
(_valueController.text != '' ||
|
|
||||||
_defaultReminderDuration != 0 ||
|
|
||||||
_notesController.text != '' ||
|
|
||||||
_hasEndTime)) ||
|
|
||||||
(!isNew &&
|
|
||||||
(_valueController.text != _logEventType!.value ||
|
|
||||||
_defaultReminderDuration !=
|
|
||||||
_logEventType!.defaultReminderDuration ||
|
|
||||||
_notesController.text != (_logEventType!.notes ?? '') ||
|
|
||||||
_hasEndTime != _logEventType!.hasEndTime)))) {
|
|
||||||
DialogUtils.showCancelConfirmationDialog(
|
|
||||||
context: context,
|
|
||||||
isNew: isNew,
|
|
||||||
onSave: handleSaveAction,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
Navigator.pop(context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Scaffold(
|
|
||||||
appBar: AppBar(
|
|
||||||
title: Text(_isNew ? 'New Log Event Type' : _logEventType!.value),
|
|
||||||
),
|
|
||||||
drawer:
|
|
||||||
const Navigation(currentLocation: EventTypeDetailScreen.routeName),
|
|
||||||
body: Scrollbar(
|
|
||||||
controller: _scrollController,
|
|
||||||
child: SingleChildScrollView(
|
|
||||||
controller: _scrollController,
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
||||||
children: <Widget>[
|
|
||||||
FormWrapper(formState: _logEventTypeForm, fields: [
|
|
||||||
TextFormField(
|
|
||||||
controller: _valueController,
|
|
||||||
decoration: const InputDecoration(
|
|
||||||
labelText: 'Name',
|
|
||||||
),
|
|
||||||
validator: (value) {
|
|
||||||
if (value!.trim().isEmpty) {
|
|
||||||
return 'Empty name';
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
),
|
|
||||||
BooleanFormField(
|
|
||||||
value: _hasEndTime,
|
|
||||||
label: 'has end time',
|
|
||||||
onChanged: (value) {
|
|
||||||
setState(() {
|
|
||||||
_hasEndTime = value;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
),
|
|
||||||
Column(
|
|
||||||
children: _hasEndTime
|
|
||||||
? [
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.only(bottom: 10.0),
|
|
||||||
child: DurationFormField(
|
|
||||||
minutes: _defaultReminderDuration,
|
|
||||||
label: 'Default Reminder Duration',
|
|
||||||
onChanged: (value) => _defaultReminderDuration = value ?? 0,
|
|
||||||
showSteppers: true,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.only(bottom: 10.0),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: AutoCompleteDropdownButton<
|
|
||||||
BolusProfile>(
|
|
||||||
selectedItem: _bolusProfile,
|
|
||||||
controller: _bolusProfileController,
|
|
||||||
label: 'Bolus Profile',
|
|
||||||
items: _bolusProfiles,
|
|
||||||
onChanged: updateBolusProfile,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
IconButton(
|
|
||||||
onPressed: () {
|
|
||||||
Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(
|
|
||||||
builder: (context) => _bolusProfile ==
|
|
||||||
null
|
|
||||||
? const BolusProfileDetailScreen()
|
|
||||||
: BolusProfileDetailScreen(
|
|
||||||
id: _bolusProfile!.id),
|
|
||||||
),
|
|
||||||
).then((result) {
|
|
||||||
setState(() {
|
|
||||||
updateBolusProfile(result?[1]);
|
|
||||||
});
|
|
||||||
reload(message: result?[0]);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
icon: Icon(_bolusProfile == null
|
|
||||||
? Icons.add
|
|
||||||
: Icons.edit),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child:
|
|
||||||
AutoCompleteDropdownButton<BasalProfile>(
|
|
||||||
controller: _basalProfileController,
|
|
||||||
selectedItem: _basalProfile,
|
|
||||||
label: 'Basal Profile',
|
|
||||||
items: _basalProfiles,
|
|
||||||
onChanged: updateBasalProfile,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
IconButton(
|
|
||||||
onPressed: () {
|
|
||||||
Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(
|
|
||||||
builder: (context) => _basalProfile ==
|
|
||||||
null
|
|
||||||
? const BasalProfileDetailScreen()
|
|
||||||
: BasalProfileDetailScreen(
|
|
||||||
id: _basalProfile!.id),
|
|
||||||
),
|
|
||||||
).then((result) {
|
|
||||||
updateBasalProfile(result?[1]);
|
|
||||||
reload(message: result?[0]);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
icon: Icon(_basalProfile == null
|
|
||||||
? Icons.add
|
|
||||||
: Icons.edit),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
]
|
|
||||||
: []),
|
|
||||||
TextFormField(
|
|
||||||
controller: _notesController,
|
|
||||||
decoration: const InputDecoration(
|
|
||||||
labelText: 'Notes',
|
|
||||||
),
|
|
||||||
keyboardType: TextInputType.multiline,
|
|
||||||
minLines: 2,
|
|
||||||
maxLines: 5,
|
|
||||||
),
|
|
||||||
]),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
bottomNavigationBar: DetailBottomRow(
|
|
||||||
onCancel: handleCancelAction,
|
|
||||||
onAction: _isSaving ? null : handleSaveAction,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,123 +0,0 @@
|
|||||||
import 'package:diameter/models/log_event_type.dart';
|
|
||||||
import 'package:diameter/navigation.dart';
|
|
||||||
import 'package:diameter/screens/log/log_event/log_event_type_detail.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
class LogEventTypeListScreen extends StatefulWidget {
|
|
||||||
static const String routeName = '/log-event-types';
|
|
||||||
const LogEventTypeListScreen({Key? key}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
_LogEventTypeListScreenState createState() => _LogEventTypeListScreenState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _LogEventTypeListScreenState extends State<LogEventTypeListScreen> {
|
|
||||||
List<LogEventType> _logEventTypes = [];
|
|
||||||
|
|
||||||
final ScrollController _scrollController = ScrollController();
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
reload();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
_scrollController.dispose();
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
void reload({String? message}) {
|
|
||||||
setState(() {
|
|
||||||
_logEventTypes = LogEventType.getAll();
|
|
||||||
});
|
|
||||||
setState(() {
|
|
||||||
if (message != null) {
|
|
||||||
var snackBar = SnackBar(
|
|
||||||
content: Text(message),
|
|
||||||
duration: const Duration(seconds: 2),
|
|
||||||
);
|
|
||||||
ScaffoldMessenger.of(context)
|
|
||||||
..removeCurrentSnackBar()
|
|
||||||
..showSnackBar(snackBar);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Scaffold(
|
|
||||||
appBar: AppBar(title: const Text('Log Event Types'), actions: <Widget>[
|
|
||||||
IconButton(onPressed: reload, icon: const Icon(Icons.refresh))
|
|
||||||
]),
|
|
||||||
drawer:
|
|
||||||
const Navigation(currentLocation: LogEventTypeListScreen.routeName),
|
|
||||||
body: Column(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: <Widget>[
|
|
||||||
Expanded(
|
|
||||||
child: _logEventTypes.isNotEmpty
|
|
||||||
? Scrollbar(
|
|
||||||
controller: _scrollController,
|
|
||||||
child: ListView.builder(
|
|
||||||
controller: _scrollController,
|
|
||||||
padding: const EdgeInsets.all(10.0),
|
|
||||||
itemCount: _logEventTypes.length,
|
|
||||||
itemBuilder: (context, index) {
|
|
||||||
final logEventType = _logEventTypes[index];
|
|
||||||
return Card(
|
|
||||||
child: ListTile(
|
|
||||||
onTap: () {
|
|
||||||
Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(
|
|
||||||
builder: (context) => EventTypeDetailScreen(
|
|
||||||
id: logEventType.id),
|
|
||||||
),
|
|
||||||
).then((result) => reload(message: result?[0]));
|
|
||||||
},
|
|
||||||
title: Text(
|
|
||||||
logEventType.value.toUpperCase(),
|
|
||||||
style: Theme.of(context).textTheme.subtitle2,
|
|
||||||
),
|
|
||||||
subtitle: Text(logEventType.notes ?? ''),
|
|
||||||
trailing: Row(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
IconButton(
|
|
||||||
onPressed: () async {
|
|
||||||
LogEventType.remove(logEventType.id);
|
|
||||||
reload(message: 'Log Event Type deleted');
|
|
||||||
},
|
|
||||||
icon: const Icon(Icons.delete,
|
|
||||||
color: Colors.blue),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
)
|
|
||||||
: const Center(
|
|
||||||
child:
|
|
||||||
Text('You have not created any Log Event Types yet!'),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
floatingActionButton: FloatingActionButton(
|
|
||||||
onPressed: () {
|
|
||||||
Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(
|
|
||||||
builder: (context) => const EventTypeDetailScreen(),
|
|
||||||
),
|
|
||||||
).then((result) => reload(message: result?[0]));
|
|
||||||
},
|
|
||||||
child: const Icon(Icons.add),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
230
lib/screens/log/log_filter_dialog.dart
Normal file
230
lib/screens/log/log_filter_dialog.dart
Normal file
@ -0,0 +1,230 @@
|
|||||||
|
import 'package:diameter/components/forms/auto_complete_dropdown_button.dart';
|
||||||
|
import 'package:diameter/components/forms/date_time_form_field.dart';
|
||||||
|
import 'package:diameter/components/forms/number_form_field.dart';
|
||||||
|
import 'package:diameter/localization_keys.dart';
|
||||||
|
import 'package:diameter/models/meal.dart';
|
||||||
|
import 'package:diameter/models/settings.dart';
|
||||||
|
import 'package:diameter/utils/date_time_utils.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_translate/flutter_translate.dart';
|
||||||
|
|
||||||
|
class LogFilterDialog extends StatefulWidget {
|
||||||
|
static const String routeName = '/log/filter';
|
||||||
|
|
||||||
|
final DateTime? date;
|
||||||
|
final void Function(
|
||||||
|
{DateTime? startDate,
|
||||||
|
DateTime? endDate,
|
||||||
|
int? minMgPerDl,
|
||||||
|
int? maxMgPerDl,
|
||||||
|
double? minMmolPerL,
|
||||||
|
double? maxMmolPerL,
|
||||||
|
int? mealId,
|
||||||
|
String? mealName,
|
||||||
|
String? note}) onApplyFilter;
|
||||||
|
|
||||||
|
const LogFilterDialog({Key? key, this.date, required this.onApplyFilter})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
_LogFilterDialogState createState() => _LogFilterDialogState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _LogFilterDialogState extends State<LogFilterDialog> {
|
||||||
|
final ScrollController _scrollController = ScrollController();
|
||||||
|
|
||||||
|
late DateTime filterStartDate;
|
||||||
|
late DateTime filterEndDate;
|
||||||
|
|
||||||
|
Meal? meal;
|
||||||
|
List<Meal> _meals = [];
|
||||||
|
|
||||||
|
TextEditingController filterStartDateController =
|
||||||
|
TextEditingController(text: '');
|
||||||
|
TextEditingController filterEndDateController =
|
||||||
|
TextEditingController(text: '');
|
||||||
|
TextEditingController mealController = TextEditingController(text: '');
|
||||||
|
TextEditingController minMgPerDlController = TextEditingController(text: '');
|
||||||
|
TextEditingController maxMgPerDlController = TextEditingController(text: '');
|
||||||
|
TextEditingController minMmolPerLController = TextEditingController(text: '');
|
||||||
|
TextEditingController maxMmolPerLController = TextEditingController(text: '');
|
||||||
|
TextEditingController mealNameController = TextEditingController(text: '');
|
||||||
|
TextEditingController noteController = TextEditingController(text: '');
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_scrollController.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
filterStartDate = widget.date ?? DateTimeUtils.today();
|
||||||
|
filterEndDate = DateTimeUtils.today();
|
||||||
|
|
||||||
|
filterStartDateController.text = DateTimeUtils.displayDate(filterStartDate);
|
||||||
|
filterEndDateController.text = DateTimeUtils.displayDate(filterEndDate);
|
||||||
|
|
||||||
|
_meals = Meal.getAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return AlertDialog(
|
||||||
|
content: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: DateTimeFormField(
|
||||||
|
date: filterStartDate,
|
||||||
|
label: translate(LocalizationKeys.log_filter_startDate),
|
||||||
|
controller: filterStartDateController,
|
||||||
|
onChanged: (newDate) {
|
||||||
|
if (newDate != null) {
|
||||||
|
filterStartDate =
|
||||||
|
DateTime(newDate.year, newDate.month, newDate.day);
|
||||||
|
filterStartDateController.text =
|
||||||
|
DateTimeUtils.displayDate(filterStartDate);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 5.0),
|
||||||
|
child: DateTimeFormField(
|
||||||
|
date: filterEndDate,
|
||||||
|
label: translate(LocalizationKeys.log_filter_endDate),
|
||||||
|
controller: filterEndDateController,
|
||||||
|
onChanged: (newDate) {
|
||||||
|
if (newDate != null) {
|
||||||
|
filterEndDate = DateTime(
|
||||||
|
newDate.year, newDate.month, newDate.day);
|
||||||
|
filterEndDateController.text =
|
||||||
|
DateTimeUtils.displayDate(filterEndDate);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
children: Settings.glucoseMeasurement ==
|
||||||
|
GlucoseMeasurement.mgPerDl
|
||||||
|
? [
|
||||||
|
Expanded(
|
||||||
|
child: NumberFormField(
|
||||||
|
label: translate(LocalizationKeys.log_filter_minGlucose, args: {
|
||||||
|
"glucoseMeasurement": Settings.glucoseMeasurementSuffix
|
||||||
|
}),
|
||||||
|
controller: minMgPerDlController,
|
||||||
|
onChanged: (value) {
|
||||||
|
if (value != null) {
|
||||||
|
minMgPerDlController.text = value.toString();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 5.0),
|
||||||
|
child: NumberFormField(
|
||||||
|
label: translate(LocalizationKeys.log_filter_maxGlucose, args: {
|
||||||
|
"glucoseMeasurement": Settings.glucoseMeasurementSuffix
|
||||||
|
}),
|
||||||
|
controller: maxMgPerDlController,
|
||||||
|
onChanged: (value) {
|
||||||
|
if (value != null) {
|
||||||
|
maxMgPerDlController.text = value.toString();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
]
|
||||||
|
: [
|
||||||
|
Expanded(
|
||||||
|
child: NumberFormField(
|
||||||
|
label: translate(LocalizationKeys.log_filter_minGlucose, args: {
|
||||||
|
"glucoseMeasurement": Settings.glucoseMeasurementSuffix
|
||||||
|
}),
|
||||||
|
controller: minMmolPerLController,
|
||||||
|
onChanged: (value) {
|
||||||
|
if (value != null) {
|
||||||
|
minMmolPerLController.text = value.toString();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 5.0),
|
||||||
|
child: NumberFormField(
|
||||||
|
label: translate(LocalizationKeys.log_filter_maxGlucose, args: {
|
||||||
|
"glucoseMeasurement": Settings.glucoseMeasurementSuffix
|
||||||
|
}),
|
||||||
|
controller: maxMmolPerLController,
|
||||||
|
onChanged: (value) {
|
||||||
|
if (value != null) {
|
||||||
|
maxMmolPerLController.text = value.toString();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: AutoCompleteDropdownButton<Meal>(
|
||||||
|
controller: mealController,
|
||||||
|
selectedItem: meal,
|
||||||
|
label: translate(LocalizationKeys.log_filter_meal),
|
||||||
|
items: _meals,
|
||||||
|
onChanged: (value) {
|
||||||
|
setState(() {
|
||||||
|
meal = value;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
TextFormField(
|
||||||
|
controller: mealNameController,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
labelText: translate(LocalizationKeys.log_filter_mealNameContains),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
TextFormField(
|
||||||
|
controller: noteController,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
labelText: translate(LocalizationKeys.log_filter_noteContains),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
actions: <Widget>[
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.pop(context),
|
||||||
|
child: Text(translate(LocalizationKeys.general_cancel).toUpperCase()),
|
||||||
|
),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () => widget.onApplyFilter(
|
||||||
|
startDate: filterStartDate,
|
||||||
|
endDate: filterEndDate,
|
||||||
|
minMgPerDl: int.tryParse(minMgPerDlController.text),
|
||||||
|
maxMgPerDl: int.tryParse(maxMgPerDlController.text),
|
||||||
|
minMmolPerL: double.tryParse(minMmolPerLController.text),
|
||||||
|
maxMmolPerL: double.tryParse(maxMmolPerLController.text),
|
||||||
|
mealId: meal?.id,
|
||||||
|
mealName: mealNameController.text,
|
||||||
|
note: noteController.text,
|
||||||
|
),
|
||||||
|
child: Text(translate(LocalizationKeys.general_apply).toUpperCase()),
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
@ -1,3 +1,5 @@
|
|||||||
|
import 'package:diameter/localization_keys.dart';
|
||||||
|
import 'package:diameter/screens/log/log_filter_dialog.dart';
|
||||||
import 'package:diameter/screens/reports/export.dart';
|
import 'package:diameter/screens/reports/export.dart';
|
||||||
import 'package:diameter/utils/dialog_utils.dart';
|
import 'package:diameter/utils/dialog_utils.dart';
|
||||||
import 'package:diameter/models/glucose_target.dart';
|
import 'package:diameter/models/glucose_target.dart';
|
||||||
@ -11,6 +13,9 @@ import 'package:diameter/utils/date_time_utils.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'dart:math' as math;
|
import 'dart:math' as math;
|
||||||
|
|
||||||
|
import 'package:flutter_translate/flutter_translate.dart';
|
||||||
|
|
||||||
|
|
||||||
class LogScreen extends StatefulWidget {
|
class LogScreen extends StatefulWidget {
|
||||||
static const String routeName = '/log';
|
static const String routeName = '/log';
|
||||||
const LogScreen({Key? key}) : super(key: key);
|
const LogScreen({Key? key}) : super(key: key);
|
||||||
@ -65,7 +70,7 @@ class _LogScreenState extends State<LogScreen> {
|
|||||||
|
|
||||||
void onDelete(LogEntry logEntry) {
|
void onDelete(LogEntry logEntry) {
|
||||||
LogEntry.remove(logEntry.id);
|
LogEntry.remove(logEntry.id);
|
||||||
reload(message: 'Log Entry deleted');
|
reload(message: translate(LocalizationKeys.log_deleted));
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleDeleteAction(LogEntry logEntry) async {
|
void handleDeleteAction(LogEntry logEntry) async {
|
||||||
@ -73,7 +78,7 @@ class _LogScreenState extends State<LogScreen> {
|
|||||||
DialogUtils.showConfirmationDialog(
|
DialogUtils.showConfirmationDialog(
|
||||||
context: context,
|
context: context,
|
||||||
onConfirm: () => onDelete(logEntry),
|
onConfirm: () => onDelete(logEntry),
|
||||||
message: 'Are you sure you want to delete this Log Entry?',
|
message: translate(LocalizationKeys.log_confirmDelete),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
onDelete(logEntry);
|
onDelete(logEntry);
|
||||||
@ -90,15 +95,48 @@ class _LogScreenState extends State<LogScreen> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void onChangeFilter(
|
||||||
|
{DateTime? startDate,
|
||||||
|
DateTime? endDate,
|
||||||
|
int? minMgPerDl,
|
||||||
|
int? maxMgPerDl,
|
||||||
|
double? minMmolPerL,
|
||||||
|
double? maxMmolPerL,
|
||||||
|
int? mealId,
|
||||||
|
String? mealName,
|
||||||
|
String? note}) {
|
||||||
|
setState(() {
|
||||||
|
_logEntries = LogEntry.getAllByFilter(
|
||||||
|
startDate: startDate,
|
||||||
|
endDate: endDate,
|
||||||
|
minMgPerDl: minMgPerDl,
|
||||||
|
maxMgPerDl: maxMgPerDl,
|
||||||
|
minMmolPerL: minMmolPerL,
|
||||||
|
maxMmolPerL: maxMmolPerL,
|
||||||
|
mealId: mealId,
|
||||||
|
mealName: mealName,
|
||||||
|
note: note,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: const Text('Log Entries'),
|
title: Text(translate(LocalizationKeys.log_title)),
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: () => onChangeDate(DateTime.now()),
|
onPressed: () => onChangeDate(DateTime.now()),
|
||||||
icon: const Icon(Icons.today)),
|
icon: const Icon(Icons.today)),
|
||||||
|
IconButton(
|
||||||
|
onPressed: () => showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => LogFilterDialog(
|
||||||
|
date: _date,
|
||||||
|
onApplyFilter: onChangeFilter,
|
||||||
|
)),
|
||||||
|
icon: const Icon(Icons.filter_list)),
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: () => showDialog(
|
onPressed: () => showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
@ -297,7 +335,7 @@ class _LogScreenState extends State<LogScreen> {
|
|||||||
? [
|
? [
|
||||||
Text(
|
Text(
|
||||||
bolus.toStringAsPrecision(3)),
|
bolus.toStringAsPrecision(3)),
|
||||||
const Text('U',
|
Text(translate(LocalizationKeys.general_suffixes_units),
|
||||||
textScaleFactor: 0.75),
|
textScaleFactor: 0.75),
|
||||||
]
|
]
|
||||||
: [],
|
: [],
|
||||||
@ -309,8 +347,12 @@ class _LogScreenState extends State<LogScreen> {
|
|||||||
? [
|
? [
|
||||||
Text(
|
Text(
|
||||||
carbs.toStringAsPrecision(3)),
|
carbs.toStringAsPrecision(3)),
|
||||||
Text(
|
Text(translate(
|
||||||
'${Settings.nutritionMeasurementSuffix} carbs',
|
LocalizationKeys.general_suffixes_carbs,
|
||||||
|
args: {
|
||||||
|
"nutritionMeasurementSuffix": Settings.nutritionMeasurementSuffix,
|
||||||
|
}
|
||||||
|
),
|
||||||
textScaleFactor: 0.75),
|
textScaleFactor: 0.75),
|
||||||
]
|
]
|
||||||
: [],
|
: [],
|
||||||
@ -334,9 +376,10 @@ class _LogScreenState extends State<LogScreen> {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: const Center(
|
: Center(
|
||||||
child: Text(
|
child: Text(
|
||||||
'You have not created any Log Entries for this date yet!'),
|
translate(LocalizationKeys.log_empty)
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import 'package:diameter/components/detail.dart';
|
import 'package:diameter/components/detail.dart';
|
||||||
import 'package:diameter/components/forms/boolean_form_field.dart';
|
import 'package:diameter/components/forms/boolean_form_field.dart';
|
||||||
import 'package:diameter/components/forms/number_form_field.dart';
|
import 'package:diameter/components/forms/number_form_field.dart';
|
||||||
|
import 'package:diameter/localization_keys.dart';
|
||||||
import 'package:diameter/utils/dialog_utils.dart';
|
import 'package:diameter/utils/dialog_utils.dart';
|
||||||
import 'package:diameter/components/forms/auto_complete_dropdown_button.dart';
|
import 'package:diameter/components/forms/auto_complete_dropdown_button.dart';
|
||||||
import 'package:diameter/components/forms/form_wrapper.dart';
|
import 'package:diameter/components/forms/form_wrapper.dart';
|
||||||
@ -17,6 +18,7 @@ import 'package:diameter/screens/category/meal_portion_type_detail.dart';
|
|||||||
import 'package:diameter/screens/category/meal_source_detail.dart';
|
import 'package:diameter/screens/category/meal_source_detail.dart';
|
||||||
import 'package:diameter/utils/utils.dart';
|
import 'package:diameter/utils/utils.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_translate/flutter_translate.dart';
|
||||||
|
|
||||||
class MealDetailScreen extends StatefulWidget {
|
class MealDetailScreen extends StatefulWidget {
|
||||||
static const String routeName = '/meal';
|
static const String routeName = '/meal';
|
||||||
@ -195,7 +197,9 @@ class _MealDetailScreenState extends State<MealDetailScreen> {
|
|||||||
meal.carbsRatioAccuracy.target = _carbsRatioAccuracy;
|
meal.carbsRatioAccuracy.target = _carbsRatioAccuracy;
|
||||||
|
|
||||||
Meal.put(meal);
|
Meal.put(meal);
|
||||||
Navigator.pop(context, ['${_isNew ? 'New' : ''} Meal Saved', meal]);
|
Navigator.pop(context, [translate(LocalizationKeys.meal_saved, args: {
|
||||||
|
"status": _isNew ? translate(LocalizationKeys.meal_new) : '',
|
||||||
|
}), meal]);
|
||||||
}
|
}
|
||||||
setState(() {
|
setState(() {
|
||||||
_isSaving = false;
|
_isSaving = false;
|
||||||
@ -340,7 +344,10 @@ class _MealDetailScreenState extends State<MealDetailScreen> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(_isNew ? 'New Meal' : _meal!.value),
|
title: Text(translate(LocalizationKeys.meal_saved, args: {
|
||||||
|
"status": _isNew ? translate(LocalizationKeys.meal_new) : '',
|
||||||
|
"name": _meal?.value,
|
||||||
|
})),
|
||||||
),
|
),
|
||||||
drawer: const Navigation(currentLocation: MealDetailScreen.routeName),
|
drawer: const Navigation(currentLocation: MealDetailScreen.routeName),
|
||||||
body: Scrollbar(
|
body: Scrollbar(
|
||||||
@ -354,12 +361,12 @@ class _MealDetailScreenState extends State<MealDetailScreen> {
|
|||||||
fields: [
|
fields: [
|
||||||
TextFormField(
|
TextFormField(
|
||||||
controller: _valueController,
|
controller: _valueController,
|
||||||
decoration: const InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: 'Name',
|
labelText: translate(LocalizationKeys.meal_fields_name),
|
||||||
),
|
),
|
||||||
validator: (value) {
|
validator: (value) {
|
||||||
if (value!.trim().isEmpty) {
|
if (value!.trim().isEmpty) {
|
||||||
return 'Empty name';
|
return translate(LocalizationKeys.meal_fields_validators_name);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
@ -370,7 +377,7 @@ class _MealDetailScreenState extends State<MealDetailScreen> {
|
|||||||
child: AutoCompleteDropdownButton<MealSource>(
|
child: AutoCompleteDropdownButton<MealSource>(
|
||||||
controller: _mealSourceController,
|
controller: _mealSourceController,
|
||||||
selectedItem: _mealSource,
|
selectedItem: _mealSource,
|
||||||
label: 'Meal Source',
|
label: translate(LocalizationKeys.meal_fields_mealSource),
|
||||||
items: _mealSources,
|
items: _mealSources,
|
||||||
onChanged: onSelectMealSource,
|
onChanged: onSelectMealSource,
|
||||||
),
|
),
|
||||||
@ -400,7 +407,7 @@ class _MealDetailScreenState extends State<MealDetailScreen> {
|
|||||||
child: AutoCompleteDropdownButton<MealPortionType>(
|
child: AutoCompleteDropdownButton<MealPortionType>(
|
||||||
controller: _mealPortionTypeController,
|
controller: _mealPortionTypeController,
|
||||||
selectedItem: _mealPortionType,
|
selectedItem: _mealPortionType,
|
||||||
label: 'Meal Portion Type',
|
label: translate(LocalizationKeys.meal_fields_mealPortionType),
|
||||||
items: _mealPortionTypes,
|
items: _mealPortionTypes,
|
||||||
onChanged: updateMealPortionType,
|
onChanged: updateMealPortionType,
|
||||||
),
|
),
|
||||||
@ -429,7 +436,7 @@ class _MealDetailScreenState extends State<MealDetailScreen> {
|
|||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: NumberFormField(
|
child: NumberFormField(
|
||||||
label: 'Carbs ratio',
|
label: translate(LocalizationKeys.meal_fields_carbsRatio),
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
controller: _carbsRatioController,
|
controller: _carbsRatioController,
|
||||||
showSteppers: false,
|
showSteppers: false,
|
||||||
@ -445,7 +452,7 @@ class _MealDetailScreenState extends State<MealDetailScreen> {
|
|||||||
const SizedBox(width: 10),
|
const SizedBox(width: 10),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: NumberFormField(
|
child: NumberFormField(
|
||||||
label: 'Portion size',
|
label: translate(LocalizationKeys.meal_fields_portionSize),
|
||||||
suffix: Settings.nutritionMeasurementSuffix,
|
suffix: Settings.nutritionMeasurementSuffix,
|
||||||
controller: _portionSizeController,
|
controller: _portionSizeController,
|
||||||
showSteppers: false,
|
showSteppers: false,
|
||||||
@ -461,7 +468,7 @@ class _MealDetailScreenState extends State<MealDetailScreen> {
|
|||||||
const SizedBox(width: 10),
|
const SizedBox(width: 10),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: NumberFormField(
|
child: NumberFormField(
|
||||||
label: 'Carbs per portion',
|
label: translate(LocalizationKeys.meal_fields_carbsPerPortion),
|
||||||
suffix: Settings.nutritionMeasurementSuffix,
|
suffix: Settings.nutritionMeasurementSuffix,
|
||||||
controller: _carbsPerPortionController,
|
controller: _carbsPerPortionController,
|
||||||
showSteppers: false,
|
showSteppers: false,
|
||||||
@ -479,7 +486,7 @@ class _MealDetailScreenState extends State<MealDetailScreen> {
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: BooleanFormField(
|
child: BooleanFormField(
|
||||||
value: _setManually,
|
value: _setManually,
|
||||||
label: 'set carbs ratio manually',
|
label: translate(LocalizationKeys.meal_fields_setManually),
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_setManually = value;
|
_setManually = value;
|
||||||
@ -490,8 +497,8 @@ class _MealDetailScreenState extends State<MealDetailScreen> {
|
|||||||
),
|
),
|
||||||
TextFormField(
|
TextFormField(
|
||||||
controller: _notesController,
|
controller: _notesController,
|
||||||
decoration: const InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: 'Notes',
|
labelText: translate(LocalizationKeys.meal_fields_notes),
|
||||||
),
|
),
|
||||||
keyboardType: TextInputType.multiline,
|
keyboardType: TextInputType.multiline,
|
||||||
minLines: 2,
|
minLines: 2,
|
||||||
@ -503,7 +510,7 @@ class _MealDetailScreenState extends State<MealDetailScreen> {
|
|||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'BOLUS DELAY',
|
translate(LocalizationKeys.meal_fields_delay_title).toUpperCase(),
|
||||||
style: Theme.of(context).textTheme.subtitle2,
|
style: Theme.of(context).textTheme.subtitle2,
|
||||||
),
|
),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
@ -514,9 +521,9 @@ class _MealDetailScreenState extends State<MealDetailScreen> {
|
|||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
decoration: const InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: 'Duration',
|
labelText: translate(LocalizationKeys.meal_fields_delay_duration),
|
||||||
suffixText: ' min',
|
suffixText: translate(LocalizationKeys.general_suffixes_mins),
|
||||||
),
|
),
|
||||||
controller: _delayedBolusDurationController,
|
controller: _delayedBolusDurationController,
|
||||||
onChanged: (value) => setState(() {}),
|
onChanged: (value) => setState(() {}),
|
||||||
@ -553,7 +560,7 @@ class _MealDetailScreenState extends State<MealDetailScreen> {
|
|||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Text(
|
child: Text(
|
||||||
'ADDITIONAL FIELDS',
|
translate(LocalizationKeys.meal_fields_additional_title).toUpperCase(),
|
||||||
style: Theme.of(context).textTheme.subtitle2,
|
style: Theme.of(context).textTheme.subtitle2,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -574,7 +581,7 @@ class _MealDetailScreenState extends State<MealDetailScreen> {
|
|||||||
AutoCompleteDropdownButton<MealCategory>(
|
AutoCompleteDropdownButton<MealCategory>(
|
||||||
controller: _mealCategoryController,
|
controller: _mealCategoryController,
|
||||||
selectedItem: _mealCategory,
|
selectedItem: _mealCategory,
|
||||||
label: 'Meal Category',
|
label: translate(LocalizationKeys.meal_fields_additional_mealCategory),
|
||||||
items: _mealCategories,
|
items: _mealCategories,
|
||||||
onChanged: updateMealCategory,
|
onChanged: updateMealCategory,
|
||||||
),
|
),
|
||||||
@ -609,7 +616,7 @@ class _MealDetailScreenState extends State<MealDetailScreen> {
|
|||||||
AutoCompleteDropdownButton<Accuracy>(
|
AutoCompleteDropdownButton<Accuracy>(
|
||||||
controller: _portionSizeAccuracyController,
|
controller: _portionSizeAccuracyController,
|
||||||
selectedItem: _portionSizeAccuracy,
|
selectedItem: _portionSizeAccuracy,
|
||||||
label: 'Portion Size Accuracy',
|
label: translate(LocalizationKeys.meal_fields_additional_portionSizeAccuracy),
|
||||||
items: _portionSizeAccuracies,
|
items: _portionSizeAccuracies,
|
||||||
onChanged: updatePortionSizeAccuracy,
|
onChanged: updatePortionSizeAccuracy,
|
||||||
),
|
),
|
||||||
@ -645,7 +652,7 @@ class _MealDetailScreenState extends State<MealDetailScreen> {
|
|||||||
AutoCompleteDropdownButton<Accuracy>(
|
AutoCompleteDropdownButton<Accuracy>(
|
||||||
controller: _carbsRatioAccuracyController,
|
controller: _carbsRatioAccuracyController,
|
||||||
selectedItem: _carbsRatioAccuracy,
|
selectedItem: _carbsRatioAccuracy,
|
||||||
label: 'Carbs Ratio Accuracy',
|
label: translate(LocalizationKeys.meal_fields_additional_carbsRatioAccuracy),
|
||||||
items: _carbsRatioAccuracies,
|
items: _carbsRatioAccuracies,
|
||||||
onChanged: updateCarbsRatioAccuracy,
|
onChanged: updateCarbsRatioAccuracy,
|
||||||
),
|
),
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
|
import 'package:diameter/localization_keys.dart';
|
||||||
import 'package:diameter/utils/dialog_utils.dart';
|
import 'package:diameter/utils/dialog_utils.dart';
|
||||||
import 'package:diameter/models/meal.dart';
|
import 'package:diameter/models/meal.dart';
|
||||||
import 'package:diameter/models/settings.dart';
|
import 'package:diameter/models/settings.dart';
|
||||||
import 'package:diameter/navigation.dart';
|
import 'package:diameter/navigation.dart';
|
||||||
import 'package:diameter/screens/meal/meal_detail.dart';
|
import 'package:diameter/screens/meal/meal_detail.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_translate/flutter_translate.dart';
|
||||||
|
|
||||||
class MealListScreen extends StatefulWidget {
|
class MealListScreen extends StatefulWidget {
|
||||||
static const String routeName = '/meals';
|
static const String routeName = '/meals';
|
||||||
@ -50,7 +52,7 @@ class _MealListScreenState extends State<MealListScreen> {
|
|||||||
|
|
||||||
void onDelete(Meal meal) {
|
void onDelete(Meal meal) {
|
||||||
Meal.remove(meal.id);
|
Meal.remove(meal.id);
|
||||||
reload(message: 'Meal deleted');
|
reload(message: translate(LocalizationKeys.meal_deleted));
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleDeleteAction(Meal meal) async {
|
void handleDeleteAction(Meal meal) async {
|
||||||
@ -58,7 +60,7 @@ class _MealListScreenState extends State<MealListScreen> {
|
|||||||
DialogUtils.showConfirmationDialog(
|
DialogUtils.showConfirmationDialog(
|
||||||
context: context,
|
context: context,
|
||||||
onConfirm: () => onDelete(meal),
|
onConfirm: () => onDelete(meal),
|
||||||
message: 'Are you sure you want to delete this Meal?',
|
message: translate(LocalizationKeys.meal_confirmDelete),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
onDelete(meal);
|
onDelete(meal);
|
||||||
@ -68,7 +70,11 @@ class _MealListScreenState extends State<MealListScreen> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(title: const Text('Meals'), actions: <Widget>[
|
appBar: AppBar(
|
||||||
|
title: Text(
|
||||||
|
translate(LocalizationKeys.meal_title)
|
||||||
|
),
|
||||||
|
actions: <Widget>[
|
||||||
IconButton(onPressed: reload, icon: const Icon(Icons.refresh))
|
IconButton(onPressed: reload, icon: const Icon(Icons.refresh))
|
||||||
]),
|
]),
|
||||||
drawer: const Navigation(currentLocation: MealListScreen.routeName),
|
drawer: const Navigation(currentLocation: MealListScreen.routeName),
|
||||||
@ -84,7 +90,7 @@ class _MealListScreenState extends State<MealListScreen> {
|
|||||||
itemCount: _meals.length,
|
itemCount: _meals.length,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
final meal = _meals[index];
|
final meal = _meals[index];
|
||||||
String portionType = meal.mealPortionType.hasValue ? ' per ${meal.mealPortionType.target!.value}' : '';
|
String portionType = meal.mealPortionType.hasValue ? ' ${translate(LocalizationKeys.general_per)} ${meal.mealPortionType.target!.value}' : '';
|
||||||
return Card(
|
return Card(
|
||||||
child: ListTile(
|
child: ListTile(
|
||||||
isThreeLine: true,
|
isThreeLine: true,
|
||||||
@ -118,7 +124,7 @@ class _MealListScreenState extends State<MealListScreen> {
|
|||||||
? [
|
? [
|
||||||
Text(meal.carbsPerPortion!.toStringAsPrecision(3)),
|
Text(meal.carbsPerPortion!.toStringAsPrecision(3)),
|
||||||
Text(
|
Text(
|
||||||
'${Settings.nutritionMeasurementSuffix} carbs',
|
'${Settings.nutritionMeasurementSuffix} ${translate(LocalizationKeys.general_suffixes_carbs)}',
|
||||||
textScaleFactor: 0.75),
|
textScaleFactor: 0.75),
|
||||||
]
|
]
|
||||||
: [],
|
: [],
|
||||||
@ -166,8 +172,8 @@ class _MealListScreenState extends State<MealListScreen> {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
): const Center(
|
): Center(
|
||||||
child: Text('You have not created any Meals yet!'),
|
child: Text(translate(LocalizationKeys.meal_empty)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import 'package:charts_flutter/flutter.dart' as charts;
|
import 'package:charts_flutter/flutter.dart' as charts;
|
||||||
|
import 'package:diameter/localization_keys.dart';
|
||||||
import 'package:diameter/models/basal.dart';
|
import 'package:diameter/models/basal.dart';
|
||||||
import 'package:diameter/models/glucose_target.dart';
|
import 'package:diameter/models/glucose_target.dart';
|
||||||
import 'package:diameter/models/log_bolus.dart';
|
import 'package:diameter/models/log_bolus.dart';
|
||||||
@ -9,6 +10,7 @@ import 'package:diameter/models/settings.dart';
|
|||||||
import 'package:diameter/navigation.dart';
|
import 'package:diameter/navigation.dart';
|
||||||
import 'package:diameter/utils/date_time_utils.dart';
|
import 'package:diameter/utils/date_time_utils.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_translate/flutter_translate.dart';
|
||||||
|
|
||||||
charts.TimeSeriesChart generateChart(
|
charts.TimeSeriesChart generateChart(
|
||||||
DateTime date,
|
DateTime date,
|
||||||
@ -48,7 +50,7 @@ charts.TimeSeriesChart generateChart(
|
|||||||
return charts.TimeSeriesChart(
|
return charts.TimeSeriesChart(
|
||||||
[
|
[
|
||||||
charts.Series<LogEntry, DateTime>(
|
charts.Series<LogEntry, DateTime>(
|
||||||
id: 'Glucose',
|
id: translate(LocalizationKeys.reports_ids_glucose),
|
||||||
colorFn: (LogEntry entry, _) => charts.Color.black,
|
colorFn: (LogEntry entry, _) => charts.Color.black,
|
||||||
domainFn: (LogEntry entry, _) => entry.time,
|
domainFn: (LogEntry entry, _) => entry.time,
|
||||||
measureFn: (LogEntry entry, _) =>
|
measureFn: (LogEntry entry, _) =>
|
||||||
@ -58,7 +60,7 @@ charts.TimeSeriesChart generateChart(
|
|||||||
data: logEntries,
|
data: logEntries,
|
||||||
)..setAttribute(charts.rendererIdKey, 'glucoseRenderer'),
|
)..setAttribute(charts.rendererIdKey, 'glucoseRenderer'),
|
||||||
charts.Series<LogEntry, DateTime>(
|
charts.Series<LogEntry, DateTime>(
|
||||||
id: 'Carbohydrates',
|
id: translate(LocalizationKeys.reports_ids_carbs),
|
||||||
colorFn: (LogEntry entry, _) =>
|
colorFn: (LogEntry entry, _) =>
|
||||||
charts.MaterialPalette.yellow.shadeDefault,
|
charts.MaterialPalette.yellow.shadeDefault,
|
||||||
domainFn: (LogEntry entry, _) => entry.time,
|
domainFn: (LogEntry entry, _) => entry.time,
|
||||||
@ -67,7 +69,7 @@ charts.TimeSeriesChart generateChart(
|
|||||||
data: showMeals ? logEntries : [],
|
data: showMeals ? logEntries : [],
|
||||||
)..setAttribute(charts.rendererIdKey, 'carbsRenderer'),
|
)..setAttribute(charts.rendererIdKey, 'carbsRenderer'),
|
||||||
charts.Series<Basal, DateTime>(
|
charts.Series<Basal, DateTime>(
|
||||||
id: 'Basal',
|
id: translate(LocalizationKeys.reports_ids_basal),
|
||||||
colorFn: (Basal basal, _) => charts.Color.black.lighter,
|
colorFn: (Basal basal, _) => charts.Color.black.lighter,
|
||||||
domainFn: (Basal basal, _) => basal.startTime,
|
domainFn: (Basal basal, _) => basal.startTime,
|
||||||
measureFn: (Basal basal, _) => basal.units,
|
measureFn: (Basal basal, _) => basal.units,
|
||||||
@ -77,7 +79,7 @@ charts.TimeSeriesChart generateChart(
|
|||||||
charts.measureAxisIdKey, charts.Axis.secondaryMeasureAxisId)
|
charts.measureAxisIdKey, charts.Axis.secondaryMeasureAxisId)
|
||||||
..setAttribute(charts.rendererIdKey, 'basalRenderer'),
|
..setAttribute(charts.rendererIdKey, 'basalRenderer'),
|
||||||
charts.Series<LogEntry, DateTime>(
|
charts.Series<LogEntry, DateTime>(
|
||||||
id: 'Bolus',
|
id: translate(LocalizationKeys.reports_ids_bolus),
|
||||||
colorFn: (LogEntry entry, _) =>
|
colorFn: (LogEntry entry, _) =>
|
||||||
charts.MaterialPalette.blue.shadeDefault,
|
charts.MaterialPalette.blue.shadeDefault,
|
||||||
domainFn: (LogEntry entry, _) => entry.time,
|
domainFn: (LogEntry entry, _) => entry.time,
|
||||||
@ -260,7 +262,7 @@ class _DailyChartState extends State<DailyChart> {
|
|||||||
value: showChart,
|
value: showChart,
|
||||||
onChanged: (_) =>
|
onChanged: (_) =>
|
||||||
setState(() => showChart = !showChart),
|
setState(() => showChart = !showChart),
|
||||||
title: const Text('show Chart'),
|
title: Text(translate(LocalizationKeys.reports_dailyCharts_showChart)),
|
||||||
controlAffinity: ListTileControlAffinity.leading,
|
controlAffinity: ListTileControlAffinity.leading,
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
@ -271,7 +273,7 @@ class _DailyChartState extends State<DailyChart> {
|
|||||||
? (_) =>
|
? (_) =>
|
||||||
setState(() => showBolus = !showBolus)
|
setState(() => showBolus = !showBolus)
|
||||||
: null,
|
: null,
|
||||||
title: const Text('show Bolus'),
|
title: Text(translate(LocalizationKeys.reports_dailyCharts_showBolus)),
|
||||||
controlAffinity:
|
controlAffinity:
|
||||||
ListTileControlAffinity.leading,
|
ListTileControlAffinity.leading,
|
||||||
),
|
),
|
||||||
@ -284,7 +286,7 @@ class _DailyChartState extends State<DailyChart> {
|
|||||||
? (_) =>
|
? (_) =>
|
||||||
setState(() => showBasal = !showBasal)
|
setState(() => showBasal = !showBasal)
|
||||||
: null,
|
: null,
|
||||||
title: const Text('show Basal'),
|
title: Text(translate(LocalizationKeys.reports_dailyCharts_showBasal)),
|
||||||
controlAffinity:
|
controlAffinity:
|
||||||
ListTileControlAffinity.leading,
|
ListTileControlAffinity.leading,
|
||||||
),
|
),
|
||||||
@ -297,7 +299,7 @@ class _DailyChartState extends State<DailyChart> {
|
|||||||
? (_) =>
|
? (_) =>
|
||||||
setState(() => showMeals = !showMeals)
|
setState(() => showMeals = !showMeals)
|
||||||
: null,
|
: null,
|
||||||
title: const Text('show Meals'),
|
title: Text(translate(LocalizationKeys.reports_dailyCharts_showMeals)),
|
||||||
controlAffinity:
|
controlAffinity:
|
||||||
ListTileControlAffinity.leading,
|
ListTileControlAffinity.leading,
|
||||||
),
|
),
|
||||||
@ -307,7 +309,7 @@ class _DailyChartState extends State<DailyChart> {
|
|||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: () => Navigator.pop(context),
|
onPressed: () => Navigator.pop(context),
|
||||||
child: const Text('CLOSE'),
|
child: Text(translate(LocalizationKeys.general_close).toUpperCase()),
|
||||||
),
|
),
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
@ -378,9 +380,8 @@ class _DailyChartState extends State<DailyChart> {
|
|||||||
child: logEntries.isNotEmpty
|
child: logEntries.isNotEmpty
|
||||||
? generateChart(date, logEntries, logEvents, targets, showMeals,
|
? generateChart(date, logEntries, logEvents, targets, showMeals,
|
||||||
showBasal, showBolus)
|
showBasal, showBolus)
|
||||||
: const Center(
|
: Center(
|
||||||
child: Text(
|
child: Text(translate(LocalizationKeys.reports_dailyCharts_empty)),
|
||||||
'You have not created any Log Entries for this date yet!'),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -2,6 +2,7 @@ import 'dart:io';
|
|||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
import 'package:diameter/components/forms/date_time_form_field.dart';
|
import 'package:diameter/components/forms/date_time_form_field.dart';
|
||||||
|
import 'package:diameter/localization_keys.dart';
|
||||||
import 'package:diameter/models/glucose_target.dart';
|
import 'package:diameter/models/glucose_target.dart';
|
||||||
import 'package:diameter/models/log_bolus.dart';
|
import 'package:diameter/models/log_bolus.dart';
|
||||||
import 'package:diameter/models/log_entry.dart';
|
import 'package:diameter/models/log_entry.dart';
|
||||||
@ -12,6 +13,7 @@ import 'package:diameter/screens/reports/daily_chart.dart';
|
|||||||
import 'package:diameter/utils/date_time_utils.dart';
|
import 'package:diameter/utils/date_time_utils.dart';
|
||||||
import 'package:diameter/utils/utils.dart';
|
import 'package:diameter/utils/utils.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_translate/flutter_translate.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
import 'package:open_file/open_file.dart';
|
import 'package:open_file/open_file.dart';
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
@ -121,7 +123,7 @@ class _ExportDialogState extends State<ExportDialog> {
|
|||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: RadioListTile(
|
child: RadioListTile(
|
||||||
title: const Text('single date'),
|
title: Text(translate(LocalizationKeys.reports_export_singleDate)),
|
||||||
groupValue: exportRange,
|
groupValue: exportRange,
|
||||||
value: false,
|
value: false,
|
||||||
onChanged: (_) {
|
onChanged: (_) {
|
||||||
@ -132,7 +134,7 @@ class _ExportDialogState extends State<ExportDialog> {
|
|||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: RadioListTile(
|
child: RadioListTile(
|
||||||
title: const Text('range'),
|
title: Text(translate(LocalizationKeys.reports_export_range)),
|
||||||
groupValue: exportRange,
|
groupValue: exportRange,
|
||||||
value: true,
|
value: true,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
@ -148,7 +150,7 @@ class _ExportDialogState extends State<ExportDialog> {
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: DateTimeFormField(
|
child: DateTimeFormField(
|
||||||
date: exportStartDate,
|
date: exportStartDate,
|
||||||
label: 'Date',
|
label: translate(LocalizationKeys.reports_export_date),
|
||||||
controller: exportStartDateController,
|
controller: exportStartDateController,
|
||||||
onChanged: (newDate) {
|
onChanged: (newDate) {
|
||||||
if (newDate != null) {
|
if (newDate != null) {
|
||||||
@ -166,7 +168,7 @@ class _ExportDialogState extends State<ExportDialog> {
|
|||||||
padding: const EdgeInsets.only(left: 5.0),
|
padding: const EdgeInsets.only(left: 5.0),
|
||||||
child: DateTimeFormField(
|
child: DateTimeFormField(
|
||||||
date: exportEndDate,
|
date: exportEndDate,
|
||||||
label: 'End Date',
|
label: translate(LocalizationKeys.reports_export_endDate),
|
||||||
controller: exportEndDateController,
|
controller: exportEndDateController,
|
||||||
onChanged: (newDate) {
|
onChanged: (newDate) {
|
||||||
if (newDate != null) {
|
if (newDate != null) {
|
||||||
@ -185,7 +187,7 @@ class _ExportDialogState extends State<ExportDialog> {
|
|||||||
CheckboxListTile(
|
CheckboxListTile(
|
||||||
value: showChart,
|
value: showChart,
|
||||||
onChanged: (_) => setState(() => showChart = !showChart),
|
onChanged: (_) => setState(() => showChart = !showChart),
|
||||||
title: const Text('show Chart'),
|
title: Text(translate(LocalizationKeys.reports_export_showChart)),
|
||||||
controlAffinity: ListTileControlAffinity.leading,
|
controlAffinity: ListTileControlAffinity.leading,
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
@ -195,7 +197,7 @@ class _ExportDialogState extends State<ExportDialog> {
|
|||||||
onChanged: showChart
|
onChanged: showChart
|
||||||
? (_) => setState(() => showBolus = !showBolus)
|
? (_) => setState(() => showBolus = !showBolus)
|
||||||
: null,
|
: null,
|
||||||
title: const Text('show Bolus'),
|
title: Text(translate(LocalizationKeys.reports_export_showBolus)),
|
||||||
controlAffinity: ListTileControlAffinity.leading,
|
controlAffinity: ListTileControlAffinity.leading,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -206,7 +208,7 @@ class _ExportDialogState extends State<ExportDialog> {
|
|||||||
onChanged: showChart
|
onChanged: showChart
|
||||||
? (_) => setState(() => showBasal = !showBasal)
|
? (_) => setState(() => showBasal = !showBasal)
|
||||||
: null,
|
: null,
|
||||||
title: const Text('show Basal'),
|
title: Text(translate(LocalizationKeys.reports_export_showBasal)),
|
||||||
controlAffinity: ListTileControlAffinity.leading,
|
controlAffinity: ListTileControlAffinity.leading,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -217,14 +219,14 @@ class _ExportDialogState extends State<ExportDialog> {
|
|||||||
onChanged: showChart
|
onChanged: showChart
|
||||||
? (_) => setState(() => showMeals = !showMeals)
|
? (_) => setState(() => showMeals = !showMeals)
|
||||||
: null,
|
: null,
|
||||||
title: const Text('show Meals'),
|
title: Text(translate(LocalizationKeys.reports_export_showMeals)),
|
||||||
controlAffinity: ListTileControlAffinity.leading,
|
controlAffinity: ListTileControlAffinity.leading,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
CheckboxListTile(
|
CheckboxListTile(
|
||||||
value: showTable,
|
value: showTable,
|
||||||
onChanged: (_) => setState(() => showTable = !showTable),
|
onChanged: (_) => setState(() => showTable = !showTable),
|
||||||
title: const Text('show Table'),
|
title: Text(translate(LocalizationKeys.reports_export_showTable)),
|
||||||
controlAffinity: ListTileControlAffinity.leading,
|
controlAffinity: ListTileControlAffinity.leading,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -232,13 +234,13 @@ class _ExportDialogState extends State<ExportDialog> {
|
|||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.pop(context),
|
onPressed: () => Navigator.pop(context),
|
||||||
child: const Text('CANCEL'),
|
child: Text(translate(LocalizationKeys.general_cancel).toUpperCase()),
|
||||||
),
|
),
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: !_isSaving && (showChart || showTable)
|
onPressed: !_isSaving && (showChart || showTable)
|
||||||
? () => onExport(context)
|
? () => onExport(context)
|
||||||
: null,
|
: null,
|
||||||
child: const Text('EXPORT'),
|
child: Text(translate(LocalizationKeys.reports_export_export).toUpperCase()),
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@ -273,15 +275,14 @@ pw.Table generateTable(List<LogEntry> logEntries) {
|
|||||||
const small = pw.TextStyle(fontSize: 8.0);
|
const small = pw.TextStyle(fontSize: 8.0);
|
||||||
|
|
||||||
final tableHeaders = [
|
final tableHeaders = [
|
||||||
'Time',
|
translate(LocalizationKeys.reports_export_tableHeaders_time),
|
||||||
'Glucose',
|
translate(LocalizationKeys.reports_export_tableHeaders_glucose),
|
||||||
'Bolus',
|
translate(LocalizationKeys.reports_export_tableHeaders_notes),
|
||||||
'Notes',
|
translate(LocalizationKeys.reports_export_tableHeaders_meals),
|
||||||
'Meals',
|
translate(LocalizationKeys.reports_export_tableHeaders_portionSize),
|
||||||
'Portion Size',
|
translate(LocalizationKeys.reports_export_tableHeaders_carbs),
|
||||||
'Carbohydrates',
|
translate(LocalizationKeys.reports_export_tableHeaders_mealBolus),
|
||||||
'Meal Bolus',
|
translate(LocalizationKeys.reports_export_tableHeaders_mealNotes),
|
||||||
'Meal Notes',
|
|
||||||
];
|
];
|
||||||
|
|
||||||
final List<pw.TableRow> data = logEntries.map((logEntry) {
|
final List<pw.TableRow> data = logEntries.map((logEntry) {
|
||||||
@ -304,7 +305,9 @@ pw.Table generateTable(List<LogEntry> logEntries) {
|
|||||||
for (var bolus in boli
|
for (var bolus in boli
|
||||||
.where((bolus) => bolus.meal.targetId == meal.id)
|
.where((bolus) => bolus.meal.targetId == meal.id)
|
||||||
.toList())
|
.toList())
|
||||||
'${bolus.units} U${bolus.delay != null ? ' (over ${bolus.delay} min)' : ''}'
|
'${bolus.units} ${translate(LocalizationKeys.general_suffixes_units)} ${bolus.delay != null ? translate(LocalizationKeys.log_detail_tabs_bolus_delayedBy, args: {
|
||||||
|
"delay": '${bolus.delay} ${translate(LocalizationKeys.general_suffixes_mins)}'
|
||||||
|
}) : ''}'
|
||||||
].join(' + '),
|
].join(' + '),
|
||||||
notes: meal.notes ?? '',
|
notes: meal.notes ?? '',
|
||||||
))
|
))
|
||||||
@ -320,7 +323,9 @@ pw.Table generateTable(List<LogEntry> logEntries) {
|
|||||||
bolus.meal.targetId != 0 &&
|
bolus.meal.targetId != 0 &&
|
||||||
!meals.any((meal) => meal.id == bolus.meal.targetId))
|
!meals.any((meal) => meal.id == bolus.meal.targetId))
|
||||||
.map((bolus) =>
|
.map((bolus) =>
|
||||||
'${bolus.units} U${bolus.delay != null ? ' (over ${bolus.delay} min)' : ''}${bolus.meal.target != null ? ' (for ${bolus.meal.target!.value})' : ''}')
|
'${bolus.units} ${translate(LocalizationKeys.general_suffixes_units)} ${bolus.delay != null ? translate(LocalizationKeys.log_detail_tabs_bolus_delayedBy, args: {
|
||||||
|
"delay": '${bolus.delay} ${translate(LocalizationKeys.general_suffixes_mins)}'
|
||||||
|
}) : ''}')
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
return pw.TableRow(
|
return pw.TableRow(
|
||||||
@ -358,7 +363,7 @@ pw.Table generateTable(List<LogEntry> logEntries) {
|
|||||||
),
|
),
|
||||||
// Bolus
|
// Bolus
|
||||||
pw.Text(
|
pw.Text(
|
||||||
[for (var bolus in glucoseBoli) '${bolus.units} U'].join(' + ')),
|
[for (var bolus in glucoseBoli) '${bolus.units} ${translate(LocalizationKeys.general_suffixes_units)}'].join(' + ')),
|
||||||
// Notes
|
// Notes
|
||||||
pw.Text(logEntry.notes ?? '', style: small),
|
pw.Text(logEntry.notes ?? '', style: small),
|
||||||
// Meals
|
// Meals
|
||||||
@ -449,7 +454,7 @@ Future<Uint8List> generateLogReport(
|
|||||||
return pw.Column(
|
return pw.Column(
|
||||||
children: [
|
children: [
|
||||||
pw.Text(
|
pw.Text(
|
||||||
'LOG REPORT',
|
translate(LocalizationKeys.reports_export_title).toUpperCase(),
|
||||||
style: pw.TextStyle(
|
style: pw.TextStyle(
|
||||||
fontWeight: pw.FontWeight.bold,
|
fontWeight: pw.FontWeight.bold,
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
|
import 'package:diameter/localization_keys.dart';
|
||||||
import 'package:diameter/navigation.dart';
|
import 'package:diameter/navigation.dart';
|
||||||
import 'package:diameter/screens/reports/export.dart';
|
import 'package:diameter/screens/reports/export.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_translate/flutter_translate.dart';
|
||||||
|
|
||||||
class ReportsOverviewScreen extends StatefulWidget {
|
class ReportsOverviewScreen extends StatefulWidget {
|
||||||
static const String routeName = '/reports';
|
static const String routeName = '/reports';
|
||||||
@ -23,7 +25,7 @@ class _ReportsOverviewScreenState extends State<ReportsOverviewScreen> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: const Text('Reports'),
|
title: Text(translate(LocalizationKeys.reports_title)),
|
||||||
),
|
),
|
||||||
drawer:
|
drawer:
|
||||||
const Navigation(currentLocation: ReportsOverviewScreen.routeName),
|
const Navigation(currentLocation: ReportsOverviewScreen.routeName),
|
||||||
@ -47,7 +49,7 @@ class _ReportsOverviewScreenState extends State<ReportsOverviewScreen> {
|
|||||||
child: Icon(Icons.today, size: 50, color: Theme.of(context).textTheme.subtitle2?.color),
|
child: Icon(Icons.today, size: 50, color: Theme.of(context).textTheme.subtitle2?.color),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
'DAILY REPORT',
|
translate(LocalizationKeys.reports_sections_dailyReport).toUpperCase(),
|
||||||
style: Theme.of(context).textTheme.subtitle2,
|
style: Theme.of(context).textTheme.subtitle2,
|
||||||
textAlign: TextAlign.center
|
textAlign: TextAlign.center
|
||||||
),
|
),
|
||||||
@ -72,7 +74,7 @@ class _ReportsOverviewScreenState extends State<ReportsOverviewScreen> {
|
|||||||
child: Icon(Icons.today, size: 50, color: Theme.of(context).textTheme.subtitle2?.color),
|
child: Icon(Icons.today, size: 50, color: Theme.of(context).textTheme.subtitle2?.color),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
'PDF REPORT',
|
translate(LocalizationKeys.reports_sections_pdfReport).toUpperCase(),
|
||||||
style: Theme.of(context).textTheme.subtitle2,
|
style: Theme.of(context).textTheme.subtitle2,
|
||||||
textAlign: TextAlign.center
|
textAlign: TextAlign.center
|
||||||
),
|
),
|
||||||
|
@ -2,9 +2,9 @@ import 'package:diameter/components/detail.dart';
|
|||||||
import 'package:diameter/utils/dialog_utils.dart';
|
import 'package:diameter/utils/dialog_utils.dart';
|
||||||
import 'package:diameter/components/forms/auto_complete_dropdown_button.dart';
|
import 'package:diameter/components/forms/auto_complete_dropdown_button.dart';
|
||||||
import 'package:diameter/components/forms/form_wrapper.dart';
|
import 'package:diameter/components/forms/form_wrapper.dart';
|
||||||
import 'package:diameter/models/ingredient.dart';
|
import 'package:diameter/models/x_ingredient.dart';
|
||||||
import 'package:diameter/models/meal.dart';
|
import 'package:diameter/models/meal.dart';
|
||||||
import 'package:diameter/models/recipe.dart';
|
import 'package:diameter/models/x_recipe.dart';
|
||||||
import 'package:diameter/models/settings.dart';
|
import 'package:diameter/models/settings.dart';
|
||||||
import 'package:diameter/navigation.dart';
|
import 'package:diameter/navigation.dart';
|
||||||
import 'package:diameter/screens/meal/meal_detail.dart';
|
import 'package:diameter/screens/meal/meal_detail.dart';
|
@ -1,9 +1,9 @@
|
|||||||
|
import 'package:diameter/screens/x_recipe/recipe_detail.dart';
|
||||||
import 'package:diameter/utils/dialog_utils.dart';
|
import 'package:diameter/utils/dialog_utils.dart';
|
||||||
import 'package:diameter/models/ingredient.dart';
|
import 'package:diameter/models/x_ingredient.dart';
|
||||||
import 'package:diameter/models/recipe.dart';
|
import 'package:diameter/models/x_recipe.dart';
|
||||||
import 'package:diameter/models/settings.dart';
|
import 'package:diameter/models/settings.dart';
|
||||||
import 'package:diameter/navigation.dart';
|
import 'package:diameter/navigation.dart';
|
||||||
import 'package:diameter/screens/recipe/recipe_detail.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class RecipeListScreen extends StatefulWidget {
|
class RecipeListScreen extends StatefulWidget {
|
@ -1,11 +1,13 @@
|
|||||||
import 'package:diameter/components/forms/boolean_form_field.dart';
|
import 'package:diameter/components/forms/boolean_form_field.dart';
|
||||||
import 'package:diameter/components/forms/number_form_field.dart';
|
import 'package:diameter/components/forms/number_form_field.dart';
|
||||||
|
import 'package:diameter/localization_keys.dart';
|
||||||
import 'package:diameter/utils/dialog_utils.dart';
|
import 'package:diameter/utils/dialog_utils.dart';
|
||||||
import 'package:diameter/components/forms/auto_complete_dropdown_button.dart';
|
import 'package:diameter/components/forms/auto_complete_dropdown_button.dart';
|
||||||
import 'package:diameter/models/settings.dart';
|
import 'package:diameter/models/settings.dart';
|
||||||
import 'package:diameter/navigation.dart';
|
import 'package:diameter/navigation.dart';
|
||||||
import 'package:diameter/utils/utils.dart';
|
import 'package:diameter/utils/utils.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_translate/flutter_translate.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
|
|
||||||
class SettingsScreen extends StatefulWidget {
|
class SettingsScreen extends StatefulWidget {
|
||||||
@ -152,19 +154,19 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
showConfirmationDialogOnDelete: _showConfirmationDialogOnDelete,
|
showConfirmationDialogOnDelete: _showConfirmationDialogOnDelete,
|
||||||
showConfirmationDialogOnStopEvent: _showConfirmationDialogOnStopEvent,
|
showConfirmationDialogOnStopEvent: _showConfirmationDialogOnStopEvent,
|
||||||
));
|
));
|
||||||
reload(message: 'Settings updated');
|
reload(message: translate(LocalizationKeys.settings_updated));
|
||||||
}
|
}
|
||||||
|
|
||||||
void onReset() {
|
void onReset() {
|
||||||
Settings.reset();
|
Settings.reset();
|
||||||
reload(message: 'Settings have been reset to default');
|
reload(message: translate(LocalizationKeys.settings_reset));
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleResetAction() async {
|
void handleResetAction() async {
|
||||||
DialogUtils.showConfirmationDialog(
|
DialogUtils.showConfirmationDialog(
|
||||||
context: context,
|
context: context,
|
||||||
onConfirm: onReset,
|
onConfirm: onReset,
|
||||||
message: 'Are you sure you want to reset all settings?',
|
message: translate(LocalizationKeys.settings_confirmReset),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,7 +174,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: const Text('Application Settings'),
|
title: Text(translate(LocalizationKeys.settings_title)),
|
||||||
),
|
),
|
||||||
drawer: const Navigation(currentLocation: SettingsScreen.routeName),
|
drawer: const Navigation(currentLocation: SettingsScreen.routeName),
|
||||||
body: SingleChildScrollView(
|
body: SingleChildScrollView(
|
||||||
@ -191,7 +193,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Text(
|
child: Text(
|
||||||
'MEASUREMENTS',
|
translate(LocalizationKeys.settings_sections_measurements).toUpperCase(),
|
||||||
style: Theme.of(context).textTheme.subtitle2,
|
style: Theme.of(context).textTheme.subtitle2,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -208,7 +210,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
AutoCompleteDropdownButton<String>(
|
AutoCompleteDropdownButton<String>(
|
||||||
controller: _nutritionMeasurementLabelController,
|
controller: _nutritionMeasurementLabelController,
|
||||||
selectedItem: _nutritionMeasurementLabelController.text,
|
selectedItem: _nutritionMeasurementLabelController.text,
|
||||||
label: 'Preferred Nutrition Measurement',
|
label: translate(LocalizationKeys.settings_fields_nutritionMeasurement),
|
||||||
items: nutritionMeasurementLabels,
|
items: nutritionMeasurementLabels,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
_nutritionMeasurementLabelController.text =
|
_nutritionMeasurementLabelController.text =
|
||||||
@ -221,7 +223,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
child: AutoCompleteDropdownButton<String>(
|
child: AutoCompleteDropdownButton<String>(
|
||||||
controller: _glucoseMeasurementLabelController,
|
controller: _glucoseMeasurementLabelController,
|
||||||
selectedItem: _glucoseMeasurementLabelController.text,
|
selectedItem: _glucoseMeasurementLabelController.text,
|
||||||
label: 'Preferred Glucose Measurement',
|
label: translate(LocalizationKeys.settings_fields_glucoseMeasurement),
|
||||||
items: glucoseMeasurementLabels,
|
items: glucoseMeasurementLabels,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
_glucoseMeasurementLabelController.text =
|
_glucoseMeasurementLabelController.text =
|
||||||
@ -232,8 +234,8 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
),
|
),
|
||||||
Settings.glucoseMeasurement == GlucoseMeasurement.mgPerDl
|
Settings.glucoseMeasurement == GlucoseMeasurement.mgPerDl
|
||||||
? NumberFormField(
|
? NumberFormField(
|
||||||
label: 'Target glucose',
|
label: translate(LocalizationKeys.settings_fields_targetGlucose),
|
||||||
suffix: 'mg/dl',
|
suffix: Settings.glucoseMeasurementSuffix,
|
||||||
controller: _targetGlucoseMgPerDlController,
|
controller: _targetGlucoseMgPerDlController,
|
||||||
showSteppers: false,
|
showSteppers: false,
|
||||||
onChanged: (_) async {
|
onChanged: (_) async {
|
||||||
@ -254,8 +256,8 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
: NumberFormField(
|
: NumberFormField(
|
||||||
label: 'Target glucose',
|
label: translate(LocalizationKeys.settings_fields_targetGlucose),
|
||||||
suffix: 'mmol/l',
|
suffix: Settings.glucoseMeasurementSuffix,
|
||||||
controller: _targetGlucoseMmolPerLController,
|
controller: _targetGlucoseMmolPerLController,
|
||||||
showSteppers: false,
|
showSteppers: false,
|
||||||
onChanged: (_) async {
|
onChanged: (_) async {
|
||||||
@ -277,7 +279,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
child: NumberFormField(
|
child: NumberFormField(
|
||||||
controller: _insulinIncrementsController,
|
controller: _insulinIncrementsController,
|
||||||
showSteppers: false,
|
showSteppers: false,
|
||||||
label: 'Insulin increment',
|
label: translate(LocalizationKeys.settings_fields_insulinIncrement),
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
_insulinIncrementsController.text =
|
_insulinIncrementsController.text =
|
||||||
(value ?? 0).toString();
|
(value ?? 0).toString();
|
||||||
@ -287,7 +289,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
NumberFormField(
|
NumberFormField(
|
||||||
controller: _nutritionIncrementsController,
|
controller: _nutritionIncrementsController,
|
||||||
showSteppers: false,
|
showSteppers: false,
|
||||||
label: 'Nutrition increment',
|
label: translate(LocalizationKeys.settings_fields_nutritionIncrement),
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
_nutritionIncrementsController.text =
|
_nutritionIncrementsController.text =
|
||||||
(value ?? 0).toString();
|
(value ?? 0).toString();
|
||||||
@ -298,7 +300,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
child: NumberFormField(
|
child: NumberFormField(
|
||||||
controller: _mmolPerLIncrementsController,
|
controller: _mmolPerLIncrementsController,
|
||||||
showSteppers: false,
|
showSteppers: false,
|
||||||
label: 'Mmol/L increment',
|
label: translate(LocalizationKeys.settings_fields_mmolLIncrement),
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
_mmolPerLIncrementsController.text =
|
_mmolPerLIncrementsController.text =
|
||||||
(value ?? 0).toString();
|
(value ?? 0).toString();
|
||||||
@ -307,7 +309,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
),
|
),
|
||||||
BooleanFormField(
|
BooleanFormField(
|
||||||
value: _onlyDisplayActiveGlucoseMeasurement,
|
value: _onlyDisplayActiveGlucoseMeasurement,
|
||||||
label: 'only display active glucose measurement',
|
label: translate(LocalizationKeys.settings_fields_onlyDisplayActive),
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
_onlyDisplayActiveGlucoseMeasurement = value;
|
_onlyDisplayActiveGlucoseMeasurement = value;
|
||||||
saveSettings();
|
saveSettings();
|
||||||
@ -317,7 +319,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
value: _displayBothGlucoseMeasurementsInDetailView,
|
value: _displayBothGlucoseMeasurementsInDetailView,
|
||||||
enabled: !_onlyDisplayActiveGlucoseMeasurement,
|
enabled: !_onlyDisplayActiveGlucoseMeasurement,
|
||||||
label:
|
label:
|
||||||
'display both glucose measurements in detail view',
|
translate(LocalizationKeys.settings_fields_displayBothDetail),
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
_displayBothGlucoseMeasurementsInDetailView = value;
|
_displayBothGlucoseMeasurementsInDetailView = value;
|
||||||
saveSettings();
|
saveSettings();
|
||||||
@ -326,7 +328,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
BooleanFormField(
|
BooleanFormField(
|
||||||
value: _displayBothGlucoseMeasurementsInListView,
|
value: _displayBothGlucoseMeasurementsInListView,
|
||||||
enabled: !_onlyDisplayActiveGlucoseMeasurement,
|
enabled: !_onlyDisplayActiveGlucoseMeasurement,
|
||||||
label: 'display both glucose measurements in list view',
|
label: translate(LocalizationKeys.settings_fields_displayBothList),
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
_displayBothGlucoseMeasurementsInListView = value;
|
_displayBothGlucoseMeasurementsInListView = value;
|
||||||
saveSettings();
|
saveSettings();
|
||||||
@ -347,7 +349,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Text(
|
child: Text(
|
||||||
'CONFIRMATION PROMPTS',
|
translate(LocalizationKeys.settings_sections_confirmation).toUpperCase(),
|
||||||
style: Theme.of(context).textTheme.subtitle2,
|
style: Theme.of(context).textTheme.subtitle2,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -364,7 +366,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
BooleanFormField(
|
BooleanFormField(
|
||||||
value: _showConfirmationDialogOnCancel,
|
value: _showConfirmationDialogOnCancel,
|
||||||
label:
|
label:
|
||||||
'on cancelling edit or creation of a record if changes have already been made',
|
translate(LocalizationKeys.settings_fields_confirmOnCancel),
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
_showConfirmationDialogOnCancel = value;
|
_showConfirmationDialogOnCancel = value;
|
||||||
saveSettings();
|
saveSettings();
|
||||||
@ -372,7 +374,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
),
|
),
|
||||||
BooleanFormField(
|
BooleanFormField(
|
||||||
value: _showConfirmationDialogOnDelete,
|
value: _showConfirmationDialogOnDelete,
|
||||||
label: 'on deleting a record',
|
label: translate(LocalizationKeys.settings_fields_confirmOnDelete),
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
_showConfirmationDialogOnDelete = value;
|
_showConfirmationDialogOnDelete = value;
|
||||||
saveSettings();
|
saveSettings();
|
||||||
@ -380,7 +382,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
),
|
),
|
||||||
BooleanFormField(
|
BooleanFormField(
|
||||||
value: _showConfirmationDialogOnStopEvent,
|
value: _showConfirmationDialogOnStopEvent,
|
||||||
label: 'on stopping (ending) an event',
|
label: translate(LocalizationKeys.settings_fields_confirmOnEndEvent),
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
_showConfirmationDialogOnStopEvent = value;
|
_showConfirmationDialogOnStopEvent = value;
|
||||||
saveSettings();
|
saveSettings();
|
||||||
@ -401,7 +403,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Text(
|
child: Text(
|
||||||
'TIME & DATE FORMAT',
|
translate(LocalizationKeys.settings_sections_dateTimeFormat).toUpperCase(),
|
||||||
style: Theme.of(context).textTheme.subtitle2,
|
style: Theme.of(context).textTheme.subtitle2,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -421,15 +423,9 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
controller: _dateFormatController,
|
controller: _dateFormatController,
|
||||||
decoration: const InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: 'Date Format',
|
labelText: translate(LocalizationKeys.settings_fields_dateFormat),
|
||||||
),
|
),
|
||||||
validator: (value) {
|
|
||||||
if (value!.trim().isEmpty) {
|
|
||||||
return 'Empty title';
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
@ -439,7 +435,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
const Text('Example', textScaleFactor: 0.75),
|
Text(translate(LocalizationKeys.general_example), textScaleFactor: 0.75),
|
||||||
Text(
|
Text(
|
||||||
DateFormat(_dateFormatController.text)
|
DateFormat(_dateFormatController.text)
|
||||||
.format(DateTime.now()),
|
.format(DateTime.now()),
|
||||||
@ -459,15 +455,9 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
controller: _longDateFormatController,
|
controller: _longDateFormatController,
|
||||||
decoration: const InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: 'Long Date Format',
|
labelText: translate(LocalizationKeys.settings_fields_longDateFormat),
|
||||||
),
|
),
|
||||||
validator: (value) {
|
|
||||||
if (value!.trim().isEmpty) {
|
|
||||||
return 'Empty title';
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
@ -477,7 +467,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
const Text('Example',
|
Text(translate(LocalizationKeys.general_example),
|
||||||
textScaleFactor: 0.75),
|
textScaleFactor: 0.75),
|
||||||
Text(
|
Text(
|
||||||
DateFormat(_longDateFormatController.text)
|
DateFormat(_longDateFormatController.text)
|
||||||
@ -497,15 +487,9 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
controller: _timeFormatController,
|
controller: _timeFormatController,
|
||||||
decoration: const InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: 'Time Format',
|
labelText: translate(LocalizationKeys.settings_fields_timeFormat),
|
||||||
),
|
),
|
||||||
validator: (value) {
|
|
||||||
if (value!.trim().isEmpty) {
|
|
||||||
return 'Empty title';
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
@ -515,7 +499,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
const Text('Example', textScaleFactor: 0.75),
|
Text(translate(LocalizationKeys.general_example), textScaleFactor: 0.75),
|
||||||
Text(
|
Text(
|
||||||
DateFormat(_timeFormatController.text)
|
DateFormat(_timeFormatController.text)
|
||||||
.format(DateTime.now()),
|
.format(DateTime.now()),
|
||||||
@ -535,15 +519,9 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
controller: _longTimeFormatController,
|
controller: _longTimeFormatController,
|
||||||
decoration: const InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: 'Long Time Format',
|
labelText: translate(LocalizationKeys.settings_fields_longTimeFormat),
|
||||||
),
|
),
|
||||||
validator: (value) {
|
|
||||||
if (value!.trim().isEmpty) {
|
|
||||||
return 'Empty title';
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
@ -553,7 +531,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
const Text('Example',
|
Text(translate(LocalizationKeys.general_example),
|
||||||
textScaleFactor: 0.75),
|
textScaleFactor: 0.75),
|
||||||
Text(
|
Text(
|
||||||
DateFormat(_longTimeFormatController.text)
|
DateFormat(_longTimeFormatController.text)
|
||||||
@ -584,7 +562,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
Icons.settings_backup_restore,
|
Icons.settings_backup_restore,
|
||||||
size: 18.0,
|
size: 18.0,
|
||||||
),
|
),
|
||||||
label: const Text('RESET ALL'),
|
label: Text(translate(LocalizationKeys.settings_resetAll).toUpperCase()),
|
||||||
),
|
),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
],
|
],
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
|
import 'package:diameter/localization_keys.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_translate/flutter_translate.dart';
|
||||||
|
|
||||||
class DialogUtils {
|
class DialogUtils {
|
||||||
static void showCancelConfirmationDialog(
|
static void showCancelConfirmationDialog(
|
||||||
@ -13,30 +15,29 @@ class DialogUtils {
|
|||||||
List<Widget> actions = [
|
List<Widget> actions = [
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.pop(context, 'CANCEL'),
|
onPressed: () => Navigator.pop(context, 'CANCEL'),
|
||||||
child: const Text('CANCEL'),
|
child: Text(translate(LocalizationKeys.general_cancel).toUpperCase()),
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
actions.add(isNew
|
actions.add(isNew
|
||||||
? ElevatedButton(
|
? ElevatedButton(
|
||||||
onPressed: () => Navigator.pop(context, 'DISCARD'),
|
onPressed: () => Navigator.pop(context, 'DISCARD'),
|
||||||
child: const Text('DISCARD'),
|
child: Text(translate(LocalizationKeys.general_discard).toUpperCase()),
|
||||||
)
|
)
|
||||||
: TextButton(
|
: TextButton(
|
||||||
onPressed: () => Navigator.pop(context, 'DISCARD'),
|
onPressed: () => Navigator.pop(context, 'DISCARD'),
|
||||||
child: const Text('DISCARD'),
|
child: Text(translate(LocalizationKeys.general_discard).toUpperCase()),
|
||||||
));
|
));
|
||||||
|
|
||||||
if (!isNew) {
|
if (!isNew) {
|
||||||
actions.add(ElevatedButton(
|
actions.add(ElevatedButton(
|
||||||
onPressed: () => Navigator.pop(context, 'SAVE'),
|
onPressed: () => Navigator.pop(context, 'SAVE'),
|
||||||
child: const Text('SAVE'),
|
child: Text(translate(LocalizationKeys.general_save).toUpperCase()),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
content: Text(message ??
|
content: Text(message ?? translate(LocalizationKeys.general_confirmDiscard)),
|
||||||
'You already made some changes. Discard your input?'),
|
|
||||||
actions: actions,
|
actions: actions,
|
||||||
);
|
);
|
||||||
}).then((value) {
|
}).then((value) {
|
||||||
@ -52,21 +53,21 @@ class DialogUtils {
|
|||||||
static void showConfirmationDialog(
|
static void showConfirmationDialog(
|
||||||
{required BuildContext context,
|
{required BuildContext context,
|
||||||
required void Function() onConfirm,
|
required void Function() onConfirm,
|
||||||
String message = 'Are you sure you want to delete this record?',
|
String? message,
|
||||||
String confirmationLabel = 'DELETE'}) {
|
String? confirmationLabel}) {
|
||||||
showDialog(
|
showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
content: Text(message),
|
content: Text(message ?? translate(LocalizationKeys.general_confirmDelete)),
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.pop(context, 'CANCEL'),
|
onPressed: () => Navigator.pop(context, 'CANCEL'),
|
||||||
child: const Text('CANCEL'),
|
child: Text(translate(LocalizationKeys.general_cancel).toUpperCase()),
|
||||||
),
|
),
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: () => Navigator.pop(context, 'CONFIRM'),
|
onPressed: () => Navigator.pop(context, 'CONFIRM'),
|
||||||
child: Text(confirmationLabel),
|
child: Text(confirmationLabel ?? translate(LocalizationKeys.general_confirm).toUpperCase()),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
Binary file not shown.
Binary file not shown.
77
pubspec.lock
77
pubspec.lock
@ -1,27 +1,34 @@
|
|||||||
# Generated by pub
|
# Generated by pub
|
||||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||||
packages:
|
packages:
|
||||||
|
_discoveryapis_commons:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: _discoveryapis_commons
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.2"
|
||||||
_fe_analyzer_shared:
|
_fe_analyzer_shared:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: _fe_analyzer_shared
|
name: _fe_analyzer_shared
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "36.0.0"
|
version: "38.0.0"
|
||||||
analyzer:
|
analyzer:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
name: analyzer
|
name: analyzer
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.3.1"
|
version: "3.4.1"
|
||||||
archive:
|
archive:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: archive
|
name: archive
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.2.2"
|
version: "3.3.0"
|
||||||
args:
|
args:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -231,7 +238,7 @@ packages:
|
|||||||
name: flex_color_scheme
|
name: flex_color_scheme
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.1"
|
version: "4.2.0"
|
||||||
flutter:
|
flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description: flutter
|
description: flutter
|
||||||
@ -244,11 +251,23 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.4"
|
version: "1.0.4"
|
||||||
|
flutter_localizations:
|
||||||
|
dependency: "direct main"
|
||||||
|
description: flutter
|
||||||
|
source: sdk
|
||||||
|
version: "0.0.0"
|
||||||
flutter_test:
|
flutter_test:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
version: "0.0.0"
|
||||||
|
flutter_translate:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: flutter_translate
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.1"
|
||||||
flutter_web_plugins:
|
flutter_web_plugins:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description: flutter
|
description: flutter
|
||||||
@ -268,6 +287,34 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.2"
|
version: "2.0.2"
|
||||||
|
google_sign_in:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: google_sign_in
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "5.2.4"
|
||||||
|
google_sign_in_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: google_sign_in_platform_interface
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.2"
|
||||||
|
google_sign_in_web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: google_sign_in_web
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.10.0+5"
|
||||||
|
googleapis:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: googleapis
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "7.0.0"
|
||||||
graphs:
|
graphs:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -519,7 +566,7 @@ packages:
|
|||||||
name: printing
|
name: printing
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.7.4"
|
version: "5.7.5"
|
||||||
process:
|
process:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -555,13 +602,20 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.0"
|
version: "3.0.0"
|
||||||
|
quiver:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: quiver
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.1+1"
|
||||||
shelf:
|
shelf:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shelf
|
name: shelf
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.0"
|
version: "1.3.0"
|
||||||
shelf_web_socket:
|
shelf_web_socket:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -644,6 +698,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.0"
|
version: "1.3.0"
|
||||||
|
universal_io:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: universal_io
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.4"
|
||||||
vector_math:
|
vector_math:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -671,7 +732,7 @@ packages:
|
|||||||
name: win32
|
name: win32
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.2"
|
version: "2.5.1"
|
||||||
xdg_directories:
|
xdg_directories:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -694,5 +755,5 @@ packages:
|
|||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.0"
|
version: "3.1.0"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=2.15.0 <3.0.0"
|
dart: ">=2.16.0 <3.0.0"
|
||||||
flutter: ">=2.8.0"
|
flutter: ">=2.8.0"
|
||||||
|
11
pubspec.yaml
11
pubspec.yaml
@ -11,16 +11,21 @@ environment:
|
|||||||
dependencies:
|
dependencies:
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
flutter_localizations:
|
||||||
|
sdk: flutter
|
||||||
path_provider: ^2.0.9
|
path_provider: ^2.0.9
|
||||||
cupertino_icons: ^1.0.2
|
cupertino_icons: ^1.0.2
|
||||||
flex_color_scheme: ^3.0.1
|
flex_color_scheme: ^4.2.0
|
||||||
intl: ^0.17.0
|
intl: ^0.17.0
|
||||||
objectbox: ^1.2.0
|
objectbox: ^1.2.0
|
||||||
objectbox_sync_flutter_libs: any
|
objectbox_sync_flutter_libs: any
|
||||||
charts_flutter: ^0.12.0
|
|
||||||
printing: ^5.7.2
|
printing: ^5.7.2
|
||||||
pdf: ^3.7.1
|
pdf: ^3.7.1
|
||||||
open_file: ^3.2.1
|
open_file: ^3.2.1
|
||||||
|
flutter_translate: ^3.0.1
|
||||||
|
googleapis: ^7.0.0
|
||||||
|
google_sign_in: ^5.2.1
|
||||||
|
charts_flutter: ^0.12.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
@ -33,3 +38,5 @@ dev_dependencies:
|
|||||||
|
|
||||||
flutter:
|
flutter:
|
||||||
uses-material-design: true
|
uses-material-design: true
|
||||||
|
assets:
|
||||||
|
- assets/i18n/
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
// import 'package:flutter/material.dart';
|
// import 'package:flutter/material.dart';
|
||||||
// import 'package:flutter_test/flutter_test.dart';
|
// import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
// import 'package:tide/main.dart';
|
// import 'package:diameter/main.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
// testWidgets('Counter increments smoke test', (WidgetTester tester) async {
|
// testWidgets('Counter increments smoke test', (WidgetTester tester) async {
|
||||||
|
@ -14,20 +14,20 @@
|
|||||||
This is a placeholder for base href that will be replaced by the value of
|
This is a placeholder for base href that will be replaced by the value of
|
||||||
the `--base-href` argument provided to `flutter build`.
|
the `--base-href` argument provided to `flutter build`.
|
||||||
-->
|
-->
|
||||||
<base href="$FLUTTER_BASE_HREF">
|
<base href="$FLUTTER_BASE_HREF" />
|
||||||
|
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8" />
|
||||||
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
|
<meta content="IE=Edge" http-equiv="X-UA-Compatible" />
|
||||||
<meta name="description" content="A new Flutter project.">
|
<meta name="description" content="A new Flutter project." />
|
||||||
|
|
||||||
<!-- iOS meta tags & icons -->
|
<!-- iOS meta tags & icons -->
|
||||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||||
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
|
||||||
<meta name="apple-mobile-web-app-title" content="tide">
|
<meta name="apple-mobile-web-app-title" content="diameter" />
|
||||||
<link rel="apple-touch-icon" href="icons/Icon-192.png">
|
<link rel="apple-touch-icon" href="icons/Icon-192.png" />
|
||||||
|
|
||||||
<title>tide</title>
|
<title>diameter</title>
|
||||||
<link rel="manifest" href="manifest.json">
|
<link rel="manifest" href="manifest.json" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<!-- This script installs service_worker.js to provide PWA functionality to
|
<!-- This script installs service_worker.js to provide PWA functionality to
|
||||||
@ -41,42 +41,60 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
scriptLoaded = true;
|
scriptLoaded = true;
|
||||||
var scriptTag = document.createElement('script');
|
var scriptTag = document.createElement("script");
|
||||||
scriptTag.src = 'main.dart.js';
|
scriptTag.src = "main.dart.js";
|
||||||
scriptTag.type = 'application/javascript';
|
scriptTag.type = "application/javascript";
|
||||||
document.body.append(scriptTag);
|
document.body.append(scriptTag);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('serviceWorker' in navigator) {
|
if ("serviceWorker" in navigator) {
|
||||||
// Service workers are supported. Use them.
|
// Service workers are supported. Use them.
|
||||||
window.addEventListener('load', function () {
|
window.addEventListener("load", function () {
|
||||||
// Wait for registration to finish before dropping the <script> tag.
|
// Wait for registration to finish before dropping the <script> tag.
|
||||||
// Otherwise, the browser will load the script multiple times,
|
// Otherwise, the browser will load the script multiple times,
|
||||||
// potentially different versions.
|
// potentially different versions.
|
||||||
var serviceWorkerUrl = 'flutter_service_worker.js?v=' + serviceWorkerVersion;
|
var serviceWorkerUrl =
|
||||||
navigator.serviceWorker.register(serviceWorkerUrl)
|
"flutter_service_worker.js?v=" + serviceWorkerVersion;
|
||||||
|
navigator.serviceWorker
|
||||||
|
.register(serviceWorkerUrl)
|
||||||
.then((reg) => {
|
.then((reg) => {
|
||||||
function waitForActivation(serviceWorker) {
|
function waitForActivation(serviceWorker) {
|
||||||
serviceWorker.addEventListener('statechange', () => {
|
serviceWorker.addEventListener(
|
||||||
if (serviceWorker.state == 'activated') {
|
"statechange",
|
||||||
console.log('Installed new service worker.');
|
() => {
|
||||||
|
if (
|
||||||
|
serviceWorker.state == "activated"
|
||||||
|
) {
|
||||||
|
console.log(
|
||||||
|
"Installed new service worker."
|
||||||
|
);
|
||||||
loadMainDartJs();
|
loadMainDartJs();
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
if (!reg.active && (reg.installing || reg.waiting)) {
|
);
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
!reg.active &&
|
||||||
|
(reg.installing || reg.waiting)
|
||||||
|
) {
|
||||||
// No active web worker and we have installed or are installing
|
// No active web worker and we have installed or are installing
|
||||||
// one for the first time. Simply wait for it to activate.
|
// one for the first time. Simply wait for it to activate.
|
||||||
waitForActivation(reg.installing || reg.waiting);
|
waitForActivation(
|
||||||
} else if (!reg.active.scriptURL.endsWith(serviceWorkerVersion)) {
|
reg.installing || reg.waiting
|
||||||
|
);
|
||||||
|
} else if (
|
||||||
|
!reg.active.scriptURL.endsWith(
|
||||||
|
serviceWorkerVersion
|
||||||
|
)
|
||||||
|
) {
|
||||||
// When the app updates the serviceWorkerVersion changes, so we
|
// When the app updates the serviceWorkerVersion changes, so we
|
||||||
// need to ask the service worker to update.
|
// need to ask the service worker to update.
|
||||||
console.log('New service worker available.');
|
console.log("New service worker available.");
|
||||||
reg.update();
|
reg.update();
|
||||||
waitForActivation(reg.installing);
|
waitForActivation(reg.installing);
|
||||||
} else {
|
} else {
|
||||||
// Existing service worker is still good.
|
// Existing service worker is still good.
|
||||||
console.log('Loading app from service worker.');
|
console.log("Loading app from service worker.");
|
||||||
loadMainDartJs();
|
loadMainDartJs();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -86,7 +104,7 @@
|
|||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (!scriptLoaded) {
|
if (!scriptLoaded) {
|
||||||
console.warn(
|
console.warn(
|
||||||
'Failed to load app from service worker. Falling back to plain <script> tag.',
|
"Failed to load app from service worker. Falling back to plain <script> tag."
|
||||||
);
|
);
|
||||||
loadMainDartJs();
|
loadMainDartJs();
|
||||||
}
|
}
|
||||||
|
@ -89,7 +89,7 @@ BEGIN
|
|||||||
BEGIN
|
BEGIN
|
||||||
BLOCK "040904e4"
|
BLOCK "040904e4"
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "com.example" "\0"
|
VALUE "CompanyName", "at.sarahziesel" "\0"
|
||||||
VALUE "FileDescription", "diameter" "\0"
|
VALUE "FileDescription", "diameter" "\0"
|
||||||
VALUE "FileVersion", VERSION_AS_STRING "\0"
|
VALUE "FileVersion", VERSION_AS_STRING "\0"
|
||||||
VALUE "InternalName", "diameter" "\0"
|
VALUE "InternalName", "diameter" "\0"
|
||||||
|
Loading…
Reference in New Issue
Block a user