diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt
index 3b45fd55a..442ec4da3 100644
--- a/app/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt
+++ b/app/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt
@@ -741,10 +741,10 @@ object LocalCache {
// Already processed this event.
if (version.event?.id() == event.id()) return
- if (version.event == null) {
- // makes sure the OTS has a valid certificate
- if (event.cacheVerify() == null) return // no valid OTS
+ // makes sure the OTS has a valid certificate
+ if (event.cacheVerify() == null) return // no valid OTS
+ if (version.event == null) {
version.loadEvent(event, author, emptyList())
version.liveSet?.innerOts?.invalidateData()
diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt
index 35929b150..7725b9ead 100644
--- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt
+++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt
@@ -241,6 +241,8 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.io.File
import java.net.URL
+import java.text.SimpleDateFormat
+import java.util.Date
import java.util.Locale
@OptIn(ExperimentalFoundationApi::class)
@@ -2560,15 +2562,27 @@ fun DisplayOts(
LoadOts(
note,
accountViewModel,
- whenConfirmed = {
+ whenConfirmed = { unixtimestamp ->
val context = LocalContext.current
- val timeStr by remember(note) { mutableStateOf(timeAgo(it, context = context)) }
+ val timeStr by remember(unixtimestamp) { mutableStateOf(timeAgoNoDot(unixtimestamp, context = context)) }
- Text(
- stringResource(id = R.string.existed_since, timeStr),
- color = MaterialTheme.colorScheme.lessImportantLink,
- fontSize = Font14SP,
- fontWeight = FontWeight.Bold,
+ ClickableText(
+ text = buildAnnotatedString { append(stringResource(id = R.string.existed_since, timeStr)) },
+ onClick = {
+ val fullDateTime =
+ SimpleDateFormat.getDateTimeInstance().format(Date(unixtimestamp * 1000))
+
+ accountViewModel.toast(
+ context.getString(R.string.ots_info_title),
+ context.getString(R.string.ots_info_description, fullDateTime),
+ )
+ },
+ style =
+ LocalTextStyle.current.copy(
+ color = MaterialTheme.colorScheme.lessImportantLink,
+ fontSize = Font14SP,
+ fontWeight = FontWeight.Bold,
+ ),
maxLines = 1,
)
},
@@ -2688,11 +2702,12 @@ fun LoadOts(
LaunchedEffect(key1 = noteStatus) {
accountViewModel.findOtsEventsForNote(noteStatus?.note ?: note) { newOts ->
- if (newOts == null) {
- earliestDate = GenericLoadable.Empty()
- } else {
- earliestDate = GenericLoadable.Loaded(newOts)
- }
+ earliestDate =
+ if (newOts == null) {
+ GenericLoadable.Empty()
+ } else {
+ GenericLoadable.Loaded(newOts)
+ }
}
}
diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/TimeAgoFormatter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/TimeAgoFormatter.kt
index aa381ac24..d2040b21a 100644
--- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/TimeAgoFormatter.kt
+++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/TimeAgoFormatter.kt
@@ -71,6 +71,46 @@ fun timeAgo(
}
}
+fun timeAgoNoDot(
+ time: Long?,
+ context: Context,
+): String {
+ if (time == null) return " "
+ if (time == 0L) return " ${context.getString(R.string.never)}"
+
+ val timeDifference = TimeUtils.now() - time
+
+ return if (timeDifference > TimeUtils.ONE_YEAR) {
+ // Dec 12, 2022
+
+ if (locale != Locale.getDefault()) {
+ locale = Locale.getDefault()
+ yearFormatter = SimpleDateFormat("MMM dd, yyyy", locale)
+ monthFormatter = SimpleDateFormat("MMM dd", locale)
+ }
+
+ yearFormatter.format(time * 1000)
+ } else if (timeDifference > TimeUtils.ONE_MONTH) {
+ // Dec 12
+ if (locale != Locale.getDefault()) {
+ locale = Locale.getDefault()
+ yearFormatter = SimpleDateFormat("MMM dd, yyyy", locale)
+ monthFormatter = SimpleDateFormat("MMM dd", locale)
+ }
+
+ monthFormatter.format(time * 1000)
+ } else if (timeDifference > TimeUtils.ONE_DAY) {
+ // 2 days
+ (timeDifference / TimeUtils.ONE_DAY).toString() + context.getString(R.string.d)
+ } else if (timeDifference > TimeUtils.ONE_HOUR) {
+ (timeDifference / TimeUtils.ONE_HOUR).toString() + context.getString(R.string.h)
+ } else if (timeDifference > TimeUtils.ONE_MINUTE) {
+ (timeDifference / TimeUtils.ONE_MINUTE).toString() + context.getString(R.string.m)
+ } else {
+ context.getString(R.string.now)
+ }
+}
+
fun timeAgoShort(
mills: Long?,
stringForNow: String,
diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/ThreadFeedView.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/ThreadFeedView.kt
index 511a8caa4..2d3153de5 100644
--- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/ThreadFeedView.kt
+++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/ThreadFeedView.kt
@@ -104,6 +104,7 @@ import com.vitorpamplona.amethyst.ui.note.BlankNote
import com.vitorpamplona.amethyst.ui.note.CreateImageHeader
import com.vitorpamplona.amethyst.ui.note.DisplayHighlight
import com.vitorpamplona.amethyst.ui.note.DisplayLocation
+import com.vitorpamplona.amethyst.ui.note.DisplayOts
import com.vitorpamplona.amethyst.ui.note.DisplayPeopleList
import com.vitorpamplona.amethyst.ui.note.DisplayRelaySet
import com.vitorpamplona.amethyst.ui.note.FileHeaderDisplay
@@ -449,6 +450,8 @@ fun NoteMaster(
if (pow > 20) {
DisplayPoW(pow)
}
+
+ DisplayOts(note, accountViewModel)
}
}
}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 5451e48e9..d36dbb21a 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -787,4 +787,7 @@
Web:
Clone:
OTS: %1$s
+
+ Timestamp Proof
+ There\'s proof this post was signed sometime before %1$s. The proof was stamped in the Bitcoin blockchain at that date and time.