mirror of
https://github.com/Novaloop-AG/element-x-android.git
synced 2026-11-02 21:32:34 +00:00
Fix forwarding an event not working in threads (#7743)
* Fix forwarding an event not working in threads Add the `TimelineProvider` for the event to the navigation flow so the events can be fetched from the right timeline.
This commit is contained in:
committed by
GitHub
parent
4e47c6170e
commit
bec3780c9c
+12
-12
@@ -87,6 +87,7 @@ import io.element.android.libraries.matrix.api.room.alias.matches
|
||||
import io.element.android.libraries.matrix.api.room.joinedRoomMembers
|
||||
import io.element.android.libraries.matrix.api.roomlist.RoomListService
|
||||
import io.element.android.libraries.matrix.api.timeline.Timeline
|
||||
import io.element.android.libraries.matrix.api.timeline.TimelineProvider
|
||||
import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo
|
||||
import io.element.android.libraries.matrix.ui.messages.RoomMemberProfilesCache
|
||||
import io.element.android.libraries.matrix.ui.messages.RoomNamesCache
|
||||
@@ -104,6 +105,7 @@ import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.parcelize.IgnoredOnParcel
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
|
||||
@@ -180,7 +182,8 @@ class MessagesFlowNode(
|
||||
@Parcelize
|
||||
data class ForwardEvent(
|
||||
val eventId: EventId,
|
||||
val fromPinnedEvents: Boolean,
|
||||
@IgnoredOnParcel
|
||||
val timelineProvider: TimelineProvider? = null,
|
||||
) : NavTarget
|
||||
|
||||
@Parcelize
|
||||
@@ -303,8 +306,8 @@ class MessagesFlowNode(
|
||||
backstack.push(NavTarget.EventDebugInfo(eventId, debugInfo))
|
||||
}
|
||||
|
||||
override fun forwardEvent(eventId: EventId) {
|
||||
backstack.push(NavTarget.ForwardEvent(eventId, fromPinnedEvents = false))
|
||||
override fun forwardEvent(eventId: EventId, timelineProvider: TimelineProvider) {
|
||||
backstack.push(NavTarget.ForwardEvent(eventId, timelineProvider))
|
||||
}
|
||||
|
||||
override fun navigateToReportMessage(eventId: EventId, senderId: UserId) {
|
||||
@@ -459,11 +462,8 @@ class MessagesFlowNode(
|
||||
createNode<EventDebugInfoNode>(buildContext, listOf(inputs))
|
||||
}
|
||||
is NavTarget.ForwardEvent -> {
|
||||
val timelineProvider = if (navTarget.fromPinnedEvents) {
|
||||
pinnedEventsTimelineProvider
|
||||
} else {
|
||||
timelineController
|
||||
}
|
||||
// If no timeline provider is received, assume the live timeline should be used
|
||||
val timelineProvider = navTarget.timelineProvider ?: timelineController
|
||||
val params = ForwardEntryPoint.Params(navTarget.eventId, timelineProvider)
|
||||
val callback = object : ForwardEntryPoint.Callback {
|
||||
override fun onDone(roomIds: List<RoomId>) {
|
||||
@@ -550,8 +550,8 @@ class MessagesFlowNode(
|
||||
backstack.push(NavTarget.EventDebugInfo(eventId, debugInfo))
|
||||
}
|
||||
|
||||
override fun handleForwardEventClick(eventId: EventId) {
|
||||
backstack.push(NavTarget.ForwardEvent(eventId = eventId, fromPinnedEvents = true))
|
||||
override fun handleForwardEventClick(eventId: EventId, timelineProvider: TimelineProvider) {
|
||||
backstack.push(NavTarget.ForwardEvent(eventId = eventId, timelineProvider = timelineProvider))
|
||||
}
|
||||
|
||||
override fun navigateToThread(threadRootId: ThreadId) {
|
||||
@@ -617,8 +617,8 @@ class MessagesFlowNode(
|
||||
backstack.push(NavTarget.EventDebugInfo(eventId, debugInfo))
|
||||
}
|
||||
|
||||
override fun handleForwardEventClick(eventId: EventId) {
|
||||
backstack.push(NavTarget.ForwardEvent(eventId, fromPinnedEvents = false))
|
||||
override fun handleForwardEventClick(eventId: EventId, timelineProvider: TimelineProvider) {
|
||||
backstack.push(NavTarget.ForwardEvent(eventId, timelineProvider))
|
||||
}
|
||||
|
||||
override fun navigateToReportMessage(eventId: EventId, senderId: UserId) {
|
||||
|
||||
+2
-1
@@ -13,12 +13,13 @@ import io.element.android.libraries.matrix.api.core.EventId
|
||||
import io.element.android.libraries.matrix.api.core.RoomId
|
||||
import io.element.android.libraries.matrix.api.core.ThreadId
|
||||
import io.element.android.libraries.matrix.api.core.UserId
|
||||
import io.element.android.libraries.matrix.api.timeline.TimelineProvider
|
||||
import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
||||
interface MessagesNavigator {
|
||||
fun navigateToEventDebugInfo(eventId: EventId?, debugInfo: TimelineItemDebugInfo)
|
||||
fun forwardEvent(eventId: EventId)
|
||||
fun forwardEvent(eventId: EventId, timelineProvider: TimelineProvider)
|
||||
fun navigateToReportMessage(eventId: EventId, senderId: UserId)
|
||||
fun navigateToEditPoll(eventId: EventId)
|
||||
fun navigateToPreviewAttachments(attachments: ImmutableList<Attachment>, inReplyToEventId: EventId?)
|
||||
|
||||
+4
-3
@@ -68,6 +68,7 @@ import io.element.android.libraries.matrix.api.permalink.PermalinkParser
|
||||
import io.element.android.libraries.matrix.api.room.JoinedRoom
|
||||
import io.element.android.libraries.matrix.api.room.alias.matches
|
||||
import io.element.android.libraries.matrix.api.timeline.Timeline
|
||||
import io.element.android.libraries.matrix.api.timeline.TimelineProvider
|
||||
import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo
|
||||
import io.element.android.libraries.matrix.ui.media.contentvalidation.EventContentValidationCache
|
||||
import io.element.android.libraries.matrix.ui.media.contentvalidation.LocalEventContentValidationState
|
||||
@@ -137,7 +138,7 @@ class MessagesNode(
|
||||
fun navigateToRoomMemberDetails(userId: UserId)
|
||||
fun handlePermalinkClick(data: PermalinkData)
|
||||
fun navigateToEventDebugInfo(eventId: EventId?, debugInfo: TimelineItemDebugInfo)
|
||||
fun forwardEvent(eventId: EventId)
|
||||
fun forwardEvent(eventId: EventId, timelineProvider: TimelineProvider)
|
||||
fun navigateToReportMessage(eventId: EventId, senderId: UserId)
|
||||
fun navigateToSendLocation()
|
||||
fun navigateToCreatePoll()
|
||||
@@ -220,8 +221,8 @@ class MessagesNode(
|
||||
callback.navigateToEventDebugInfo(eventId, debugInfo)
|
||||
}
|
||||
|
||||
override fun forwardEvent(eventId: EventId) {
|
||||
callback.forwardEvent(eventId)
|
||||
override fun forwardEvent(eventId: EventId, timelineProvider: TimelineProvider) {
|
||||
callback.forwardEvent(eventId, timelineProvider)
|
||||
}
|
||||
|
||||
override fun navigateToReportMessage(eventId: EventId, senderId: UserId) {
|
||||
|
||||
+1
-1
@@ -615,7 +615,7 @@ class MessagesPresenter(
|
||||
|
||||
private fun handleForwardAction(event: TimelineItem.Event) {
|
||||
if (event.eventId == null) return
|
||||
navigator.forwardEvent(event.eventId)
|
||||
navigator.forwardEvent(eventId = event.eventId, timelineProvider = timelineController)
|
||||
}
|
||||
|
||||
private fun handleReportAction(event: TimelineItem.Event) {
|
||||
|
||||
+2
-1
@@ -10,11 +10,12 @@ package io.element.android.features.messages.impl.pinned.list
|
||||
|
||||
import io.element.android.libraries.matrix.api.core.EventId
|
||||
import io.element.android.libraries.matrix.api.core.ThreadId
|
||||
import io.element.android.libraries.matrix.api.timeline.TimelineProvider
|
||||
import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo
|
||||
|
||||
interface PinnedMessagesListNavigator {
|
||||
fun viewInTimeline(eventId: EventId)
|
||||
fun navigateToEventDebugInfo(eventId: EventId?, debugInfo: TimelineItemDebugInfo)
|
||||
fun forwardEvent(eventId: EventId)
|
||||
fun forwardEvent(eventId: EventId, timelineProvider: TimelineProvider)
|
||||
fun navigateToThread(threadRootId: ThreadId)
|
||||
}
|
||||
|
||||
+4
-3
@@ -37,6 +37,7 @@ import io.element.android.libraries.matrix.api.core.UserId
|
||||
import io.element.android.libraries.matrix.api.permalink.PermalinkData
|
||||
import io.element.android.libraries.matrix.api.permalink.PermalinkParser
|
||||
import io.element.android.libraries.matrix.api.timeline.Timeline
|
||||
import io.element.android.libraries.matrix.api.timeline.TimelineProvider
|
||||
import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
import io.element.android.libraries.ui.utils.a11y.hasExternalKeyboard
|
||||
@@ -60,7 +61,7 @@ class PinnedMessagesListNode(
|
||||
fun viewInTimeline(eventId: EventId)
|
||||
fun handlePermalinkClick(data: PermalinkData.RoomLink)
|
||||
fun navigateToEventDebugInfo(eventId: EventId?, debugInfo: TimelineItemDebugInfo)
|
||||
fun handleForwardEventClick(eventId: EventId)
|
||||
fun handleForwardEventClick(eventId: EventId, timelineProvider: TimelineProvider)
|
||||
fun navigateToThread(threadRootId: ThreadId)
|
||||
}
|
||||
|
||||
@@ -98,8 +99,8 @@ class PinnedMessagesListNode(
|
||||
callback.navigateToEventDebugInfo(eventId, debugInfo)
|
||||
}
|
||||
|
||||
override fun forwardEvent(eventId: EventId) {
|
||||
callback.handleForwardEventClick(eventId)
|
||||
override fun forwardEvent(eventId: EventId, timelineProvider: TimelineProvider) {
|
||||
callback.handleForwardEventClick(eventId, timelineProvider)
|
||||
}
|
||||
|
||||
override fun navigateToThread(threadRootId: ThreadId) {
|
||||
|
||||
+1
-1
@@ -181,7 +181,7 @@ class PinnedMessagesListPresenter(
|
||||
}
|
||||
TimelineItemAction.Forward -> {
|
||||
targetEvent.eventId?.let { eventId ->
|
||||
navigator.forwardEvent(eventId)
|
||||
navigator.forwardEvent(eventId, timelineProvider)
|
||||
}
|
||||
}
|
||||
TimelineItemAction.Unpin -> handleUnpinAction(targetEvent)
|
||||
|
||||
+4
-3
@@ -70,6 +70,7 @@ import io.element.android.libraries.matrix.api.room.CreateTimelineParams
|
||||
import io.element.android.libraries.matrix.api.room.JoinedRoom
|
||||
import io.element.android.libraries.matrix.api.room.alias.matches
|
||||
import io.element.android.libraries.matrix.api.timeline.Timeline
|
||||
import io.element.android.libraries.matrix.api.timeline.TimelineProvider
|
||||
import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo
|
||||
import io.element.android.libraries.matrix.ui.model.getBestName
|
||||
import io.element.android.libraries.ui.utils.a11y.hasExternalKeyboard
|
||||
@@ -142,7 +143,7 @@ class ThreadedMessagesNode(
|
||||
fun navigateToRoomMemberDetails(userId: UserId)
|
||||
fun handlePermalinkClick(data: PermalinkData)
|
||||
fun navigateToEventDebugInfo(eventId: EventId?, debugInfo: TimelineItemDebugInfo)
|
||||
fun handleForwardEventClick(eventId: EventId)
|
||||
fun handleForwardEventClick(eventId: EventId, timelineProvider: TimelineProvider)
|
||||
fun navigateToReportMessage(eventId: EventId, senderId: UserId)
|
||||
fun navigateToSendLocation()
|
||||
fun navigateToCreatePoll()
|
||||
@@ -226,8 +227,8 @@ class ThreadedMessagesNode(
|
||||
callback.navigateToEventDebugInfo(eventId, debugInfo)
|
||||
}
|
||||
|
||||
override fun forwardEvent(eventId: EventId) {
|
||||
callback.handleForwardEventClick(eventId)
|
||||
override fun forwardEvent(eventId: EventId, timelineProvider: TimelineProvider) {
|
||||
callback.handleForwardEventClick(eventId, timelineProvider)
|
||||
}
|
||||
|
||||
override fun navigateToReportMessage(eventId: EventId, senderId: UserId) {
|
||||
|
||||
+4
-3
@@ -13,13 +13,14 @@ import io.element.android.libraries.matrix.api.core.EventId
|
||||
import io.element.android.libraries.matrix.api.core.RoomId
|
||||
import io.element.android.libraries.matrix.api.core.ThreadId
|
||||
import io.element.android.libraries.matrix.api.core.UserId
|
||||
import io.element.android.libraries.matrix.api.timeline.TimelineProvider
|
||||
import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo
|
||||
import io.element.android.tests.testutils.lambda.lambdaError
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
||||
class FakeMessagesNavigator(
|
||||
private val onShowEventDebugInfoClickLambda: (eventId: EventId?, debugInfo: TimelineItemDebugInfo) -> Unit = { _, _ -> lambdaError() },
|
||||
private val onForwardEventClickLambda: (eventId: EventId) -> Unit = { _ -> lambdaError() },
|
||||
private val onForwardEventClickLambda: (eventId: EventId, timelineProvider: TimelineProvider) -> Unit = { _, _ -> lambdaError() },
|
||||
private val onReportContentClickLambda: (eventId: EventId, senderId: UserId) -> Unit = { _, _ -> lambdaError() },
|
||||
private val onEditPollClickLambda: (eventId: EventId) -> Unit = { _ -> lambdaError() },
|
||||
private val onPreviewAttachmentLambda: (attachments: ImmutableList<Attachment>, inReplyToEventId: EventId?) -> Unit = { _, _ -> lambdaError() },
|
||||
@@ -34,8 +35,8 @@ class FakeMessagesNavigator(
|
||||
onShowEventDebugInfoClickLambda(eventId, debugInfo)
|
||||
}
|
||||
|
||||
override fun forwardEvent(eventId: EventId) {
|
||||
onForwardEventClickLambda(eventId)
|
||||
override fun forwardEvent(eventId: EventId, timelineProvider: TimelineProvider) {
|
||||
onForwardEventClickLambda(eventId, timelineProvider)
|
||||
}
|
||||
|
||||
override fun navigateToReportMessage(eventId: EventId, senderId: UserId) {
|
||||
|
||||
+4
-2
@@ -71,6 +71,7 @@ import io.element.android.libraries.matrix.api.room.StateEventType
|
||||
import io.element.android.libraries.matrix.api.room.history.RoomHistoryVisibility
|
||||
import io.element.android.libraries.matrix.api.room.tombstone.SuccessorRoom
|
||||
import io.element.android.libraries.matrix.api.timeline.Timeline
|
||||
import io.element.android.libraries.matrix.api.timeline.TimelineProvider
|
||||
import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.EventOrTransactionId
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.LocalEventSendState
|
||||
@@ -109,6 +110,7 @@ import io.element.android.tests.testutils.FakeLifecycleOwner
|
||||
import io.element.android.tests.testutils.WarmUpRule
|
||||
import io.element.android.tests.testutils.consumeItemsUntilPredicate
|
||||
import io.element.android.tests.testutils.consumeItemsUntilTimeout
|
||||
import io.element.android.tests.testutils.lambda.any
|
||||
import io.element.android.tests.testutils.lambda.assert
|
||||
import io.element.android.tests.testutils.lambda.lambdaError
|
||||
import io.element.android.tests.testutils.lambda.lambdaRecorder
|
||||
@@ -288,7 +290,7 @@ class MessagesPresenterTest {
|
||||
|
||||
@Test
|
||||
fun `present - handle action forward`() = runTest {
|
||||
val onForwardEventClickLambda = lambdaRecorder<EventId, Unit> { }
|
||||
val onForwardEventClickLambda = lambdaRecorder<EventId, TimelineProvider, Unit> { _, _ -> }
|
||||
val navigator = FakeMessagesNavigator(
|
||||
onForwardEventClickLambda = onForwardEventClickLambda,
|
||||
)
|
||||
@@ -297,7 +299,7 @@ class MessagesPresenterTest {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink(MessagesEvent.HandleAction(TimelineItemAction.Forward, aMessageEvent()))
|
||||
assertThat(awaitItem().actionListState.target).isEqualTo(ActionListState.Target.None)
|
||||
onForwardEventClickLambda.assertions().isCalledOnce().with(value(AN_EVENT_ID))
|
||||
onForwardEventClickLambda.assertions().isCalledOnce().with(value(AN_EVENT_ID), any())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-3
@@ -10,6 +10,7 @@ package io.element.android.features.messages.impl.pinned.list
|
||||
|
||||
import io.element.android.libraries.matrix.api.core.EventId
|
||||
import io.element.android.libraries.matrix.api.core.ThreadId
|
||||
import io.element.android.libraries.matrix.api.timeline.TimelineProvider
|
||||
import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo
|
||||
|
||||
class FakePinnedMessagesListNavigator : PinnedMessagesListNavigator {
|
||||
@@ -23,9 +24,9 @@ class FakePinnedMessagesListNavigator : PinnedMessagesListNavigator {
|
||||
onShowEventDebugInfoClickLambda?.invoke(eventId, debugInfo)
|
||||
}
|
||||
|
||||
var onForwardEventClickLambda: ((EventId) -> Unit)? = null
|
||||
override fun forwardEvent(eventId: EventId) {
|
||||
onForwardEventClickLambda?.invoke(eventId)
|
||||
var onForwardEventClickLambda: ((EventId, TimelineProvider) -> Unit)? = null
|
||||
override fun forwardEvent(eventId: EventId, timelineProvider: TimelineProvider) {
|
||||
onForwardEventClickLambda?.invoke(eventId, timelineProvider)
|
||||
}
|
||||
|
||||
var onOpenThreadLambda: ((ThreadId) -> Unit)? = null
|
||||
|
||||
+4
-2
@@ -27,6 +27,7 @@ import io.element.android.libraries.matrix.api.core.UniqueId
|
||||
import io.element.android.libraries.matrix.api.room.JoinedRoom
|
||||
import io.element.android.libraries.matrix.api.sync.SyncService
|
||||
import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem
|
||||
import io.element.android.libraries.matrix.api.timeline.TimelineProvider
|
||||
import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.FailedToParseMessageLikeContent
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.UnknownContent
|
||||
@@ -47,6 +48,7 @@ import io.element.android.libraries.matrix.test.timeline.anEventTimelineItem
|
||||
import io.element.android.services.analytics.api.AnalyticsService
|
||||
import io.element.android.services.analytics.test.FakeAnalyticsService
|
||||
import io.element.android.tests.testutils.consumeItemsUntilPredicate
|
||||
import io.element.android.tests.testutils.lambda.any
|
||||
import io.element.android.tests.testutils.lambda.assert
|
||||
import io.element.android.tests.testutils.lambda.lambdaRecorder
|
||||
import io.element.android.tests.testutils.lambda.value
|
||||
@@ -329,7 +331,7 @@ class PinnedMessagesListPresenterTest {
|
||||
|
||||
@Test
|
||||
fun `present - forward event`() = runTest {
|
||||
val onForwardEventClickLambda = lambdaRecorder { _: EventId -> }
|
||||
val onForwardEventClickLambda = lambdaRecorder { _: EventId, _: TimelineProvider -> }
|
||||
val navigator = FakePinnedMessagesListNavigator().apply {
|
||||
this.onForwardEventClickLambda = onForwardEventClickLambda
|
||||
}
|
||||
@@ -352,7 +354,7 @@ class PinnedMessagesListPresenterTest {
|
||||
cancelAndIgnoreRemainingEvents()
|
||||
assert(onForwardEventClickLambda)
|
||||
.isCalledOnce()
|
||||
.with(value(AN_EVENT_ID))
|
||||
.with(value(AN_EVENT_ID), any())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user