Skip to content

Commit

Permalink
TF-2871 Block notification on folders Sent, Outbox, Drafts, `Sp…
Browse files Browse the repository at this point in the history
…am` and `Trash`
  • Loading branch information
dab246 committed Jul 15, 2024
1 parent a592ce2 commit 6ab6507
Show file tree
Hide file tree
Showing 11 changed files with 182 additions and 40 deletions.
2 changes: 1 addition & 1 deletion ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ SPEC CHECKSUMS:
FirebaseInstallations: 558b1da7d65afeb996fd5c814332f013234ece4e
FirebaseMessaging: e345b219fd15d325f0cf2fef28cb8ce00d851b3f
fk_user_agent: 1f47ec39291e8372b1d692b50084b0d54103c545
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
flutter_appauth: 1ce438877bc111c5d8f42da47729909290624886
flutter_downloader: b7301ae057deadd4b1650dc7c05375f10ff12c39
flutter_image_compress_common: ec1d45c362c9d30a3f6a0426c297f47c52007e3e
Expand Down
18 changes: 16 additions & 2 deletions ios/TwakeCore/Jmap/JmapClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ class JmapClient {
accountId: String,
onComplete: @escaping ([Email], [Error]) -> Void) {
guard hasMoreChanges, let sinceState = currentSinceState else {
if !self.totalListEmails.isEmpty {
let sortedListEmails = self.sortListEmails(currentListEmails: self.totalListEmails)
self.totalListEmails = sortedListEmails
}

return onComplete(self.totalListEmails, self.listErrors)
}

Expand All @@ -85,8 +90,7 @@ class JmapClient {
if let response = data.parsing(methodName: JmapConstants.EMAIL_GET_METHOD_NAME, methodCallId: "c1") {
if let listEmail = response.list,
!listEmail.isEmpty {
let sortedListEmails = self.sortListEmails(currentListEmails: listEmail)
self.totalListEmails.append(contentsOf: sortedListEmails)
self.totalListEmails.append(contentsOf: listEmail)
}
self.hasMoreChanges = response.hasMoreChanges ?? false
self.currentSinceState = response.newState
Expand All @@ -97,6 +101,11 @@ class JmapClient {
self.hasMoreChanges = false
self.currentSinceState = nil

if !self.totalListEmails.isEmpty {
let sortedListEmails = self.sortListEmails(currentListEmails: self.totalListEmails)
self.totalListEmails = sortedListEmails
}

onComplete(self.totalListEmails, self.listErrors)
}
},
Expand All @@ -105,6 +114,11 @@ class JmapClient {
self.hasMoreChanges = false
self.currentSinceState = nil

if !self.totalListEmails.isEmpty {
let sortedListEmails = self.sortListEmails(currentListEmails: self.totalListEmails)
self.totalListEmails = sortedListEmails
}

onComplete(self.totalListEmails, self.listErrors)
}
)
Expand Down
10 changes: 10 additions & 0 deletions ios/TwakeCore/Jmap/Model/Email/Email.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,21 @@ struct Email: Codable {
let preview: String?
let from: [EmailAddress]?
let receivedAt: String?
let mailboxIds: [String: Bool]?

func getSenderName() -> String? {
if (from == nil || from?.isEmpty == true) {
return nil
}
return from?.first?.name ?? from?.first?.email
}

func listMailboxIds() -> [String] {
if let mailboxIds = mailboxIds {
let filteredIds = mailboxIds.filter { $0.value }.map { $0.key }
return filteredIds
} else {
return []
}
}
}
7 changes: 5 additions & 2 deletions ios/TwakeMailNSE/Model/KeychainSharingSession.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ struct KeychainSharingSession: Codable {
let basicAuth: String?
let tokenEndpoint: String?
let oidcScopes: [String]?
let mailboxIdsBlockNotification: [String]?
}

extension KeychainSharingSession {
Expand All @@ -25,7 +26,8 @@ extension KeychainSharingSession {
tokenOIDC: self.tokenOIDC,
basicAuth: self.basicAuth,
tokenEndpoint: self.tokenEndpoint,
oidcScopes: self.oidcScopes
oidcScopes: self.oidcScopes,
mailboxIdsBlockNotification: self.mailboxIdsBlockNotification
)
}

Expand All @@ -45,7 +47,8 @@ extension KeychainSharingSession {
),
basicAuth: self.basicAuth,
tokenEndpoint: self.tokenEndpoint,
oidcScopes: self.oidcScopes
oidcScopes: self.oidcScopes,
mailboxIdsBlockNotification: self.mailboxIdsBlockNotification
)
}

Expand Down
75 changes: 46 additions & 29 deletions ios/TwakeMailNSE/NotificationService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -85,31 +85,16 @@ class NotificationService: UNNotificationServiceExtension {
newEmailDeliveryState: newEmailDeliveryState
)

