From 1bad43dd9c4a240aa4595cb8f18c0125eb54cf7b Mon Sep 17 00:00:00 2001 From: dab246 Date: Wed, 23 Nov 2022 15:16:11 +0700 Subject: [PATCH] TF-1217 Create local notification manager --- .../local_notification_config.dart | 38 +++++++ .../local_notification_manager.dart | 101 ++++++++++++++++++ pubspec.lock | 28 +++++ pubspec.yaml | 1 + 4 files changed, 168 insertions(+) create mode 100644 lib/features/push_notification/presentation/notification/local_notification_config.dart create mode 100644 lib/features/push_notification/presentation/notification/local_notification_manager.dart diff --git a/lib/features/push_notification/presentation/notification/local_notification_config.dart b/lib/features/push_notification/presentation/notification/local_notification_config.dart new file mode 100644 index 000000000..d8feb30eb --- /dev/null +++ b/lib/features/push_notification/presentation/notification/local_notification_config.dart @@ -0,0 +1,38 @@ +import 'package:flutter_local_notifications/flutter_local_notifications.dart'; + +class LocalNotificationConfig { + static const channelId = 'team_mail_channel_id'; + static const channelKey = 'team_mail_channel_key'; + static const channelName = 'Team Mail notifications'; + static const channelDescription = 'Team Mail notifications'; + + static const iosInitializationSettings = DarwinInitializationSettings(); + + static const androidInitializationSettings = AndroidInitializationSettings('background'); + + static const androidNotificationChannel = AndroidNotificationChannel( + channelId, + channelName, + description: channelDescription, + importance: Importance.max, + enableLights: true, + ); + + static const pushNotificationDetails = NotificationDetails( + android: AndroidNotificationDetails( + channelId, + channelName, + channelDescription: channelDescription, + visibility: NotificationVisibility.public, + importance: Importance.max, + ledOnMs: 100, + ledOffMs: 1000, + category: AndroidNotificationCategory.message, + ), + iOS: DarwinNotificationDetails( + presentSound: true, + presentAlert: true, + presentBadge: true, + ), + ); +} \ No newline at end of file diff --git a/lib/features/push_notification/presentation/notification/local_notification_manager.dart b/lib/features/push_notification/presentation/notification/local_notification_manager.dart new file mode 100644 index 000000000..ce8a7ecf6 --- /dev/null +++ b/lib/features/push_notification/presentation/notification/local_notification_manager.dart @@ -0,0 +1,101 @@ + +import 'dart:io'; + +import 'package:core/utils/app_logger.dart'; +import 'package:flutter_local_notifications/flutter_local_notifications.dart'; +import 'package:tmail_ui_user/features/push_notification/presentation/notification/local_notification_config.dart'; + +@pragma('vm:entry-point') +void _handleReceiveBackgroundNotificationResponse(NotificationResponse notificationResponse) { + log('LocalNotificationManager::_handleReceiveBackgroundNotificationResponse():notificationResponse: $notificationResponse'); +} + +class LocalNotificationManager { + + LocalNotificationManager._internal(); + + static final LocalNotificationManager _instance = LocalNotificationManager._internal(); + + static LocalNotificationManager get instance => _instance; + + final _localNotificationsPlugin = FlutterLocalNotificationsPlugin(); + bool notificationsEnabled = false; + + Future setUp() async { + try { + await _initLocalNotification(); + _checkLocalNotificationPermission(); + if (Platform.isAndroid) { + await _createAndroidNotificationChannels(); + } + } catch (e) { + logError('LocalNotificationManager::setUp(): ERROR: ${e.toString()}'); + } + } + + Future _initLocalNotification() async { + return await _localNotificationsPlugin.initialize( + const InitializationSettings( + android: LocalNotificationConfig.androidInitializationSettings, + iOS: LocalNotificationConfig.iosInitializationSettings + ), + onDidReceiveNotificationResponse: _handleReceiveNotificationResponse, + onDidReceiveBackgroundNotificationResponse: _handleReceiveBackgroundNotificationResponse + ); + } + + void _handleReceiveNotificationResponse(NotificationResponse response) { + log('LocalNotificationManager::handleReceiveNotificationResponse(): $response'); + } + + void _checkLocalNotificationPermission() async { + if (notificationsEnabled) { + return; + } + + if (Platform.isAndroid) { + final granted = await _isAndroidPermissionGranted(); + if (!granted) { + notificationsEnabled = await _requestPermissions(); + } + } else { + notificationsEnabled = await _requestPermissions(); + } + } + + Future _isAndroidPermissionGranted() async { + return await _localNotificationsPlugin + .resolvePlatformSpecificImplementation() + ?.areNotificationsEnabled() ?? false; + } + + Future _requestPermissions() async { + if (Platform.isAndroid) { + return await _localNotificationsPlugin + .resolvePlatformSpecificImplementation() + ?.requestPermission() ?? false; + } else { + return await _localNotificationsPlugin + .resolvePlatformSpecificImplementation() + ?.requestPermissions(alert: true, badge: true, sound: true) ?? false; + } + } + + Future _createAndroidNotificationChannels() async { + return await _localNotificationsPlugin + .resolvePlatformSpecificImplementation() + ?.createNotificationChannel(LocalNotificationConfig.androidNotificationChannel); + } + + void showPushNotification({String? title, String? message, String? payload}) async { + final generateNotificationId = DateTime.now().millisecondsSinceEpoch.remainder(100000); + + await _localNotificationsPlugin.show( + generateNotificationId, + title ?? LocalNotificationConfig.channelName, + message ?? LocalNotificationConfig.channelDescription, + LocalNotificationConfig.pushNotificationDetails, + payload: payload + ); + } +} \ No newline at end of file diff --git a/pubspec.lock b/pubspec.lock index 4298a3e5f..76c97fe42 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -623,6 +623,27 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.4" + flutter_local_notifications: + dependency: "direct main" + description: + name: flutter_local_notifications + url: "https://pub.dartlang.org" + source: hosted + version: "12.0.3" + flutter_local_notifications_linux: + dependency: transitive + description: + name: flutter_local_notifications_linux + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + flutter_local_notifications_platform_interface: + dependency: transitive + description: + name: flutter_local_notifications_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "6.0.0" flutter_localizations: dependency: "direct main" description: flutter @@ -1386,6 +1407,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.2.2" + timezone: + dependency: transitive + description: + name: timezone + url: "https://pub.dartlang.org" + source: hosted + version: "0.9.0" timing: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index be83d1bb2..3758d8fca 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -198,6 +198,7 @@ dependencies: url_launcher: 6.1.5 firebase_core: 2.2.0 firebase_messaging: 14.0.4 + flutter_local_notifications: 12.0.3 dev_dependencies: flutter_test: