mirror of
https://github.com/chenasraf/pantry-flutter.git
synced 2026-05-17 17:28:03 +00:00
134 lines
3.8 KiB
Dart
134 lines
3.8 KiB
Dart
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
|
import 'package:pantry/services/deep_link_service.dart';
|
|
|
|
class LocalNotificationsService {
|
|
LocalNotificationsService._();
|
|
static final LocalNotificationsService instance =
|
|
LocalNotificationsService._();
|
|
|
|
final _plugin = FlutterLocalNotificationsPlugin();
|
|
bool _initialized = false;
|
|
|
|
static const _channelId = 'pantry_notifications';
|
|
static const _channelName = 'Pantry notifications';
|
|
static const _channelDescription = 'Household activity from your pantry';
|
|
|
|
Future<void> init() async {
|
|
if (_initialized) return;
|
|
|
|
const androidSettings = AndroidInitializationSettings(
|
|
'@mipmap/ic_launcher',
|
|
);
|
|
const darwinSettings = DarwinInitializationSettings(
|
|
requestAlertPermission: false,
|
|
requestBadgePermission: false,
|
|
requestSoundPermission: false,
|
|
);
|
|
const settings = InitializationSettings(
|
|
android: androidSettings,
|
|
iOS: darwinSettings,
|
|
macOS: darwinSettings,
|
|
);
|
|
|
|
await _plugin.initialize(
|
|
settings,
|
|
onDidReceiveNotificationResponse: _onTap,
|
|
);
|
|
|
|
// If the app was launched by tapping a notification (cold start),
|
|
// capture that payload so the home view can consume it after startup.
|
|
final launchDetails = await _plugin.getNotificationAppLaunchDetails();
|
|
if (launchDetails?.didNotificationLaunchApp ?? false) {
|
|
final payload = launchDetails?.notificationResponse?.payload;
|
|
final link = DeepLink.decode(payload);
|
|
if (link != null) DeepLinkService.instance.push(link);
|
|
}
|
|
|
|
// Create the Android channel (no-op on iOS).
|
|
final androidPlugin = _plugin
|
|
.resolvePlatformSpecificImplementation<
|
|
AndroidFlutterLocalNotificationsPlugin
|
|
>();
|
|
await androidPlugin?.createNotificationChannel(
|
|
const AndroidNotificationChannel(
|
|
_channelId,
|
|
_channelName,
|
|
description: _channelDescription,
|
|
importance: Importance.defaultImportance,
|
|
),
|
|
);
|
|
|
|
_initialized = true;
|
|
}
|
|
|
|
/// Request runtime notification permission (Android 13+ and iOS).
|
|
Future<bool> requestPermission() async {
|
|
await init();
|
|
|
|
final android = _plugin
|
|
.resolvePlatformSpecificImplementation<
|
|
AndroidFlutterLocalNotificationsPlugin
|
|
>();
|
|
final androidGranted =
|
|
await android?.requestNotificationsPermission() ?? true;
|
|
|
|
final ios = _plugin
|
|
.resolvePlatformSpecificImplementation<
|
|
IOSFlutterLocalNotificationsPlugin
|
|
>();
|
|
final iosGranted =
|
|
await ios?.requestPermissions(alert: true, badge: true, sound: true) ??
|
|
true;
|
|
|
|
final macos = _plugin
|
|
.resolvePlatformSpecificImplementation<
|
|
MacOSFlutterLocalNotificationsPlugin
|
|
>();
|
|
final macosGranted =
|
|
await macos?.requestPermissions(
|
|
alert: true,
|
|
badge: true,
|
|
sound: true,
|
|
) ??
|
|
true;
|
|
|
|
return androidGranted && iosGranted && macosGranted;
|
|
}
|
|
|
|
Future<void> show({
|
|
required int id,
|
|
required String title,
|
|
String? body,
|
|
String? payload,
|
|
}) async {
|
|
await init();
|
|
await _plugin.show(
|
|
id,
|
|
title,
|
|
body,
|
|
const NotificationDetails(
|
|
android: AndroidNotificationDetails(
|
|
_channelId,
|
|
_channelName,
|
|
channelDescription: _channelDescription,
|
|
importance: Importance.defaultImportance,
|
|
priority: Priority.defaultPriority,
|
|
),
|
|
iOS: DarwinNotificationDetails(),
|
|
macOS: DarwinNotificationDetails(),
|
|
),
|
|
payload: payload,
|
|
);
|
|
}
|
|
|
|
static void _onTap(NotificationResponse response) {
|
|
final link = DeepLink.decode(response.payload);
|
|
if (link != null) DeepLinkService.instance.push(link);
|
|
}
|
|
|
|
Future<void> cancelAll() async {
|
|
await init();
|
|
await _plugin.cancelAll();
|
|
}
|
|
}
|