Bump Rust SDK to v0.2.18 and bump app version (#2836)

* Adapt to changes in SDK:
    - Remove name from MatrixRoom, we should use displayName instead.
    - Remove separate invites room list.
    - Added runBlocking to get the now async NotificationClient from the Rust SDK.
    - Made some other functions suspend.
    - Client.resolveRoomAlias now returns a roomId and via parameters, we pass the roomId.

* Add logs removal migration again as `AppMigration03` to make sure we don't leak private data in existing logs.

* Bump app version to `0.4.12`
This commit is contained in:
Jorge Martin Espinosa
2024-05-13 16:48:23 +02:00
committed by GitHub
parent 51df9f5297
commit 6257425344
24 changed files with 111 additions and 79 deletions

View File

@@ -21,6 +21,9 @@ import io.element.android.features.rageshake.api.logs.LogFilesRemover
import io.element.android.libraries.di.AppScope import io.element.android.libraries.di.AppScope
import javax.inject.Inject import javax.inject.Inject
/**
* Remove existing logs from the device to remove any leaks of sensitive data.
*/
@ContributesMultibinding(AppScope::class) @ContributesMultibinding(AppScope::class)
class AppMigration01 @Inject constructor( class AppMigration01 @Inject constructor(
private val logFilesRemover: LogFilesRemover, private val logFilesRemover: LogFilesRemover,

View File

@@ -24,6 +24,10 @@ import io.element.android.libraries.sessionstorage.api.SessionStore
import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.coroutineScope
import javax.inject.Inject import javax.inject.Inject
/**
* This migration sets the skip session verification preference to true for all existing sessions.
* This way we don't force existing users to verify their session again.
*/
@ContributesMultibinding(AppScope::class) @ContributesMultibinding(AppScope::class)
class AppMigration02 @Inject constructor( class AppMigration02 @Inject constructor(
private val sessionStore: SessionStore, private val sessionStore: SessionStore,

View File

@@ -0,0 +1,35 @@
/*
* Copyright (c) 2024 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.features.migration.impl.migrations
import com.squareup.anvil.annotations.ContributesMultibinding
import io.element.android.libraries.di.AppScope
import javax.inject.Inject
/**
* This performs the same operation as [AppMigration01], since we need to clear the local logs again.
*/
@ContributesMultibinding(AppScope::class)
class AppMigration03 @Inject constructor(
private val migration01: AppMigration01,
) : AppMigration {
override val order: Int = 3
override suspend fun migrate() {
migration01.migrate()
}
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright (c) 2024 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.features.migration.impl.migrations
import io.element.android.features.rageshake.test.logs.FakeLogFilesRemover
import kotlinx.coroutines.test.runTest
import org.junit.Test
class AppMigration03Test {
@Test
fun `test migration`() = runTest {
val logsFileRemover = FakeLogFilesRemover()
val migration = AppMigration03(migration01 = AppMigration01(logsFileRemover))
migration.migrate()
logsFileRemover.performLambda.assertions().isCalledOnce()
}
}

View File

@@ -75,7 +75,7 @@ class RoomDetailsPresenter @Inject constructor(
val roomAvatar by remember { derivedStateOf { roomInfo?.avatarUrl ?: room.avatarUrl } } val roomAvatar by remember { derivedStateOf { roomInfo?.avatarUrl ?: room.avatarUrl } }
val roomName by remember { derivedStateOf { (roomInfo?.name ?: room.name ?: room.displayName).trim() } } val roomName by remember { derivedStateOf { (roomInfo?.name ?: room.displayName).trim() } }
val roomTopic by remember { derivedStateOf { roomInfo?.topic ?: room.topic } } val roomTopic by remember { derivedStateOf { roomInfo?.topic ?: room.topic } }
val isFavorite by remember { derivedStateOf { roomInfo?.isFavorite.orFalse() } } val isFavorite by remember { derivedStateOf { roomInfo?.isFavorite.orFalse() } }
val isPublic by remember { derivedStateOf { roomInfo?.isPublic.orFalse() } } val isPublic by remember { derivedStateOf { roomInfo?.isPublic.orFalse() } }

View File

@@ -65,7 +65,7 @@ class RoomDetailsEditPresenter @Inject constructor(
// just erase the local value when the room field has changed // just erase the local value when the room field has changed
var roomAvatarUri by rememberSaveable(room.avatarUrl) { mutableStateOf(room.avatarUrl?.toUri()) } var roomAvatarUri by rememberSaveable(room.avatarUrl) { mutableStateOf(room.avatarUrl?.toUri()) }
var roomName by rememberSaveable { mutableStateOf((room.name ?: room.displayName).trim()) } var roomName by rememberSaveable { mutableStateOf(room.displayName.trim()) }
var roomTopic by rememberSaveable { mutableStateOf(room.topic?.trim()) } var roomTopic by rememberSaveable { mutableStateOf(room.topic?.trim()) }
val saveButtonEnabled by remember( val saveButtonEnabled by remember(
@@ -76,7 +76,7 @@ class RoomDetailsEditPresenter @Inject constructor(
) { ) {
derivedStateOf { derivedStateOf {
roomAvatarUri?.toString()?.trim() != room.avatarUrl?.toUri()?.toString()?.trim() || roomAvatarUri?.toString()?.trim() != room.avatarUrl?.toUri()?.toString()?.trim() ||
roomName.trim() != (room.name ?: room.displayName).trim() || roomName.trim() != room.displayName.trim() ||
roomTopic.orEmpty().trim() != room.topic.orEmpty().trim() roomTopic.orEmpty().trim() != room.topic.orEmpty().trim()
} }
} }
@@ -168,7 +168,7 @@ class RoomDetailsEditPresenter @Inject constructor(
Timber.e(it, "Failed to set room topic") Timber.e(it, "Failed to set room topic")
}) })
} }
if (name.isNotEmpty() && name.trim() != room.name.orEmpty().trim()) { if (name.isNotEmpty() && name.trim() != room.displayName.trim()) {
results.add(room.setName(name).onFailure { results.add(room.setName(name).onFailure {
Timber.e(it, "Failed to set room name") Timber.e(it, "Failed to set room name")
}) })

View File

@@ -118,7 +118,7 @@ class RoomDetailsPresenterTests {
presenter.test { presenter.test {
val initialState = awaitItem() val initialState = awaitItem()
assertThat(initialState.roomId).isEqualTo(room.roomId) assertThat(initialState.roomId).isEqualTo(room.roomId)
assertThat(initialState.roomName).isEqualTo(room.name) assertThat(initialState.roomName).isEqualTo(room.displayName)
assertThat(initialState.roomAvatarUrl).isEqualTo(room.avatarUrl) assertThat(initialState.roomAvatarUrl).isEqualTo(room.avatarUrl)
assertThat(initialState.roomTopic).isEqualTo(RoomTopicState.ExistingTopic(room.topic!!)) assertThat(initialState.roomTopic).isEqualTo(RoomTopicState.ExistingTopic(room.topic!!))
assertThat(initialState.memberCount).isEqualTo(room.joinedMemberCount) assertThat(initialState.memberCount).isEqualTo(room.joinedMemberCount)
@@ -148,7 +148,7 @@ class RoomDetailsPresenterTests {
@Test @Test
fun `present - initial state with no room name`() = runTest { fun `present - initial state with no room name`() = runTest {
val room = aMatrixRoom(name = null) val room = aMatrixRoom(displayName = "")
val presenter = createRoomDetailsPresenter(room) val presenter = createRoomDetailsPresenter(room)
presenter.test { presenter.test {
val initialState = awaitItem() val initialState = awaitItem()
@@ -476,8 +476,7 @@ class RoomDetailsPresenterTests {
fun aMatrixRoom( fun aMatrixRoom(
roomId: RoomId = A_ROOM_ID, roomId: RoomId = A_ROOM_ID,
name: String? = A_ROOM_NAME, displayName: String = A_ROOM_NAME,
displayName: String = "A fallback display name",
topic: String? = "A topic", topic: String? = "A topic",
avatarUrl: String? = "https://matrix.org/avatar.jpg", avatarUrl: String? = "https://matrix.org/avatar.jpg",
isEncrypted: Boolean = true, isEncrypted: Boolean = true,
@@ -486,7 +485,6 @@ fun aMatrixRoom(
notificationSettingsService: FakeNotificationSettingsService = FakeNotificationSettingsService() notificationSettingsService: FakeNotificationSettingsService = FakeNotificationSettingsService()
) = FakeMatrixRoom( ) = FakeMatrixRoom(
roomId = roomId, roomId = roomId,
name = name,
displayName = displayName, displayName = displayName,
topic = topic, topic = topic,
avatarUrl = avatarUrl, avatarUrl = avatarUrl,

View File

@@ -98,7 +98,7 @@ class RoomDetailsEditPresenterTest {
}.test { }.test {
val initialState = awaitItem() val initialState = awaitItem()
assertThat(initialState.roomId).isEqualTo(room.roomId.value) assertThat(initialState.roomId).isEqualTo(room.roomId.value)
assertThat(initialState.roomName).isEqualTo(room.name) assertThat(initialState.roomName).isEqualTo(room.displayName)
assertThat(initialState.roomAvatarUrl).isEqualTo(roomAvatarUri) assertThat(initialState.roomAvatarUrl).isEqualTo(roomAvatarUri)
assertThat(initialState.roomTopic).isEqualTo(room.topic.orEmpty()) assertThat(initialState.roomTopic).isEqualTo(room.topic.orEmpty())
assertThat(initialState.avatarActions).containsExactly( assertThat(initialState.avatarActions).containsExactly(
@@ -191,7 +191,7 @@ class RoomDetailsEditPresenterTest {
@Test @Test
fun `present - updates state in response to changes`() = runTest { fun `present - updates state in response to changes`() = runTest {
val room = aMatrixRoom(topic = "My topic", name = "Name", avatarUrl = AN_AVATAR_URL) val room = aMatrixRoom(topic = "My topic", displayName = "Name", avatarUrl = AN_AVATAR_URL)
val presenter = createRoomDetailsEditPresenter(room) val presenter = createRoomDetailsEditPresenter(room)
moleculeFlow(RecompositionMode.Immediate) { moleculeFlow(RecompositionMode.Immediate) {
@@ -234,7 +234,7 @@ class RoomDetailsEditPresenterTest {
@Test @Test
fun `present - obtains avatar uris from gallery`() = runTest { fun `present - obtains avatar uris from gallery`() = runTest {
val room = aMatrixRoom(topic = "My topic", name = "Name", avatarUrl = AN_AVATAR_URL) val room = aMatrixRoom(topic = "My topic", displayName = "Name", avatarUrl = AN_AVATAR_URL)
fakePickerProvider.givenResult(anotherAvatarUri) fakePickerProvider.givenResult(anotherAvatarUri)
@@ -255,7 +255,7 @@ class RoomDetailsEditPresenterTest {
@Test @Test
fun `present - obtains avatar uris from camera`() = runTest { fun `present - obtains avatar uris from camera`() = runTest {
val room = aMatrixRoom(topic = "My topic", name = "Name", avatarUrl = AN_AVATAR_URL) val room = aMatrixRoom(topic = "My topic", displayName = "Name", avatarUrl = AN_AVATAR_URL)
fakePickerProvider.givenResult(anotherAvatarUri) fakePickerProvider.givenResult(anotherAvatarUri)
val fakePermissionsPresenter = FakePermissionsPresenter() val fakePermissionsPresenter = FakePermissionsPresenter()
@@ -288,7 +288,7 @@ class RoomDetailsEditPresenterTest {
@Test @Test
fun `present - updates save button state`() = runTest { fun `present - updates save button state`() = runTest {
val room = aMatrixRoom(topic = "My topic", name = "Name", avatarUrl = AN_AVATAR_URL) val room = aMatrixRoom(topic = "My topic", displayName = "Name", avatarUrl = AN_AVATAR_URL)
fakePickerProvider.givenResult(roomAvatarUri) fakePickerProvider.givenResult(roomAvatarUri)
@@ -340,7 +340,7 @@ class RoomDetailsEditPresenterTest {
@Test @Test
fun `present - updates save button state when initial values are null`() = runTest { fun `present - updates save button state when initial values are null`() = runTest {
val room = aMatrixRoom(topic = null, name = null, displayName = "fallback", avatarUrl = null) val room = aMatrixRoom(topic = null, displayName = "fallback", avatarUrl = null)
fakePickerProvider.givenResult(roomAvatarUri) fakePickerProvider.givenResult(roomAvatarUri)
@@ -392,7 +392,7 @@ class RoomDetailsEditPresenterTest {
@Test @Test
fun `present - save changes room details if different`() = runTest { fun `present - save changes room details if different`() = runTest {
val room = aMatrixRoom(topic = "My topic", name = "Name", avatarUrl = AN_AVATAR_URL) val room = aMatrixRoom(topic = "My topic", displayName = "Name", avatarUrl = AN_AVATAR_URL)
val presenter = createRoomDetailsEditPresenter(room) val presenter = createRoomDetailsEditPresenter(room)
@@ -417,7 +417,7 @@ class RoomDetailsEditPresenterTest {
@Test @Test
fun `present - save doesn't change room details if they're the same trimmed`() = runTest { fun `present - save doesn't change room details if they're the same trimmed`() = runTest {
val room = aMatrixRoom(topic = "My topic", name = "Name", avatarUrl = AN_AVATAR_URL) val room = aMatrixRoom(topic = "My topic", displayName = "Name", avatarUrl = AN_AVATAR_URL)
val presenter = createRoomDetailsEditPresenter(room) val presenter = createRoomDetailsEditPresenter(room)
@@ -441,7 +441,7 @@ class RoomDetailsEditPresenterTest {
@Test @Test
fun `present - save doesn't change topic if it was unset and is now blank`() = runTest { fun `present - save doesn't change topic if it was unset and is now blank`() = runTest {
val room = aMatrixRoom(topic = null, name = "Name", avatarUrl = AN_AVATAR_URL) val room = aMatrixRoom(topic = null, displayName = "Name", avatarUrl = AN_AVATAR_URL)
val presenter = createRoomDetailsEditPresenter(room) val presenter = createRoomDetailsEditPresenter(room)
@@ -464,7 +464,7 @@ class RoomDetailsEditPresenterTest {
@Test @Test
fun `present - save doesn't change name if it's now empty`() = runTest { fun `present - save doesn't change name if it's now empty`() = runTest {
val room = aMatrixRoom(topic = "My topic", name = "Name", avatarUrl = AN_AVATAR_URL) val room = aMatrixRoom(topic = "My topic", displayName = "Name", avatarUrl = AN_AVATAR_URL)
val presenter = createRoomDetailsEditPresenter(room) val presenter = createRoomDetailsEditPresenter(room)
@@ -487,7 +487,7 @@ class RoomDetailsEditPresenterTest {
@Test @Test
fun `present - save processes and sets avatar when processor returns successfully`() = runTest { fun `present - save processes and sets avatar when processor returns successfully`() = runTest {
val room = aMatrixRoom(topic = "My topic", name = "Name", avatarUrl = AN_AVATAR_URL) val room = aMatrixRoom(topic = "My topic", displayName = "Name", avatarUrl = AN_AVATAR_URL)
givenPickerReturnsFile() givenPickerReturnsFile()
@@ -511,7 +511,7 @@ class RoomDetailsEditPresenterTest {
@Test @Test
fun `present - save does not set avatar data if processor fails`() = runTest { fun `present - save does not set avatar data if processor fails`() = runTest {
val room = aMatrixRoom(topic = "My topic", name = "Name", avatarUrl = AN_AVATAR_URL) val room = aMatrixRoom(topic = "My topic", displayName = "Name", avatarUrl = AN_AVATAR_URL)
fakePickerProvider.givenResult(anotherAvatarUri) fakePickerProvider.givenResult(anotherAvatarUri)
fakeMediaPreProcessor.givenResult(Result.failure(Throwable("Oh no"))) fakeMediaPreProcessor.givenResult(Result.failure(Throwable("Oh no")))
@@ -538,7 +538,7 @@ class RoomDetailsEditPresenterTest {
@Test @Test
fun `present - sets save action to failure if name update fails`() = runTest { fun `present - sets save action to failure if name update fails`() = runTest {
val room = aMatrixRoom(topic = "My topic", name = "Name", avatarUrl = AN_AVATAR_URL).apply { val room = aMatrixRoom(topic = "My topic", displayName = "Name", avatarUrl = AN_AVATAR_URL).apply {
givenSetNameResult(Result.failure(Throwable("!"))) givenSetNameResult(Result.failure(Throwable("!")))
} }
@@ -547,7 +547,7 @@ class RoomDetailsEditPresenterTest {
@Test @Test
fun `present - sets save action to failure if topic update fails`() = runTest { fun `present - sets save action to failure if topic update fails`() = runTest {
val room = aMatrixRoom(topic = "My topic", name = "Name", avatarUrl = AN_AVATAR_URL).apply { val room = aMatrixRoom(topic = "My topic", displayName = "Name", avatarUrl = AN_AVATAR_URL).apply {
givenSetTopicResult(Result.failure(Throwable("!"))) givenSetTopicResult(Result.failure(Throwable("!")))
} }
@@ -556,7 +556,7 @@ class RoomDetailsEditPresenterTest {
@Test @Test
fun `present - sets save action to failure if removing avatar fails`() = runTest { fun `present - sets save action to failure if removing avatar fails`() = runTest {
val room = aMatrixRoom(topic = "My topic", name = "Name", avatarUrl = AN_AVATAR_URL).apply { val room = aMatrixRoom(topic = "My topic", displayName = "Name", avatarUrl = AN_AVATAR_URL).apply {
givenRemoveAvatarResult(Result.failure(Throwable("!"))) givenRemoveAvatarResult(Result.failure(Throwable("!")))
} }
@@ -567,7 +567,7 @@ class RoomDetailsEditPresenterTest {
fun `present - sets save action to failure if setting avatar fails`() = runTest { fun `present - sets save action to failure if setting avatar fails`() = runTest {
givenPickerReturnsFile() givenPickerReturnsFile()
val room = aMatrixRoom(topic = "My topic", name = "Name", avatarUrl = AN_AVATAR_URL).apply { val room = aMatrixRoom(topic = "My topic", displayName = "Name", avatarUrl = AN_AVATAR_URL).apply {
givenUpdateAvatarResult(Result.failure(Throwable("!"))) givenUpdateAvatarResult(Result.failure(Throwable("!")))
} }
@@ -578,7 +578,7 @@ class RoomDetailsEditPresenterTest {
fun `present - CancelSaveChanges resets save action state`() = runTest { fun `present - CancelSaveChanges resets save action state`() = runTest {
givenPickerReturnsFile() givenPickerReturnsFile()
val room = aMatrixRoom(topic = "My topic", name = "Name", avatarUrl = AN_AVATAR_URL).apply { val room = aMatrixRoom(topic = "My topic", displayName = "Name", avatarUrl = AN_AVATAR_URL).apply {
givenSetTopicResult(Result.failure(Throwable("!"))) givenSetTopicResult(Result.failure(Throwable("!")))
} }

View File

@@ -159,7 +159,7 @@ jsoup = "org.jsoup:jsoup:1.17.2"
appyx_core = { module = "com.bumble.appyx:core", version.ref = "appyx" } appyx_core = { module = "com.bumble.appyx:core", version.ref = "appyx" }
molecule-runtime = "app.cash.molecule:molecule-runtime:1.4.2" molecule-runtime = "app.cash.molecule:molecule-runtime:1.4.2"
timber = "com.jakewharton.timber:timber:5.0.1" timber = "com.jakewharton.timber:timber:5.0.1"
matrix_sdk = "org.matrix.rustcomponents:sdk-android:0.2.16" matrix_sdk = "org.matrix.rustcomponents:sdk-android:0.2.18"
matrix_richtexteditor = { module = "io.element.android:wysiwyg", version.ref = "wysiwyg" } matrix_richtexteditor = { module = "io.element.android:wysiwyg", version.ref = "wysiwyg" }
matrix_richtexteditor_compose = { module = "io.element.android:wysiwyg-compose", version.ref = "wysiwyg" } matrix_richtexteditor_compose = { module = "io.element.android:wysiwyg-compose", version.ref = "wysiwyg" }
sqldelight-driver-android = { module = "app.cash.sqldelight:android-driver", version.ref = "sqldelight" } sqldelight-driver-android = { module = "app.cash.sqldelight:android-driver", version.ref = "sqldelight" }

View File

@@ -44,7 +44,6 @@ import java.io.File
interface MatrixRoom : Closeable { interface MatrixRoom : Closeable {
val sessionId: SessionId val sessionId: SessionId
val roomId: RoomId val roomId: RoomId
val name: String?
val displayName: String val displayName: String
val alias: RoomAlias? val alias: RoomAlias?
val alternativeAliases: List<RoomAlias> val alternativeAliases: List<RoomAlias>

View File

@@ -39,14 +39,12 @@ interface RoomList {
/** /**
* The source of the room list data. * The source of the room list data.
* All: all rooms except invites. * All: all rooms.
* Invites: only invites.
* *
* To apply some dynamic filtering on top of that, use [DynamicRoomList]. * To apply some dynamic filtering on top of that, use [DynamicRoomList].
*/ */
enum class Source { enum class Source {
All, All
Invites,
} }
/** /**

View File

@@ -59,11 +59,6 @@ interface RoomListService {
*/ */
val allRooms: DynamicRoomList val allRooms: DynamicRoomList
/**
* returns a [RoomList] object of all invites.
*/
val invites: RoomList
/** /**
* Will set the visible range of all rooms. * Will set the visible range of all rooms.
* This is useful to load more data when the user scrolls down. * This is useful to load more data when the user scrolls down.

View File

@@ -96,6 +96,7 @@ import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import kotlinx.coroutines.withTimeout import kotlinx.coroutines.withTimeout
import org.matrix.rustcomponents.sdk.BackupState import org.matrix.rustcomponents.sdk.BackupState
@@ -145,12 +146,7 @@ class RustMatrixClient(
dispatchers = dispatchers, dispatchers = dispatchers,
) )
private val notificationProcessSetup = NotificationProcessSetup.SingleProcess(syncService) private val notificationProcessSetup = NotificationProcessSetup.SingleProcess(syncService)
private val notificationClient = client.notificationClient(notificationProcessSetup) private val notificationClient = runBlocking { client.notificationClient(notificationProcessSetup) }
.use { builder ->
builder
.filterByPushRules()
.finish()
}
private val notificationService = RustNotificationService(sessionId, notificationClient, dispatchers, clock) private val notificationService = RustNotificationService(sessionId, notificationClient, dispatchers, clock)
private val notificationSettingsService = RustNotificationSettingsService(client, dispatchers) private val notificationSettingsService = RustNotificationSettingsService(client, dispatchers)
.apply { start() } .apply { start() }
@@ -465,7 +461,7 @@ class RustMatrixClient(
override suspend fun resolveRoomAlias(roomAlias: RoomAlias): Result<RoomId> = withContext(sessionDispatcher) { override suspend fun resolveRoomAlias(roomAlias: RoomAlias): Result<RoomId> = withContext(sessionDispatcher) {
runCatching { runCatching {
client.resolveRoomAlias(roomAlias.value).let(::RoomId) client.resolveRoomAlias(roomAlias.value).roomId.let(::RoomId)
} }
} }

View File

@@ -71,7 +71,6 @@ class RustMatrixClientFactory @Inject constructor(
val syncService = client.syncService() val syncService = client.syncService()
.withUtdHook(utdTracker) .withUtdHook(utdTracker)
.withUnifiedInvitesInRoomList(true)
.finish() .finish()
RustMatrixClient( RustMatrixClient(

View File

@@ -38,7 +38,7 @@ class MatrixRoomInfoMapper(
fun map(rustRoomInfo: RustRoomInfo): MatrixRoomInfo = rustRoomInfo.use { fun map(rustRoomInfo: RustRoomInfo): MatrixRoomInfo = rustRoomInfo.use {
return MatrixRoomInfo( return MatrixRoomInfo(
id = RoomId(it.id), id = RoomId(it.id),
name = it.name, name = it.displayName,
topic = it.topic, topic = it.topic,
avatarUrl = it.avatarUrl, avatarUrl = it.avatarUrl,
isDirect = it.isDirect, isDirect = it.isDirect,

View File

@@ -191,9 +191,6 @@ class RustMatrixRoom(
roomListItem.destroy() roomListItem.destroy()
} }
override val name: String?
get() = runCatching { roomListItem.name() }.getOrDefault(null)
override val displayName: String override val displayName: String
get() = runCatching { innerRoom.displayName() }.getOrDefault("") get() = runCatching { innerRoom.displayName() }.getOrDefault("")

View File

@@ -126,7 +126,7 @@ internal fun RoomListServiceInterface.syncIndicator(): Flow<RoomListServiceSyncI
} }
}.buffer(Channel.UNLIMITED) }.buffer(Channel.UNLIMITED)
internal fun RoomListServiceInterface.roomOrNull(roomId: String): RoomListItem? { internal suspend fun RoomListServiceInterface.roomOrNull(roomId: String): RoomListItem? {
return try { return try {
room(roomId) room(roomId)
} catch (exception: Exception) { } catch (exception: Exception) {

View File

@@ -33,7 +33,7 @@ class RoomSummaryDetailsFactory(private val roomMessageFactory: RoomMessageFacto
} }
return RoomSummaryDetails( return RoomSummaryDetails(
roomId = RoomId(roomInfo.id), roomId = RoomId(roomInfo.id),
name = roomInfo.name, name = roomInfo.displayName,
canonicalAlias = roomInfo.canonicalAlias?.let(::RoomAlias), canonicalAlias = roomInfo.canonicalAlias?.let(::RoomAlias),
isDirect = roomInfo.isDirect, isDirect = roomInfo.isDirect,
avatarUrl = roomInfo.avatarUrl, avatarUrl = roomInfo.avatarUrl,

View File

@@ -58,7 +58,6 @@ internal class RustRoomListService(
) { ) {
when (source) { when (source) {
RoomList.Source.All -> innerRoomListService.allRooms() RoomList.Source.All -> innerRoomListService.allRooms()
RoomList.Source.Invites -> innerRoomListService.invites()
} }
} }
} }
@@ -70,13 +69,6 @@ internal class RustRoomListService(
innerRoomListService.allRooms() innerRoomListService.allRooms()
} }
override val invites: RoomList = roomListFactory.createRoomList(
pageSize = Int.MAX_VALUE,
coroutineContext = sessionDispatcher,
) {
innerRoomListService.invites()
}
init { init {
allRooms.loadAllIncrementally(sessionCoroutineScope) allRooms.loadAllIncrementally(sessionCoroutineScope)
} }

View File

@@ -515,7 +515,7 @@ class RustTimeline(
} }
} }
private fun fetchDetailsForEvent(eventId: EventId): Result<Unit> { private suspend fun fetchDetailsForEvent(eventId: EventId): Result<Unit> {
return runCatching { return runCatching {
inner.fetchDetailsForEvent(eventId.value) inner.fetchDetailsForEvent(eventId.value)
} }

View File

@@ -170,11 +170,7 @@ class RoomSummaryListProcessorTests {
override suspend fun applyInput(input: RoomListInput) = Unit override suspend fun applyInput(input: RoomListInput) = Unit
override suspend fun invites(): RoomList { override suspend fun room(roomId: String): RoomListItem {
return RoomList(Pointer.NULL)
}
override fun room(roomId: String): RoomListItem {
return RoomListItem(Pointer.NULL) return RoomListItem(Pointer.NULL)
} }

View File

@@ -70,7 +70,6 @@ import java.io.File
class FakeMatrixRoom( class FakeMatrixRoom(
override val sessionId: SessionId = A_SESSION_ID, override val sessionId: SessionId = A_SESSION_ID,
override val roomId: RoomId = A_ROOM_ID, override val roomId: RoomId = A_ROOM_ID,
override val name: String? = null,
override val displayName: String = "", override val displayName: String = "",
override val topic: String? = null, override val topic: String? = null,
override val avatarUrl: String? = null, override val avatarUrl: String? = null,

View File

@@ -28,7 +28,6 @@ class FakeRoomListService : RoomListService {
private val allRoomSummariesFlow = MutableStateFlow<List<RoomSummary>>(emptyList()) private val allRoomSummariesFlow = MutableStateFlow<List<RoomSummary>>(emptyList())
private val inviteRoomSummariesFlow = MutableStateFlow<List<RoomSummary>>(emptyList()) private val inviteRoomSummariesFlow = MutableStateFlow<List<RoomSummary>>(emptyList())
private val allRoomsLoadingStateFlow = MutableStateFlow<RoomList.LoadingState>(RoomList.LoadingState.NotLoaded) private val allRoomsLoadingStateFlow = MutableStateFlow<RoomList.LoadingState>(RoomList.LoadingState.NotLoaded)
private val inviteRoomsLoadingStateFlow = MutableStateFlow<RoomList.LoadingState>(RoomList.LoadingState.NotLoaded)
private val roomListStateFlow = MutableStateFlow<RoomListService.State>(RoomListService.State.Idle) private val roomListStateFlow = MutableStateFlow<RoomListService.State>(RoomListService.State.Idle)
private val syncIndicatorStateFlow = MutableStateFlow<RoomListService.SyncIndicator>(RoomListService.SyncIndicator.Hide) private val syncIndicatorStateFlow = MutableStateFlow<RoomListService.SyncIndicator>(RoomListService.SyncIndicator.Hide)
@@ -44,10 +43,6 @@ class FakeRoomListService : RoomListService {
allRoomsLoadingStateFlow.emit(loadingState) allRoomsLoadingStateFlow.emit(loadingState)
} }
suspend fun postInviteRoomsLoadingState(loadingState: RoomList.LoadingState) {
inviteRoomsLoadingStateFlow.emit(loadingState)
}
suspend fun postState(state: RoomListService.State) { suspend fun postState(state: RoomListService.State) {
roomListStateFlow.emit(state) roomListStateFlow.emit(state)
} }
@@ -66,7 +61,6 @@ class FakeRoomListService : RoomListService {
): DynamicRoomList { ): DynamicRoomList {
return when (source) { return when (source) {
RoomList.Source.All -> allRooms RoomList.Source.All -> allRooms
RoomList.Source.Invites -> invites
} }
} }
@@ -76,12 +70,6 @@ class FakeRoomListService : RoomListService {
MutableStateFlow(RoomListFilter.all()) MutableStateFlow(RoomListFilter.all())
) )
override val invites = SimplePagedRoomList(
inviteRoomSummariesFlow,
inviteRoomsLoadingStateFlow,
MutableStateFlow(RoomListFilter.all())
)
override fun updateAllRoomsVisibleRange(range: IntRange) { override fun updateAllRoomsVisibleRange(range: IntRange) {
latestSlidingSyncRange = range latestSlidingSyncRange = range
} }

View File

@@ -56,7 +56,7 @@ private const val versionMinor = 4
// Note: even values are reserved for regular release, odd values for hotfix release. // Note: even values are reserved for regular release, odd values for hotfix release.
// When creating a hotfix, you should decrease the value, since the current value // When creating a hotfix, you should decrease the value, since the current value
// is the value for the next regular release. // is the value for the next regular release.
private const val versionPatch = 11 private const val versionPatch = 12
object Versions { object Versions {
val versionCode = 4_000_000 + versionMajor * 1_00_00 + versionMinor * 1_00 + versionPatch val versionCode = 4_000_000 + versionMajor * 1_00_00 + versionMinor * 1_00 + versionPatch