Merge branch 'develop' into feature/bma/scroll-to-unread-messages

This commit is contained in:
Benoit Marty
2026-07-03 14:30:14 +02:00
committed by GitHub
1562 changed files with 11824 additions and 6140 deletions
@@ -27,6 +27,7 @@ import io.element.android.libraries.matrix.api.media.MediaPreviewService
import io.element.android.libraries.matrix.api.notification.NotificationService
import io.element.android.libraries.matrix.api.notificationsettings.NotificationSettingsService
import io.element.android.libraries.matrix.api.oauth.AccountManagementAction
import io.element.android.libraries.matrix.api.paths.SessionPaths
import io.element.android.libraries.matrix.api.pusher.PushersService
import io.element.android.libraries.matrix.api.room.BaseRoom
import io.element.android.libraries.matrix.api.room.JoinedRoom
@@ -53,6 +54,7 @@ import java.util.Optional
interface MatrixClient {
val sessionId: SessionId
val deviceId: DeviceId
val sessionPaths: SessionPaths
val userProfile: StateFlow<MatrixUser>
val roomListService: RoomListService
val spaceService: SpaceService
@@ -201,6 +203,12 @@ interface MatrixClient {
*/
suspend fun markRoomAsFullyRead(roomId: RoomId, eventId: EventId): Result<Unit>
/**
* Mark all joined rooms as read by sending public, private and fully-read receipts
* on each room's latest event. Per-room errors are logged and skipped by the SDK.
*/
suspend fun markAllRoomsAsRead(): Result<Unit>
/**
* Check if linking a new device using QrCode is supported by the server.
*/
@@ -10,5 +10,5 @@ package io.element.android.libraries.matrix.api.analytics
import io.element.android.libraries.matrix.api.core.SessionId
fun interface GetDatabaseSizesUseCase {
suspend operator fun invoke(sessionId: SessionId): Result<SdkStoreSizes>
operator fun invoke(sessionId: SessionId): Result<SdkStoreSizes>
}
@@ -24,9 +24,15 @@ interface EncryptionService {
suspend fun enableBackups(): Result<Unit>
/**
* Enable recovery. Observe enableProgressStateFlow to get progress and recovery key.
* Enable recovery and return the SDK-generated recovery key on success.
* Observe [enableRecoveryProgressStateFlow] for in-progress UI updates.
*
* @param waitForBackupsToUpload when true, suspends until existing room keys finish uploading.
* @param passphrase optional user-supplied passphrase. When set, the SDK derives the
* secret-storage key from it instead of a random base58 key; the passphrase can later be
* passed to [recover], and the returned base58 key should not be surfaced to the user.
*/
suspend fun enableRecovery(waitForBackupsToUpload: Boolean): Result<Unit>
suspend fun enableRecovery(waitForBackupsToUpload: Boolean, passphrase: String? = null): Result<String>
/**
* Change the recovery and return the new recovery key.
@@ -16,6 +16,9 @@ interface LinkMobileHandler {
sealed interface LinkMobileStep {
data object Uninitialized : LinkMobileStep
// Internal application step, for the UI
data object CreatingQrCode : LinkMobileStep
data object Starting : LinkMobileStep
data class QrReady(val data: String) : LinkMobileStep
data object QrRotating : LinkMobileStep
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2026 Element Creations 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.media
import java.io.File
sealed interface GalleryItemInfo {
val file: File
data class Image(
override val file: File,
val imageInfo: ImageInfo,
val thumbnailFile: File?,
) : GalleryItemInfo
data class Video(
override val file: File,
val videoInfo: VideoInfo,
val thumbnailFile: File?,
) : GalleryItemInfo
data class Audio(
override val file: File,
val audioInfo: AudioInfo,
) : GalleryItemInfo
data class MediaFile(
override val file: File,
val fileInfo: FileInfo,
) : GalleryItemInfo
}
@@ -0,0 +1,20 @@
/*
* Copyright (c) 2026 Element Creations 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.paths
import java.io.File
data class SessionPaths(
val fileDirectory: File,
val cacheDirectory: File,
) {
fun deleteRecursively() {
fileDirectory.deleteRecursively()
cacheDirectory.deleteRecursively()
}
}
@@ -157,11 +157,6 @@ interface BaseRoom : Closeable {
*/
suspend fun setUnreadFlag(isUnread: Boolean): Result<Unit>
/**
* Clear the event cache storage for the current room.
*/
suspend fun clearEventCacheStorage(): Result<Unit>
/**
* Get the permalink for the room.
*/
@@ -34,6 +34,7 @@ sealed interface StateEventType {
data object MemberHints : StateEventType
data object RoomImagePack : StateEventType
data object RoomLanguage : StateEventType
data object RoomPolicy : StateEventType
data class Custom(val type: String) : StateEventType
}
@@ -16,6 +16,7 @@ import io.element.android.libraries.matrix.api.core.ThreadId
import io.element.android.libraries.matrix.api.core.TransactionId
import io.element.android.libraries.matrix.api.media.AudioInfo
import io.element.android.libraries.matrix.api.media.FileInfo
import io.element.android.libraries.matrix.api.media.GalleryItemInfo
import io.element.android.libraries.matrix.api.media.ImageInfo
import io.element.android.libraries.matrix.api.media.MediaUploadHandler
import io.element.android.libraries.matrix.api.media.VideoInfo
@@ -157,6 +158,13 @@ interface Timeline : AutoCloseable {
inReplyToEventId: EventId?,
): Result<MediaUploadHandler>
suspend fun sendGallery(
items: List<GalleryItemInfo>,
caption: String?,
formattedCaption: String?,
inReplyToEventId: EventId?,
): Result<MediaUploadHandler>
suspend fun redactEvent(eventOrTransactionId: EventOrTransactionId, reason: String?): Result<Unit>
suspend fun toggleReaction(emoji: String, eventOrTransactionId: EventOrTransactionId): Result<Boolean>
@@ -102,6 +102,21 @@ data class TextMessageType(
val formatted: FormattedBody?
) : MessageType
data class GalleryMessageType(
val body: String,
val formatted: FormattedBody?,
val items: List<GalleryItemType>,
) : MessageType
@Immutable
sealed interface GalleryItemType {
data class Image(val content: ImageMessageType) : GalleryItemType
data class Audio(val content: AudioMessageType) : GalleryItemType
data class Video(val content: VideoMessageType) : GalleryItemType
data class File(val content: FileMessageType) : GalleryItemType
data class Other(val itemType: String, val body: String) : GalleryItemType
}
data class OtherMessageType(
val msgType: String,
val body: String,