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

feat: Add missing schedule date format in ThreadListFragment #2164

Merged
merged 9 commits into from
Feb 17, 2025
26 changes: 0 additions & 26 deletions app/src/main/java/com/infomaniak/mail/data/models/thread/Thread.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,7 @@

package com.infomaniak.mail.data.models.thread

import android.content.Context
import android.os.Build
import com.infomaniak.lib.core.utils.*
import com.infomaniak.mail.MatomoMail.SEARCH_FOLDER_FILTER_NAME
import com.infomaniak.mail.R
import com.infomaniak.mail.data.api.RealmInstantSerializer
import com.infomaniak.mail.data.cache.mailboxContent.FolderController
import com.infomaniak.mail.data.models.Bimi
Expand All @@ -32,8 +28,6 @@ import com.infomaniak.mail.data.models.Folder.FolderRole
import com.infomaniak.mail.data.models.correspondent.Recipient
import com.infomaniak.mail.data.models.message.Message
import com.infomaniak.mail.utils.AccountUtils
import com.infomaniak.mail.utils.extensions.isSmallerThanDays
import com.infomaniak.mail.utils.extensions.toDate
import com.infomaniak.mail.utils.extensions.toRealmInstant
import io.realm.kotlin.MutableRealm
import io.realm.kotlin.Realm
Expand All @@ -51,7 +45,6 @@ import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
import kotlinx.serialization.UseSerializers
import java.time.format.FormatStyle
import java.util.Date

@Serializable
Expand Down Expand Up @@ -221,25 +214,6 @@ class Thread : RealmObject {
subject = messages.first().subject
}

fun formatDate(context: Context): String = with(date.toDate()) {
when {
isInTheFuture() -> formatNumericalDayMonthYear()
isToday() -> format(FORMAT_DATE_HOUR_MINUTE)
isYesterday() -> context.getString(R.string.messageDetailsYesterday)
isSmallerThanDays(6) -> format(FORMAT_DAY_OF_THE_WEEK)
isThisYear() -> format(FORMAT_DATE_SHORT_DAY_ONE_CHAR)
else -> formatNumericalDayMonthYear()
}
}

private fun Date.formatNumericalDayMonthYear(): String {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
formatWithLocal(FormatData.DATE, FormatStyle.SHORT)
} else {
format(FORMAT_DATE_CLEAR_MONTH_DAY_ONE_CHAR) // Fallback on unambiguous date format for any local
}
}

fun computeAvatarRecipient(): Pair<Recipient?, Bimi?> = runCatching {

val message = messages.lastOrNull {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Infomaniak Mail - Android
* Copyright (C) 2025 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 <http://www.gnu.org/licenses/>.
*/
package com.infomaniak.mail.ui.main.folder

import android.content.Context
import android.os.Build
import android.text.format.DateUtils
import androidx.annotation.DrawableRes
import com.infomaniak.lib.core.utils.*
import com.infomaniak.mail.R
import com.infomaniak.mail.data.models.thread.Thread.Companion.FORMAT_DAY_OF_THE_WEEK
import com.infomaniak.mail.utils.extensions.isSmallerThanDays
import com.infomaniak.mail.utils.extensions.toDate
import io.realm.kotlin.types.RealmInstant
import java.time.format.FormatStyle
import java.util.Date

enum class DateDisplay(@DrawableRes val icon: Int?, val formatDate: Context.(RealmInstant) -> String) {
Default(
icon = null,
formatDate = { date -> defaultFormatting(date) }
),
Scheduled(
icon = R.drawable.ic_scheduled_messages,
formatDate = { date -> relativeFormatting(date) }
),
}

private fun Context.relativeFormatting(date: RealmInstant) = DateUtils.getRelativeDateTimeString(
this,
date.epochSeconds * 1000,
DateUtils.DAY_IN_MILLIS,
DateUtils.WEEK_IN_MILLIS,
DateUtils.FORMAT_SHOW_YEAR or DateUtils.FORMAT_ABBREV_MONTH,
)?.toString() ?: ""

private fun Context.defaultFormatting(date: RealmInstant) = with(date.toDate()) {
when {
isInTheFuture() -> formatNumericalDayMonthYear()
isToday() -> format(FORMAT_DATE_HOUR_MINUTE)
isYesterday() -> getString(R.string.messageDetailsYesterday)
isSmallerThanDays(6) -> format(FORMAT_DAY_OF_THE_WEEK)
isThisYear() -> format(FORMAT_DATE_SHORT_DAY_ONE_CHAR)
else -> formatNumericalDayMonthYear()
}
}

private fun Date.formatNumericalDayMonthYear(): String {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
formatWithLocal(FormatData.DATE, FormatStyle.SHORT)
} else {
format(FORMAT_DATE_CLEAR_MONTH_DAY_ONE_CHAR) // Fallback on unambiguous date format for any local
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -231,9 +231,13 @@ class ThreadListAdapter @Inject constructor(
expeditor.text = formatRecipientNames(computeDisplayedRecipients())
mailSubject.text = context.formatSubject(subject)
mailBodyPreview.text = computePreview().ifBlank { context.getString(R.string.noBodyTitle) }
mailDate.text = formatDate(context)

scheduleSendIcon.isVisible = numberOfScheduledDrafts > 0 && folderRole == FolderRole.SCHEDULED_DRAFTS
val dateDisplay = computeDateDisplay()
mailDate.text = dateDisplay.formatDate(context, date)
mailDateIcon.apply {
isVisible = dateDisplay.icon != null
dateDisplay.icon?.let { setImageResource(it) }
}
draftPrefix.isVisible = hasDrafts

val (isIconReplyVisible, isIconForwardVisible) = computeReplyAndForwardIcon(thread.isAnswered, thread.isForwarded)
Expand Down Expand Up @@ -484,6 +488,11 @@ class ThreadListAdapter @Inject constructor(
}
}

private fun Thread.computeDateDisplay() = when {
numberOfScheduledDrafts > 0 && folderRole == FolderRole.SCHEDULED_DRAFTS -> DateDisplay.Scheduled
else -> DateDisplay.Default
}

private fun CardviewThreadItemBinding.setThreadUiRead() {
newMailBullet.isInvisible = true

Expand Down
6 changes: 3 additions & 3 deletions app/src/main/res/layout/cardview_thread_item.xml
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@
app:cardBackgroundColor="@color/backgroundColor"
app:cardCornerRadius="2dp"
app:layout_constraintBottom_toBottomOf="@id/expeditor"
app:layout_constraintEnd_toStartOf="@id/scheduleSendIcon"
app:layout_constraintEnd_toStartOf="@id/mailDateIcon"
app:layout_constraintStart_toEndOf="@id/expeditor"
app:layout_constraintTop_toTopOf="@id/expeditor"
app:strokeColor="@color/progressbarTrackColor"
Expand All @@ -217,17 +217,17 @@
</com.google.android.material.card.MaterialCardView>

<ImageView
android:id="@+id/scheduleSendIcon"
android:id="@+id/mailDateIcon"
android:layout_width="@dimen/smallIconSize"
android:layout_height="@dimen/smallIconSize"
android:layout_marginHorizontal="@dimen/marginStandardVerySmall"
android:contentDescription="@string/contentDescriptionScheduleSend"
android:src="@drawable/ic_scheduled_messages"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="@id/mailDate"
app:layout_constraintEnd_toStartOf="@id/mailDate"
app:layout_constraintTop_toTopOf="@id/mailDate"
app:tint="@color/scheduledIconColor"
tools:src="@drawable/ic_scheduled_messages"
tools:visibility="visible" />

<TextView
Expand Down