diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/conversation/ui/ChatDateLabel.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/conversation/ui/ChatDateLabel.kt index 0b7f628f..14745fee 100644 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/conversation/ui/ChatDateLabel.kt +++ b/presentation/src/main/java/org/monogram/presentation/features/chats/conversation/ui/ChatDateLabel.kt @@ -1,5 +1,7 @@ package org.monogram.presentation.features.chats.conversation.ui +import android.content.Context +import org.monogram.presentation.R import java.text.SimpleDateFormat import java.util.Calendar import java.util.Date @@ -15,13 +17,36 @@ fun isTodayTimestamp(timestamp: Int, locale: Locale = Locale.getDefault()): Bool calendar.get(Calendar.DAY_OF_YEAR) == todayDayOfYear } -fun formatChatDayLabel(timestamp: Int, locale: Locale = Locale.getDefault()): String { +fun formatChatDayLabel(timestamp: Int, context: Context, locale: Locale = Locale.getDefault()): String { val date = Date(timestamp.toLong() * 1000) - val calendar = Calendar.getInstance(locale) - val currentYear = calendar.get(Calendar.YEAR) - calendar.time = date - val messageYear = calendar.get(Calendar.YEAR) + val now = Calendar.getInstance(locale) + val msgCal = Calendar.getInstance(locale).apply { time = date } + + val nowYear = now.get(Calendar.YEAR) + val nowDay = now.get(Calendar.DAY_OF_YEAR) + val msgYear = msgCal.get(Calendar.YEAR) + val msgDay = msgCal.get(Calendar.DAY_OF_YEAR) + + if (nowYear == msgYear) { + val dayDiff = nowDay - msgDay + return when { + dayDiff == 0 -> context.getString(R.string.chat_date_today) + dayDiff == 1 -> context.getString(R.string.chat_date_yesterday) + dayDiff in 2..6 -> SimpleDateFormat("EEEE", locale).format(date) + else -> SimpleDateFormat("d MMMM", locale).format(date) + } + } + + if (nowYear - msgYear == 1 && msgDay >= 359 && nowDay <= 6) { + val daysInMsgYear = msgCal.getActualMaximum(Calendar.DAY_OF_YEAR) + val dayDiff = (daysInMsgYear - msgDay) + nowDay + return when { + dayDiff == 0 -> context.getString(R.string.chat_date_today) + dayDiff == 1 -> context.getString(R.string.chat_date_yesterday) + dayDiff in 2..6 -> SimpleDateFormat("EEEE", locale).format(date) + else -> SimpleDateFormat("d MMMM yyyy", locale).format(date) + } + } - val pattern = if (messageYear == currentYear) "d MMMM" else "d MMMM yyyy" - return SimpleDateFormat(pattern, locale).format(date) + return SimpleDateFormat("d MMMM yyyy", locale).format(date) } diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/conversation/ui/DateSeparator.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/conversation/ui/DateSeparator.kt index 36efa6df..0f497119 100644 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/conversation/ui/DateSeparator.kt +++ b/presentation/src/main/java/org/monogram/presentation/features/chats/conversation/ui/DateSeparator.kt @@ -10,11 +10,13 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.unit.dp @Composable fun DateSeparator(timestamp: Int) { - val text = formatChatDayLabel(timestamp) + val context = LocalContext.current + val text = formatChatDayLabel(timestamp, context) Box( modifier = Modifier .fillMaxWidth() diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/conversation/ui/content/ChatContentList.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/conversation/ui/content/ChatContentList.kt index 5be70b77..7d9a7522 100644 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/conversation/ui/content/ChatContentList.kt +++ b/presentation/src/main/java/org/monogram/presentation/features/chats/conversation/ui/content/ChatContentList.kt @@ -73,6 +73,7 @@ import androidx.compose.ui.geometry.Offset import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.graphics.luminance +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.res.stringResource import androidx.compose.ui.semantics.contentDescription @@ -191,6 +192,7 @@ fun ChatContentList( ) { val isComments = state.isComments val appearance = state.toAppearanceConfig() + val context = LocalContext.current val density = LocalDensity.current val isScrolling by remember(scrollState) { derivedStateOf { scrollState.isScrollInProgress } } val latestState by rememberUpdatedState(state) @@ -306,7 +308,7 @@ fun ChatContentList( viewportTopOffset = viewportTopOffset ) ?: return@derivedStateOf null - formatChatDayLabel(anchor.mainTimestamp()) + formatChatDayLabel(anchor.mainTimestamp(), context) } } diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/conversation/ui/message/ForwardContent.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/conversation/ui/message/ForwardContent.kt index 07363902..d05387dc 100644 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/conversation/ui/message/ForwardContent.kt +++ b/presentation/src/main/java/org/monogram/presentation/features/chats/conversation/ui/message/ForwardContent.kt @@ -33,6 +33,7 @@ import org.monogram.domain.models.ForwardInfo import org.monogram.domain.models.ForwardOriginType import org.monogram.presentation.core.ui.Avatar import org.monogram.presentation.core.util.DateFormatManager +import org.monogram.presentation.features.chats.conversation.ui.isTodayTimestamp @Composable fun ForwardContent( @@ -132,9 +133,16 @@ fun ForwardContent( ) if (forwardInfo.date > 0) { + val forwardDateText = remember(forwardInfo.date, timeFormat) { + if (isTodayTimestamp(forwardInfo.date)) { + formatTime(forwardInfo.date, timeFormat) + } else { + formatForwardDate(forwardInfo.date, timeFormat) + } + } Spacer(modifier = Modifier.width(6.dp)) Text( - text = formatTime(forwardInfo.date, timeFormat), + text = forwardDateText, style = MaterialTheme.typography.labelSmall.copy(fontSize = 11.sp), color = contentColor.copy(alpha = 0.56f), maxLines = 1 diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/conversation/ui/message/MessageUtils.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/conversation/ui/message/MessageUtils.kt index 113730c3..b78a12e3 100644 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/conversation/ui/message/MessageUtils.kt +++ b/presentation/src/main/java/org/monogram/presentation/features/chats/conversation/ui/message/MessageUtils.kt @@ -55,6 +55,7 @@ import org.monogram.presentation.features.chats.conversation.ui.channel.formatVi import java.io.File import java.text.BreakIterator import java.text.SimpleDateFormat +import java.util.Calendar import java.util.Date import java.util.Locale import kotlin.math.log10 @@ -67,6 +68,17 @@ val LocalLinkHandler = staticCompositionLocalOf<(String) -> Unit> { fun formatTime(ts: Int, timeFormat: String): String = SimpleDateFormat(timeFormat, Locale.getDefault()).format(Date(ts.toLong() * 1000)) +fun formatForwardDate(ts: Int, timeFormat: String): String { + val date = Date(ts.toLong() * 1000) + val locale = Locale.getDefault() + val cal = Calendar.getInstance(locale).apply { time = date } + val now = Calendar.getInstance(locale) + val datePattern = if (cal.get(Calendar.YEAR) == now.get(Calendar.YEAR)) "d MMM" else "d MMM yyyy" + val datePart = SimpleDateFormat(datePattern, locale).format(date) + val timePart = SimpleDateFormat(timeFormat, locale).format(date) + return "$datePart, $timePart" +} + fun formatDuration(seconds: Int): String { val m = seconds / 60 val s = seconds % 60 diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/creation/DefaultNewChatComponent.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/creation/DefaultNewChatComponent.kt index 455f023b..4e477873 100644 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/creation/DefaultNewChatComponent.kt +++ b/presentation/src/main/java/org/monogram/presentation/features/chats/creation/DefaultNewChatComponent.kt @@ -225,15 +225,13 @@ class DefaultNewChatComponent( when (currentState.step) { NewChatComponent.Step.GROUP_MEMBERS -> { - if (currentState.selectedUserIds.isNotEmpty()) { - _state.update { - it.copy( - step = NewChatComponent.Step.GROUP_INFO, - searchQuery = "", - searchResults = emptyList(), - validationError = null - ) - } + _state.update { + it.copy( + step = NewChatComponent.Step.GROUP_INFO, + searchQuery = "", + searchResults = emptyList(), + validationError = null + ) } } diff --git a/presentation/src/main/res/values/string.xml b/presentation/src/main/res/values/string.xml index 352ffd67..03454849 100644 --- a/presentation/src/main/res/values/string.xml +++ b/presentation/src/main/res/values/string.xml @@ -2102,6 +2102,8 @@ Unsupported message + Today + Yesterday %1$02d:%2$02d