if (emails.count > 1) {
for email in emails {
if (email.id == emails.last?.id) {
self.showModifiedNotification(title: email.getSenderName(),
subtitle: email.subject,
body: email.preview,
badgeCount: emails.count,
userInfo: [JmapConstants.EMAIL_ID : email.id])
return self.notify()
} else {
self.showNewNotification(title: email.getSenderName(),
subtitle: email.subject,
body: email.preview,
badgeCount: emails.count,
notificationId: email.id,
userInfo: [JmapConstants.EMAIL_ID : email.id])
}
}
let mailboxIdsBlockNotification = keychainSharingSession.mailboxIdsBlockNotification ?? []

if (mailboxIdsBlockNotification.isEmpty) {
return self.showListNotification(emails: emails)
} else {
self.showModifiedNotification(title: emails.first!.getSenderName(),
subtitle: emails.first!.subject,
body: emails.first!.preview,
badgeCount: 1,
userInfo: [JmapConstants.EMAIL_ID : emails.first!.id])
return self.notify()
let emailFiltered = self.filterEmailsToPushNotificacation(
emails: emails,
mailboxIdsBlockNotification: mailboxIdsBlockNotification)

return self.showListNotification(emails: emailFiltered)
}
}
} catch {
Expand All @@ -121,7 +106,39 @@ class NotificationService: UNNotificationServiceExtension {
)
}
}


private func filterEmailsToPushNotificacation(emails: [Email], mailboxIdsBlockNotification: [String]) -> [Email] {
return emails.filter { email in
if email.listMailboxIds().isEmpty {
return true
} else if mailboxIdsBlockNotification.contains(where: { $0 == email.listMailboxIds().first }) {
return false
} else {
return true
}
}
}

private func showListNotification(emails: [Email]) {
for email in emails {
if (email.id == emails.last?.id) {
self.showModifiedNotification(title: email.getSenderName(),
subtitle: email.subject,
body: email.preview,
badgeCount: emails.count,
userInfo: [JmapConstants.EMAIL_ID : email.id])
return self.notify()
} else {
self.showNewNotification(title: email.getSenderName(),
subtitle: email.subject,
body: email.preview,
badgeCount: emails.count,
notificationId: email.id,
userInfo: [JmapConstants.EMAIL_ID : email.id])
}
}
}

private func showDefaultNotification(message: String) {
self.modifiedContent?.title = InfoPlistReader(bundle: .app).bundleDisplayName
self.modifiedContent?.body = message
Expand Down Expand Up @@ -156,12 +173,12 @@ class NotificationService: UNNotificationServiceExtension {
content.sound = .default
content.badge = NSNumber(value: badgeCount)
content.userInfo = userInfo

// Create a notification trigger
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 2, repeats: false)
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 2, repeats: false)
// Create a notification request
let request = UNNotificationRequest(identifier: notificationId, content: content, trigger: trigger)

// Schedule the notification
UNUserNotificationCenter.current().add(request) { error in
if let error = error {
Expand All @@ -171,7 +188,7 @@ class NotificationService: UNNotificationServiceExtension {
}
}
}

