Merge branch 'develop' into feature/fga/message_queuing

This commit is contained in:
ganfra 2024-06-11 17:08:47 +02:00
commit b927daffe7
620 changed files with 6821 additions and 1244 deletions

View file

@ -27,6 +27,8 @@ import org.matrix.rustcomponents.sdk.RoomListService
import org.matrix.rustcomponents.sdk.RoomSubscription
import timber.log.Timber
private const val DEFAULT_TIMELINE_LIMIT = 20u
class RoomSyncSubscriber(
private val roomListService: RoomListService,
private val dispatchers: CoroutineDispatchers,
@ -41,8 +43,9 @@ class RoomSyncSubscriber(
RequiredState(key = EventType.STATE_ROOM_JOIN_RULES, value = ""),
RequiredState(key = EventType.STATE_ROOM_POWER_LEVELS, value = ""),
),
timelineLimit = null,
includeHeroes = true,
timelineLimit = DEFAULT_TIMELINE_LIMIT,
// We don't need heroes here as they're already included in the `all_rooms` list
includeHeroes = false,
)
suspend fun subscribe(roomId: RoomId) = mutex.withLock {

View file

@ -590,6 +590,10 @@ class RustMatrixRoom(
innerRoom.matrixToEventPermalink(eventId.value)
}
override suspend fun sendCallNotificationIfNeeded(): Result<Unit> = runCatching {
innerRoom.sendCallNotificationIfNeeded()
}
private fun createTimeline(
timeline: InnerTimeline,
isLive: Boolean,

View file

@ -25,11 +25,27 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.buffer
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.catch
import org.matrix.rustcomponents.sdk.PaginationStatusListener
import org.matrix.rustcomponents.sdk.Timeline
import org.matrix.rustcomponents.sdk.TimelineDiff
import org.matrix.rustcomponents.sdk.TimelineItem
import org.matrix.rustcomponents.sdk.TimelineListener
import timber.log.Timber
import uniffi.matrix_sdk_ui.LiveBackPaginationStatus
internal fun Timeline.liveBackPaginationStatus(): Flow<LiveBackPaginationStatus> = callbackFlow {
val listener = object : PaginationStatusListener {
override fun onUpdate(status: LiveBackPaginationStatus) {
trySend(status)
}
}
val result = subscribeToBackPaginationStatus(listener)
awaitClose {
result.cancelAndDestroy()
}
}.catch {
Timber.d(it, "liveBackPaginationStatus() failed")
}.buffer(Channel.UNLIMITED)
internal fun Timeline.timelineDiffFlow(onInitialList: suspend (List<TimelineItem>) -> Unit): Flow<List<TimelineDiff>> =
callbackFlow {

View file

@ -79,6 +79,7 @@ import org.matrix.rustcomponents.sdk.messageEventContentFromMarkdown
import org.matrix.rustcomponents.sdk.use
import timber.log.Timber
import uniffi.matrix_sdk_ui.EventItemOrigin
import uniffi.matrix_sdk_ui.LiveBackPaginationStatus
import java.io.File
import java.util.Date
import java.util.concurrent.atomic.AtomicBoolean
@ -154,6 +155,21 @@ class RustTimeline(
launch {
fetchMembers()
}
if (isLive) {
// When timeline is live, we need to listen to the back pagination status as
// sdk can automatically paginate backwards.
inner.liveBackPaginationStatus()
.onEach { backPaginationStatus ->
updatePaginationStatus(Timeline.PaginationDirection.BACKWARDS) {
when (backPaginationStatus) {
is LiveBackPaginationStatus.Idle -> it.copy(isPaginating = false, hasMoreToLoad = !backPaginationStatus.hitStartOfTimeline)
is LiveBackPaginationStatus.Paginating -> it.copy(isPaginating = true, hasMoreToLoad = true)
}
}
}
.launchIn(this)
}
}
}
@ -333,13 +349,28 @@ class RustTimeline(
}
}
override suspend fun replyMessage(eventId: EventId, body: String, htmlBody: String?, mentions: List<Mention>): Result<Unit> = withContext(dispatcher) {
override suspend fun replyMessage(
eventId: EventId,
body: String,
htmlBody: String?,
mentions: List<Mention>,
fromNotification: Boolean,
): Result<Unit> = withContext(dispatcher) {
runCatching {
val inReplyTo = specialModeEventTimelineItem ?: inner.getEventTimelineItemByEventId(eventId.value)
inReplyTo.use { eventTimelineItem ->
inner.sendReply(messageEventContentFromParts(body, htmlBody).withMentions(mentions.map()), eventTimelineItem)
val msg = messageEventContentFromParts(body, htmlBody).withMentions(mentions.map())
if (fromNotification) {
// When replying from a notification, do not interfere with `specialModeEventTimelineItem`
val inReplyTo = inner.getEventTimelineItemByEventId(eventId.value)
inReplyTo.use { eventTimelineItem ->
inner.sendReply(msg, eventTimelineItem)
}
} else {
val inReplyTo = specialModeEventTimelineItem ?: inner.getEventTimelineItemByEventId(eventId.value)
inReplyTo.use { eventTimelineItem ->
inner.sendReply(msg, eventTimelineItem)
}
specialModeEventTimelineItem = null
}
specialModeEventTimelineItem = null
}
}

View file

@ -17,6 +17,7 @@
package io.element.android.libraries.matrix.impl.timeline.item.event
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.timeline.item.event.CallNotifyContent
import io.element.android.libraries.matrix.api.timeline.item.event.EventContent
import io.element.android.libraries.matrix.api.timeline.item.event.FailedToParseMessageLikeContent
import io.element.android.libraries.matrix.api.timeline.item.event.FailedToParseStateContent
@ -103,7 +104,7 @@ class TimelineEventContentMapper(private val eventMessageMapper: EventMessageMap
StickerContent(
body = kind.body,
info = kind.info.map(),
url = kind.url,
source = kind.source.map(),
)
}
is TimelineItemContentKind.Poll -> {
@ -125,6 +126,7 @@ class TimelineEventContentMapper(private val eventMessageMapper: EventMessageMap
)
}
is TimelineItemContentKind.CallInvite -> LegacyCallInviteContent
is TimelineItemContentKind.CallNotify -> CallNotifyContent
else -> UnknownContent
}
}