Implement permalink support for /relations live thread timeline

This commit is contained in:
ariskotsomitopoulos 2022-02-21 17:23:17 +02:00
parent f4f48b919e
commit 2b740a1ab6
3 changed files with 32 additions and 2 deletions

View file

@ -301,7 +301,13 @@ internal class DefaultTimeline(private val roomId: String,
Timber.v("Post snapshot of ${snapshot.size} events") Timber.v("Post snapshot of ${snapshot.size} events")
withContext(coroutineDispatchers.main) { withContext(coroutineDispatchers.main) {
listeners.forEach { listeners.forEach {
tryOrNull { it.onTimelineUpdated(snapshot) } if (initialEventId != null && isFromThreadTimeline && snapshot.firstOrNull { it.eventId == initialEventId } == null) {
// We are in a thread timeline with a permalink, post update timeline only when the appropriate message have been found
tryOrNull { it.onTimelineUpdated(arrayListOf()) }
} else {
// In all the other cases update timeline as expected
tryOrNull { it.onTimelineUpdated(snapshot) }
}
} }
} }
} }

View file

@ -171,11 +171,12 @@ internal class TimelineChunk(private val chunkEntity: ChunkEntity,
* always fetch results, while we want our data to be up to dated. * always fetch results, while we want our data to be up to dated.
*/ */
suspend fun loadMoreThread(count: Int, direction: Timeline.Direction): LoadMoreResult { suspend fun loadMoreThread(count: Int, direction: Timeline.Direction): LoadMoreResult {
val rootThreadEventId = timelineSettings.rootThreadEventId ?: return LoadMoreResult.FAILURE
return if (direction == Timeline.Direction.BACKWARDS) { return if (direction == Timeline.Direction.BACKWARDS) {
try { try {
fetchThreadTimelineTask.execute(FetchThreadTimelineTask.Params( fetchThreadTimelineTask.execute(FetchThreadTimelineTask.Params(
roomId, roomId,
timelineSettings.rootThreadEventId!!, rootThreadEventId,
chunkEntity.prevToken, chunkEntity.prevToken,
count count
)).toLoadMoreResult() )).toLoadMoreResult()

View file

@ -156,6 +156,9 @@ class TimelineViewModel @AssistedInject constructor(
companion object : MavericksViewModelFactory<TimelineViewModel, RoomDetailViewState> by hiltMavericksViewModelFactory() { companion object : MavericksViewModelFactory<TimelineViewModel, RoomDetailViewState> by hiltMavericksViewModelFactory() {
const val PAGINATION_COUNT = 50 const val PAGINATION_COUNT = 50
// The larger the number the faster the results, COUNT=200 for 500 thread messages its x4 faster than COUNT=50
const val PAGINATION_COUNT_THREADS_PERMALINK = 200
} }
init { init {
@ -1174,10 +1177,30 @@ class TimelineViewModel @AssistedInject constructor(
} }
} }
/**
* Navigates to the appropriate event (by paginating the thread timeline until the event is found
* in the snapshot. The main reason for this function is to support the /relations api
*/
private var threadPermalinkHandled = false
private fun navigateToThreadEventIfNeeded(snapshot: List<TimelineEvent>) {
if (eventId != null && initialState.rootThreadEventId != null) {
// When we have a permalink and we are in a thread timeline
if (snapshot.firstOrNull { it.eventId == eventId } != null && !threadPermalinkHandled) {
// Permalink event found lets navigate there
handleNavigateToEvent(RoomDetailAction.NavigateToEvent(eventId, true))
threadPermalinkHandled = true
} else {
// Permalink event not found yet continue paginating
timeline.paginate(Timeline.Direction.BACKWARDS, PAGINATION_COUNT_THREADS_PERMALINK)
}
}
}
override fun onTimelineUpdated(snapshot: List<TimelineEvent>) { override fun onTimelineUpdated(snapshot: List<TimelineEvent>) {
viewModelScope.launch { viewModelScope.launch {
// tryEmit doesn't work with SharedFlow without cache // tryEmit doesn't work with SharedFlow without cache
timelineEvents.emit(snapshot) timelineEvents.emit(snapshot)
navigateToThreadEventIfNeeded(snapshot)
} }
} }