Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change mail periodic refresh condition & dismiss notifications of already read messages #1812

Merged
merged 8 commits into from
Apr 22, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import com.infomaniak.mail.data.models.mailbox.Mailbox
import com.infomaniak.mail.data.models.thread.Thread
import com.infomaniak.mail.utils.NotificationPayload.NotificationBehavior
import com.infomaniak.mail.utils.NotificationPayload.NotificationBehavior.NotificationType
import com.infomaniak.mail.utils.NotificationUtils.Companion.EXTRA_MESSAGE_UID
import com.infomaniak.mail.utils.extensions.formatSubject
import com.infomaniak.mail.utils.extensions.removeLineBreaksFromHtml
import io.realm.kotlin.Realm
Expand Down Expand Up @@ -77,6 +78,8 @@ class FetchMessagesManager @Inject constructor(
messageUid = sentryMessageUid,
mailbox = mailbox,
)

realm.close()
return
}

Expand All @@ -93,6 +96,8 @@ class FetchMessagesManager @Inject constructor(
messageUid = sentryMessageUid,
mailbox = mailbox,
)

realm.close()
return
}

Expand All @@ -116,13 +121,24 @@ class FetchMessagesManager @Inject constructor(
mailbox = mailbox,
throwable = throwable,
)

realm.close()
return
}
return@let threads.toList()
}

SentryLog.d(TAG, "LaunchWork: ${mailbox.email} has ${threadsWithNewMessages.count()} Threads with new Messages")

// Dismiss Notifications for Messages that have been read on another device
notificationManagerCompat.activeNotifications.forEach { statusBarNotification ->
statusBarNotification.notification.extras.getString(EXTRA_MESSAGE_UID)?.let { messageUid ->
if (MessageController.getMessage(messageUid, realm)?.isSeen == true) {
FabianDevel marked this conversation as resolved.
Show resolved Hide resolved
notificationManagerCompat.cancel(statusBarNotification.id)
}
}
}

if (threadsWithNewMessages.isEmpty()) {
SentryDebug.sendFailedNotification(
reason = "No new Message",
Expand All @@ -132,6 +148,8 @@ class FetchMessagesManager @Inject constructor(
messageUid = sentryMessageUid,
mailbox = mailbox,
)

realm.close()
return
}

Expand Down
19 changes: 13 additions & 6 deletions app/src/main/java/com/infomaniak/mail/utils/NotificationUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ class NotificationUtils @Inject constructor(
fun buildGeneralNotification(title: String, description: String? = null): NotificationCompat.Builder {
return appContext.buildNotification(
channelId = appContext.getString(R.string.notification_channel_id_general),
icon = DEFAULT_SMALL_ICON,
icon = defaultSmallIcon,
title = title,
description = description,
)
Expand All @@ -125,7 +125,7 @@ class NotificationUtils @Inject constructor(
val channelId = getString(R.string.notification_channel_id_draft_service)
return NotificationCompat.Builder(this, channelId)
.setContentTitle(getString(R.string.notificationSyncDraftChannelName))
.setSmallIcon(DEFAULT_SMALL_ICON)
.setSmallIcon(defaultSmallIcon)
.setProgress(100, 0, true)
}

Expand All @@ -144,7 +144,6 @@ class NotificationUtils @Inject constructor(
notificationManagerCompat: NotificationManagerCompat,
payload: NotificationPayload,
) = with(payload) {

val mailbox = MailboxController.getMailbox(userId, mailboxId, mailboxInfoRealm) ?: run {
SentryDebug.sendFailedNotification(
reason = "Created Notif: no Mailbox in Realm",
Expand Down Expand Up @@ -185,8 +184,12 @@ class NotificationUtils @Inject constructor(
title: String,
description: String?,
): NotificationCompat.Builder {
return appContext.buildNotification(channelId, DEFAULT_SMALL_ICON, title, description)
.setCategory(Notification.CATEGORY_EMAIL)
return appContext.buildNotification(
channelId,
defaultSmallIcon,
title,
description,
).setCategory(Notification.CATEGORY_EMAIL)
}

private fun initMessageNotificationContent(
Expand All @@ -210,6 +213,7 @@ class NotificationUtils @Inject constructor(
setContentIntent(contentIntent)
setGroup(mailbox.notificationGroupKey)
setGroupSummary(payload.isSummary)
setExtras(Bundle().apply { putString(EXTRA_MESSAGE_UID, payload.messageUid) })
color = localSettings.accentColor.getPrimary(appContext)

SentryLog.i(TAG, "Display notification | Email: ${mailbox.email} | MessageUid: ${payload.messageUid}")
Expand Down Expand Up @@ -293,14 +297,17 @@ class NotificationUtils @Inject constructor(
addAction(replyAction)
}

@Suppress("MayBeConstant")
companion object : NotificationUtilsCore() {

private val TAG: String = NotificationUtils::class.java.simpleName

private const val DEFAULT_SMALL_ICON = R.drawable.ic_logo_notification
private const val DELAY_DEBOUNCE_NOTIF_MS = 500L

private val defaultSmallIcon = R.drawable.ic_logo_notification

const val DRAFT_ACTIONS_ID = 1
const val EXTRA_MESSAGE_UID = "messageUid"

fun Context.deleteMailNotificationChannel(mailbox: List<Mailbox>) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,11 @@ class SyncMailboxesWorker @AssistedInject constructor(

suspend fun scheduleWorkIfNeeded() = withContext(ioDispatcher) {

if (!playServicesUtils.areGooglePlayServicesAvailable() && AccountUtils.getAllUsersCount() > 0) {
if (AccountUtils.getAllUsersCount() > 0) {
SentryLog.d(TAG, "Work scheduled")

val workRequest =
PeriodicWorkRequestBuilder<SyncMailboxesWorker>(MIN_PERIODIC_INTERVAL_MILLIS, TimeUnit.MILLISECONDS)
PeriodicWorkRequestBuilder<SyncMailboxesWorker>(getPeriodicInterval(), TimeUnit.MILLISECONDS)
.setConstraints(Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build())
// We start with a delayed duration, so that when the app is rebooted the service is not launched
.setInitialDelay(INITIAL_DELAY, TimeUnit.MINUTES)
Expand All @@ -89,10 +89,16 @@ class SyncMailboxesWorker @AssistedInject constructor(
SentryLog.d(TAG, "Work cancelled")
workManager.cancelUniqueWork(TAG)
}

private fun getPeriodicInterval(): Long {
val hasGooglePlayServices = playServicesUtils.areGooglePlayServicesAvailable()
return if (hasGooglePlayServices) PERIODIC_INTERVAL_MILLIS else MIN_PERIODIC_INTERVAL_MILLIS
}
}

companion object {
private const val TAG = "SyncMessagesWorker" // To support the old services, don't change this name
private const val INITIAL_DELAY = 2L
private const val PERIODIC_INTERVAL_MILLIS = 4 * 60 * 60 * 1_000L // 4 hours
}
}
Loading