[Room details] DM designs (#313)

* Implement member details screen

* Add DM-only sections to the room details screen.
This commit is contained in:
Jorge Martin Espinosa 2023-04-17 18:41:10 +02:00 committed by GitHub
parent 97917e7a2d
commit 30eb794d9c
44 changed files with 379 additions and 113 deletions

View file

@ -48,7 +48,7 @@ object PermalinkBuilder {
}
Result.success(url)
} else {
Result.failure(PermalinkBuilderError.InvalidRoomAlias)
Result.failure(PermalinkBuilderError.InvalidUserId)
}
}
@ -87,4 +87,5 @@ object PermalinkBuilder {
sealed class PermalinkBuilderError : Throwable() {
object InvalidRoomAlias : PermalinkBuilderError()
object InvalidRoomId : PermalinkBuilderError()
object InvalidUserId : PermalinkBuilderError()
}

View file

@ -33,6 +33,7 @@ interface MatrixRoom: Closeable {
val topic: String?
val avatarUrl: String?
val isEncrypted: Boolean
val isDirect: Boolean
val isPublic: Boolean
suspend fun members() : List<RoomMember>
@ -41,15 +42,17 @@ interface MatrixRoom: Closeable {
fun getMember(userId: UserId): RoomMember?
fun getDmMember(): RoomMember?
fun syncUpdateFlow(): Flow<Long>
fun timeline(): MatrixTimeline
suspend fun fetchMembers(): Result<Unit>
suspend fun userDisplayName(userId: String): Result<String?>
suspend fun userDisplayName(userId: UserId): Result<String?>
suspend fun userAvatarUrl(userId: String): Result<String?>
suspend fun userAvatarUrl(userId: UserId): Result<String?>
suspend fun sendMessage(message: String): Result<Unit>

View file

@ -17,11 +17,12 @@
package io.element.android.libraries.matrix.api.room
import android.os.Parcelable
import io.element.android.libraries.matrix.api.core.UserId
import kotlinx.parcelize.Parcelize
@Parcelize
data class RoomMember(
val userId: String,
val userId: UserId,
val displayName: String?,
val avatarUrl: String?,
val membership: RoomMembershipState,

View file

@ -168,6 +168,7 @@ class RustMatrixClient constructor(
val slidingSyncRoom = slidingSync.getRoom(roomId.value) ?: return null
val fullRoom = slidingSyncRoom.fullRoom() ?: return null
return RustMatrixRoom(
currentUserId = sessionId,
slidingSyncUpdateFlow = slidingSyncObserverProxy.updateSummaryFlow,
slidingSyncRoom = slidingSyncRoom,
innerRoom = fullRoom,

View file

@ -16,6 +16,7 @@
package io.element.android.libraries.matrix.impl.room
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.room.RoomMember
import io.element.android.libraries.matrix.api.room.RoomMembershipState
import org.matrix.rustcomponents.sdk.MembershipState as RustMembershipState
@ -25,7 +26,7 @@ object RoomMemberMapper {
fun map(roomMember: RustRoomMember): RoomMember =
RoomMember(
roomMember.userId(),
UserId(roomMember.userId()),
roomMember.displayName(),
roomMember.avatarUrl(),
mapMembership(roomMember.membership()),

View file

@ -40,6 +40,7 @@ import org.matrix.rustcomponents.sdk.genTransactionId
import org.matrix.rustcomponents.sdk.messageEventContentFromMarkdown
class RustMatrixRoom(
private val currentUserId: UserId,
private val slidingSyncUpdateFlow: Flow<UpdateSummary>,
private val slidingSyncRoom: SlidingSyncRoom,
private val innerRoom: Room,
@ -70,7 +71,15 @@ class RustMatrixRoom(
}
override fun getMember(userId: UserId): RoomMember? {
return cachedMembers.firstOrNull { it.userId == userId.value }
return cachedMembers.find { it.userId == userId }
}
override fun getDmMember(): RoomMember? {
return if (cachedMembers.size == 2 && isDirect && isEncrypted) {
cachedMembers.find { it.userId != currentUserId }
} else {
null
}
}
override fun syncUpdateFlow(): Flow<Long> {
@ -127,7 +136,7 @@ class RustMatrixRoom(
}
override val isEncrypted: Boolean
get() = innerRoom.isEncrypted()
get() = runCatching { innerRoom.isEncrypted() }.getOrDefault(false)
override val alias: String?
get() = innerRoom.canonicalAlias()
@ -138,23 +147,26 @@ class RustMatrixRoom(
override val isPublic: Boolean
get() = innerRoom.isPublic()
override val isDirect: Boolean
get() = innerRoom.isDirect()
override suspend fun fetchMembers(): Result<Unit> = withContext(coroutineDispatchers.io) {
runCatching {
innerRoom.fetchMembers()
}
}
override suspend fun userDisplayName(userId: String): Result<String?> =
override suspend fun userDisplayName(userId: UserId): Result<String?> =
withContext(coroutineDispatchers.io) {
runCatching {
innerRoom.memberDisplayName(userId)
innerRoom.memberDisplayName(userId.value)
}
}
override suspend fun userAvatarUrl(userId: String): Result<String?> =
override suspend fun userAvatarUrl(userId: UserId): Result<String?> =
withContext(coroutineDispatchers.io) {
runCatching {
innerRoom.memberAvatarUrl(userId)
innerRoom.memberAvatarUrl(userId.value)
}
}

View file

@ -39,10 +39,14 @@ class FakeMatrixRoom(
override val alias: String? = null,
override val alternativeAliases: List<String> = emptyList(),
override val isPublic: Boolean = true,
override val isDirect: Boolean = false,
private val members: List<RoomMember> = emptyList(),
private val matrixTimeline: MatrixTimeline = FakeMatrixTimeline(),
) : MatrixRoom {
private var userDisplayNameResult = Result.success<String?>(null)
private var userAvatarUrlResult = Result.success<String?>(null)
private var dmMember: RoomMember? = null
private var fetchMemberResult: Result<Unit> = Result.success(Unit)
var areMembersFetched: Boolean = false
@ -66,12 +70,16 @@ class FakeMatrixRoom(
}
}
override suspend fun userDisplayName(userId: String): Result<String?> {
return Result.success("")
override fun getDmMember(): RoomMember? {
return dmMember
}
override suspend fun userAvatarUrl(userId: String): Result<String?> {
TODO("Not yet implemented")
override suspend fun userDisplayName(userId: UserId): Result<String?> {
return userDisplayNameResult
}
override suspend fun userAvatarUrl(userId: UserId): Result<String?> {
return userAvatarUrlResult
}
override suspend fun members(): List<RoomMember> {
@ -87,7 +95,7 @@ class FakeMatrixRoom(
}
override fun getMember(userId: UserId): RoomMember? {
return members.firstOrNull { it.userId == userId.value }
return members.firstOrNull { it.userId == userId }
}
override suspend fun sendMessage(message: String): Result<Unit> {
@ -133,4 +141,16 @@ class FakeMatrixRoom(
fun givenFetchMemberResult(result: Result<Unit>) {
fetchMemberResult = result
}
fun givenDmMember(roomMember: RoomMember) {
this.dmMember = roomMember
}
fun givenUserDisplayNameResult(displayName: Result<String?>) {
userDisplayNameResult = displayName
}
fun givenUserAvatarUrlResult(avatarUrl: Result<String?>) {
userAvatarUrlResult = avatarUrl
}
}