Alias permalink navigation - WIP

This commit is contained in:
Benoit Marty 2024-04-16 12:20:25 +02:00 committed by Benoit Marty
parent a602849ec5
commit c1188ebb2d
12 changed files with 137 additions and 68 deletions

View file

@ -19,6 +19,7 @@ package io.element.android.libraries.matrix.api
import io.element.android.libraries.matrix.api.core.ProgressCallback
import io.element.android.libraries.matrix.api.core.RoomAlias
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.core.RoomIdOrAlias
import io.element.android.libraries.matrix.api.core.SessionId
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.createroom.CreateRoomParameters
@ -94,12 +95,12 @@ interface MatrixClient : Closeable {
suspend fun getAccountManagementUrl(action: AccountManagementAction?): Result<String?>
suspend fun uploadMedia(mimeType: String, data: ByteArray, progressCallback: ProgressCallback?): Result<String>
fun roomMembershipObserver(): RoomMembershipObserver
fun getRoomInfoFlow(roomId: RoomId): Flow<Optional<MatrixRoomInfo>>
fun getRoomInfoFlow(roomIdOrAlias: RoomIdOrAlias): Flow<Optional<MatrixRoomInfo>>
fun isMe(userId: UserId?) = userId == sessionId
suspend fun trackRecentlyVisitedRoom(roomId: RoomId): Result<Unit>
suspend fun getRecentlyVisitedRooms(): Result<List<RoomId>>
suspend fun resolveRoomAlias(roomAlias: RoomAlias): Result<RoomId>
suspend fun getRoomPreview(roomIdOrAlias: String): Result<RoomPreview>
suspend fun getRoomPreview(roomIdOrAlias: RoomIdOrAlias): Result<RoomPreview>
}

View file

@ -0,0 +1,39 @@
/*
* 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.libraries.matrix.api.core
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
sealed interface RoomIdOrAlias : Parcelable {
@Parcelize
@JvmInline
value class Id(val roomId: RoomId) : RoomIdOrAlias
@Parcelize
@JvmInline
value class Alias(val roomAlias: RoomAlias) : RoomIdOrAlias
val identifier: String
get() = when (this) {
is Id -> roomId.value
is Alias -> roomAlias.value
}
}
fun RoomId.toRoomIdOrAlias() = RoomIdOrAlias.Id(this)
fun RoomAlias.toRoomIdOrAlias() = RoomIdOrAlias.Alias(this)

View file

@ -25,6 +25,7 @@ import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.core.ProgressCallback
import io.element.android.libraries.matrix.api.core.RoomAlias
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.core.RoomIdOrAlias
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.createroom.CreateRoomParameters
import io.element.android.libraries.matrix.api.createroom.RoomPreset
@ -469,9 +470,9 @@ class RustMatrixClient(
}
}
override suspend fun getRoomPreview(roomIdOrAlias: String): Result<RoomPreview> = withContext(sessionDispatcher) {
override suspend fun getRoomPreview(roomIdOrAlias: RoomIdOrAlias): Result<RoomPreview> = withContext(sessionDispatcher) {
runCatching {
client.getRoomPreview(roomIdOrAlias).let(RoomPreviewMapper::map)
client.getRoomPreview(roomIdOrAlias.identifier).let(RoomPreviewMapper::map)
}
}
@ -561,18 +562,33 @@ class RustMatrixClient(
override fun roomMembershipObserver(): RoomMembershipObserver = roomMembershipObserver
override fun getRoomInfoFlow(roomId: RoomId): Flow<Optional<MatrixRoomInfo>> {
override fun getRoomInfoFlow(roomIdOrAlias: RoomIdOrAlias): Flow<Optional<MatrixRoomInfo>> {
return flow {
var room = getRoom(roomId)
if (room == null) {
emit(Optional.empty())
awaitRoom(roomId, INFINITE)
room = getRoom(roomId)
val roomId = when (roomIdOrAlias) {
is RoomIdOrAlias.Alias -> {
resolveRoomAlias(roomIdOrAlias.roomAlias)
.onFailure {
// TODO Get a way to emit an error
Timber.e("Unable to resolve room alias ${roomIdOrAlias.roomAlias}")
emit(Optional.empty())
return@flow
}
.getOrNull()
}
is RoomIdOrAlias.Id -> roomIdOrAlias.roomId
}
room?.use {
room.roomInfoFlow
.map { roomInfo -> Optional.of(roomInfo) }
.collect(this)
if (roomId != null) {
var room = getRoom(roomId)
if (room == null) {
emit(Optional.empty())
awaitRoom(roomId, INFINITE)
room = getRoom(roomId)
}
room?.use {
room.roomInfoFlow
.map { roomInfo -> Optional.of(roomInfo) }
.collect(this)
}
}
}.distinctUntilChanged()
}

View file

@ -20,6 +20,7 @@ import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.core.ProgressCallback
import io.element.android.libraries.matrix.api.core.RoomAlias
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.core.RoomIdOrAlias
import io.element.android.libraries.matrix.api.core.SessionId
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.createroom.CreateRoomParameters
@ -76,7 +77,7 @@ class FakeMatrixClient(
private val roomDirectoryService: RoomDirectoryService = FakeRoomDirectoryService(),
private val accountManagementUrlString: Result<String?> = Result.success(null),
private val resolveRoomAliasResult: (RoomAlias) -> Result<RoomId> = { Result.success(A_ROOM_ID) },
private val getRoomPreviewResult: (String) -> Result<RoomPreview> = { TODO("Not implemented") },
private val getRoomPreviewResult: (RoomIdOrAlias) -> Result<RoomPreview> = { TODO("Not implemented") },
) : MatrixClient {
var setDisplayNameCalled: Boolean = false
private set
@ -106,7 +107,7 @@ class FakeMatrixClient(
Result.success(it)
}
var getRoomInfoFlowLambda = { _: RoomId ->
var getRoomInfoFlowLambda = { _: RoomIdOrAlias ->
flowOf<Optional<MatrixRoomInfo>>(Optional.empty())
}
@ -284,7 +285,7 @@ class FakeMatrixClient(
return resolveRoomAliasResult(roomAlias)
}
override suspend fun getRoomPreview(roomIdOrAlias: String): Result<RoomPreview> {
override suspend fun getRoomPreview(roomIdOrAlias: RoomIdOrAlias): Result<RoomPreview> {
return getRoomPreviewResult(roomIdOrAlias)
}
@ -292,5 +293,5 @@ class FakeMatrixClient(
return Result.success(visitedRoomsId)
}
override fun getRoomInfoFlow(roomId: RoomId) = getRoomInfoFlowLambda(roomId)
override fun getRoomInfoFlow(roomIdOrAlias: RoomIdOrAlias) = getRoomInfoFlowLambda(roomIdOrAlias)
}