Timeline permalink : branch permalink on event of other room

This commit is contained in:
ganfra
2024-04-23 18:02:12 +02:00
parent 1c06db1a78
commit 9b83cedac4
7 changed files with 41 additions and 16 deletions

View File

@@ -282,7 +282,7 @@ class LoggedInFlowNode @AssistedInject constructor(
is PermalinkData.RoomLink -> {
backstack.push(
NavTarget.Room(
data.roomIdOrAlias,
roomIdOrAlias = data.roomIdOrAlias,
initialElement = RoomNavigationTarget.Messages(data.eventId),
// TODO Use the viaParameters
)

View File

@@ -80,7 +80,7 @@ class RoomFlowNode @AssistedInject constructor(
data class Inputs(
val roomIdOrAlias: RoomIdOrAlias,
val roomDescription: Optional<RoomDescription>,
val initialElement: RoomNavigationTarget = RoomNavigationTarget.Messages(),
val initialElement: RoomNavigationTarget,
) : NodeInputs
private val inputs: Inputs = inputs()
@@ -166,7 +166,10 @@ class RoomFlowNode @AssistedInject constructor(
}
is NavTarget.JoinedRoom -> {
val roomFlowNodeCallback = plugins<JoinedRoomLoadedFlowNode.Callback>()
val inputs = JoinedRoomFlowNode.Inputs(navTarget.roomId, initialElement = inputs.initialElement)
val inputs = JoinedRoomFlowNode.Inputs(
roomId = navTarget.roomId,
initialElement = inputs.initialElement
)
createNode<JoinedRoomFlowNode>(buildContext, plugins = listOf(inputs) + roomFlowNodeCallback)
}
}

View File

@@ -69,7 +69,7 @@ class JoinedRoomFlowNode @AssistedInject constructor(
) {
data class Inputs(
val roomId: RoomId,
val initialElement: RoomNavigationTarget = RoomNavigationTarget.Messages(),
val initialElement: RoomNavigationTarget,
) : NodeInputs
private val inputs: Inputs = inputs()
@@ -106,7 +106,10 @@ class JoinedRoomFlowNode @AssistedInject constructor(
val roomFlowNodeCallback = plugins<JoinedRoomLoadedFlowNode.Callback>()
val awaitRoomState = loadingRoomStateStateFlow.value
if (awaitRoomState is LoadingRoomState.Loaded) {
val inputs = JoinedRoomLoadedFlowNode.Inputs(awaitRoomState.room, initialElement = inputs.initialElement)
val inputs = JoinedRoomLoadedFlowNode.Inputs(
room = awaitRoomState.room,
initialElement = inputs.initialElement
)
createNode<JoinedRoomLoadedFlowNode>(buildContext, plugins = listOf(inputs) + roomFlowNodeCallback)
} else {
loadingNode(buildContext, this::navigateUp)

View File

@@ -84,7 +84,7 @@ class JoinedRoomLoadedFlowNode @AssistedInject constructor(
data class Inputs(
val room: MatrixRoom,
val initialElement: RoomNavigationTarget = RoomNavigationTarget.Messages(),
val initialElement: RoomNavigationTarget,
) : NodeInputs
private val inputs: Inputs = inputs()

View File

@@ -32,7 +32,7 @@ class DefaultMessagesEntryPoint @Inject constructor() : MessagesEntryPoint {
return object : MessagesEntryPoint.NodeBuilder {
override fun params(params: MessagesEntryPoint.Params): MessagesEntryPoint.NodeBuilder {
plugins += MessagesNode.Inputs(focusedEventId = params.focusedEventId)
plugins += MessagesFlowNode.Inputs(focusedEventId = params.focusedEventId)
return this
}

View File

@@ -54,6 +54,7 @@ import io.element.android.libraries.architecture.BackstackWithOverlayBox
import io.element.android.libraries.architecture.BaseFlowNode
import io.element.android.libraries.architecture.NodeInputs
import io.element.android.libraries.architecture.createNode
import io.element.android.libraries.architecture.inputs
import io.element.android.libraries.architecture.overlay.Overlay
import io.element.android.libraries.architecture.overlay.operation.show
import io.element.android.libraries.di.ApplicationContext
@@ -81,7 +82,7 @@ class MessagesFlowNode @AssistedInject constructor(
private val createPollEntryPoint: CreatePollEntryPoint,
) : BaseFlowNode<MessagesFlowNode.NavTarget>(
backstack = BackStack(
initialElement = NavTarget.Messages(plugins.filterIsInstance<Inputs>().firstOrNull()?.focusedEventId),
initialElement = NavTarget.Messages,
savedStateMap = buildContext.savedStateMap,
),
overlay = Overlay(
@@ -91,15 +92,14 @@ class MessagesFlowNode @AssistedInject constructor(
plugins = plugins
) {
data class Inputs(val focusedEventId: EventId?) : NodeInputs
private val inputs = inputs<Inputs>()
sealed interface NavTarget : Parcelable {
@Parcelize
data object Empty : NavTarget
@Parcelize
data class Messages(
val focusedEventId: EventId? = null,
) : NavTarget
data object Messages: NavTarget
@Parcelize
data class MediaViewer(
@@ -191,10 +191,10 @@ class MessagesFlowNode @AssistedInject constructor(
ElementCallActivity.start(context, inputs)
}
}
val params = MessagesNode.Inputs(
focusedEventId = navTarget.focusedEventId,
val inputs = MessagesNode.Inputs(
focusedEventId = inputs.focusedEventId,
)
createNode<MessagesNode>(buildContext, listOf(callback, params))
createNode<MessagesNode>(buildContext, listOf(callback, inputs))
}
is NavTarget.MediaViewer -> {
val inputs = MediaViewerNode.Inputs(

View File

@@ -19,6 +19,11 @@ package io.element.android.features.messages.impl
import android.content.Context
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import com.bumble.appyx.core.lifecycle.subscribe
@@ -37,6 +42,7 @@ import io.element.android.features.messages.impl.timeline.model.TimelineItem
import io.element.android.libraries.androidutils.system.openUrlInExternalApp
import io.element.android.libraries.androidutils.system.toast
import io.element.android.libraries.architecture.NodeInputs
import io.element.android.libraries.architecture.inputs
import io.element.android.libraries.core.bool.orFalse
import io.element.android.libraries.di.ApplicationContext
import io.element.android.libraries.di.RoomScope
@@ -69,9 +75,10 @@ class MessagesNode @AssistedInject constructor(
private val presenter = presenterFactory.create(this)
private val callback = plugins<Callback>().firstOrNull()
// TODO Handle navigation to the Event
data class Inputs(val focusedEventId: EventId?) : NodeInputs
private val inputs = inputs<Inputs>()
interface Callback : Plugin {
fun onRoomDetailsClicked()
fun onEventClicked(event: TimelineItem.Event): Boolean
@@ -87,7 +94,8 @@ class MessagesNode @AssistedInject constructor(
fun onJoinCallClicked(roomId: RoomId)
}
init {
override fun onBuilt() {
super.onBuilt()
lifecycle.subscribe(
onCreate = {
analyticsService.capture(room.toAnalyticsViewRoom())
@@ -197,6 +205,17 @@ class MessagesNode @AssistedInject constructor(
onJoinCallClicked = this::onJoinCallClicked,
modifier = modifier,
)
var focusedEventId by rememberSaveable {
mutableStateOf(inputs.focusedEventId)
}
LaunchedEffect(Unit) {
focusedEventId?.also { eventId ->
state.timelineState.eventSink(TimelineEvents.FocusOnEvent(eventId))
}
// Reset the focused event id to null to avoid refocusing when restoring node.
focusedEventId = null
}
}
}
}