private func notify() {
guard let modifiedContent else {
return discard()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ import 'package:tmail_ui_user/main/routes/route_navigation.dart';
import 'package:tmail_ui_user/main/routes/route_utils.dart';
import 'package:tmail_ui_user/main/utils/email_receive_manager.dart';
import 'package:tmail_ui_user/main/utils/ios_notification_manager.dart';
import 'package:tmail_ui_user/main/utils/ios_sharing_manager.dart';
import 'package:uuid/uuid.dart';

class MailboxDashBoardController extends ReloadableController {
Expand Down Expand Up @@ -198,6 +199,7 @@ class MailboxDashBoardController extends ReloadableController {
DeleteMailboxStateToRefreshInteractor? _deleteMailboxStateToRefreshInteractor;
GetAutoCompleteInteractor? _getAutoCompleteInteractor;
IOSNotificationManager? _iosNotificationManager;
IOSSharingManager? _iosSharingManager;

final scaffoldKey = GlobalKey<ScaffoldState>();
final selectedMailbox = Rxn<PresentationMailbox>();
Expand Down Expand Up @@ -291,6 +293,7 @@ class MailboxDashBoardController extends ReloadableController {
_registerPendingFileInfo();
if (PlatformInfo.isIOS) {
_registerPendingCurrentEmailIdInNotification();
_iosSharingManager = getBinding<IOSSharingManager>();
}
_handleArguments();
super.onReady();
Expand Down Expand Up @@ -517,8 +520,6 @@ class MailboxDashBoardController extends ReloadableController {

void _handleSessionFromArguments(Session session) {
log('MailboxDashBoardController::_handleSession:');
updateAccountCache(session);

_setUpComponentsFromSession(session);

if (PlatformInfo.isWeb) {
Expand Down Expand Up @@ -550,6 +551,10 @@ class MailboxDashBoardController extends ReloadableController {
getAllSendingEmails();
_storeSessionAction(session);
}

if (PlatformInfo.isIOS) {
_iosSharingManager?.updateMailboxIdsBlockNotificationInKeyChain(session, currentAccountId);
}
}

void _handleMailtoURL(MailtoArguments arguments) {
Expand Down Expand Up @@ -2553,6 +2558,7 @@ class MailboxDashBoardController extends ReloadableController {
if (PlatformInfo.isIOS) {
_iosNotificationManager?.dispose();
_currentEmailIdInNotificationIOSStreamSubscription?.cancel();
_iosSharingManager = null;
}
_emailAddressStreamSubscription.cancel();
_emailContentStreamSubscription.cancel();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@

import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:tmail_ui_user/features/push_notification/data/keychain/keychain_sharing_session.dart';

extension KeychainSharingSessionExtension on KeychainSharingSession {

KeychainSharingSession updating({String? emailState}) {
KeychainSharingSession updating({String? emailState, List<MailboxId>? mailboxIdsBlockNotification}) {
return KeychainSharingSession(
accountId: accountId,
userName: userName,
authenticationType: authenticationType,
apiUrl: apiUrl,
emailState: emailState ?? emailState,
emailState: emailState ?? this.emailState,
emailDeliveryState: emailDeliveryState,
tokenOIDC: tokenOIDC,
basicAuth: basicAuth,
tokenEndpoint: tokenEndpoint,
oidcScopes: oidcScopes,
mailboxIdsBlockNotification: mailboxIdsBlockNotification ?? this.mailboxIdsBlockNotification,
);
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import 'package:equatable/equatable.dart';
import 'package:jmap_dart_client/http/converter/account_id_converter.dart';
import 'package:jmap_dart_client/http/converter/mailbox_id_converter.dart';
import 'package:jmap_dart_client/http/converter/user_name_converter.dart';
import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/user_name.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:model/account/authentication_type.dart';
import 'package:model/oidc/token_oidc.dart';

part 'keychain_sharing_session.g.dart';

@MailboxIdConverter()
@UserNameConverter()
@AccountIdConverter()
@JsonSerializable(includeIfNull: false, explicitToJson: true)
Expand All @@ -23,6 +26,7 @@ class KeychainSharingSession with EquatableMixin {
String? basicAuth;
String? tokenEndpoint;
List<String>? oidcScopes;
List<MailboxId>? mailboxIdsBlockNotification;

KeychainSharingSession({
required this.accountId,
Expand All @@ -35,6 +39,7 @@ class KeychainSharingSession with EquatableMixin {
this.basicAuth,
this.tokenEndpoint,
this.oidcScopes,
this.mailboxIdsBlockNotification,
});

factory KeychainSharingSession.fromJson(Map<String, dynamic> json) => _$KeychainSharingSessionFromJson(json);
Expand All @@ -53,5 +58,6 @@ class KeychainSharingSession with EquatableMixin {
basicAuth,
tokenEndpoint,
oidcScopes,
mailboxIdsBlockNotification,
];
}
5 changes: 4 additions & 1 deletion lib/main/bindings/network/network_bindings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import 'package:tmail_ui_user/features/login/data/network/dns_service.dart';
import 'package:tmail_ui_user/features/login/data/network/interceptors/authorization_interceptors.dart';
import 'package:tmail_ui_user/features/login/data/network/oidc_http_client.dart';
import 'package:tmail_ui_user/features/login/data/utils/library_platform/app_auth_plugin/app_auth_plugin.dart';
import 'package:tmail_ui_user/features/mailbox/data/local/mailbox_cache_manager.dart';
import 'package:tmail_ui_user/features/mailbox/data/local/state_cache_manager.dart';
import 'package:tmail_ui_user/features/mailbox/data/network/mailbox_api.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/data/network/spam_report_api.dart';
Expand All @@ -47,12 +48,12 @@ class NetworkBindings extends Bindings {
_bindingConnection();
_bindingBaseOption();
_bindingDio();
_bindingSharing();
_bindingInterceptors();
_bindingApi();
_bindingTransformer();
_bindingServices();
_bindingException();
_bindingSharing();
}

void _bindingBaseOption() {
Expand Down Expand Up @@ -80,6 +81,8 @@ class NetworkBindings extends Bindings {
Get.find<AuthenticationInfoCacheManager>(),
Get.find<OidcConfigurationCacheManager>(),
Get.find<OIDCHttpClient>(),
Get.find<MailboxCacheManager>(),
Get.find<MailboxAPI>(),
));
}

Expand Down
Loading

0 comments on commit 6ab6507

Please sign in to comment.