Add fetchMembers and use it when init timeline (import again rust-sdk with fix on poisoning)
This commit is contained in:
@@ -83,11 +83,11 @@ import io.element.android.features.messages.timeline.model.virtual.TimelineItemL
|
||||
import io.element.android.libraries.designsystem.components.avatar.Avatar
|
||||
import io.element.android.libraries.designsystem.components.avatar.AvatarData
|
||||
import io.element.android.libraries.designsystem.utils.PairCombinedPreviewParameter
|
||||
import io.element.android.libraries.matrix.core.EventId
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
|
||||
@Composable
|
||||
fun TimelineView(
|
||||
@@ -117,14 +117,6 @@ fun TimelineView(
|
||||
onLongClick = onMessageLongClicked
|
||||
)
|
||||
}
|
||||
/*
|
||||
if (state.hasMoreToLoad) {
|
||||
item {
|
||||
TimelineLoadingMoreIndicator()
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
fun onReachedLoadMore() {
|
||||
@@ -165,12 +157,23 @@ fun TimelineItemRow(
|
||||
is TimelineItem.Virtual -> TimelineItemVirtualRow(
|
||||
virtual = timelineItem
|
||||
)
|
||||
is TimelineItem.Event -> TimelineItemEventRow(
|
||||
event = timelineItem,
|
||||
isHighlighted = isHighlighted,
|
||||
onClick = { onClick(timelineItem) },
|
||||
onLongClick = { onLongClick(timelineItem) }
|
||||
)
|
||||
is TimelineItem.Event -> {
|
||||
|
||||
fun onClick() {
|
||||
onClick(timelineItem)
|
||||
}
|
||||
|
||||
fun onLongClick() {
|
||||
onLongClick(timelineItem)
|
||||
}
|
||||
|
||||
TimelineItemEventRow(
|
||||
event = timelineItem,
|
||||
isHighlighted = isHighlighted,
|
||||
onClick = ::onClick,
|
||||
onLongClick = ::onLongClick
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ class TimelineItemEventFactory @Inject constructor(
|
||||
private val contentFactory: TimelineItemContentFactory,
|
||||
) {
|
||||
|
||||
suspend fun create(
|
||||
fun create(
|
||||
currentTimelineItem: MatrixTimelineItem.Event,
|
||||
index: Int,
|
||||
timelineItems: List<MatrixTimelineItem>,
|
||||
|
||||
@@ -29,7 +29,7 @@ class TimelineItemVirtualFactory @Inject constructor(
|
||||
private val daySeparatorFactory: TimelineItemDaySeparatorFactory,
|
||||
) {
|
||||
|
||||
suspend fun create(
|
||||
fun create(
|
||||
currentTimelineItem: MatrixTimelineItem.Virtual,
|
||||
index: Int,
|
||||
timelineItems: List<MatrixTimelineItem>,
|
||||
|
||||
@@ -24,11 +24,19 @@ import io.element.android.libraries.matrix.core.EventId
|
||||
|
||||
@Immutable
|
||||
sealed interface TimelineItem {
|
||||
|
||||
fun identifier(): String = when(this){
|
||||
is Event -> id
|
||||
is Virtual -> id
|
||||
}
|
||||
|
||||
@Immutable
|
||||
data class Virtual(
|
||||
val id: String,
|
||||
val model: TimelineItemVirtualModel
|
||||
) : TimelineItem
|
||||
|
||||
@Immutable
|
||||
data class Event(
|
||||
val id: String,
|
||||
val eventId: EventId? = null,
|
||||
|
||||
@@ -43,7 +43,7 @@ import timber.log.Timber
|
||||
import java.io.File
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
|
||||
internal class RustMatrixClient internal constructor(
|
||||
class RustMatrixClient constructor(
|
||||
private val client: Client,
|
||||
private val sessionStore: SessionStore,
|
||||
private val coroutineScope: CoroutineScope,
|
||||
@@ -132,11 +132,11 @@ internal class RustMatrixClient internal constructor(
|
||||
|
||||
override fun getRoom(roomId: RoomId): MatrixRoom? {
|
||||
val slidingSyncRoom = slidingSync.getRoom(roomId.value) ?: return null
|
||||
val room = slidingSyncRoom.fullRoom() ?: return null
|
||||
val fullRoom = slidingSyncRoom.fullRoom() ?: return null
|
||||
return RustMatrixRoom(
|
||||
slidingSyncUpdateFlow = slidingSyncObserverProxy.updateSummaryFlow,
|
||||
slidingSyncRoom = slidingSyncRoom,
|
||||
room = room,
|
||||
innerRoom = fullRoom,
|
||||
coroutineScope = coroutineScope,
|
||||
coroutineDispatchers = dispatchers
|
||||
)
|
||||
|
||||
@@ -31,6 +31,6 @@ object MatrixModule {
|
||||
@Provides
|
||||
@SingleIn(AppScope::class)
|
||||
fun providesRustAuthenticationService(baseDirectory: File): AuthenticationService {
|
||||
return AuthenticationService(baseDirectory.absolutePath, null)
|
||||
return AuthenticationService(baseDirectory.absolutePath, null, null)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,8 @@ interface MatrixRoom {
|
||||
|
||||
fun timeline(): MatrixTimeline
|
||||
|
||||
suspend fun fetchMembers(): Result<Unit>
|
||||
|
||||
suspend fun userDisplayName(userId: String): Result<String?>
|
||||
|
||||
suspend fun userAvatarUrl(userId: String): Result<String?>
|
||||
@@ -44,4 +46,5 @@ interface MatrixRoom {
|
||||
suspend fun replyMessage(eventId: EventId, message: String): Result<Unit>
|
||||
|
||||
suspend fun redactEvent(eventId: EventId, reason: String? = null): Result<Unit>
|
||||
|
||||
}
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2022 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.libraries.matrix.room
|
||||
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.channels.awaitClose
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.callbackFlow
|
||||
import kotlinx.coroutines.launch
|
||||
import org.matrix.rustcomponents.sdk.Room
|
||||
import org.matrix.rustcomponents.sdk.TimelineDiff
|
||||
import org.matrix.rustcomponents.sdk.TimelineListener
|
||||
|
||||
fun Room.timelineDiff(scope: CoroutineScope): Flow<TimelineDiff> = callbackFlow {
|
||||
val listener = object : TimelineListener {
|
||||
override fun onUpdate(update: TimelineDiff) {
|
||||
scope.launch {
|
||||
send(update)
|
||||
}
|
||||
}
|
||||
}
|
||||
addTimelineListener(listener)
|
||||
awaitClose {
|
||||
removeTimeline()
|
||||
}
|
||||
}
|
||||
@@ -32,11 +32,12 @@ import org.matrix.rustcomponents.sdk.SlidingSyncRoom
|
||||
import org.matrix.rustcomponents.sdk.UpdateSummary
|
||||
import org.matrix.rustcomponents.sdk.genTransactionId
|
||||
import org.matrix.rustcomponents.sdk.messageEventContentFromMarkdown
|
||||
import timber.log.Timber
|
||||
|
||||
class RustMatrixRoom(
|
||||
private val slidingSyncUpdateFlow: Flow<UpdateSummary>,
|
||||
private val slidingSyncRoom: SlidingSyncRoom,
|
||||
private val room: Room,
|
||||
private val innerRoom: Room,
|
||||
private val coroutineScope: CoroutineScope,
|
||||
private val coroutineDispatchers: CoroutineDispatchers,
|
||||
) : MatrixRoom {
|
||||
@@ -44,7 +45,7 @@ class RustMatrixRoom(
|
||||
override fun syncUpdateFlow(): Flow<Long> {
|
||||
return slidingSyncUpdateFlow
|
||||
.filter {
|
||||
it.rooms.contains(room.id())
|
||||
it.rooms.contains(innerRoom.id())
|
||||
}
|
||||
.map {
|
||||
System.currentTimeMillis()
|
||||
@@ -55,14 +56,14 @@ class RustMatrixRoom(
|
||||
override fun timeline(): MatrixTimeline {
|
||||
return RustMatrixTimeline(
|
||||
matrixRoom = this,
|
||||
room = room,
|
||||
innerRoom = innerRoom,
|
||||
slidingSyncRoom = slidingSyncRoom,
|
||||
coroutineScope = coroutineScope,
|
||||
coroutineDispatchers = coroutineDispatchers
|
||||
)
|
||||
}
|
||||
|
||||
override val roomId = RoomId(room.id())
|
||||
override val roomId = RoomId(innerRoom.id())
|
||||
|
||||
override val name: String?
|
||||
get() {
|
||||
@@ -71,35 +72,41 @@ class RustMatrixRoom(
|
||||
|
||||
override val bestName: String
|
||||
get() {
|
||||
return name?.takeIf { it.isNotEmpty() } ?: room.id()
|
||||
return name?.takeIf { it.isNotEmpty() } ?: innerRoom.id()
|
||||
}
|
||||
|
||||
override val displayName: String
|
||||
get() {
|
||||
return room.displayName()
|
||||
return innerRoom.displayName()
|
||||
}
|
||||
|
||||
override val topic: String?
|
||||
get() {
|
||||
return room.topic()
|
||||
return innerRoom.topic()
|
||||
}
|
||||
|
||||
override val avatarUrl: String?
|
||||
get() {
|
||||
return room.avatarUrl()
|
||||
return innerRoom.avatarUrl()
|
||||
}
|
||||
|
||||
override suspend fun fetchMembers(): Result<Unit> = withContext(coroutineDispatchers.io) {
|
||||
runCatching {
|
||||
innerRoom.fetchMembers()
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun userDisplayName(userId: String): Result<String?> =
|
||||
withContext(coroutineDispatchers.io) {
|
||||
runCatching {
|
||||
room.memberDisplayName(userId)
|
||||
innerRoom.memberDisplayName(userId)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun userAvatarUrl(userId: String): Result<String?> =
|
||||
withContext(coroutineDispatchers.io) {
|
||||
runCatching {
|
||||
room.memberAvatarUrl(userId)
|
||||
innerRoom.memberAvatarUrl(userId)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,7 +114,7 @@ class RustMatrixRoom(
|
||||
val transactionId = genTransactionId()
|
||||
val content = messageEventContentFromMarkdown(message)
|
||||
runCatching {
|
||||
room.send(content, transactionId)
|
||||
innerRoom.send(content, transactionId)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,7 +122,7 @@ class RustMatrixRoom(
|
||||
val transactionId = genTransactionId()
|
||||
// val content = messageEventContentFromMarkdown(message)
|
||||
runCatching {
|
||||
room.edit(/* TODO use content */ message, originalEventId.value, transactionId)
|
||||
innerRoom.edit(/* TODO use content */ message, originalEventId.value, transactionId)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,14 +130,14 @@ class RustMatrixRoom(
|
||||
val transactionId = genTransactionId()
|
||||
// val content = messageEventContentFromMarkdown(message)
|
||||
runCatching {
|
||||
room.sendReply(/* TODO use content */ message, eventId.value, transactionId)
|
||||
innerRoom.sendReply(/* TODO use content */ message, eventId.value, transactionId)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun redactEvent(eventId: EventId, reason: String?) = withContext(coroutineDispatchers.io) {
|
||||
val transactionId = genTransactionId()
|
||||
runCatching {
|
||||
room.redact(eventId.value, reason, transactionId)
|
||||
innerRoom.redact(eventId.value, reason, transactionId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +54,8 @@ class PreferencesSessionStore @Inject constructor(
|
||||
val homeserverUrl: String,
|
||||
val isSoftLogout: Boolean,
|
||||
val refreshToken: String?,
|
||||
val userId: String
|
||||
val userId: String,
|
||||
val slidingSyncProxy: String?
|
||||
)
|
||||
|
||||
private val store = context.dataStore
|
||||
@@ -73,7 +74,8 @@ class PreferencesSessionStore @Inject constructor(
|
||||
homeserverUrl = session.homeserverUrl,
|
||||
isSoftLogout = session.isSoftLogout,
|
||||
refreshToken = session.refreshToken,
|
||||
userId = session.userId
|
||||
userId = session.userId,
|
||||
slidingSyncProxy = session.slidingSyncProxy
|
||||
)
|
||||
val encodedSession = Json.encodeToString(sessionData)
|
||||
prefs[sessionKey] = encodedSession
|
||||
@@ -90,7 +92,8 @@ class PreferencesSessionStore @Inject constructor(
|
||||
homeserverUrl = sessionData.homeserverUrl,
|
||||
isSoftLogout = sessionData.isSoftLogout,
|
||||
refreshToken = sessionData.refreshToken,
|
||||
userId = sessionData.userId
|
||||
userId = sessionData.userId,
|
||||
slidingSyncProxy = sessionData.slidingSyncProxy
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,15 +34,25 @@ import org.matrix.rustcomponents.sdk.TimelineChange
|
||||
import org.matrix.rustcomponents.sdk.TimelineDiff
|
||||
import org.matrix.rustcomponents.sdk.TimelineListener
|
||||
import timber.log.Timber
|
||||
import java.util.*
|
||||
import java.util.Collections
|
||||
|
||||
class RustMatrixTimeline(
|
||||
private val matrixRoom: RustMatrixRoom,
|
||||
private val room: Room,
|
||||
private val innerRoom: Room,
|
||||
private val slidingSyncRoom: SlidingSyncRoom,
|
||||
private val coroutineScope: CoroutineScope,
|
||||
private val coroutineDispatchers: CoroutineDispatchers,
|
||||
) : TimelineListener, MatrixTimeline {
|
||||
) : MatrixTimeline {
|
||||
|
||||
private val innerTimelineListener = object : TimelineListener {
|
||||
override fun onUpdate(update: TimelineDiff) {
|
||||
coroutineScope.launch {
|
||||
updateTimelineItems {
|
||||
applyDiff(update)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override var callback: MatrixTimeline.Callback? = null
|
||||
|
||||
@@ -59,46 +69,38 @@ class RustMatrixTimeline(
|
||||
private fun MutableList<MatrixTimelineItem>.applyDiff(diff: TimelineDiff) {
|
||||
when (diff.change()) {
|
||||
TimelineChange.PUSH -> {
|
||||
Timber.v("Apply push on list with size: $size")
|
||||
val item = diff.push()?.asMatrixTimelineItem() ?: return
|
||||
callback?.onPushedTimelineItem(item)
|
||||
add(item)
|
||||
}
|
||||
TimelineChange.UPDATE_AT -> {
|
||||
val updateAtData = diff.updateAt() ?: return
|
||||
Timber.v("Apply $updateAtData on list with size: $size")
|
||||
val item = updateAtData.item.asMatrixTimelineItem()
|
||||
callback?.onUpdatedTimelineItem(item)
|
||||
set(updateAtData.index.toInt(), item)
|
||||
}
|
||||
TimelineChange.INSERT_AT -> {
|
||||
val insertAtData = diff.insertAt() ?: return
|
||||
Timber.v("Apply $insertAtData on list with size: $size")
|
||||
val item = insertAtData.item.asMatrixTimelineItem()
|
||||
add(insertAtData.index.toInt(), item)
|
||||
}
|
||||
TimelineChange.MOVE -> {
|
||||
val moveData = diff.move() ?: return
|
||||
Timber.v("Apply $moveData on list with size: $size")
|
||||
Collections.swap(this, moveData.oldIndex.toInt(), moveData.newIndex.toInt())
|
||||
}
|
||||
TimelineChange.REMOVE_AT -> {
|
||||
val removeAtData = diff.removeAt() ?: return
|
||||
Timber.v("Apply $removeAtData on list with size: $size")
|
||||
removeAt(removeAtData.toInt())
|
||||
}
|
||||
TimelineChange.REPLACE -> {
|
||||
Timber.v("Apply REPLACE on list with size: $size")
|
||||
clear()
|
||||
val items = diff.replace()?.map { it.asMatrixTimelineItem() } ?: return
|
||||
addAll(items)
|
||||
}
|
||||
TimelineChange.POP -> {
|
||||
Timber.v("Apply POP on list with size: $size")
|
||||
removeLast()
|
||||
}
|
||||
TimelineChange.CLEAR -> {
|
||||
Timber.v("Apply CLEAR on list with size: $size")
|
||||
clear()
|
||||
}
|
||||
}
|
||||
@@ -106,11 +108,16 @@ class RustMatrixTimeline(
|
||||
|
||||
override suspend fun paginateBackwards(requestSize: Int, untilNumberOfItems: Int): Result<Unit> = withContext(coroutineDispatchers.io) {
|
||||
runCatching {
|
||||
Timber.v("Start back paginating for room ${slidingSyncRoom.roomId()} ")
|
||||
val paginationOptions = PaginationOptions.UntilNumItems(
|
||||
eventLimit = requestSize.toUShort(),
|
||||
items = untilNumberOfItems.toUShort()
|
||||
)
|
||||
room.paginateBackwards(paginationOptions)
|
||||
innerRoom.paginateBackwards(paginationOptions)
|
||||
}.onFailure {
|
||||
Timber.e(it, "Fail to paginate for room ${slidingSyncRoom.roomId()}")
|
||||
}.onSuccess {
|
||||
Timber.v("Success back paginating for room ${slidingSyncRoom.roomId()}")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,14 +129,24 @@ class RustMatrixTimeline(
|
||||
}
|
||||
|
||||
override fun addListener(timelineListener: TimelineListener) {
|
||||
listenerTokens += slidingSyncRoom.subscribeAndAddTimelineListener(timelineListener, settings = null)
|
||||
listenerTokens += slidingSyncRoom.subscribeAndAddTimelineListener(timelineListener, null)
|
||||
}
|
||||
|
||||
override fun initialize() {
|
||||
addListener(this)
|
||||
Timber.v("Init timeline for room ${slidingSyncRoom.roomId()}")
|
||||
coroutineScope.launch {
|
||||
matrixRoom.fetchMembers()
|
||||
.onFailure {
|
||||
Timber.e(it, "Fail to fetch members for room ${slidingSyncRoom.roomId()}")
|
||||
}.onSuccess {
|
||||
Timber.v("Success fetching members for room ${slidingSyncRoom.roomId()}")
|
||||
}
|
||||
}
|
||||
addListener(innerTimelineListener)
|
||||
}
|
||||
|
||||
override fun dispose() {
|
||||
Timber.v("Dispose timeline for room ${slidingSyncRoom.roomId()}")
|
||||
listenerTokens.dispose()
|
||||
}
|
||||
|
||||
@@ -147,12 +164,4 @@ class RustMatrixTimeline(
|
||||
override suspend fun replyMessage(inReplyToEventId: EventId, message: String): Result<Unit> {
|
||||
return matrixRoom.replyMessage(inReplyToEventId, message)
|
||||
}
|
||||
|
||||
override fun onUpdate(update: TimelineDiff) {
|
||||
coroutineScope.launch {
|
||||
updateTimelineItems {
|
||||
applyDiff(update)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,15 +23,16 @@ data class TracingConfiguration(
|
||||
) {
|
||||
|
||||
// Order should matters
|
||||
private val targets = mutableMapOf(
|
||||
Target.MatrixSdk.HttpClient to LogLevel.Trace,
|
||||
Target.MatrixSdk.SlidingSync to LogLevel.Trace,
|
||||
Target.MatrixSdk.BaseSlidingSync to LogLevel.Trace,
|
||||
Target.MatrixSdk.Root to LogLevel.Warn,
|
||||
Target.MatrixSdk.Sled to LogLevel.Warn,
|
||||
private val targets: MutableMap<Target, LogLevel> = mutableMapOf(
|
||||
Target.Common to LogLevel.Warn,
|
||||
Target.Hyper to LogLevel.Warn,
|
||||
Target.Sled to LogLevel.Warn,
|
||||
Target.Common to LogLevel.Warn,
|
||||
Target.MatrixSdk.Root to LogLevel.Warn,
|
||||
Target.MatrixSdk.Sled to LogLevel.Warn,
|
||||
Target.MatrixSdk.Crypto to LogLevel.Debug,
|
||||
Target.MatrixSdk.HttpClient to LogLevel.Debug,
|
||||
Target.MatrixSdk.SlidingSync to LogLevel.Trace,
|
||||
Target.MatrixSdk.BaseSlidingSync to LogLevel.Trace,
|
||||
)
|
||||
|
||||
val filter: String
|
||||
@@ -56,6 +57,7 @@ sealed class Target(open val filter: String) {
|
||||
sealed class MatrixSdk(override val filter: String) : Target(filter) {
|
||||
object Root : MatrixSdk("matrix_sdk")
|
||||
object Sled : MatrixSdk("matrix_sdk_sled")
|
||||
object Crypto: MatrixSdk("matrix_sdk_crypto")
|
||||
object FFI : MatrixSdk("matrix_sdk_ffi")
|
||||
object HttpClient : MatrixSdk("matrix_sdk::http_client")
|
||||
object UniffiAPI : MatrixSdk("matrix_sdk_ffi::uniffi_api")
|
||||
|
||||
@@ -41,6 +41,10 @@ class FakeMatrixRoom(
|
||||
return FakeMatrixTimeline()
|
||||
}
|
||||
|
||||
override suspend fun fetchMembers(): Result<Unit> {
|
||||
return Result.success(Unit)
|
||||
}
|
||||
|
||||
override suspend fun userDisplayName(userId: String): Result<String?> {
|
||||
return Result.success("")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user