Skip to content

Commit c1728eb

Browse files
authored
feat: Add missing schedule date format in ThreadListFragment (#2164)
2 parents 1d66090 + 99dac32 commit c1728eb

File tree

4 files changed

+83
-31
lines changed

4 files changed

+83
-31
lines changed

app/src/main/java/com/infomaniak/mail/data/models/thread/Thread.kt

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,7 @@
1919

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

22-
import android.content.Context
23-
import android.os.Build
24-
import com.infomaniak.lib.core.utils.*
2522
import com.infomaniak.mail.MatomoMail.SEARCH_FOLDER_FILTER_NAME
26-
import com.infomaniak.mail.R
2723
import com.infomaniak.mail.data.api.RealmInstantSerializer
2824
import com.infomaniak.mail.data.cache.mailboxContent.FolderController
2925
import com.infomaniak.mail.data.models.Bimi
@@ -32,8 +28,6 @@ import com.infomaniak.mail.data.models.Folder.FolderRole
3228
import com.infomaniak.mail.data.models.correspondent.Recipient
3329
import com.infomaniak.mail.data.models.message.Message
3430
import com.infomaniak.mail.utils.AccountUtils
35-
import com.infomaniak.mail.utils.extensions.isSmallerThanDays
36-
import com.infomaniak.mail.utils.extensions.toDate
3731
import com.infomaniak.mail.utils.extensions.toRealmInstant
3832
import io.realm.kotlin.MutableRealm
3933
import io.realm.kotlin.Realm
@@ -51,7 +45,6 @@ import kotlinx.serialization.SerialName
5145
import kotlinx.serialization.Serializable
5246
import kotlinx.serialization.Transient
5347
import kotlinx.serialization.UseSerializers
54-
import java.time.format.FormatStyle
5548
import java.util.Date
5649

5750
@Serializable
@@ -221,25 +214,6 @@ class Thread : RealmObject {
221214
subject = messages.first().subject
222215
}
223216

224-
fun formatDate(context: Context): String = with(date.toDate()) {
225-
when {
226-
isInTheFuture() -> formatNumericalDayMonthYear()
227-
isToday() -> format(FORMAT_DATE_HOUR_MINUTE)
228-
isYesterday() -> context.getString(R.string.messageDetailsYesterday)
229-
isSmallerThanDays(6) -> format(FORMAT_DAY_OF_THE_WEEK)
230-
isThisYear() -> format(FORMAT_DATE_SHORT_DAY_ONE_CHAR)
231-
else -> formatNumericalDayMonthYear()
232-
}
233-
}
234-
235-
private fun Date.formatNumericalDayMonthYear(): String {
236-
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
237-
formatWithLocal(FormatData.DATE, FormatStyle.SHORT)
238-
} else {
239-
format(FORMAT_DATE_CLEAR_MONTH_DAY_ONE_CHAR) // Fallback on unambiguous date format for any local
240-
}
241-
}
242-
243217
fun computeAvatarRecipient(): Pair<Recipient?, Bimi?> = runCatching {
244218

245219
val message = messages.lastOrNull {

app/src/main/java/com/infomaniak/mail/ui/main/folder/ThreadListAdapter.kt

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,9 +231,13 @@ class ThreadListAdapter @Inject constructor(
231231
expeditor.text = formatRecipientNames(computeDisplayedRecipients())
232232
mailSubject.text = context.formatSubject(subject)
233233
mailBodyPreview.text = computePreview().ifBlank { context.getString(R.string.noBodyTitle) }
234-
mailDate.text = formatDate(context)
235234

236-
scheduleSendIcon.isVisible = numberOfScheduledDrafts > 0 && folderRole == FolderRole.SCHEDULED_DRAFTS
235+
val dateDisplay = computeDateDisplay()
236+
mailDate.text = dateDisplay.formatDate(context, date)
237+
mailDateIcon.apply {
238+
isVisible = dateDisplay.icon != null
239+
dateDisplay.icon?.let { setImageResource(it) }
240+
}
237241
draftPrefix.isVisible = hasDrafts
238242

239243
val (isIconReplyVisible, isIconForwardVisible) = computeReplyAndForwardIcon(thread.isAnswered, thread.isForwarded)
@@ -484,6 +488,11 @@ class ThreadListAdapter @Inject constructor(
484488
}
485489
}
486490

491+
private fun Thread.computeDateDisplay() = when {
492+
numberOfScheduledDrafts > 0 && folderRole == FolderRole.SCHEDULED_DRAFTS -> ThreadListDateDisplay.Scheduled
493+
else -> ThreadListDateDisplay.Default
494+
}
495+
487496
private fun CardviewThreadItemBinding.setThreadUiRead() {
488497
newMailBullet.isInvisible = true
489498

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* Infomaniak Mail - Android
3+
* Copyright (C) 2025 Infomaniak Network SA
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
*/
18+
package com.infomaniak.mail.ui.main.folder
19+
20+
import android.content.Context
21+
import android.os.Build
22+
import android.text.format.DateUtils
23+
import androidx.annotation.DrawableRes
24+
import com.infomaniak.lib.core.utils.*
25+
import com.infomaniak.mail.R
26+
import com.infomaniak.mail.data.models.thread.Thread.Companion.FORMAT_DAY_OF_THE_WEEK
27+
import com.infomaniak.mail.utils.extensions.isSmallerThanDays
28+
import com.infomaniak.mail.utils.extensions.toDate
29+
import io.realm.kotlin.types.RealmInstant
30+
import java.time.format.FormatStyle
31+
import java.util.Date
32+
33+
enum class ThreadListDateDisplay(@DrawableRes val icon: Int?, val formatDate: Context.(RealmInstant) -> String) {
34+
Default(
35+
icon = null,
36+
formatDate = { date -> defaultFormatting(date) }
37+
),
38+
Scheduled(
39+
icon = R.drawable.ic_scheduled_messages,
40+
formatDate = { date -> relativeFormatting(date) }
41+
),
42+
}
43+
44+
private fun Context.relativeFormatting(date: RealmInstant) = DateUtils.getRelativeDateTimeString(
45+
this,
46+
date.epochSeconds * 1000,
47+
DateUtils.DAY_IN_MILLIS,
48+
DateUtils.WEEK_IN_MILLIS,
49+
0,
50+
)?.toString() ?: ""
51+
52+
private fun Context.defaultFormatting(date: RealmInstant) = with(date.toDate()) {
53+
when {
54+
isInTheFuture() -> formatNumericalDayMonthYear()
55+
isToday() -> format(FORMAT_DATE_HOUR_MINUTE)
56+
isYesterday() -> getString(R.string.messageDetailsYesterday)
57+
isSmallerThanDays(6) -> format(FORMAT_DAY_OF_THE_WEEK)
58+
isThisYear() -> format(FORMAT_DATE_SHORT_DAY_ONE_CHAR)
59+
else -> formatNumericalDayMonthYear()
60+
}
61+
}
62+
63+
private fun Date.formatNumericalDayMonthYear(): String {
64+
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
65+
formatWithLocal(FormatData.DATE, FormatStyle.SHORT)
66+
} else {
67+
format(FORMAT_DATE_CLEAR_MONTH_DAY_ONE_CHAR) // Fallback on unambiguous date format for any local
68+
}
69+
}

app/src/main/res/layout/cardview_thread_item.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@
199199
app:cardBackgroundColor="@color/backgroundColor"
200200
app:cardCornerRadius="2dp"
201201
app:layout_constraintBottom_toBottomOf="@id/expeditor"
202-
app:layout_constraintEnd_toStartOf="@id/scheduleSendIcon"
202+
app:layout_constraintEnd_toStartOf="@id/mailDateIcon"
203203
app:layout_constraintStart_toEndOf="@id/expeditor"
204204
app:layout_constraintTop_toTopOf="@id/expeditor"
205205
app:strokeColor="@color/progressbarTrackColor"
@@ -217,17 +217,17 @@
217217
</com.google.android.material.card.MaterialCardView>
218218

219219
<ImageView
220-
android:id="@+id/scheduleSendIcon"
220+
android:id="@+id/mailDateIcon"
221221
android:layout_width="@dimen/smallIconSize"
222222
android:layout_height="@dimen/smallIconSize"
223223
android:layout_marginHorizontal="@dimen/marginStandardVerySmall"
224224
android:contentDescription="@string/contentDescriptionScheduleSend"
225-
android:src="@drawable/ic_scheduled_messages"
226225
android:visibility="gone"
227226
app:layout_constraintBottom_toBottomOf="@id/mailDate"
228227
app:layout_constraintEnd_toStartOf="@id/mailDate"
229228
app:layout_constraintTop_toTopOf="@id/mailDate"
230229
app:tint="@color/scheduledIconColor"
230+
tools:src="@drawable/ic_scheduled_messages"
231231
tools:visibility="visible" />
232232

233233
<TextView

0 commit comments

Comments
 (0)