diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/ConversationItemFooter.java b/app/src/main/java/org/thoughtcrime/securesms/components/ConversationItemFooter.java index a78c9437ae..a171ce8247 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/ConversationItemFooter.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/ConversationItemFooter.java @@ -327,7 +327,11 @@ public class ConversationItemFooter extends ConstraintLayout { } String date = DateUtils.getDatelessRelativeTimeSpanString(getContext(), locale, timestamp); if (displayMode != ConversationItemDisplayMode.Detailed.INSTANCE && messageRecord.isEditMessage() && messageRecord.isLatestRevision()) { - date = getContext().getString(R.string.ConversationItem_edited_timestamp_footer, date); + if (DateUtils.isNow(timestamp)) { + date = getContext().getString(R.string.ConversationItem_edited_now_timestamp_footer); + } else { + date = getContext().getString(R.string.ConversationItem_edited_timestamp_footer, date); + } } dateView.setText(date); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationMessage.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationMessage.java index 9fcd3ac98d..0e8488dea0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationMessage.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationMessage.java @@ -161,7 +161,7 @@ public class ConversationMessage { } public static @NonNull FormattedDate getFormattedDate(@NonNull Context context, @NonNull MessageRecord messageRecord) { - return MessageRecordUtil.isScheduled(messageRecord) ? new FormattedDate(false, DateUtils.getOnlyTimeString(context, ((MmsMessageRecord) messageRecord).getScheduledDate())) + return MessageRecordUtil.isScheduled(messageRecord) ? new FormattedDate(false, false, DateUtils.getOnlyTimeString(context, ((MmsMessageRecord) messageRecord).getScheduledDate())) : DateUtils.getDatelessRelativeTimeSpanFormattedDate(context, Locale.getDefault(), messageRecord.getTimestamp()); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/computed/FormattedDate.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/computed/FormattedDate.kt index 52176d9142..d28dfb185c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/computed/FormattedDate.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/computed/FormattedDate.kt @@ -7,5 +7,6 @@ package org.thoughtcrime.securesms.conversation.v2.computed data class FormattedDate( val isRelative: Boolean, + val isNow: Boolean, val value: String ) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/items/V2ConversationItemTextOnlyViewHolder.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/items/V2ConversationItemTextOnlyViewHolder.kt index 9f0da5a09b..cbd96d4456 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/items/V2ConversationItemTextOnlyViewHolder.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/items/V2ConversationItemTextOnlyViewHolder.kt @@ -643,7 +643,11 @@ open class V2ConversationItemTextOnlyViewHolder>( } else { var date = dateString if (conversationContext.displayMode != ConversationItemDisplayMode.Detailed && record is MmsMessageRecord && record.isEditMessage()) { - date = getContext().getString(R.string.ConversationItem_edited_timestamp_footer, date) + date = if (conversationMessage.computedProperties.formattedDate.isNow) { + getContext().getString(R.string.ConversationItem_edited_now_timestamp_footer) + } else { + getContext().getString(R.string.ConversationItem_edited_timestamp_footer, date) + } binding.footerDate.setOnClickListener { conversationContext.clickListener.onEditedIndicatorClicked(record) diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/DateUtils.kt b/app/src/main/java/org/thoughtcrime/securesms/util/DateUtils.kt index 6db505a07e..9a560e367e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/DateUtils.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/util/DateUtils.kt @@ -60,7 +60,7 @@ object DateUtils : android.text.format.DateUtils() { @JvmStatic fun getBriefRelativeTimeSpanString(c: Context, locale: Locale, timestamp: Long): String { return when { - timestamp.isWithin(1.minutes) -> { + isNow(timestamp) -> { c.getString(R.string.DateUtils_just_now) } timestamp.isWithin(1.hours) -> { @@ -89,7 +89,7 @@ object DateUtils : android.text.format.DateUtils() { @JvmStatic fun getExtendedRelativeTimeSpanString(context: Context, locale: Locale, timestamp: Long): String { return when { - timestamp.isWithin(1.minutes) -> { + isNow(timestamp) -> { context.getString(R.string.DateUtils_just_now) } timestamp.isWithin(1.hours) -> { @@ -130,15 +130,15 @@ object DateUtils : android.text.format.DateUtils() { @JvmStatic fun getDatelessRelativeTimeSpanFormattedDate(context: Context, locale: Locale, timestamp: Long): FormattedDate { return when { - timestamp.isWithin(1.minutes) -> { - FormattedDate(true, context.getString(R.string.DateUtils_just_now)) + isNow(timestamp) -> { + FormattedDate(isRelative = true, isNow = true, value = context.getString(R.string.DateUtils_just_now)) } timestamp.isWithin(1.hours) -> { val minutes = timestamp.convertDeltaTo(DurationUnit.MINUTES) - FormattedDate(true, context.resources.getString(R.string.DateUtils_minutes_ago, minutes)) + FormattedDate(isRelative = true, isNow = false, value = context.resources.getString(R.string.DateUtils_minutes_ago, minutes)) } else -> { - FormattedDate(false, getOnlyTimeString(context, timestamp)) + FormattedDate(isRelative = false, isNow = false, value = getOnlyTimeString(context, timestamp)) } } } @@ -336,6 +336,16 @@ object DateUtils : android.text.format.DateUtils() { } } + /** + * This exposes "now" (defined here as a one minute window) to other classes. + * This is because certain locales use different linguistic constructions for "modified n minutes ago" and "modified just now", + * and therefore the caller will need to load different string resources in these situations. + * + * @param timestamp a Unix timestamp + */ + @JvmStatic + fun isNow(timestamp: Long) = timestamp.isWithin(1.minutes) + private fun Long.isWithin(duration: Duration): Boolean { return System.currentTimeMillis() - this <= duration.inWholeMilliseconds } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8e51c33230..4de6262225 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -323,6 +323,8 @@ Can\'t download image. You will need to send it again. Can\'t download video. You will need to send it again. + + Edited\u2000Now Edited\u2000%1$s