Update Matrix Room API and allow media swipe on pinned event only.
This commit is contained in:
parent
728a2c1a32
commit
2e9a158fb0
30 changed files with 268 additions and 181 deletions
|
|
@ -71,6 +71,7 @@ import io.element.android.libraries.matrix.api.permalink.PermalinkData
|
|||
import io.element.android.libraries.matrix.api.room.MatrixRoom
|
||||
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.timeline.Timeline
|
||||
import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo
|
||||
import io.element.android.libraries.matrix.ui.messages.LocalRoomMemberProfilesCache
|
||||
import io.element.android.libraries.matrix.ui.messages.RoomMemberProfilesCache
|
||||
|
|
@ -187,8 +188,11 @@ class MessagesFlowNode @AssistedInject constructor(
|
|||
callbacks.forEach { it.onRoomDetailsClick() }
|
||||
}
|
||||
|
||||
override fun onEventClick(event: TimelineItem.Event): Boolean {
|
||||
return processEventClick(event)
|
||||
override fun onEventClick(isLive: Boolean, event: TimelineItem.Event): Boolean {
|
||||
return processEventClick(
|
||||
timelineMode = if (isLive) Timeline.Mode.LIVE else Timeline.Mode.FOCUSED_ON_EVENT,
|
||||
event = event,
|
||||
)
|
||||
}
|
||||
|
||||
override fun onPreviewAttachments(attachments: ImmutableList<Attachment>) {
|
||||
|
|
@ -316,7 +320,10 @@ class MessagesFlowNode @AssistedInject constructor(
|
|||
NavTarget.PinnedMessagesList -> {
|
||||
val callback = object : PinnedMessagesListNode.Callback {
|
||||
override fun onEventClick(event: TimelineItem.Event) {
|
||||
processEventClick(event)
|
||||
processEventClick(
|
||||
timelineMode = Timeline.Mode.PINNED_EVENTS,
|
||||
event = event,
|
||||
)
|
||||
}
|
||||
|
||||
override fun onUserDataClick(userId: UserId) {
|
||||
|
|
@ -358,11 +365,14 @@ class MessagesFlowNode @AssistedInject constructor(
|
|||
callbacks.forEach { it.onPermalinkClick(permalinkData, pushToBackstack = false) }
|
||||
}
|
||||
|
||||
private fun processEventClick(event: TimelineItem.Event): Boolean {
|
||||
private fun processEventClick(
|
||||
timelineMode: Timeline.Mode,
|
||||
event: TimelineItem.Event,
|
||||
): Boolean {
|
||||
val navTarget = when (event.content) {
|
||||
is TimelineItemImageContent -> {
|
||||
buildMediaViewerNavTarget(
|
||||
mode = MediaViewerEntryPoint.MediaViewerMode.TimelineImagesAndVideos,
|
||||
mode = MediaViewerEntryPoint.MediaViewerMode.TimelineImagesAndVideos(timelineMode),
|
||||
event = event,
|
||||
content = event.content,
|
||||
mediaSource = event.content.mediaSource,
|
||||
|
|
@ -374,7 +384,7 @@ class MessagesFlowNode @AssistedInject constructor(
|
|||
if encrypted on certain bridges */
|
||||
event.content.preferredMediaSource?.let { preferredMediaSource ->
|
||||
buildMediaViewerNavTarget(
|
||||
mode = MediaViewerEntryPoint.MediaViewerMode.TimelineImagesAndVideos,
|
||||
mode = MediaViewerEntryPoint.MediaViewerMode.TimelineImagesAndVideos(timelineMode),
|
||||
event = event,
|
||||
content = event.content,
|
||||
mediaSource = preferredMediaSource,
|
||||
|
|
@ -384,7 +394,7 @@ class MessagesFlowNode @AssistedInject constructor(
|
|||
}
|
||||
is TimelineItemVideoContent -> {
|
||||
buildMediaViewerNavTarget(
|
||||
mode = MediaViewerEntryPoint.MediaViewerMode.TimelineImagesAndVideos,
|
||||
mode = MediaViewerEntryPoint.MediaViewerMode.TimelineImagesAndVideos(timelineMode),
|
||||
event = event,
|
||||
content = event.content,
|
||||
mediaSource = event.content.mediaSource,
|
||||
|
|
@ -393,7 +403,7 @@ class MessagesFlowNode @AssistedInject constructor(
|
|||
}
|
||||
is TimelineItemFileContent -> {
|
||||
buildMediaViewerNavTarget(
|
||||
mode = MediaViewerEntryPoint.MediaViewerMode.TimelineFilesAndAudios,
|
||||
mode = MediaViewerEntryPoint.MediaViewerMode.TimelineFilesAndAudios(timelineMode),
|
||||
event = event,
|
||||
content = event.content,
|
||||
mediaSource = event.content.mediaSource,
|
||||
|
|
@ -402,7 +412,7 @@ class MessagesFlowNode @AssistedInject constructor(
|
|||
}
|
||||
is TimelineItemAudioContent -> {
|
||||
buildMediaViewerNavTarget(
|
||||
mode = MediaViewerEntryPoint.MediaViewerMode.TimelineFilesAndAudios,
|
||||
mode = MediaViewerEntryPoint.MediaViewerMode.TimelineFilesAndAudios(timelineMode),
|
||||
event = event,
|
||||
content = event.content,
|
||||
mediaSource = event.content.mediaSource,
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ class MessagesNode @AssistedInject constructor(
|
|||
|
||||
interface Callback : Plugin {
|
||||
fun onRoomDetailsClick()
|
||||
fun onEventClick(event: TimelineItem.Event): Boolean
|
||||
fun onEventClick(isLive: Boolean, event: TimelineItem.Event): Boolean
|
||||
fun onPreviewAttachments(attachments: ImmutableList<Attachment>)
|
||||
fun onUserDataClick(userId: UserId)
|
||||
fun onPermalinkClick(data: PermalinkData)
|
||||
|
|
@ -120,12 +120,12 @@ class MessagesNode @AssistedInject constructor(
|
|||
callbacks.forEach { it.onRoomDetailsClick() }
|
||||
}
|
||||
|
||||
private fun onEventClick(event: TimelineItem.Event): Boolean {
|
||||
private fun onEventClick(isLive: Boolean, event: TimelineItem.Event): Boolean {
|
||||
// Note: cannot use `callbacks.all { it.onEventClick(event) }` because:
|
||||
// - if callbacks is empty, it will return true and we want to return false.
|
||||
// - if a callback returns false, the other callback will not be invoked.
|
||||
return callbacks.takeIf { it.isNotEmpty() }
|
||||
?.map { it.onEventClick(event) }
|
||||
?.map { it.onEventClick(isLive, event) }
|
||||
?.all { it }
|
||||
.orFalse()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ fun MessagesView(
|
|||
state: MessagesState,
|
||||
onBackClick: () -> Unit,
|
||||
onRoomDetailsClick: () -> Unit,
|
||||
onEventContentClick: (event: TimelineItem.Event) -> Boolean,
|
||||
onEventContentClick: (isLive: Boolean, event: TimelineItem.Event) -> Boolean,
|
||||
onUserDataClick: (UserId) -> Unit,
|
||||
onLinkClick: (String, Boolean) -> Unit,
|
||||
onSendLocationClick: () -> Unit,
|
||||
|
|
@ -140,7 +140,7 @@ fun MessagesView(
|
|||
|
||||
fun onContentClick(event: TimelineItem.Event) {
|
||||
Timber.v("onMessageClick= ${event.id}")
|
||||
val hideKeyboard = onEventContentClick(event)
|
||||
val hideKeyboard = onEventContentClick(state.timelineState.isLive, event)
|
||||
if (hideKeyboard) {
|
||||
localView.hideKeyboard()
|
||||
}
|
||||
|
|
@ -535,7 +535,7 @@ internal fun MessagesViewPreview(@PreviewParameter(MessagesStateProvider::class)
|
|||
state = state,
|
||||
onBackClick = {},
|
||||
onRoomDetailsClick = {},
|
||||
onEventContentClick = { false },
|
||||
onEventContentClick = { _, _ -> false },
|
||||
onUserDataClick = {},
|
||||
onLinkClick = { _, _ -> },
|
||||
onSendLocationClick = {},
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ internal fun MessagesViewWithIdentityChangePreview(
|
|||
),
|
||||
onBackClick = {},
|
||||
onRoomDetailsClick = {},
|
||||
onEventContentClick = { false },
|
||||
onEventContentClick = { _, _ -> false },
|
||||
onUserDataClick = {},
|
||||
onLinkClick = { _, _ -> },
|
||||
onSendLocationClick = {},
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ class PinnedEventsTimelineProvider @Inject constructor(
|
|||
is AsyncData.Uninitialized, is AsyncData.Failure -> {
|
||||
timelineStateFlow.emit(AsyncData.Loading())
|
||||
withContext(dispatchers.io) {
|
||||
room.pinnedEventsTimeline()
|
||||
room.createTimeline(onlyPinnedEvents = true)
|
||||
}
|
||||
.fold(
|
||||
{ timelineStateFlow.emit(AsyncData.Success(it)) },
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ class TimelineController @Inject constructor(
|
|||
}
|
||||
|
||||
suspend fun focusOnEvent(eventId: EventId): Result<Unit> {
|
||||
return room.timelineFocusedOnEvent(eventId)
|
||||
return room.createTimeline(focusedOnEventId = eventId)
|
||||
.onFailure {
|
||||
if (it is CancellationException) {
|
||||
throw it
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue