- Murattal: Spotify-style 5-button controls [Shuffle, Prev, Play, Next, Playlist] - Murattal: Animated 7-bar equalizer visualization in player circle - Murattal: Unsplash API background with frosted glass player overlay - Murattal: Transparent AppBar with backdrop blur - Murattal: Surah playlist bottom sheet with full 114 Surah list - Murattal: Auto-play disabled on screen open, enabled on navigation - Murattal: Shuffle mode for random Surah playback - Murattal: Photographer attribution per Unsplash guidelines - Dashboard: Auto-scroll prayer schedule to next active prayer - Fix: setState lifecycle errors on Reading & Murattal screens - Setup: flutter_dotenv, cached_network_image, url_launcher deps
99 lines
2.9 KiB
Dart
99 lines
2.9 KiB
Dart
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
|
import 'package:timezone/timezone.dart' as tz;
|
|
|
|
/// Notification service for Adhan and Iqamah notifications.
|
|
class NotificationService {
|
|
NotificationService._();
|
|
static final NotificationService instance = NotificationService._();
|
|
|
|
final FlutterLocalNotificationsPlugin _plugin =
|
|
FlutterLocalNotificationsPlugin();
|
|
|
|
bool _initialized = false;
|
|
|
|
/// Initialize notification channels.
|
|
Future<void> init() async {
|
|
if (_initialized) return;
|
|
|
|
const androidSettings = AndroidInitializationSettings('@mipmap/ic_launcher');
|
|
const darwinSettings = DarwinInitializationSettings(
|
|
requestAlertPermission: true,
|
|
requestBadgePermission: true,
|
|
requestSoundPermission: true,
|
|
);
|
|
|
|
const settings = InitializationSettings(
|
|
android: androidSettings,
|
|
iOS: darwinSettings,
|
|
macOS: darwinSettings,
|
|
);
|
|
|
|
await _plugin.initialize(settings);
|
|
_initialized = true;
|
|
}
|
|
|
|
/// Schedule an Adhan notification at a specific time.
|
|
Future<void> scheduleAdhan({
|
|
required int id,
|
|
required String prayerName,
|
|
required DateTime time,
|
|
}) async {
|
|
await _plugin.zonedSchedule(
|
|
id,
|
|
'Adhan - $prayerName',
|
|
'It\'s time for $prayerName prayer',
|
|
tz.TZDateTime.from(time, tz.local),
|
|
const NotificationDetails(
|
|
android: AndroidNotificationDetails(
|
|
'adhan_channel',
|
|
'Adhan Notifications',
|
|
channelDescription: 'Prayer time adhan notifications',
|
|
importance: Importance.high,
|
|
priority: Priority.high,
|
|
),
|
|
iOS: DarwinNotificationDetails(
|
|
presentAlert: true,
|
|
presentBadge: true,
|
|
presentSound: true,
|
|
),
|
|
),
|
|
androidScheduleMode: AndroidScheduleMode.exactAllowWhileIdle,
|
|
);
|
|
}
|
|
|
|
/// Schedule an Iqamah reminder notification.
|
|
Future<void> scheduleIqamah({
|
|
required int id,
|
|
required String prayerName,
|
|
required DateTime adhanTime,
|
|
required int offsetMinutes,
|
|
}) async {
|
|
final iqamahTime = adhanTime.add(Duration(minutes: offsetMinutes));
|
|
await _plugin.zonedSchedule(
|
|
id + 100, // Offset IDs for iqamah
|
|
'Iqamah - $prayerName',
|
|
'Iqamah for $prayerName in $offsetMinutes minutes',
|
|
tz.TZDateTime.from(iqamahTime, tz.local),
|
|
const NotificationDetails(
|
|
android: AndroidNotificationDetails(
|
|
'iqamah_channel',
|
|
'Iqamah Reminders',
|
|
channelDescription: 'Iqamah reminder notifications',
|
|
importance: Importance.defaultImportance,
|
|
priority: Priority.defaultPriority,
|
|
),
|
|
iOS: DarwinNotificationDetails(
|
|
presentAlert: true,
|
|
presentSound: true,
|
|
),
|
|
),
|
|
androidScheduleMode: AndroidScheduleMode.exactAllowWhileIdle,
|
|
);
|
|
}
|
|
|
|
/// Cancel all pending notifications.
|
|
Future<void> cancelAll() async {
|
|
await _plugin.cancelAll();
|
|
}
|
|
}
|