Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
edbf4c9
i18n: Update Hindi translation
bpurohit8302-png Sep 27, 2026
62a449b
i18n: Add Indonesian translation
noasukki Sep 27, 2026
8bd1cf1
i18n: Update Hindi translation
bpurohit8302-png Sep 27, 2026
775a2e5
i18n: Update Hindi translation
bpurohit8302-png Sep 27, 2026
4c00914
i18n: Merge origin/translations into Weblate
weblate Sep 27, 2026
39ae287
i18n: Merge origin/translations into Weblate
weblate Sep 27, 2026
02d9ecc
Merge branch 'dev' into translations
delia-cheminot Sep 27, 2026
109641f
i18n: Merge origin/translations into Weblate
weblate Sep 27, 2026
dd8f2f4
Merge remote-tracking branch 'weblate/translations' into translations
delia-cheminot Sep 27, 2026
8fd85fc
feat: add indonesian to settings
delia-cheminot Sep 27, 2026
2cae6ae
i18n: replace language missing by translations missing
delia-cheminot Sep 27, 2026
16ddbb7
feat: center target date in graph
delia-cheminot Sep 27, 2026
91a61ec
Merge pull request #387 from mona-hrt/consistent-graph-zoom
delia-cheminot Sep 28, 2026
8202401
i18n: Update Hindi translation
delia-cheminot Sep 28, 2026
f2eb5d1
i18n: Add Hungarian translation
WampireDev Sep 28, 2026
3789043
fix: put back "other" decimal forms that are not handled by Weblate
delia-cheminot Sep 28, 2026
d6ff6d2
chore: add screenshots generation script
delia-cheminot Aug 27, 2026
04e978c
chore: refine screenshots
delia-cheminot Aug 28, 2026
feabbed
chore: add text to screenshots
delia-cheminot Sep 3, 2026
aaf9d49
fix: adjust text size and placement
delia-cheminot Sep 11, 2026
658202c
chore: run screenshot generation
delia-cheminot Sep 11, 2026
ebf5e33
fix: use new fields
delia-cheminot Sep 28, 2026
86bbb85
fix: use iphone 17 pro max for screenshots
delia-cheminot Sep 28, 2026
1d03435
refactor: inline caption_source
delia-cheminot Sep 28, 2026
380a2ec
reafactor: use a folder
delia-cheminot Sep 28, 2026
07df497
chore: run simulation
delia-cheminot Sep 28, 2026
4441433
chore: update gitignore
delia-cheminot Sep 28, 2026
fb139c9
cix: show status bar on android with fixed clock
delia-cheminot Sep 28, 2026
0826456
chore: rename screenshot output file names
delia-cheminot Sep 28, 2026
bcf8e39
fix: force default colors for screenshots
delia-cheminot Sep 28, 2026
ef4e735
fix: swap captions
delia-cheminot Sep 28, 2026
38b3404
refactor: move the driver in the same folder
delia-cheminot Sep 28, 2026
d46ce31
Merge branch 'dev' into decimal-translation-bug
delia-cheminot Sep 28, 2026
8875fd7
Merge branch 'dev' into translations
delia-cheminot Sep 28, 2026
3b99b89
i18n: Update Hungarian translation
WampireDev Sep 28, 2026
148fbc3
i18n: Update Hungarian translation
WampireDev Sep 28, 2026
34952ce
i18n: Merge origin/translations into Weblate
weblate Sep 28, 2026
4b22a10
i18n: Update Hungarian translation
WampireDev Sep 28, 2026
1f5fc0d
i18n: Merge origin/translations into Weblate
weblate Sep 28, 2026
81d64bf
feat: add hungarian
delia-cheminot Sep 28, 2026
1bb08af
Merge branch 'translations' of https://github.com/delia-cheminot/tran…
delia-cheminot Sep 28, 2026
a65a507
Merge branch 'dev' into decimal-translation-bug
delia-cheminot Sep 28, 2026
7303928
Merge pull request #390 from mona-hrt/decimal-translation-bug
delia-cheminot Sep 28, 2026
7de747b
feat: put the schedule id in notifications payload
delia-cheminot Sep 29, 2026
ad84767
feat: add injection type enum
delia-cheminot Sep 29, 2026
f66739f
feat: add injectionType to intakes
delia-cheminot Sep 29, 2026
c458128
feat: set injection type in takeMedication
delia-cheminot Sep 29, 2026
85147a7
feat: create injection type picker
delia-cheminot Sep 29, 2026
e18b03f
feat: use injectionType in editIntake
delia-cheminot Sep 29, 2026
c1b8626
feat: allow picking injection type in ui
delia-cheminot Sep 29, 2026
657332e
feat: add suggestInjectionType
delia-cheminot Sep 29, 2026
9f975a9
feat: dynamically suggest injection type
delia-cheminot Sep 29, 2026
0a12028
feat: add navigator key to the app
delia-cheminot Sep 29, 2026
b2d587f
fix: only init injection type once in takeMedicationPage
delia-cheminot Sep 29, 2026
e637843
fix: align icons in the supply picker
delia-cheminot Sep 29, 2026
55ab3aa
feat: add onTap and getAppLaunchTap to notificationService
delia-cheminot Sep 30, 2026
e3fbbba
feat: create slot router
delia-cheminot Sep 30, 2026
13afd6f
Merge pull request #392 from mona-hrt/add-injection-type
delia-cheminot Sep 30, 2026
a4d167d
feat: wire the tap action in the app
delia-cheminot Sep 30, 2026
573cf35
refactor: centralize encodePayload and decodePayload
delia-cheminot Sep 30, 2026
038491a
refactor: remove slot router dependency on notification service
delia-cheminot Sep 30, 2026
0000a8b
refactor: return slots with the slot finder + rename
delia-cheminot Sep 30, 2026
222264e
i18n: Update Portuguese (Brazil) translation
wanuvi Sep 30, 2026
782be0f
i18n: Update Hungarian translation
WampireDev Sep 29, 2026
29b45b9
Merge branch 'dev' into translations
delia-cheminot Sep 30, 2026
46a1a47
fix: unwrap malformed level entries
delia-cheminot Sep 30, 2026
c5f59e8
feat: add blood test from the levels tab
delia-cheminot Sep 30, 2026
bbe91ba
Merge pull request #393 from mona-hrt/levels-repair-migration
delia-cheminot Sep 30, 2026
798587c
Merge pull request #398 from mona-hrt/new-blood-test-button
delia-cheminot Sep 30, 2026
e90529b
i18n: Update Portuguese (Brazil) translation
wanuvi Sep 30, 2026
fc5133e
i18n: Update Hungarian translation
WampireDev Sep 30, 2026
d3a46bc
i18n: Merge origin/translations into Weblate
weblate Sep 30, 2026
2033361
Merge pull request #391 from mona-hrt/open-intake-from-notification
delia-cheminot Sep 30, 2026
58bfaed
fix: don't color the switch tile when it's trailing
delia-cheminot Sep 30, 2026
1d42956
Merge pull request #400 from mona-hrt/optional-toggle-color
delia-cheminot Sep 30, 2026
6d5fc82
i18n: Update Portuguese (Brazil) translation
wanuvi Oct 1, 2026
476b748
Merge branch 'dev' into translations
delia-cheminot Oct 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,9 @@ lib/i18n/generated/

