diff --git a/OldKotlin/realm-models/src/main/kotlin/com/infomaniak/mail/data/models/message/Message.kt b/OldKotlin/realm-models/src/main/kotlin/com/infomaniak/mail/data/models/message/Message.kt index 4a1aff4df66..bdba2e24822 100644 --- a/OldKotlin/realm-models/src/main/kotlin/com/infomaniak/mail/data/models/message/Message.kt +++ b/OldKotlin/realm-models/src/main/kotlin/com/infomaniak/mail/data/models/message/Message.kt @@ -140,6 +140,10 @@ class Message : RealmObject, Snoozable { @InternalModelProperties set var mentions = realmListOf() + @SerialName("reminder") + var reminder: ReminderMessageInfo? = null + @SerialName("reminder_action") + var reminderAction: String? = null //endregion //region Local data (Transient) @@ -301,6 +305,14 @@ class Message : RealmObject, Snoozable { fun isOrphan(): Boolean = threads.isEmpty() && threadsDuplicatedIn.isEmpty() + fun extractFromNames(): List { + return from.map { it.name.ifBlank { it.email } } + } + + fun extractRecipientNames(): List { + return allRecipients.map { it.name.ifBlank { it.email } } + } + // Be careful when using this method because some folders might contain messages from other folders than itself. This // operation should only happen in very specific situations like computing the shortUid of a Message from its uid. private fun String.toShortUid(): Int = substringBefore('@').toInt() diff --git a/OldKotlin/realm-models/src/main/kotlin/com/infomaniak/mail/data/models/message/ReminderMessageInfo.kt b/OldKotlin/realm-models/src/main/kotlin/com/infomaniak/mail/data/models/message/ReminderMessageInfo.kt new file mode 100644 index 00000000000..36032974936 --- /dev/null +++ b/OldKotlin/realm-models/src/main/kotlin/com/infomaniak/mail/data/models/message/ReminderMessageInfo.kt @@ -0,0 +1,40 @@ +/* + * Infomaniak Mail - Android + * Copyright (C) 2026 Infomaniak Network SA + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +@file:UseSerializers(RealmInstantSerializer::class) + +package com.infomaniak.mail.data.models.message + +import com.infomaniak.mail.data.api.RealmInstantSerializer +import io.realm.kotlin.types.EmbeddedRealmObject +import io.realm.kotlin.types.RealmInstant +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import kotlinx.serialization.UseSerializers + +@Serializable +class ReminderMessageInfo : EmbeddedRealmObject { + // API returns date and uuid for an already sent email, and only returns a delta for a scheduled email + @SerialName("date") + var date: RealmInstant? = null + @SerialName("uuid") + var uuid: String? = null + @SerialName("delta") + var delta: Int? = null + + companion object +} diff --git a/OldKotlin/realm-models/src/main/kotlin/com/infomaniak/mail/data/models/thread/Thread.kt b/OldKotlin/realm-models/src/main/kotlin/com/infomaniak/mail/data/models/thread/Thread.kt index a95753a99b0..0cf90275d7e 100644 --- a/OldKotlin/realm-models/src/main/kotlin/com/infomaniak/mail/data/models/thread/Thread.kt +++ b/OldKotlin/realm-models/src/main/kotlin/com/infomaniak/mail/data/models/thread/Thread.kt @@ -89,6 +89,8 @@ class Thread : RealmObject, Snoozable { var hasAttachable: Boolean = false @Transient var hasUnseenMentions: Boolean = false + @Transient + var hasReminders: Boolean = false // Has been moved (archived, spammed, deleted, moved) but API call hasn't been done yet. // It's only used to locally filter the Threads' list. @Transient diff --git a/app/src/main/java/com/infomaniak/mail/MatomoMail.kt b/app/src/main/java/com/infomaniak/mail/MatomoMail.kt index 8a6c5111437..895441cfda5 100644 --- a/app/src/main/java/com/infomaniak/mail/MatomoMail.kt +++ b/app/src/main/java/com/infomaniak/mail/MatomoMail.kt @@ -279,11 +279,13 @@ object MatomoMail : Matomo { ReplaceSubjectConfirm("replaceSubjectConfirm"), ReplaceSubjectDialog("replaceSubjectDialog"), Reply("reply"), + FollowUp("followUp"), ReplyAll("replyAll"), ReplyMaybe("replyMaybe"), ReplyNo("replyNo"), ReplyYes("replyYes"), ReprogramSchedule("reprogramSchedule"), + ReprogramReminder("reprogramReminder"), RequestPassword("requestPassword"), Restore("restore"), RestoreEmails("restoreEmails"), diff --git a/app/src/main/java/com/infomaniak/mail/data/cache/RealmDatabase.kt b/app/src/main/java/com/infomaniak/mail/data/cache/RealmDatabase.kt index 40d2687c01e..7b44689cd94 100644 --- a/app/src/main/java/com/infomaniak/mail/data/cache/RealmDatabase.kt +++ b/app/src/main/java/com/infomaniak/mail/data/cache/RealmDatabase.kt @@ -47,6 +47,7 @@ import com.infomaniak.mail.data.models.message.EmojiReactionAuthor import com.infomaniak.mail.data.models.message.EmojiReactionState import com.infomaniak.mail.data.models.message.Headers import com.infomaniak.mail.data.models.message.Message +import com.infomaniak.mail.data.models.message.ReminderMessageInfo import com.infomaniak.mail.data.models.message.SubBody import com.infomaniak.mail.data.models.signature.Signature import com.infomaniak.mail.data.models.thread.Thread @@ -237,6 +238,7 @@ object RealmDatabase { Folder::class, Thread::class, Message::class, + ReminderMessageInfo::class, ReminderDraftInfo::class, Headers::class, Draft::class, diff --git a/app/src/main/java/com/infomaniak/mail/data/cache/mailboxContent/refreshStrategies/ThreadRecomputations.kt b/app/src/main/java/com/infomaniak/mail/data/cache/mailboxContent/refreshStrategies/ThreadRecomputations.kt index 2ce324b8a37..295a3bf1d64 100644 --- a/app/src/main/java/com/infomaniak/mail/data/cache/mailboxContent/refreshStrategies/ThreadRecomputations.kt +++ b/app/src/main/java/com/infomaniak/mail/data/cache/mailboxContent/refreshStrategies/ThreadRecomputations.kt @@ -24,6 +24,7 @@ import com.infomaniak.mail.data.models.message.Message.Companion.parseMessagesId import com.infomaniak.mail.data.models.thread.Thread import com.infomaniak.mail.data.models.thread.computeReactionsPerMessageId import com.infomaniak.mail.data.models.thread.overrideWith +import com.infomaniak.mail.utils.ThreadListUtils.hasReminders import com.infomaniak.mail.utils.ThreadListUtils.hasUnseenMentions import io.realm.kotlin.MutableRealm import io.realm.kotlin.Realm @@ -82,6 +83,7 @@ object ThreadRecomputations { isForwarded = false hasAttachable = false hasUnseenMentions = false + hasReminders = false numberOfScheduledDrafts = 0 snoozeState = null snoozeEndDate = null @@ -100,6 +102,7 @@ object ThreadRecomputations { } hasUnseenMentions = hasUnseenMentions(aliases?.toList() ?: emptyList(), allMessages) + hasReminders = hasReminders(allMessages) displayDate = lastMessage.displayDate internalDate = lastMessage.internalDate diff --git a/app/src/main/java/com/infomaniak/mail/ui/main/folder/ThreadListAdapter.kt b/app/src/main/java/com/infomaniak/mail/ui/main/folder/ThreadListAdapter.kt index 0b1152d583d..f758d41859e 100644 --- a/app/src/main/java/com/infomaniak/mail/ui/main/folder/ThreadListAdapter.kt +++ b/app/src/main/java/com/infomaniak/mail/ui/main/folder/ThreadListAdapter.kt @@ -52,6 +52,7 @@ import com.infomaniak.mail.R import com.infomaniak.mail.data.LocalSettings import com.infomaniak.mail.data.LocalSettings.ThreadDensity import com.infomaniak.mail.data.cache.RealmDatabase +import com.infomaniak.mail.data.models.FeatureFlag import com.infomaniak.mail.data.models.FolderRole import com.infomaniak.mail.data.models.SwipeAction import com.infomaniak.mail.data.models.correspondent.MergedContact @@ -320,6 +321,8 @@ class ThreadListAdapter @Inject constructor( iconMention.isVisible = hasUnseenMentions iconCalendar.isGone = true // TODO: See with API when we should display this icon iconFavorite.isVisible = isFavorite + iconReminder.isVisible = hasReminders && + callbacks?.getFeatureFlags?.invoke()?.contains(FeatureFlag.RESPONSE_REQUIRED) == true val messagesCount = getDisplayedMessages(callbacks?.getFeatureFlags?.invoke(), localSettings).count() threadCountText.text = "$messagesCount" diff --git a/app/src/main/java/com/infomaniak/mail/ui/main/thread/MessageAlertView.kt b/app/src/main/java/com/infomaniak/mail/ui/main/thread/MessageAlertView.kt index 717cf948f82..c15f2f8fc58 100644 --- a/app/src/main/java/com/infomaniak/mail/ui/main/thread/MessageAlertView.kt +++ b/app/src/main/java/com/infomaniak/mail/ui/main/thread/MessageAlertView.kt @@ -48,6 +48,7 @@ class MessageAlertView @JvmOverloads constructor( private val action1LoadingTimer = Utils.createRefreshTimer(onTimerFinish = { binding.action1.showProgress() }) private val action2LoadingTimer = Utils.createRefreshTimer(onTimerFinish = { binding.action2.showProgress() }) + private val action3LoadingTimer = Utils.createRefreshTimer(onTimerFinish = { binding.action3.showProgress() }) init { attrs?.getAttributes(context, R.styleable.MessageAlertView) { @@ -63,7 +64,12 @@ class MessageAlertView @JvmOverloads constructor( text = getString(R.styleable.MessageAlertView_action2) isVisible = hasAction2 } - divider.isVisible = hasAction2 + + val hasAction3 = hasValue(R.styleable.MessageAlertView_action3) + action3.apply { + text = getString(R.styleable.MessageAlertView_action3) + isVisible = hasAction3 + } } } } @@ -72,6 +78,7 @@ class MessageAlertView @JvmOverloads constructor( super.setEnabled(isEnabled) action1.isEnabled = isEnabled action2.isEnabled = isEnabled + action3.isEnabled = isEnabled } fun setDescription(text: String) { @@ -116,6 +123,23 @@ class MessageAlertView @JvmOverloads constructor( } } + fun onAction3(listener: OnClickListener) { + binding.action3.setOnClickListener(listener) + } + + fun showAction3Progress() { + binding.action3.isEnabled = false + action3LoadingTimer.start() + } + + fun hideAction3Progress(@StringRes text: Int) { + action3LoadingTimer.cancel() + binding.action3.apply { + hideProgressCatching(text) + isEnabled = true + } + } + fun setActionsVisibility(shouldDisplayAction: Boolean) { binding.actionsLayout.isVisible = shouldDisplayAction val margin = if (shouldDisplayAction) RCore.dimen.marginStandardMedium else RCore.dimen.marginStandardSmall diff --git a/app/src/main/java/com/infomaniak/mail/ui/main/thread/ThreadAdapter.kt b/app/src/main/java/com/infomaniak/mail/ui/main/thread/ThreadAdapter.kt index bc95be5c611..f5e8384918d 100644 --- a/app/src/main/java/com/infomaniak/mail/ui/main/thread/ThreadAdapter.kt +++ b/app/src/main/java/com/infomaniak/mail/ui/main/thread/ThreadAdapter.kt @@ -39,6 +39,7 @@ import androidx.recyclerview.widget.RecyclerView.ViewHolder import androidx.viewbinding.ViewBinding import com.infomaniak.core.common.FormatterFileSize.formatShortFileSize import com.infomaniak.core.common.extensions.isNightModeEnabled +import com.infomaniak.core.common.utils.FORMAT_DATE_DAY_FULL_MONTH_WITH_TIME import com.infomaniak.core.common.utils.FORMAT_DATE_DAY_FULL_MONTH_YEAR_WITH_TIME import com.infomaniak.core.common.utils.FormatData import com.infomaniak.core.common.utils.format @@ -53,6 +54,7 @@ import com.infomaniak.mail.R import com.infomaniak.mail.data.models.Attachable import com.infomaniak.mail.data.models.Attachment import com.infomaniak.mail.data.models.Bimi +import com.infomaniak.mail.data.models.FeatureFlag import com.infomaniak.mail.data.models.calendar.AttendanceState import com.infomaniak.mail.data.models.calendar.Attendee import com.infomaniak.mail.data.models.calendar.CalendarEventResponse @@ -63,6 +65,7 @@ import com.infomaniak.mail.data.models.extensions.isInSpamFolder import com.infomaniak.mail.data.models.extensions.isMe import com.infomaniak.mail.data.models.extensions.isPendingAcknowledgementForMe import com.infomaniak.mail.data.models.extensions.isReplyAuthorized +import com.infomaniak.mail.data.models.mailbox.Mailbox import com.infomaniak.mail.data.models.mailbox.SenderDetails import com.infomaniak.mail.data.models.mailbox.SendersRestrictions import com.infomaniak.mail.data.models.message.Message @@ -89,6 +92,7 @@ import com.infomaniak.mail.utils.WebViewUtils import com.infomaniak.mail.utils.WebViewUtils.Companion.configureOnTouchListener import com.infomaniak.mail.utils.WebViewUtils.Companion.setupThreadWebViewSettings import com.infomaniak.mail.utils.WebViewUtils.Companion.toggleWebViewTheme +import com.infomaniak.mail.utils.date.DateFormatUtils.formatDelayText import com.infomaniak.mail.utils.date.DateFormatUtils.fullDateWithYear import com.infomaniak.mail.utils.date.MailDateFormatUtils.mailFormattedDate import com.infomaniak.mail.utils.extensions.AttachmentExt.AttachmentIntentType @@ -130,6 +134,7 @@ class ThreadAdapter( //endregion private val manuallyAllowedMessagesUids = mutableSetOf() + private var featureFlags: Mailbox.FeatureFlagSet? = null private lateinit var recyclerView: RecyclerView @@ -206,6 +211,7 @@ class ThreadAdapter( NotifyType.OnlyRebindEmojiReactions -> handleEmojiReactionPayload(item) NotifyType.UnsubscribeRebind -> bindUnsubscribe(item) NotifyType.AcknowledgeRebind -> bindAcknowledge(item) + NotifyType.ReminderRebind -> bindReminder(item.message) NotifyType.AiSummaryStateChanged -> holder.bindAiAction(item.message, AiAction.SUMMARY) NotifyType.AiTranslateStateChanged -> holder.bindAiAction(item.message, AiAction.TRANSLATE) is NotifyType.MessagesCollapseStateChanged -> { @@ -223,6 +229,13 @@ class ThreadAdapter( } } + fun updateFeatureFlags(featureFlags: Mailbox.FeatureFlagSet?) { + if (this.featureFlags == featureFlags) return + + this.featureFlags = featureFlags + notifyItemRangeChanged(0, itemCount, NotifyType.ReminderRebind) + } + private fun MessageViewHolder.handleToggleLightModePayload(messageUid: String) = with(threadAdapterState) { isThemeTheSameMap[messageUid] = !isThemeTheSameMap[messageUid]!! toggleContentAndQuoteTheme(messageUid) @@ -772,6 +785,7 @@ class ThreadAdapter( bindUnsubscribe(messageUi) bindAcknowledge(messageUi) + bindReminder(message) bindSpam(message) hideAlertGroupIfNoneDisplayed() // Must be called after binding all the different alerts @@ -835,6 +849,141 @@ class ThreadAdapter( } } + private fun formatNamesList(context: Context, names: List): String { + return when (names.size) { + 0 -> "" + 1 -> names[0] + 2 -> "${names[0]} ${context.getString(R.string.linkingWord)} ${names[1]}" + else -> { + val allButLast = names.dropLast(1).joinToString(", ") + "$allButLast ${context.getString(R.string.linkingWord)} ${names.last()}" + } + } + } + + private fun ItemMessageBinding.bindRecipientReminderAlert(message: Message, reminder: Date, isReminderExpired: Boolean) { + requestResponseAlert.setActionsVisibility(shouldDisplayAction = false) + val fromNames = message.extractFromNames() + val formattedNamesList = formatNamesList(context, fromNames) + + val pluralsRes = if (isReminderExpired) R.plurals.reminderAfterHeaderTitle else R.plurals.reminderBeforeHeaderTitle + val formattedDate = reminder.format(FORMAT_DATE_DAY_FULL_MONTH_WITH_TIME) + requestResponseAlert.apply { + isVisible = true + setDescription( + context.resources.getQuantityString( + pluralsRes, + message.from.size, + formattedNamesList, + formattedDate, + ) + ) + } + } + + private fun ItemMessageBinding.bindReminder(message: Message) { + reminderAlert.isGone = true + endReminderAlert.isGone = true + requestResponseAlert.isGone = true + + if (featureFlags?.contains(FeatureFlag.RESPONSE_REQUIRED) != true) return + + if (message.isScheduledDraft && message.reminder != null) { + bindScheduledDraftReminderAlert(message) + return + } + + message.reminder?.date?.toDate()?.let { reminderDate -> + val now = Date() + val isExpired = reminderDate.before(now) + when { + message.from.any { it.isMe() } -> bindSenderReminderAlert(message, reminderDate, isExpired) + message.allRecipients.any { it.isMe() } -> bindRecipientReminderAlert(message, reminderDate, isExpired) + } + } + } + + private fun ItemMessageBinding.bindScheduledDraftReminderAlert(message: Message) { + val delayMinutes = message.reminder?.delta ?: return + + reminderAlert.setActionsVisibility(shouldDisplayAction = true) + reminderAlert.setDescription( + context.getString(R.string.callIfNoResponseHeaderTitle, context.formatDelayText(delayMinutes)), + ) + + alertsGroup.isVisible = true + reminderAlert.isVisible = true + + reminderAlert.onAction1 { + trackMessageBannerEvent(MatomoName.ReprogramReminder) + threadAdapterCallbacks?.onModifyReminderClicked?.invoke(message) + } + + reminderAlert.onAction2 { + threadAdapterCallbacks?.onDisableReminderClicked?.invoke(message) + } + } + + private fun ItemMessageBinding.bindSenderReminderAlert(message: Message, reminderDate: Date, isExpired: Boolean) { + if (isExpired) bindExpiredReminderAlert(message, reminderDate) else bindActiveReminderAlert(message, reminderDate) + } + + private fun ItemMessageBinding.bindExpiredReminderAlert(message: Message, reminderDate: Date) { + endReminderAlert.setActionsVisibility(shouldDisplayAction = true) + val recipientNames = message.extractRecipientNames() + val formattedNamesList = formatNamesList(context, recipientNames) + + endReminderAlert.setDescription( + context.getString( + R.string.reminderNoResponseHeaderTitle, + formattedNamesList, + reminderDate.format(FORMAT_DATE_DAY_FULL_MONTH_YEAR_WITH_TIME), + ), + ) + + alertsGroup.isVisible = true + endReminderAlert.isVisible = true + + endReminderAlert.onAction1 { + trackMessageBannerEvent(MatomoName.FollowUp) + threadAdapterCallbacks?.onFollowUpClicked?.invoke(message) + } + + endReminderAlert.onAction2 { + trackMessageBannerEvent(MatomoName.ReprogramReminder) + threadAdapterCallbacks?.onAddReminderClicked?.invoke(message) + } + + endReminderAlert.onAction3 { + trackMessageBannerEvent(MatomoName.DeleteDraft) + threadAdapterCallbacks?.onDeleteDraftClicked?.invoke(message) + } + } + + private fun ItemMessageBinding.bindActiveReminderAlert(message: Message, reminderDate: Date) { + reminderAlert.setActionsVisibility(shouldDisplayAction = true) + + reminderAlert.setDescription( + context.getString( + R.string.callIfNoResponseHeaderTitleWithDate, + reminderDate.format(FORMAT_DATE_DAY_FULL_MONTH_YEAR_WITH_TIME), + ), + ) + + alertsGroup.isVisible = true + reminderAlert.isVisible = true + + reminderAlert.onAction1 { + trackMessageBannerEvent(MatomoName.ReprogramReminder) + threadAdapterCallbacks?.onModifyReminderClicked?.invoke(message) + } + + reminderAlert.onAction2 { + // TODO: add matomo + threadAdapterCallbacks?.onDisableReminderClicked?.invoke(message) + } + } + private fun ItemMessageBinding.bindUnsubscribe(messageUi: MessageUi) { when (messageUi.unsubscribeState) { is UnsubscribeState.CanUnsubscribe -> { @@ -1193,6 +1342,7 @@ class ThreadAdapter( setOnClickListener { threadAdapterCallbacks?.onMenuClicked?.invoke(message) } } sendingProgressText.isVisible = message.isScheduledMessage + iconReminder.isVisible = message.reminder != null && !isExpanded recipient.text = if (isExpanded) getAllRecipientsFormatted(message) else context.formatSubject(message.subject) recipientChevron.isVisible = isExpanded @@ -1243,6 +1393,7 @@ class ThreadAdapter( data object OnlyRebindEmojiReactions : NotifyType data object UnsubscribeRebind : NotifyType data object AcknowledgeRebind : NotifyType + data object ReminderRebind : NotifyType data object UpdatePermissions : NotifyType data object AiSummaryStateChanged : NotifyType data object AiTranslateStateChanged : NotifyType @@ -1290,6 +1441,7 @@ class ThreadAdapter( MessageDiffAspect.EmojiReactions.areDifferent(oldItem, newItem) -> NotifyType.OnlyRebindEmojiReactions MessageDiffAspect.Unsubscribe.areDifferent(oldItem, newItem) -> NotifyType.UnsubscribeRebind MessageDiffAspect.Acknowledge.areDifferent(oldItem, newItem) -> NotifyType.AcknowledgeRebind + MessageDiffAspect.Reminder.areDifferent(oldItem, newItem) -> NotifyType.ReminderRebind else -> getCalendarEventPayloadOrNull(oldItem.message, newItem.message) } } @@ -1329,7 +1481,7 @@ class ThreadAdapter( object MessageDiffAspect { val entries: List> get() = listOf( - EmojiReactions, Calendar, AnythingElse, Unsubscribe, Acknowledge + EmojiReactions, Calendar, Reminder, AnythingElse, Unsubscribe, Acknowledge ) data object EmojiReactions : DiffAspect({ @@ -1351,6 +1503,13 @@ class ThreadAdapter( data object AnythingElse : DiffAspect({ everythingButAttendeesIsTheSame(it) }) } + data object Reminder : DiffAspect({ + message.reminder?.uuid == it.message.reminder?.uuid && + message.reminder?.date == it.message.reminder?.date && + message.reminder?.delta == it.message.reminder?.delta && + message.reminderAction == it.message.reminderAction + }) + data object Unsubscribe : DiffAspect({ unsubscribeState == it.unsubscribeState }) data object AnythingElse : DiffAspect({ oldMessage -> @@ -1380,6 +1539,7 @@ class ThreadAdapter( var onAttachmentOptionsClicked: ((attachment: Attachable) -> Unit)? = null, var onDownloadAllClicked: ((message: Message) -> Unit)? = null, var onReplyClicked: ((Message) -> Unit)? = null, + var onFollowUpClicked: ((Message) -> Unit)? = null, var onMenuClicked: ((Message) -> Unit)? = null, var onAllExpandedMessagesLoaded: (() -> Unit)? = null, var onSuperCollapsedBlockClicked: (() -> Unit)? = null, @@ -1404,6 +1564,9 @@ class ThreadAdapter( var onAiBannerClose: ((messageUid: String, aiAction: AiAction) -> Unit)? = null, var onShowOriginal: ((messageUid: String) -> Unit)? = null, var getAiState: (() -> AiStateMap)? = null, + var onDisableReminderClicked: ((Message) -> Unit)? = null, + var onModifyReminderClicked: ((Message) -> Unit)? = null, + var onAddReminderClicked: ((Message) -> Unit)? = null, ) enum class DisplayType(val layout: Int) { diff --git a/app/src/main/java/com/infomaniak/mail/ui/main/thread/ThreadFragment.kt b/app/src/main/java/com/infomaniak/mail/ui/main/thread/ThreadFragment.kt index 86b2f50cc79..4a96956fb57 100644 --- a/app/src/main/java/com/infomaniak/mail/ui/main/thread/ThreadFragment.kt +++ b/app/src/main/java/com/infomaniak/mail/ui/main/thread/ThreadFragment.kt @@ -254,6 +254,7 @@ class ThreadFragment : Fragment(), PickerEmojiObserver { observeSubjectUpdateTriggers() observeCurrentFolderName() observeSnoozeHeaderVisibility() + observeFeatureFlags() observePickedEmoji() @@ -508,6 +509,7 @@ class ThreadFragment : Fragment(), PickerEmojiObserver { } threadAdapter.stateRestorationPolicy = StateRestorationPolicy.PREVENT_WHEN_EMPTY + threadAdapter.updateFeatureFlags(mainViewModel.currentMailbox.value?.featureFlags) } private fun openDraft(message: Message) { @@ -607,6 +609,10 @@ class ThreadFragment : Fragment(), PickerEmojiObserver { } } + private fun observeFeatureFlags() { + mainViewModel.featureFlagsLive.observe(viewLifecycleOwner, threadAdapter::updateFeatureFlags) + } + private fun updateQuickActionBarSendingState(canSend: Boolean) = with(binding.quickActionBar) { setEnableByMenuId(R.id.quickActionReply, enabled = canSend) setEnableByMenuId(R.id.quickActionForward, enabled = canSend) diff --git a/app/src/main/java/com/infomaniak/mail/utils/ThreadListUtils.kt b/app/src/main/java/com/infomaniak/mail/utils/ThreadListUtils.kt index bd2738df53d..361593546c9 100644 --- a/app/src/main/java/com/infomaniak/mail/utils/ThreadListUtils.kt +++ b/app/src/main/java/com/infomaniak/mail/utils/ThreadListUtils.kt @@ -55,4 +55,6 @@ object ThreadListUtils { !message.isSeen && message.mentions.any { mention -> mention.lowercase() in normalizedAliases } } } + + fun hasReminders(messages: List): Boolean = messages.any { message -> message.reminder != null } } diff --git a/app/src/main/res/drawable/bg_reminder_icon.xml b/app/src/main/res/drawable/bg_reminder_icon.xml new file mode 100644 index 00000000000..fc0279de76c --- /dev/null +++ b/app/src/main/res/drawable/bg_reminder_icon.xml @@ -0,0 +1,21 @@ + + + + + diff --git a/app/src/main/res/drawable/divider_vertical.xml b/app/src/main/res/drawable/divider_vertical.xml new file mode 100644 index 00000000000..3c449f4a796 --- /dev/null +++ b/app/src/main/res/drawable/divider_vertical.xml @@ -0,0 +1,27 @@ + + + + + + + + + diff --git a/app/src/main/res/layout/bottom_sheet_reminder_options.xml b/app/src/main/res/layout/bottom_sheet_reminder_options.xml new file mode 100644 index 00000000000..bde8d3639b5 --- /dev/null +++ b/app/src/main/res/layout/bottom_sheet_reminder_options.xml @@ -0,0 +1,47 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/cardview_thread_item.xml b/app/src/main/res/layout/cardview_thread_item.xml index 90d4e6e76a3..176dfac663b 100644 --- a/app/src/main/res/layout/cardview_thread_item.xml +++ b/app/src/main/res/layout/cardview_thread_item.xml @@ -315,12 +315,28 @@ android:src="@drawable/ic_at" android:visibility="gone" app:layout_constraintBottom_toBottomOf="@id/mailSubject" - app:layout_constraintEnd_toStartOf="@id/iconAttachment" + app:layout_constraintEnd_toStartOf="@id/iconReminder" app:layout_constraintStart_toEndOf="@id/folderNameCompactMode" app:layout_constraintTop_toTopOf="@id/mailSubject" app:tint="?attr/colorPrimary" tools:visibility="visible" /> + + diff --git a/app/src/main/res/layout/item_bottom_sheet_action.xml b/app/src/main/res/layout/item_bottom_sheet_action.xml index 47adb04db3f..5793e0ed34f 100644 --- a/app/src/main/res/layout/item_bottom_sheet_action.xml +++ b/app/src/main/res/layout/item_bottom_sheet_action.xml @@ -36,14 +36,13 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" - android:paddingHorizontal="@dimen/marginStandardMedium"> + android:padding="@dimen/marginStandardMedium"> + + + + + + + + + app:layout_constraintTop_toBottomOf="@id/description" + app:showDividerVertical="middle"> - - + + diff --git a/app/src/main/res/navigation/main_navigation.xml b/app/src/main/res/navigation/main_navigation.xml index c7bc940ab60..fcdbc6f9f39 100644 --- a/app/src/main/res/navigation/main_navigation.xml +++ b/app/src/main/res/navigation/main_navigation.xml @@ -300,6 +300,23 @@ app:argType="boolean" /> + + + + + + Du er ikke inviteret %s (Arrangør) Påmind mig, hvis der ikke er svar: %s efter afsendelse + Påmind mig, hvis der ikke er svar: %s Cc: Kommer snart… Tilbud @@ -222,6 +223,7 @@ Videresendt Du er blevet nævnt. Ny + Er en påmindelse Svar Lagringsstatus Åbn mailhandlinger @@ -242,6 +244,7 @@ Ring op Skriv en SMS Navn på mappen + Tilføj en påmindelse Vælg en dato og et tidspunkt Dato: @@ -488,6 +491,19 @@ Læs mere Seneste søgninger Du er blevet afbrudt + + %1$s har ventet på svar siden %2$s + %1$s har ventet på svar siden %2$s + + + %1$s afventer et svar senest %2$s + %1$s afventer et svar senest %2$s + + Udsæt påmindelsen + Følg op + Hej,\nEr det muligt at få feedback om dette emne?\nPå forhånd tak. + Marker som udført + Påmindelse: intet svar fra %1$s på denne e-mail siden %2$s Påmindelsens synlighed Omdøb mappen Er du enig i at dele dine data med vores udviklere, så de kan hjælpe dig med dit problem? @@ -610,11 +626,15 @@ Del e-mail Kunne ikke sende Kvittering for læsning sendt + Kunne ikke tilføje påmindelsen + Påmindelse tilføjet En administrator har deaktiveret beskedafsendelse Afsender er nu blokeret Svar taget i betragtning Ny kontakt succesfuldt registreret Samtalen eksisterer ikke længere + Kunne ikke deaktivere påmindelsen + Påmindelsen blev deaktiveret Visningsproblem rapporteret Download i gang… Kladde slettet @@ -628,6 +648,8 @@ Besked slettet Besked flyttet til %s Besked flyttet til spam og bruger blokeret + Kunne ikke ændre påmindelsen + Påmindelse ændret Flytning annulleret Adgangskode kopieret Nummer kopieret til udklipsholderen diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index f45b4c4c8f1..517e024e2b5 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -182,6 +182,7 @@ Sie zählen nicht zu den eingeladenen Personen %s (Organisator) Erinnern, wenn keine Antwort: %s nach dem Senden + Mich erinnern, wenn keine Antwort erfolgt: %s Cc: Demnächst… Werbeaktionen @@ -222,6 +223,7 @@ Weitergeleitet Du wurdest erwähnt. Neu + Ist eine Erinnerung Antwort Speicherstatus Mail-Aktionen öffnen @@ -242,6 +244,7 @@ Wählen Eine SMS schreiben Name des Ordners + Erinnerung hinzufügen Wählen Sie ein Datum und eine Uhrzeit Datum: @@ -488,6 +491,19 @@ Mehr erfahren Letzte Suchen Sie wurden abgemeldet + + %1$s wartet seit %2$s auf eine Antwort + %1$s warten seit %2$s auf eine Antwort + + + %1$s erwartet eine Antwort bis %2$s + %1$s erwarten eine Antwort bis %2$s + + Erinnerung verschieben + Nachfassen + Hallo,\nIst es möglich, ein Feedback zu diesem Thema zu erhalten?\nVielen Dank im Voraus. + Als erledigt markieren + Erinnerung: keine Antwort von %1$s auf diese E-Mail seit dem %2$s Sichtbarkeit der Erinnerung Benennen Sie den Ordner um Sind Sie damit einverstanden, Ihre Daten mit unseren Entwicklern zu teilen, damit diese Ihnen bei Ihrem Problem helfen können? @@ -610,11 +626,15 @@ E-Mail austauschen Senden fehlgeschlagen Lesebestätigung gesendet + Fehler beim Hinzufügen der Erinnerung + Erinnerung hinzugefügt Ein Administrator hat den Nachrichtenversand deaktiviert Absender ist jetzt blockiert Antwort berücksichtigt Neuer Kontakt erfolgreich registriert Unterhaltung existiert nicht mehr + Erinnerung konnte nicht deaktiviert werden + Erinnerung erfolgreich deaktiviert Anzeigeproblem gemeldet Download läuft… Entwurf gelöscht @@ -628,6 +648,8 @@ Nachricht gelöscht Nachricht an %s verschoben Nachricht in den Spam verschoben und Benutzer blockiert + Ändern der Erinnerung fehlgeschlagen + Erinnerung geändert Umzug abgesagt Passwort kopiert Nummer in die Zwischenablage kopiert diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index e53dcfe5a5c..0c5322f7a11 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -182,6 +182,7 @@ Δεν είστε προσκεκλημένος %s (Διοργανωτής) Υπενθύμιση αν δεν υπάρχει απάντηση: %s μετά την αποστολή + Θύμισέ μου αν δεν υπάρχει απάντηση: %s Κοινοποίηση: Έρχεται σύντομα… Προσφορές @@ -222,6 +223,7 @@ Προωθήθηκε Έχετε αναφερθεί. Νέο + Είναι μια υπενθύμιση Απάντηση Κατάσταση αποθήκευσης Άνοιγμα ενεργειών μηνύματος @@ -242,6 +244,7 @@ Κλήση Σύνταξη SMS Όνομα φακέλου + Προσθήκη υπενθύμισης Επιλέξτε ημερομηνία και ώρα Ημερομηνία: @@ -488,6 +491,19 @@ Διαβάστε περισσότερα Πρόσφατες αναζητήσεις Έχετε αποσυνδεθεί + + %1$s περιμένει απάντηση από %2$s + %1$s περιμένουν απάντηση από %2$s + + + %1$s περιμένει απάντηση έως %2$s + %1$s περιμένουν απάντηση έως %2$s + + Αναβολή της υπενθύμισης + Παρακολούθηση + Γεια σας,\nΕίναι δυνατόν να λάβετε κάποια ανατροφοδότηση για αυτό το θέμα;\nΣας ευχαριστώ εκ των προτέρων. + Σημείωση ως ολοκληρωμένο + Υπενθύμιση: καμία απάντηση από %1$s σε αυτό το email από τις %2$s Ορατότητα υπενθύμισης Μετονομασία φακέλου Συμφωνείτε να μοιραστείτε τα δεδομένα σας με τους προγραμματιστές μας ώστε να σας βοηθήσουν με το πρόβλημά σας; @@ -610,11 +626,15 @@ Κοινοποίηση email Αποτυχία αποστολής Η απόδειξη ανάγνωσης εστάλη + Δεν ήταν δυνατή η προσθήκη υπενθύμισης + Η υπενθύμιση προστέθηκε Ένας διαχειριστής έχει απενεργοποιήσει την αποστολή μηνυμάτων Ο αποστολέας έχει αποκλειστεί Η απάντηση καταχωρήθηκε Η επαφή καταχωρήθηκε με επιτυχία Η συνομιλία δεν υπάρχει πλέον + Δεν ήταν δυνατή η απενεργοποίηση της υπενθύμισης + Η υπενθύμιση απενεργοποιήθηκε με επιτυχία Το πρόβλημα εμφάνισης αναφέρθηκε Η λήψη βρίσκεται σε εξέλιξη… Το πρόχειρο διαγράφηκε @@ -628,6 +648,8 @@ Το μήνυμα διαγράφηκε Το μήνυμα μετακινήθηκε στο %s Το μήνυμα μεταφέρθηκε στα spam και ο χρήστης εμποδίστηκε + Αποτυχία τροποποίησης της υπενθύμισης + Η υπενθύμιση τροποποιήθηκε Η μετακίνηση ακυρώθηκε Ο κωδικός αντιγράφηκε Ο αριθμός αντιγράφηκε στο πρόχειρο diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 3fdf684ba18..97b0570a8c0 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -182,6 +182,7 @@ No estás invitado %s (Organizador) Recordarme si no hay respuesta: %s después del envío + Recuérdame si no hay respuesta: %s Cc: Próximamente… Promociones @@ -222,6 +223,7 @@ Reenviado Has sido mencionado. Nuevo + Es un recordatorio Respuesta Estado de almacenamiento Acciones de mensajes abiertos @@ -242,6 +244,7 @@ Marcar Escribir un SMS Nombre de la carpeta + Añadir un recordatorio Elige una fecha y hora Fecha: @@ -488,6 +491,19 @@ Seguir leyendo Búsquedas recientes Ha sido desconectado + + %1$s espera una respuesta desde %2$s + %1$s esperan una respuesta desde %2$s + + + %1$s espera una respuesta antes de %2$s + %1$s esperan una respuesta antes de %2$s + + Posponer el recordatorio + Relanzar + Hola,\n¿Es posible obtener algún comentario sobre este tema?\nGracias de antemano. + Marcar como hecho + Recordatorio: sin respuesta de %1$s a este correo electrónico desde el %2$s Visibilidad del recordatorio Cambiar el nombre de la carpeta ¿Aceptas compartir tus datos con nuestros desarrolladores para que puedan ayudarte con tu problema? @@ -610,11 +626,15 @@ Compartir correo electrónico Error al enviar Recibo de lectura enviado + Error al añadir el recordatorio + Recordatorio añadido Un administrador ha deshabilitado el envío de mensajes El remitente está bloqueado Respuesta tenida en cuenta Nuevo contacto registrado correctamente La conversación ya no existe + No se ha podido desactivar el recordatorio + Recordatorio desactivado correctamente Problema de visualización notificado Descarga en proceso… Borrador suprimido @@ -628,6 +648,8 @@ Mensaje eliminado Mensaje trasladado a %s Mensaje movido a spam y usuario bloqueado + Error al modificar el recordatorio + Recordatorio modificado Desplazamiento cancelado Contraseña copiada Número copiado en el portapapeles diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index df0b058f28b..29f0e440e0e 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -182,6 +182,7 @@ Et ole kutsuttu %s (Järjestäjä) Muistuta, jos vastausta ei kuulu: %s lähettämisen jälkeen + Muistuta minua, jos vastausta ei tule: %s Kopio: Tulossa pian… Tarjoukset @@ -222,6 +223,7 @@ Välitetty Sinut on mainittu. Uusi + On muistutus Vastaus Tallennustilan tila Avaa sähköpostin toiminnot @@ -242,6 +244,7 @@ Soita Kirjoita tekstiviesti Kansion nimi + Lisää muistutus Valitse päivämäärä ja aika Päivämäärä: @@ -488,6 +491,19 @@ Lue lisää Viimeisimmät haut Sinut on kirjattu ulos + + %1$s on odottanut vastausta %2$s lähtien + %1$s ovat odottaneet vastausta %2$s lähtien + + + %1$s odottaa vastausta %2$s mennessä + %1$s odottavat vastausta %2$s mennessä + + Lykkää muistutusta + Seuraa + Hei,\nOnko mahdollista saada palautetta tästä aiheesta?\nKiitos etukäteen. + Merkitse valmiiksi + Muistutus: ei vastausta %1$s:ltä tähän sähköpostiin lähtien %2$s Muistutuksen näkyvyys Nimeä kansio uudelleen Suostutko jakamaan tietojasi kehittäjiemme kanssa, jotta he voivat auttaa sinua ongelmassasi? @@ -610,11 +626,15 @@ Jaa sähköposti Lähetys epäonnistui Vastaanottokuittaus lähetetty + Muistutuksen lisääminen epäonnistui + Muistutus lisätty Järjestelmänvalvoja on poistanut viestinlähetyksen käytöstä Lähettäjä on nyt estetty Vastaus otettu huomioon Uusi yhteystieto rekisteröity onnistuneesti Keskustelua ei ole enää olemassa + Muistutusta ei voitu poistaa käytöstä + Muistutus poistettu onnistuneesti käytöstä Näyttöongelma ilmoitettu Lataus käynnissä… Luonnos poistettu @@ -628,6 +648,8 @@ Viesti poistettu Viesti siirretty kohteeseen %s Viesti siirretty roskapostiksi ja käyttäjä estetty + Muistutuksen muokkaaminen epäonnistui + Muistutus muutettu Siirto peruutettu Salasana kopioitu Numero kopioitu leikepöydälle diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 4351327ff3d..a55a684ad80 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -182,6 +182,7 @@ Vous ne faites pas partie des invités %s (Organisateur) Me rappeler si pas de réponse : %s après envoi + Me rappeler si pas de réponse : %s Cc : À venir… Promotions @@ -222,6 +223,7 @@ Transféré Vous avez été mentionné. Nouveau + Est un rappel Réponse État du stockage Ouvrir les actions du message @@ -242,6 +244,7 @@ Composer Rédiger un SMS Nom du dossier + Créer un rappel Choisir une date et une heure Date : @@ -488,6 +491,19 @@ En savoir plus Recherches récentes Vous avez été déconnecté + + %1$s attend une réponse depuis %2$s + %1$s attendent une réponse depuis %2$s + + + %1$s attend une réponse avant le %2$s + %1$s attendent une réponse avant le %2$s + + Reporter le rappel + Relancer + Bonjour,\nEst-il possible d’avoir un retour sur ce sujet ?\nMerci d’avance. + Marquer comme terminé + Rappel : aucune réponse de %1$s à cet e-mail depuis le %2$s Visibilité du rappel Renommer le dossier Acceptez-vous de partager vos données avec nos développeurs pour qu’ils puissent vous aider concernant votre problème ? @@ -610,11 +626,15 @@ Partager l’e-mail Échec de l’envoi Accusé de lecture envoyé + Échec de l’ajout du rappel + Rappel ajouté Un administrateur a désactivé l’envoi de message L’expéditeur est maintenant bloqué Réponse prise en compte Nouveau contact enregistré avec succès La conversation n’existe plus + Échec de la désactivation du rappel + Le rappel a bien été désactivé Problème d’affichage signalé Téléchargement en cours… Brouillon supprimé @@ -628,6 +648,8 @@ Message supprimé Message déplacé vers %s Message déplacé vers Spam et utilisateur bloqué + Échec de la modification du rappel + Le rappel a bien été modifié Déplacement annulé Mot de passe copié Numéro copié dans le presse-papiers diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index aeadc32925b..a1802c8ddfd 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -182,6 +182,7 @@ Non fai parte degli invitati %s (Organizzatore) Ricordami se non c’è risposta: %s dopo l’invio + Ricordami se non c’è risposta: %s Cc: Prossimamente… Promozioni @@ -222,6 +223,7 @@ Inoltrato Sei stato menzionato. Nuovo + È un promemoria Risposta Stato di conservazione Azioni di apertura dei messaggi @@ -242,6 +244,7 @@ Componi Scrivi un SMS Nome della cartella + Aggiungi un promemoria Scegli una data e un’ora Data: @@ -488,6 +491,19 @@ Per saperne di più Ricerche recenti Sei stato disconnesso + + %1$s attende una risposta da %2$s + %1$s attendono una risposta da %2$s + + + %1$s attende una risposta entro %2$s + %1$s attendono una risposta entro %2$s + + Posticipare il promemoria + Sollecita + Ciao,\nÈ possibile avere un feedback su questo argomento?\nGrazie in anticipo. + Segna come fatto + Promemoria: nessuna risposta da %1$s a questa email dal %2$s Visibilità del promemoria Rinominare la cartella Accetti di condividere i tuoi dati con i nostri sviluppatori in modo che possano aiutarvi a risolvere il vostro problema? @@ -610,11 +626,15 @@ Condividi e-mail Invio non riuscito Ricevuta di lettura inviata + Impossibile aggiungere il promemoria + Promemoria aggiunto Un amministratore ha disabilitato l’invio di messaggi Il mittente è ora bloccato Risposta presa in considerazione Nuovo contatto registrato con successo La conversazione non esiste più + Impossibile disattivare il promemoria + Promemoria disattivato con successo Problema di visualizzazione segnalato Download in corso… Bozza cancellata @@ -628,6 +648,8 @@ Messaggio cancellato Messaggio spostato a %s Messaggio spostato nello spam e utente bloccato + Impossibile modificare il promemoria + Promemoria modificato Spostamento annullato Password copiata Numero copiato negli appunti diff --git a/app/src/main/res/values-nb/strings.xml b/app/src/main/res/values-nb/strings.xml index 368a6f25627..9b4243af3da 100644 --- a/app/src/main/res/values-nb/strings.xml +++ b/app/src/main/res/values-nb/strings.xml @@ -182,6 +182,7 @@ Du er ikke invitert %s (Arrangør) Påminn meg hvis det ikke er svar: %s etter sending + Påminn meg hvis det ikke er svar: %s Cc: Kommer snart… Kampanjer @@ -222,6 +223,7 @@ Videresendt Du har blitt nevnt. Ny + Er en påminnelse Svar Lagringsstatus Åpne e-posthandlinger @@ -242,6 +244,7 @@ Ring Skriv en SMS Navn på mappen + Legg til en påminnelse Velg dato og tid Dato: @@ -488,6 +491,19 @@ Les mer Nylige søk Du har blitt koblet fra + + %1$s har ventet på svar siden %2$s + %1$s har ventet på svar siden %2$s + + + %1$s avventer svar innen %2$s + %1$s avventer svar innen %2$s + + Utsett påminnelsen + Følg opp + Hei,\nEr det mulig å få tilbakemelding om dette emnet?\nPå forhånd takk. + Merk som fullført + Påminnelse: ingen respons fra %1$s på denne e-posten siden %2$s Påminnelsens synlighet Gi nytt navn til mappen Godtar du å dele dataene dine med utviklerne våre slik at de kan hjelpe deg med problemet? @@ -610,11 +626,15 @@ Del e-post Kunne ikke sende Lesebekreftelse sendt + Kunne ikke legge til påminnelsen + Påminnelse lagt til En administrator har deaktivert sending av meldinger Avsender er nå blokkert Svar tatt i betraktning Ny kontakt registrert Samtalen finnes ikke lenger + Kunne ikke deaktivere påminnelsen + Påminnelsen ble deaktivert Visningsproblem rapportert Nedlasting pågår… Utkast slettet @@ -628,6 +648,8 @@ Melding slettet Melding flyttet til %s Melding flyttet til spam og bruker blokkert + Kunne ikke endre påminnelsen + Påminnelse endret Flytting avbrutt Passord kopiert Nummer kopiert til utklippstavlen diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index aadb4d43686..f68f9c4c60b 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -182,6 +182,7 @@ U bent niet uitgenodigd %s (Organisator) Herinner me als er geen reactie is: %s na verzending + Herinner me als er geen reactie is: %s Cc: Binnenkort… Promoties @@ -222,6 +223,7 @@ Doorgestuurd Je bent vermeld. Nieuw + Is een herinnering Antwoord Opslagstatus E-mailacties openen @@ -242,6 +244,7 @@ Kiezen SMS schrijven Naam van de map + Herinnering toevoegen Kies een datum en tijd Datum: @@ -488,6 +491,19 @@ Meer informatie Recente zoekopdrachten U bent uitgelogd + + %1$s wacht sinds %2$s op een antwoord + %1$s wachten sinds %2$s op een antwoord + + + %1$s wacht op een antwoord voor %2$s + %1$s wachten op een antwoord voor %2$s + + Herinnering uitstellen + Opvolgen + Hallo,\nIs het mogelijk om feedback te krijgen over dit onderwerp?\nBij voorbaat dank. + Markeer als voltooid + Herinnering: geen reactie van %1$s op deze e-mail sinds %2$s Zichtbaarheid van de herinnering De map hernoemen Gaat u akkoord om uw gegevens te delen met onze ontwikkelaars zodat zij u kunnen helpen met uw probleem? @@ -610,11 +626,15 @@ E-mail delen Verzenden mislukt Leesbevestiging verzonden + Herinnering kon niet worden toegevoegd + Herinnering toegevoegd Een beheerder heeft het verzenden van berichten uitgeschakeld De afzender is nu geblokkeerd Antwoord verwerkt Nieuw contact succesvol geregistreerd Het gesprek bestaat niet meer + Herinnering kon niet worden uitgeschakeld + Herinnering succesvol uitgeschakeld Weergaveprobleem gemeld Download bezig… Concept verwijderd @@ -628,6 +648,8 @@ Bericht verwijderd Bericht verplaatst naar %s Bericht verplaatst naar spam en gebruiker geblokkeerd + Wijzigen van herinnering mislukt + Herinnering gewijzigd Verplaatsing geannuleerd Wachtwoord gekopieerd Nummer gekopieerd naar het klembord diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index c3dfe7a86b6..095d0530ff9 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -188,6 +188,7 @@ Nie jesteś zaproszony %s (Organizator) Przypomnij mi, jeśli brak odpowiedzi: %s po wysłaniu + Przypomnij mi, jeśli nie ma odpowiedzi: %s DW: Wkrótce… Promocje @@ -228,6 +229,7 @@ Przekazane dalej Zostałeś wspomniany. Nowe + Jest przypomnieniem Odpowiedź Status pamięci Otwórz akcje wiadomości @@ -248,6 +250,7 @@ Wybierz numer Napisz SMS Nazwa folderu + Dodaj przypomnienie Wybierz datę i godzinę Data: @@ -514,6 +517,23 @@ Czytaj więcej Ostatnie wyszukiwania Zostałeś/aś rozłączony/a + + %1$s czeka na odpowiedź od %2$s + %1$s czekają na odpowiedź od %2$s + %1$s czeka na odpowiedź od %2$s + %1$s czeka na odpowiedź od %2$s + + + %1$s czeka na odpowiedź do %2$s + %1$s czekają na odpowiedź do %2$s + %1$s czeka na odpowiedź do %2$s + %1$s czekają na odpowiedź do %2$s + + Opóźnij przypomnienie + Przypomnij + Cześć,\nCzy możliwe jest uzyskanie informacji zwrotnej na ten temat?\nZ góry dziękuję. + Zaznacz jako zakończone + Przypomnienie: brak odpowiedzi od %1$s na ten e-mail od %2$s Widoczność przypomnienia Zmień nazwę folderu Czy wyrażasz zgodę na udostępnienie swoich danych naszym deweloperom, aby mogli Ci pomóc w rozwiązaniu problemu? @@ -640,11 +660,15 @@ Udostępnij wiadomość Nie udało się wysłać Potwierdzenie odbioru wysłane + Nie udało się dodać przypomnienia + Przypomnienie dodane Administrator wyłączył wysyłanie wiadomości Nadawca został zablokowany Odpowiedź uwzględniona Nowy kontakt został pomyślnie zapisany Konwersacja już nie istnieje + Nie udało się wyłączyć przypomnienia + Przypomnienie zostało pomyślnie wyłączone Problem z wyświetlaniem zgłoszony Pobieranie w toku… Wersja robocza usunięta @@ -658,6 +682,8 @@ Wiadomość usunięta Wiadomość przeniesiona do %s Wiadomość przeniesiona do spamu i użytkownik zablokowany + Nie udało się zmodyfikować przypomnienia + Zmodyfikowano przypomnienie Przeniesienie anulowane Hasło skopiowane Numer skopiowany do schowka diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index a65442e6758..87c3df4f6f5 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -182,6 +182,7 @@ Não foi convidado %s (Organizador) Lembrar-me se não houver resposta: %s após o envio + Lembrar-me se não houver resposta: %s Cc: Brevemente… Promoções @@ -222,6 +223,7 @@ Encaminhado Você foi mencionado. Novo + É um lembrete Resposta Estado do armazenamento Abrir ações do e-mail @@ -242,6 +244,7 @@ Marcar Escrever uma SMS Nome da pasta + Adicionar um lembrete Escolher uma data e hora Data: @@ -488,6 +491,19 @@ Saber mais Pesquisas recentes Foi desligado + + %1$s aguarda uma resposta desde %2$s + %1$s aguardam uma resposta desde %2$s + + + %1$s aguarda uma resposta até %2$s + %1$s aguardam uma resposta até %2$s + + Adiar o lembrete + Relançar + Olá,\nÉ possível obter algum feedback sobre este assunto?\nObrigado desde já. + Marcar como concluído + Lembrete: nenhuma resposta de %1$s a este email desde %2$s Visibilidade do lembrete Renomear pasta Aceita partilhar os seus dados com os nossos programadores para que o ajudem com o seu problema? @@ -610,11 +626,15 @@ Partilhar e-mail Falha no envio Confirmação de leitura enviada + Não foi possível adicionar o lembrete + Lembrete adicionado Um administrador desabilitou o envio de mensagens Remetente bloqueado Resposta considerada Novo contacto guardado com sucesso A conversa já não existe + Não foi possível desativar o lembrete + Lembrete desativado com sucesso Problema de exibição reportado Transferência em curso… Rascunho eliminado @@ -628,6 +648,8 @@ Mensagem eliminada Mensagem movida para %s Mensagem movida para spam e utilizador bloqueado + Falha ao modificar o lembrete + Lembrete alterado Movimento cancelado Palavra-passe copiada Número copiado diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index 11c6f3d4c89..3799186c854 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -182,6 +182,7 @@ Du är inte inbjuden %s (Arrangör) Påminn mig om inget svar: %s efter sändning + Påminn mig om det inte finns något svar: %s Kopia: Kommer snart… Kampanjer @@ -222,6 +223,7 @@ Vidarebefordrad Du har blivit omnämnd. Ny + Är en påminnelse Svara Lagringsstatus Öppna e-poståtgärder @@ -242,6 +244,7 @@ Ring Skriv ett SMS Mappens namn + Lägg till en påminnelse Välj datum och tid Datum: @@ -488,6 +491,19 @@ Läs mer Senaste sökningar Du har kopplats bort + + %1$s väntar på svar sedan %2$s + %1$s väntar på svar sedan %2$s + + + %1$s väntar på svar senast %2$s + %1$s väntar på svar senast %2$s + + Skjut upp påminnelsen + Uppföljning + Hej,\nÄr det möjligt att få feedback om detta ämne?\nTack på förhand. + Markera som klar + Påminnelse: inget svar från %1$s på detta e-postmeddelande sedan %2$s Påminnelsens synlighet Byt namn på mappen Samtycker du till att dela dina data med våra utvecklare så att de kan hjälpa dig med ditt problem? @@ -610,11 +626,15 @@ Dela e-post Kunde inte skicka Läskvitto skickat + Det gick inte att lägga till påminnelsen + Påminnelse tillagd En administratör har inaktiverat meddelandesändning Avsändaren är nu blockerad Svar beaktat Ny kontakt registrerad Konversationen finns inte längre + Det gick inte att inaktivera påminnelsen + Påminnelsen har inaktiverats Visningsproblem rapporterat Nedladdning pågår… Utkast raderat @@ -628,6 +648,8 @@ Meddelande raderat Meddelande flyttat till %s Meddelande flyttat till skräppost och användare blockerad + Det gick inte att ändra påminnelsen + Påminnelsen har ändrats Flytt avbruten Lösenord kopierat Nummer kopierat till urklipp diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml index 7fa65acfd8e..114cf1faef8 100644 --- a/app/src/main/res/values/attrs.xml +++ b/app/src/main/res/values/attrs.xml @@ -169,6 +169,7 @@ + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 90d40294e00..7b4c9f74192 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -186,6 +186,7 @@ You are not invited %s (Organizer) Remind me if there is no response: %s after sending + Remind me if there is no response: %s Cc: Coming soon… Promotions @@ -226,6 +227,7 @@ Forwarded You have been mentioned. New + Is a reminder Reply Storage status Open mail actions @@ -246,6 +248,7 @@ Dial Write an SMS Name of the folder + Add a reminder Choose a date and time Date: @@ -492,6 +495,19 @@ Read more Recent searches You have been disconnected + + %1$s is awaiting a reply since %2$s + %1$s are awaiting a reply since %2$s + + + %1$s is awaiting a reply by %2$s + %1$s are awaiting a reply by %2$s + + Delay the reminder + Follow up + Hello,\nIs it possible to get some feedback on this subject?\nThank you in advance. + Mark as done + Reminder: no response from %1$s to this email since %2$s Reminder visibility Rename the folder Do you agree to share your data with our developers so that they can help you with your problem? @@ -614,11 +630,15 @@ Share email Failed to send Read receipt sent + Failed to add reminder + Reminder added An administrator has disabled message sending Sender is now blocked Response taken into account New contact successfully registered Conversation no longer exists + Failed to disable reminder + Reminder successfully disabled Display problem reported Download in progress… Draft deleted @@ -632,6 +652,8 @@ Message deleted Message moved to %s Message moved to Spam and user blocked + Failed to modify reminder + Reminder modified Move cancelled Password copied Number copied to clipboard