mirror of
https://github.com/vleeuwenmenno/supplements.git
synced 2025-12-07 21:52:35 +00:00
125 lines
4.1 KiB
Dart
125 lines
4.1 KiB
Dart
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
|
import 'package:timezone/timezone.dart' as tz;
|
|
import 'package:timezone/data/latest.dart' as tz;
|
|
import '../models/supplement.dart';
|
|
|
|
class NotificationService {
|
|
static final NotificationService _instance = NotificationService._internal();
|
|
factory NotificationService() => _instance;
|
|
NotificationService._internal();
|
|
|
|
final FlutterLocalNotificationsPlugin _notifications = FlutterLocalNotificationsPlugin();
|
|
|
|
Future<void> initialize() async {
|
|
tz.initializeTimeZones();
|
|
|
|
const AndroidInitializationSettings androidSettings = AndroidInitializationSettings('@mipmap/ic_launcher');
|
|
const DarwinInitializationSettings iosSettings = DarwinInitializationSettings(
|
|
requestAlertPermission: true,
|
|
requestBadgePermission: true,
|
|
requestSoundPermission: true,
|
|
);
|
|
|
|
const InitializationSettings initSettings = InitializationSettings(
|
|
android: androidSettings,
|
|
iOS: iosSettings,
|
|
);
|
|
|
|
await _notifications.initialize(initSettings);
|
|
}
|
|
|
|
Future<bool> requestPermissions() async {
|
|
final androidPlugin = _notifications.resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>();
|
|
if (androidPlugin != null) {
|
|
await androidPlugin.requestNotificationsPermission();
|
|
}
|
|
|
|
final iosPlugin = _notifications.resolvePlatformSpecificImplementation<IOSFlutterLocalNotificationsPlugin>();
|
|
if (iosPlugin != null) {
|
|
await iosPlugin.requestPermissions(
|
|
alert: true,
|
|
badge: true,
|
|
sound: true,
|
|
);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
Future<void> scheduleSupplementReminders(Supplement supplement) async {
|
|
// Cancel existing notifications for this supplement
|
|
await cancelSupplementReminders(supplement.id!);
|
|
|
|
for (int i = 0; i < supplement.reminderTimes.length; i++) {
|
|
final timeStr = supplement.reminderTimes[i];
|
|
final timeParts = timeStr.split(':');
|
|
final hour = int.parse(timeParts[0]);
|
|
final minute = int.parse(timeParts[1]);
|
|
|
|
final notificationId = supplement.id! * 100 + i; // Unique ID for each reminder
|
|
|
|
await _notifications.zonedSchedule(
|
|
notificationId,
|
|
'Time for ${supplement.name}',
|
|
'Take ${supplement.dosage} ${supplement.unit}',
|
|
_nextInstanceOfTime(hour, minute),
|
|
const NotificationDetails(
|
|
android: AndroidNotificationDetails(
|
|
'supplement_reminders',
|
|
'Supplement Reminders',
|
|
channelDescription: 'Notifications for supplement intake reminders',
|
|
importance: Importance.high,
|
|
priority: Priority.high,
|
|
),
|
|
iOS: DarwinNotificationDetails(),
|
|
),
|
|
androidScheduleMode: AndroidScheduleMode.exactAllowWhileIdle,
|
|
matchDateTimeComponents: DateTimeComponents.time,
|
|
);
|
|
}
|
|
}
|
|
|
|
Future<void> cancelSupplementReminders(int supplementId) async {
|
|
// Cancel all notifications for this supplement (up to 10 possible reminders)
|
|
for (int i = 0; i < 10; i++) {
|
|
final notificationId = supplementId * 100 + i;
|
|
await _notifications.cancel(notificationId);
|
|
}
|
|
}
|
|
|
|
Future<void> cancelAllReminders() async {
|
|
await _notifications.cancelAll();
|
|
}
|
|
|
|
tz.TZDateTime _nextInstanceOfTime(int hour, int minute) {
|
|
final tz.TZDateTime now = tz.TZDateTime.now(tz.local);
|
|
tz.TZDateTime scheduledDate = tz.TZDateTime(tz.local, now.year, now.month, now.day, hour, minute);
|
|
|
|
if (scheduledDate.isBefore(now)) {
|
|
scheduledDate = scheduledDate.add(const Duration(days: 1));
|
|
}
|
|
|
|
return scheduledDate;
|
|
}
|
|
|
|
Future<void> showInstantNotification(String title, String body) async {
|
|
const NotificationDetails notificationDetails = NotificationDetails(
|
|
android: AndroidNotificationDetails(
|
|
'instant_notifications',
|
|
'Instant Notifications',
|
|
channelDescription: 'Instant notifications for supplement app',
|
|
importance: Importance.high,
|
|
priority: Priority.high,
|
|
),
|
|
iOS: DarwinNotificationDetails(),
|
|
);
|
|
|
|
await _notifications.show(
|
|
DateTime.now().millisecondsSinceEpoch ~/ 1000,
|
|
title,
|
|
body,
|
|
notificationDetails,
|
|
);
|
|
}
|
|
}
|