Merge branch 'develop' into separate_import_error

This commit is contained in:
Benoit Marty 2025-10-07 17:23:19 +02:00 committed by GitHub
commit 700ea331fe
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
679 changed files with 12323 additions and 1753 deletions

View file

@ -49,9 +49,18 @@ interface MatrixClient {
val userProfile: StateFlow<MatrixUser>
val roomListService: RoomListService
val spaceService: SpaceService
val mediaLoader: MatrixMediaLoader
val syncService: SyncService
val sessionVerificationService: SessionVerificationService
val pushersService: PushersService
val notificationService: NotificationService
val notificationSettingsService: NotificationSettingsService
val encryptionService: EncryptionService
val roomDirectoryService: RoomDirectoryService
val mediaPreviewService: MediaPreviewService
val matrixMediaLoader: MatrixMediaLoader
val sessionCoroutineScope: CoroutineScope
val ignoredUsersFlow: StateFlow<ImmutableList<UserId>>
val roomMembershipObserver: RoomMembershipObserver
suspend fun getJoinedRoom(roomId: RoomId): JoinedRoom?
suspend fun getRoom(roomId: RoomId): BaseRoom?
suspend fun findDM(userId: UserId): Result<RoomId?>
@ -68,14 +77,6 @@ interface MatrixClient {
suspend fun joinRoom(roomId: RoomId): Result<RoomInfo?>
suspend fun joinRoomByIdOrAlias(roomIdOrAlias: RoomIdOrAlias, serverNames: List<String>): Result<RoomInfo?>
suspend fun knockRoom(roomIdOrAlias: RoomIdOrAlias, message: String, serverNames: List<String>): Result<RoomInfo?>
fun syncService(): SyncService
fun sessionVerificationService(): SessionVerificationService
fun pushersService(): PushersService
fun notificationService(): NotificationService
fun notificationSettingsService(): NotificationSettingsService
fun encryptionService(): EncryptionService
fun roomDirectoryService(): RoomDirectoryService
fun mediaPreviewService(): MediaPreviewService
suspend fun getCacheSize(): Long
/**
@ -97,7 +98,6 @@ interface MatrixClient {
suspend fun getUserProfile(): Result<MatrixUser>
suspend fun getAccountManagementUrl(action: AccountManagementAction?): Result<String?>
suspend fun uploadMedia(mimeType: String, data: ByteArray): Result<String>
fun roomMembershipObserver(): RoomMembershipObserver
/**
* Get a room info flow for a given room ID.

View file

@ -69,14 +69,6 @@ object MatrixPatterns {
str matches PATTERN_CONTAIN_MATRIX_USER_IDENTIFIER
}
/**
* Tells if a string is a valid space id. This is an alias for [isRoomId]
*
* @param str the string to test
* @return true if the string is a valid space Id
*/
fun isSpaceId(str: String?) = isRoomId(str)
/**
* Tells if a string is a valid room id.
*

View file

@ -7,23 +7,7 @@
package io.element.android.libraries.matrix.api.core
import io.element.android.libraries.androidutils.metadata.isInDebug
import java.io.Serializable
@JvmInline
value class SpaceId(val value: String) : Serializable {
init {
if (isInDebug && !MatrixPatterns.isSpaceId(value)) {
error(
"`$value` is not a valid space id.\n" +
"Space ids are the same as room ids.\n" +
"Example space id: `!space_id:domain`."
)
}
}
override fun toString(): String = value
}
typealias SpaceId = RoomId
/**
* Value to use when no space is selected by the user.

View file

@ -17,6 +17,7 @@ interface EncryptionService {
val recoveryStateStateFlow: StateFlow<RecoveryState>
val enableRecoveryProgressStateFlow: StateFlow<EnableRecoveryProgress>
val isLastDevice: StateFlow<Boolean>
val hasDevicesToVerifyAgainst: StateFlow<Boolean>
suspend fun enableBackups(): Result<Unit>

View file

@ -12,6 +12,7 @@ import io.element.android.libraries.matrix.api.exception.ClientException
sealed class RecoveryException(message: String) : Exception(message) {
class Import(message: String) : RecoveryException(message)
class SecretStorage(message: String) : RecoveryException(message)
class Import(message: String) : RecoveryException(message)
data object BackupExistsOnServer : RecoveryException("BackupExistsOnServer")
data class Client(val exception: ClientException) : RecoveryException(exception.message ?: "Unknown error")
}

View file

@ -58,11 +58,12 @@ sealed interface RoomListFilter {
data object Invite : RoomListFilter
/**
* A filter that matches either Group or People rooms.
* A filter that matches either Group,People rooms or Space.
*/
sealed interface Category : RoomListFilter {
data object Group : Category
data object People : Category
data object Space : Category
}
/**

View file

@ -0,0 +1,34 @@
/*
* Copyright 2025 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.libraries.matrix.api.spaces
import io.element.android.libraries.matrix.api.core.RoomId
interface LeaveSpaceHandle {
/**
* The id of the space to leave.
*/
val id: RoomId
/**
* Get a list of rooms that can be left when leaving the space.
* It will include the current space and all the subspaces and rooms that the user has joined.
*/
suspend fun rooms(): Result<List<LeaveSpaceRoom>>
/**
* Leave the space and the given rooms.
* If [roomIds] is empty, only the space will be left.
*/
suspend fun leave(roomIds: List<RoomId>): Result<Unit>
/**
* Close the handle and free resources.
*/
fun close()
}

View file

@ -0,0 +1,13 @@
/*
* Copyright 2025 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.libraries.matrix.api.spaces
data class LeaveSpaceRoom(
val spaceRoom: SpaceRoom,
val isLastAdmin: Boolean,
)

View file

@ -15,7 +15,7 @@ import io.element.android.libraries.matrix.api.room.join.JoinRule
import io.element.android.libraries.matrix.api.user.MatrixUser
data class SpaceRoom(
val name: String?,
val rawName: String?,
val avatarUrl: String?,
val canonicalAlias: RoomAlias?,
val childrenCount: Int,
@ -32,6 +32,20 @@ data class SpaceRoom(
* The via parameters of the room.
*/
val via: List<String>,
val isDirect: Boolean?,
) {
val isSpace = roomType == RoomType.Space
/**
* Temporary logic to compute a name for direct rooms with no name.
* This will be replaced by sdk logic in the future.
*/
val name = if (rawName == null && isDirect == true && heroes.size == 1) {
val dmRecipient = heroes.first()
dmRecipient.displayName
} else {
rawName
}
val visibility = SpaceRoomVisibility.fromJoinRule(joinRule)
}

View file

@ -0,0 +1,26 @@
/*
* Copyright 2025 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.libraries.matrix.api.spaces
import androidx.compose.runtime.Immutable
import io.element.android.libraries.matrix.api.room.join.JoinRule
@Immutable
sealed interface SpaceRoomVisibility {
data object Private : SpaceRoomVisibility
data object Public : SpaceRoomVisibility
data object Restricted : SpaceRoomVisibility
companion object {
fun fromJoinRule(joinRule: JoinRule?): SpaceRoomVisibility = when (joinRule) {
JoinRule.Public -> Public
is JoinRule.Restricted, is JoinRule.KnockRestricted -> Restricted
// Else fallback to Private
else -> Private
}
}
}

View file

@ -15,4 +15,6 @@ interface SpaceService {
suspend fun joinedSpaces(): Result<List<SpaceRoom>>
fun spaceRoomList(id: RoomId): SpaceRoomList
fun getLeaveSpaceHandle(spaceId: RoomId): LeaveSpaceHandle
}