TF-2384 Handle open email detailed when click notification on background mode

Signed-off-by: dab246 <tdvu@linagora.com>
(cherry picked from commit 72db39c87dbd8f06bfbb417e4fed4d384da356ea)
This commit is contained in:
dab246
2023-12-25 00:03:48 +07:00
committed by Dat H. Pham
parent aac12f5731
commit 84b7239ad0
8 changed files with 98 additions and 12 deletions
+19
View File
@@ -7,12 +7,16 @@ import flutter_local_notifications
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
var notificationInteractionChannel: FlutterMethodChannel?
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
createNotificationInteractionChannel()
if #available(iOS 10.0, *) {
UNUserNotificationCenter.current().delegate = self as UNUserNotificationCenterDelegate
}
@@ -94,7 +98,13 @@ import flutter_local_notifications
}
override func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
TwakeLogger.shared.log(message: "AppDelegate::userNotificationCenter::didReceive::response: \(response)")
updateAppBadger(currentBadgeCount: UIApplication.shared.applicationIconBadgeNumber)
if let emailId = response.notification.request.content.userInfo[JmapConstants.EMAIL_ID] as? String {
self.notificationInteractionChannel?.invokeMethod("openEmail", arguments: emailId)
}
completionHandler()
}
}
@@ -124,4 +134,13 @@ extension AppDelegate {
private func isAppForegroundActive() -> Bool {
return UIApplication.shared.applicationState == .active
}
private func createNotificationInteractionChannel() {
let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
self.notificationInteractionChannel = FlutterMethodChannel(
name: "notification_interaction_channel",
binaryMessenger: controller.binaryMessenger
)
}
}
@@ -3,6 +3,7 @@ import 'package:flutter/foundation.dart';
import 'package:flutter_downloader/flutter_downloader.dart';
import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/core/session/session.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
import 'package:model/account/personal_account.dart';
import 'package:model/email/email_content.dart';
@@ -19,6 +20,7 @@ import 'package:tmail_ui_user/features/cleanup/domain/usecases/cleanup_email_cac
import 'package:tmail_ui_user/features/cleanup/domain/usecases/cleanup_recent_login_url_cache_interactor.dart';
import 'package:tmail_ui_user/features/cleanup/domain/usecases/cleanup_recent_login_username_interactor.dart';
import 'package:tmail_ui_user/features/cleanup/domain/usecases/cleanup_recent_search_cache_interactor.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/preview_email_arguments.dart';
import 'package:tmail_ui_user/main/routes/app_routes.dart';
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
import 'package:tmail_ui_user/main/routes/route_utils.dart';
@@ -40,6 +42,7 @@ class HomeController extends ReloadableController {
);
PersonalAccount? currentAccount;
EmailId? _emailIdPreview;
@override
void onInit() {
@@ -47,6 +50,9 @@ class HomeController extends ReloadableController {
_initFlutterDownloader();
_registerReceivingSharingIntent();
}
if (PlatformInfo.isIOS && Get.arguments is EmailId) {
_emailIdPreview = Get.arguments;
}
super.onInit();
}
@@ -58,10 +64,20 @@ class HomeController extends ReloadableController {
@override
void handleReloaded(Session session) {
popAndPush(
RouteUtils.generateNavigationRoute(AppRoutes.dashboard),
arguments: session
);
if (_emailIdPreview != null) {
popAndPush(
RouteUtils.generateNavigationRoute(AppRoutes.dashboard),
arguments: PreviewEmailArguments(
session: session,
emailId: _emailIdPreview!
)
);
} else {
popAndPush(
RouteUtils.generateNavigationRoute(AppRoutes.dashboard),
arguments: session
);
}
}
void _initFlutterDownloader() {
@@ -84,6 +84,7 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/comp
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/dashboard_routes.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/download/download_task_state.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/draggable_app_state.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/preview_email_arguments.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/refresh_action_view_event.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/email_receive_time_type.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/email_sort_order_type.dart';
@@ -112,6 +113,7 @@ import 'package:tmail_ui_user/features/push_notification/domain/usecases/get_ema
import 'package:tmail_ui_user/features/push_notification/domain/usecases/get_mailbox_state_to_refresh_interactor.dart';
import 'package:tmail_ui_user/features/push_notification/presentation/notification/local_notification_manager.dart';
import 'package:tmail_ui_user/features/push_notification/presentation/services/fcm_service.dart';
import 'package:tmail_ui_user/features/push_notification/presentation/utils/fcm_utils.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/model/sending_email.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/state/get_all_sending_email_state.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/state/update_sending_email_state.dart';
@@ -438,7 +440,7 @@ class MailboxDashBoardController extends ReloadableController {
});
_refreshActionEventController.stream
.debounceTime(const Duration(milliseconds: FcmService.durationMessageComing))
.debounceTime(const Duration(milliseconds: FcmUtils.durationMessageComing))
.listen(_handleRefreshActionWhenBackToApp);
_registerLocalNotificationStreamListener();
@@ -462,6 +464,8 @@ class MailboxDashBoardController extends ReloadableController {
_handleSession(arguments);
} else if (arguments is MailtoArguments) {
_handleMailtoURL(arguments);
} else if (arguments is PreviewEmailArguments) {
_handleOpenEmailAction(arguments);
} else {
dispatchRoute(DashboardRoutes.thread);
reload();
@@ -532,6 +536,13 @@ class MailboxDashBoardController extends ReloadableController {
_handleSession(arguments.session);
}
void _handleOpenEmailAction(PreviewEmailArguments arguments) {
log('MailboxDashBoardController::_handleOpenEmailAction:arguments: $arguments');
dispatchRoute(DashboardRoutes.waiting);
_handleSession(arguments.session);
_handleNotificationMessageFromEmailId(arguments.emailId);
}
Future<void> _getAppVersion() async {
final info = await PackageInfo.fromPlatform();
log('MailboxDashBoardController::_getAppVersion(): ${info.version}');
@@ -1718,7 +1729,7 @@ class MailboxDashBoardController extends ReloadableController {
void _showWaitingView() {
popAllRouteIfHave();
dispatchRoute( DashboardRoutes.waiting);
dispatchRoute(DashboardRoutes.waiting);
}
void _openInboxMailboxFromNotification() {
@@ -0,0 +1,15 @@
import 'package:jmap_dart_client/jmap/core/session/session.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:tmail_ui_user/main/routes/router_arguments.dart';
class PreviewEmailArguments extends RouterArguments {
final Session session;
final EmailId emailId;
PreviewEmailArguments({required this.session, required this.emailId});
@override
List<Object?> get props => [session, emailId];
}
@@ -73,21 +73,21 @@ class FcmMessageController extends FcmBaseController {
void _listenForegroundMessageStream() {
FcmService.instance.foregroundMessageStreamController
?.stream
.throttleTime(const Duration(milliseconds: FcmService.durationMessageComing))
.throttleTime(const Duration(milliseconds: FcmUtils.durationMessageComing))
.listen(_handleForegroundMessageAction);
}
void _listenBackgroundMessageStream() {
FcmService.instance.backgroundMessageStreamController
?.stream
.throttleTime(const Duration(milliseconds: FcmService.durationMessageComing))
.throttleTime(const Duration(milliseconds: FcmUtils.durationMessageComing))
.listen(_handleBackgroundMessageAction);
}
void _listenTokenStream() {
FcmService.instance.fcmTokenStreamController
?.stream
.throttleTime(const Duration(milliseconds: FcmService.durationRefreshToken))
.throttleTime(const Duration(milliseconds: FcmUtils.durationRefreshToken))
.listen(FcmTokenController.instance.onFcmTokenChanged);
}
@@ -2,6 +2,7 @@
import 'package:core/utils/app_logger.dart';
import 'package:core/utils/platform_info.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/services.dart';
import 'package:tmail_ui_user/features/push_notification/presentation/controller/fcm_message_controller.dart';
import 'package:tmail_ui_user/features/push_notification/presentation/services/fcm_service.dart';
import 'package:tmail_ui_user/main/utils/app_config.dart';
@@ -20,12 +21,24 @@ class FcmReceiver {
static FcmReceiver get instance => _instance;
static const notificationInteractionChannel = MethodChannel('notification_interaction_channel');
Future onInitialFcmListener() async {
log('FcmReceiver::onInitialFcmListener:');
await _onHandleFcmToken();
_onForegroundMessage();
_onBackgroundMessage();
if (PlatformInfo.isIOS) {
notificationInteractionChannel.setMethodCallHandler((call) async {
log('FcmReceiver::onInitialFcmListener:notificationInteractionChannel: $call');
if (call.method == 'openEmail') {
log('FcmReceiver::onInitialFcmListener:openEmail with id = ${call.arguments}');
FcmService.instance.handleOpenEmailFromNotification(call.arguments);
}
});
}
}
void _onForegroundMessage() {
@@ -3,12 +3,14 @@ import 'dart:async';
import 'package:core/utils/app_logger.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:jmap_dart_client/jmap/core/id.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:tmail_ui_user/main/routes/app_routes.dart';
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
import 'package:tmail_ui_user/main/routes/route_utils.dart';
class FcmService {
static const int durationMessageComing = 2000;
static const int durationRefreshToken = 2000;
StreamController<Map<String, dynamic>>? foregroundMessageStreamController;
StreamController<Map<String, dynamic>>? backgroundMessageStreamController;
StreamController<String?>? fcmTokenStreamController;
@@ -45,6 +47,14 @@ class FcmService {
fcmTokenStreamController = StreamController<String?>.broadcast();
}
void handleOpenEmailFromNotification(String emailId) {
log('FcmService::handleOpenEmailFromNotification:emailId: $emailId');
popAndPush(
RouteUtils.generateNavigationRoute(AppRoutes.home),
arguments: EmailId(Id(emailId))
);
}
void closeStream() {
foregroundMessageStreamController?.close();
backgroundMessageStreamController?.close();
@@ -31,6 +31,8 @@ class FcmUtils {
TypeName.mailboxType,
TypeName.emailDelivery
];
static const int durationMessageComing = 2000;
static const int durationRefreshToken = 2000;
StateChange? convertFirebaseDataMessageToStateChange(Map<String, dynamic> dataMessage) {
log('FcmUtils::convertFirebaseDataMessageToStateChange():dataMessage: $dataMessage');