125 lines
3.9 KiB
Dart
125 lines
3.9 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 'package:flutter/foundation.dart'; // For kIsWeb
|
|
|
|
class NotificationService {
|
|
static final NotificationService _instance = NotificationService._internal();
|
|
|
|
factory NotificationService() {
|
|
return _instance;
|
|
}
|
|
|
|
NotificationService._internal();
|
|
|
|
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
|
|
FlutterLocalNotificationsPlugin();
|
|
|
|
bool _isInitialized = false;
|
|
|
|
Future<void> initialize() async {
|
|
if (_isInitialized) return;
|
|
|
|
// Timezone initialization
|
|
if (!kIsWeb) {
|
|
tz.initializeTimeZones();
|
|
}
|
|
|
|
const AndroidInitializationSettings initializationSettingsAndroid =
|
|
AndroidInitializationSettings('@mipmap/ic_launcher');
|
|
|
|
final DarwinInitializationSettings initializationSettingsDarwin =
|
|
DarwinInitializationSettings(
|
|
requestAlertPermission: true,
|
|
requestBadgePermission: true,
|
|
requestSoundPermission: true,
|
|
);
|
|
|
|
// Linux initialization (optional, but good for completeness)
|
|
final LinuxInitializationSettings initializationSettingsLinux =
|
|
LinuxInitializationSettings(defaultActionName: 'Open notification');
|
|
|
|
final InitializationSettings initializationSettings = InitializationSettings(
|
|
android: initializationSettingsAndroid,
|
|
iOS: initializationSettingsDarwin,
|
|
macOS: initializationSettingsDarwin,
|
|
linux: initializationSettingsLinux,
|
|
);
|
|
|
|
await flutterLocalNotificationsPlugin.initialize(
|
|
initializationSettings,
|
|
onDidReceiveNotificationResponse: (NotificationResponse details) async {
|
|
// Handle notification tap
|
|
},
|
|
);
|
|
|
|
_isInitialized = true;
|
|
}
|
|
|
|
Future<void> scheduleNotification({
|
|
required int id,
|
|
required String title,
|
|
required String body,
|
|
required DateTime scheduledDate,
|
|
}) async {
|
|
if (kIsWeb) {
|
|
// Web platform limitation: Background scheduling is complex.
|
|
// For this demo/web preview, we'll just log it or rely on the UI confirmation.
|
|
print('Web Notification Scheduled: $title - $body at $scheduledDate');
|
|
return;
|
|
}
|
|
|
|
await flutterLocalNotificationsPlugin.zonedSchedule(
|
|
id,
|
|
title,
|
|
body,
|
|
tz.TZDateTime.from(scheduledDate, tz.local),
|
|
const NotificationDetails(
|
|
android: AndroidNotificationDetails(
|
|
'pad_tracker_channel',
|
|
'Pad Tracker Reminders',
|
|
channelDescription: 'Reminders to change pad/tampon',
|
|
importance: Importance.max,
|
|
priority: Priority.high,
|
|
),
|
|
iOS: DarwinNotificationDetails(),
|
|
),
|
|
androidScheduleMode: AndroidScheduleMode.exactAllowWhileIdle,
|
|
uiLocalNotificationDateInterpretation:
|
|
UILocalNotificationDateInterpretation.absoluteTime,
|
|
);
|
|
}
|
|
|
|
// New method for specific notification types
|
|
Future<void> showLocalNotification({
|
|
required int id,
|
|
required String title,
|
|
required String body,
|
|
String? channelId,
|
|
String? channelName,
|
|
}) async {
|
|
if (kIsWeb) {
|
|
print('Web Local Notification: $title - $body');
|
|
return;
|
|
}
|
|
const AndroidNotificationDetails androidNotificationDetails =
|
|
AndroidNotificationDetails(
|
|
'tracker_general', 'General Notifications',
|
|
channelDescription: 'General app notifications',
|
|
importance: Importance.max,
|
|
priority: Priority.high,
|
|
ticker: 'ticker');
|
|
|
|
const NotificationDetails notificationDetails =
|
|
NotificationDetails(android: androidNotificationDetails);
|
|
|
|
await flutterLocalNotificationsPlugin.show(
|
|
id, title, body, notificationDetails,
|
|
payload: 'item x');
|
|
}
|
|
|
|
Future<void> cancelNotification(int id) async {
|
|
await flutterLocalNotificationsPlugin.cancel(id);
|
|
}
|
|
}
|