mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-23 02:10:44 +01:00
Improve handling of 12/24 hour timestamps on configuration change.
This fixes an edge case seen on ConversationFragment, where if the device time format is switched between 12/24 hour format while the app is running, the old time format will still be displayed when the app is resumed. This is due to a design flaw in `DateTimeFormatter.ofLocalizedTime`, where the time format is statically cached and not updated upon configuration change. The `LocalTime.formatHours()` extension method was updated to no longer rely on the misbehaving `ofLocalTime` method. In addition, `ConversationMessaageComputeWorkers.recomputeFormattedDate` was designed to skip recomputing non-relative timestamps. This works in most cases but not this specific edge case. A `force: Boolean` flag was added to force all items to be updated. And the `force = true` flag was passed upon `onResume` of the fragment. Closes #14121
This commit is contained in:
committed by
Michelle Tang
parent
918b792d83
commit
c865ed0cdc
@@ -665,6 +665,11 @@ class ConversationFragment :
|
||||
outState.putBoolean(SAVED_STATE_IS_SEARCH_REQUESTED, isSearchRequested)
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
recomputeMessageDates(forceUpdate = true)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
|
||||
@@ -1173,12 +1178,7 @@ class ConversationFragment :
|
||||
|
||||
getVoiceNoteMediaController().voiceNotePlaybackState.observe(viewLifecycleOwner, inputPanel.playbackStateObserver)
|
||||
|
||||
val conversationUpdateTick = ConversationUpdateTick {
|
||||
disposables += ConversationMessageComputeWorkers.recomputeFormattedDate(
|
||||
requireContext(),
|
||||
adapter.currentList.filterIsInstance<ConversationMessageElement>()
|
||||
).observeOn(AndroidSchedulers.mainThread()).subscribeBy { adapter.updateTimestamps() }
|
||||
}
|
||||
val conversationUpdateTick = ConversationUpdateTick { recomputeMessageDates() }
|
||||
|
||||
viewLifecycleOwner.lifecycle.addObserver(conversationUpdateTick)
|
||||
|
||||
@@ -1188,6 +1188,17 @@ class ConversationFragment :
|
||||
}
|
||||
}
|
||||
|
||||
private fun recomputeMessageDates(forceUpdate: Boolean = false) {
|
||||
disposables += ConversationMessageComputeWorkers
|
||||
.recomputeFormattedDate(
|
||||
context = requireContext(),
|
||||
items = adapter.currentList.filterIsInstance<ConversationMessageElement>(),
|
||||
forceUpdate = forceUpdate
|
||||
)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribeBy { adapter.updateTimestamps() }
|
||||
}
|
||||
|
||||
private fun initializeInlineSearch() {
|
||||
inlineQueryController.onOrientationChange(resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE)
|
||||
|
||||
|
||||
@@ -21,13 +21,14 @@ object ConversationMessageComputeWorkers {
|
||||
|
||||
fun recomputeFormattedDate(
|
||||
context: Context,
|
||||
items: List<ConversationMessageElement>
|
||||
items: List<ConversationMessageElement>,
|
||||
forceUpdate: Boolean = false
|
||||
): Single<Boolean> {
|
||||
return Single.fromCallable {
|
||||
var hasUpdatedProperties = false
|
||||
for (item in items) {
|
||||
val oldDate = item.conversationMessage.computedProperties.formattedDate
|
||||
if (oldDate.isRelative) {
|
||||
if (oldDate.isRelative || forceUpdate) {
|
||||
val newDate = ConversationMessage.getFormattedDate(context, item.conversationMessage.messageRecord)
|
||||
item.conversationMessage.computedProperties.formattedDate = newDate
|
||||
hasUpdatedProperties = true
|
||||
|
||||
Reference in New Issue
Block a user