# Widget Preview related
.widget_preview/

# Unused platforms
macos/*
linux/*
windows/*
web/*
12 changes: 12 additions & 0 deletions android/app/src/main/res/values-hi/widget_plurals.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions android/app/src/main/res/values-hi/widget_strings.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file modified fastlane/metadata/android/en-US/images/phoneScreenshots/1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 changes: 22 additions & 0 deletions fastlane/metadata/android/hi-IN/full_description.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
मोना के साथ अपने हार्मोनल स्वास्थ्य का नियंत्रण करें, पूरी तरह से स्थानीय, ओपन सोर्स ऐप आपको अपने हार्मोन यात्रा को ट्रैक करने, समझने और प्रबंधित करने में मदद करने के लिए डिज़ाइन किया गया है।

क्यों मोना अलग है:

- पूरी तरह से निजी: आपके सभी डेटा आपके डिवाइस पर रहते हैं। सर्वर पर कुछ भी नहीं भेजा जाता है।
- ओपन सोर्स: ऐप पूरी तरह से खुला स्रोत है, जो समुदाय से अधिकतम पारदर्शिता और योगदान की अनुमति देता है।
- जीवन के लिए नि: शुल्क: कोई सदस्यता, कोई प्रीमियम सुविधाएँ नहीं। मोना हर किसी के लिए स्वतंत्र है।

दवा अनुस्मारक:

- अपनी दवा रेजिमेंट जोड़ें
प्रत्येक आगामी खुराक (मात्रा, तारीख, पक्ष, मिस्ड खुराक) के लिए विस्तृत जानकारी प्राप्त करें
- अधिसूचना प्राप्त करें ताकि आप कभी भी खुराक नहीं छोड़ सकें

अपनी दवा के स्टॉक को कुशलतापूर्वक प्रबंधित करें:

- स्टॉक में प्रत्येक दवा का ट्रैक रखें
- प्रत्येक सेवन के साथ क्वांटिटी स्वचालित रूप से अपडेट की जाती है

हार्मोन का स्तर ग्राफ:

- एस्ट्राडियोल मोनोथेरेपी पर उपयोगकर्ताओं के लिए, समय के साथ नकली हार्मोन स्तर को दृश्यित करें
1 change: 1 addition & 0 deletions fastlane/metadata/android/hi-IN/short_description.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
आपका ट्रांस हेल्थ साथी
1 change: 1 addition & 0 deletions fastlane/metadata/android/hi-IN/title.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
मोना - HRT जर्नल
1 change: 1 addition & 0 deletions fastlane/metadata/android/hu-HU/title.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Mona - HRT napló
22 changes: 22 additions & 0 deletions fastlane/metadata/ios/hi/description.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
मोना के साथ अपने हार्मोनल स्वास्थ्य का नियंत्रण करें, पूरी तरह से स्थानीय, ओपन सोर्स ऐप आपको अपने हार्मोन यात्रा को ट्रैक करने, समझने और प्रबंधित करने में मदद करने के लिए डिज़ाइन किया गया है।

क्यों मोना अलग है:

- पूरी तरह से निजी: आपके सभी डेटा आपके डिवाइस पर रहते हैं। सर्वर पर कुछ भी नहीं भेजा जाता है।
- ओपन सोर्स: ऐप पूरी तरह से खुला स्रोत है, जो समुदाय से अधिकतम पारदर्शिता और योगदान की अनुमति देता है।
- जीवन के लिए नि: शुल्क: कोई सदस्यता, कोई प्रीमियम सुविधाएँ नहीं। मोना हर किसी के लिए स्वतंत्र है।

दवा अनुस्मारक:

- अपनी दवा रेजिमेंट जोड़ें
प्रत्येक आगामी खुराक (मात्रा, तारीख, पक्ष, मिस्ड खुराक) के लिए विस्तृत जानकारी प्राप्त करें
- अधिसूचना प्राप्त करें ताकि आप कभी भी खुराक नहीं छोड़ सकें

अपनी दवा के स्टॉक को कुशलतापूर्वक प्रबंधित करें:

- स्टॉक में प्रत्येक दवा का ट्रैक रखें
- प्रत्येक सेवन के साथ क्वांटिटी स्वचालित रूप से अपडेट की जाती है

हार्मोन का स्तर ग्राफ:

- एस्ट्राडियोल मोनोथेरेपी पर उपयोगकर्ताओं के लिए, समय के साथ नकली हार्मोन स्तर को दृश्यित करें
1 change: 1 addition & 0 deletions fastlane/metadata/ios/hi/keywords.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
मोना, ट्रांस, ट्रांसजेंडर, हार्मोन, हार्मोनल, ट्रैकर, लॉग, hrt, पत्रिका, मेमो, एस्ट्राडियोल, सिम्युलेटर
1 change: 1 addition & 0 deletions fastlane/metadata/ios/hi/name.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
मोना - HRT जर्नल
1 change: 1 addition & 0 deletions fastlane/metadata/ios/hi/promotional_text.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
अपने हार्मोन ट्रैक करें। अपने meds प्रबंधित करें। सभी निजी, खुला और मुक्त।।
1 change: 1 addition & 0 deletions fastlane/metadata/ios/hi/subtitle.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
आपका ट्रांस हेल्थ साथी
1 change: 1 addition & 0 deletions fastlane/metadata/ios/hu/keywords.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
mona, transz, tansznemű, hormon, hormonális, követő, napló, hrt, napló, memó, estradiol, szimulátor
1 change: 1 addition & 0 deletions fastlane/metadata/ios/hu/name.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Mona - HRT napló
6 changes: 6 additions & 0 deletions fastlane/screenshot_captions/en.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"1": "Never miss a dose",
"2": "Monitor your levels and blood tests",
"3": "See your history at a glance",
"4": "Never run out"
}
6 changes: 6 additions & 0 deletions fastlane/screenshot_captions/fr.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"1": "Ne ratez jamais une prise",
"2": "Suivez vos taux et prises de sang",
"3": "Votre historique à portée de main",
"4": "Ne manquez jamais de stock"
}
4 changes: 4 additions & 0 deletions fastlane/screenshot_locales.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[
{ "app": "en", "play": "en-US", "appstore": "en-US" },
{ "app": "fr", "play": "fr-FR", "appstore": "fr-FR" }
]
Binary file added fastlane/screenshots/en-US/1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added fastlane/screenshots/en-US/2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added fastlane/screenshots/en-US/3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added fastlane/screenshots/en-US/4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added fastlane/screenshots/fr-FR/1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added fastlane/screenshots/fr-FR/2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added fastlane/screenshots/fr-FR/3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added fastlane/screenshots/fr-FR/4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
58 changes: 55 additions & 3 deletions lib/app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:mona/controllers/notification_planner.dart';
import 'package:mona/controllers/notification_scheduler.dart';
import 'package:mona/controllers/slot_finder.dart';
import 'package:mona/controllers/slots_builder.dart';
import 'package:mona/data/providers/medication_intake_provider.dart';
import 'package:mona/data/providers/medication_schedule_provider.dart';
import 'package:mona/i18n/build_context_extensions.dart';
Expand All @@ -14,9 +16,13 @@ import 'package:mona/services/notification_service.dart';
import 'package:mona/services/preferences_service.dart';
import 'package:mona/theme/app_theme_controller.dart';
import 'package:mona/theme/material_ui_theme.dart';
import 'package:mona/ui/views/home/take_medication_page.dart';
import 'package:provider/provider.dart';
import 'ui/views/main_page.dart';

const bool _forceDefaultColors = bool.fromEnvironment(
'SCREENSHOT_DEFAULT_COLORS'); // avoid dynamic colors when generating store screenshots

class MonaApp extends StatefulWidget {
const MonaApp({super.key});

Expand All @@ -25,7 +31,9 @@ class MonaApp extends StatefulWidget {
}

class _MonaAppState extends State<MonaApp> with WidgetsBindingObserver {
final GlobalKey<NavigatorState> _navigatorKey = GlobalKey<NavigatorState>();
String? _lastTimeZone;
NotificationPayload? _pendingLaunchTap;
late MedicationScheduleProvider _medicationScheduleProvider;
late MedicationIntakeProvider _medicationIntakeProvider;
late PreferencesService _preferencesService;
Expand All @@ -41,7 +49,7 @@ class _MonaAppState extends State<MonaApp> with WidgetsBindingObserver {
_lastTimeZone = clock.now().timeZoneOffset.toString();

WidgetsBinding.instance.addPostFrameCallback((_) async {
await NotificationService().initialize();
await NotificationService().initialize(onTap: _handleNotificationTap);
if (!mounted) return;
_medicationScheduleProvider = context.read<MedicationScheduleProvider>();
_medicationIntakeProvider = context.read<MedicationIntakeProvider>();
Expand All @@ -62,6 +70,11 @@ class _MonaAppState extends State<MonaApp> with WidgetsBindingObserver {
_medicationIntakeProvider.addListener(_regenerateHomeWidget);
_localeProvider.addListener(_regenerateHomeWidget);
_regenerateHomeWidget();

_medicationScheduleProvider.addListener(_routeLaunchTap);
_medicationIntakeProvider.addListener(_routeLaunchTap);
_pendingLaunchTap = await NotificationService().getAppLaunchTap();
_routeLaunchTap();
});
}

Expand All @@ -74,6 +87,8 @@ class _MonaAppState extends State<MonaApp> with WidgetsBindingObserver {
_preferencesService.removeListener(_regenerateNotifications);
_medicationIntakeProvider.removeListener(_regenerateHomeWidget);
_localeProvider.removeListener(_regenerateHomeWidget);
_medicationScheduleProvider.removeListener(_routeLaunchTap);
_medicationIntakeProvider.removeListener(_routeLaunchTap);
}
super.dispose();
}
Expand All @@ -94,6 +109,42 @@ class _MonaAppState extends State<MonaApp> with WidgetsBindingObserver {
);
}

void _routeLaunchTap() {
final tap = _pendingLaunchTap;
if (tap == null || !_initialized || !mounted) return;
if (_medicationScheduleProvider.isLoading ||
_medicationIntakeProvider.isLoading) {
return;
}

_pendingLaunchTap = null;
_handleNotificationTap(tap);
}

void _handleNotificationTap(NotificationPayload payload) {
if (!_initialized || !mounted) return;

final slots = SlotsBuilder(
_medicationIntakeProvider,
_medicationScheduleProvider,
).intakeSlots();
final target = findSlot(payload.scheduleId, payload.scheduledTime, slots);

if (target != null) {
_navigatorKey.currentState?.push(
MaterialPageRoute<void>(
fullscreenDialog: true,
builder: (_) =>
TakeMedicationPage(target.schedule, scheduledTime: target.time),
),
);
}

final notificationId = payload.notificationId;
if (notificationId != null) NotificationService().cancel(notificationId);
if (payload.isRepeating) _regenerateNotifications();
}

void _checkTimezoneChange() {
final currentTimezone = clock.now().timeZoneOffset.toString();
if (_lastTimeZone != currentTimezone) {
Expand All @@ -117,10 +168,11 @@ class _MonaAppState extends State<MonaApp> with WidgetsBindingObserver {
return DynamicColorBuilder(
builder: (ColorScheme? lightDynamic, ColorScheme? darkDynamic) {
final themes = context.read<AppThemeProvider>().buildThemeData(
systemLight: lightDynamic,
systemDark: darkDynamic,
systemLight: _forceDefaultColors ? null : lightDynamic,
systemDark: _forceDefaultColors ? null : darkDynamic,
);
return MaterialApp(
navigatorKey: _navigatorKey,
title: 'Mona',
locale: context.watch<LocaleProvider>().locale,
supportedLocales: context.watch<LocaleProvider>().supportedLocales,
Expand Down
18 changes: 18 additions & 0 deletions lib/controllers/medication_intake_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import 'package:decimal/decimal.dart';
import 'package:flutter/material.dart';
import 'package:flutter_timezone/flutter_timezone.dart';
import 'package:mona/controllers/supply_item_manager.dart';
import 'package:mona/data/model/administration_route.dart';
import 'package:mona/data/model/generic_supply_item.dart';
import 'package:mona/data/model/injection_type.dart';
import 'package:mona/data/model/medication_schedule.dart';
import 'package:mona/data/model/medication_supply_item.dart';
import 'package:mona/data/model/placement.dart';
Expand Down Expand Up @@ -33,6 +35,7 @@ class MedicationIntakeManager {
String? notes,
Decimal? wastedAmount, // in mL
List<Placement> placements = const [],
InjectionType? injectionType,
}) async {
if (!takenDateTime.isUtc) {
throw ArgumentError('takenDateTime must be in UTC');
Expand All @@ -57,6 +60,7 @@ class MedicationIntakeManager {
deadSpace: deadSpace,
placements: placements,
dosingBasis: schedule.dosingBasis,
injectionType: injectionType,
));

final itemManager = SupplyItemManager(_supplyItemProvider);
Expand Down Expand Up @@ -111,6 +115,7 @@ class MedicationIntakeManager {
List<GenericSupply> genericItems = const [],
String? notes,
List<Placement> placements = const [],
InjectionType? injectionType,
}) async {
if (!takenDateTime.isUtc) {
throw ArgumentError('takenDateTime must be in UTC');
Expand Down Expand Up @@ -173,6 +178,7 @@ class MedicationIntakeManager {
genericSupplyItemIds: genericItems.map((item) => item.id).toList(),
notes: notes,
placements: placements,
injectionType: injectionType,
));
}

Expand Down Expand Up @@ -205,6 +211,18 @@ class MedicationIntakeManager {
Placement? suggestNextPlacement({required int scheduleId}) =>
getOrderedPlacements(scheduleId: scheduleId).firstOrNull;

InjectionType? suggestInjectionType({required int scheduleId}) {
final lastIntake =
_medicationIntakeProvider.getLastTakenIntakeForSchedule(scheduleId);

if (lastIntake == null ||
lastIntake.administrationRoute != AdministrationRoute.injection) {
return null;
}

return lastIntake.injectionType;
}

MedicationSupplyItem? suggestMedicationItem({
required MedicationSchedule schedule,
}) {
Expand Down
3 changes: 3 additions & 0 deletions lib/controllers/notification_scheduler.dart
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class NotificationScheduler {
final dateFormat = DateFormat.MMMMd(localeName);
return NotificationService().scheduleNotification(
id: _notificationIdFor(plan.schedule.id, plan.dateTime),
scheduleId: plan.schedule.id,
title: t.notificationMedicationReminderTitle(
scheduleName: plan.schedule.name),
body: t.notificationMedicationReminderBodyDate(
Expand All @@ -70,6 +71,7 @@ class NotificationScheduler {
final timeFormat = DateFormat.Hm(localeName);
return NotificationService().scheduleDailyNotification(
id: _notificationIdFor(plan.schedule.id, plan.firstFire),
scheduleId: plan.schedule.id,
title: t.notificationMedicationReminderTitle(
scheduleName: plan.schedule.name),
body: t.notificationMedicationReminderBodyTime(
Expand All @@ -86,6 +88,7 @@ class NotificationScheduler {
final weekdayFormat = DateFormat.EEEE(localeName);
return NotificationService().scheduleWeeklyNotification(
id: _notificationIdFor(plan.schedule.id, plan.firstFire),
scheduleId: plan.schedule.id,
title: t.notificationMedicationReminderTitle(
scheduleName: plan.schedule.name),
body: t.notificationMedicationReminderBodyWeekday(
Expand Down
22 changes: 22 additions & 0 deletions lib/controllers/slot_finder.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import 'package:collection/collection.dart';
import 'package:flutter/material.dart';
import 'package:mona/data/model/intake_slot.dart';

IntakeSlot? findSlot(
int scheduleId,
DateTime scheduledTime,
List<IntakeSlot> slots,
) {
final targetSlots =
slots.where((slot) => slot.schedule.id == scheduleId).toList();
if (targetSlots.isEmpty) return null;

final slot = targetSlots.length == 1
? targetSlots.single
: targetSlots.firstWhereOrNull(
(slot) => slot.time == TimeOfDay.fromDateTime(scheduledTime));
if (slot == null) return null;
if (slot.intake != null) return null;

return slot;
}
9 changes: 9 additions & 0 deletions lib/data/model/injection_type.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import 'package:dart_mappable/dart_mappable.dart';

part 'injection_type.mapper.dart';

@MappableEnum()
enum InjectionType {
intramuscular,
subcutaneous,
}
Loading
Loading