Merge branch 'develop' into feature/fga/set_user_status
This commit is contained in:
+8
@@ -38,6 +38,7 @@ import io.element.android.libraries.matrix.api.room.alias.ResolvedRoomAlias
|
||||
import io.element.android.libraries.matrix.api.room.location.BeaconInfoUpdate
|
||||
import io.element.android.libraries.matrix.api.roomdirectory.RoomDirectoryService
|
||||
import io.element.android.libraries.matrix.api.roomlist.RoomListService
|
||||
import io.element.android.libraries.matrix.api.scanner.ContentScanner
|
||||
import io.element.android.libraries.matrix.api.spaces.SpaceService
|
||||
import io.element.android.libraries.matrix.api.sync.SlidingSyncVersion
|
||||
import io.element.android.libraries.matrix.api.sync.SyncService
|
||||
@@ -72,6 +73,7 @@ interface MatrixClient {
|
||||
val ignoredUsersFlow: StateFlow<ImmutableList<UserId>>
|
||||
val roomMembershipObserver: RoomMembershipObserver
|
||||
val ownBeaconInfoUpdates: Flow<BeaconInfoUpdate>
|
||||
val contentScanner: ContentScanner?
|
||||
suspend fun getJoinedRoom(roomId: RoomId): JoinedRoom?
|
||||
suspend fun getRoom(roomId: RoomId): BaseRoom?
|
||||
suspend fun findDM(userId: UserId): Result<RoomId?>
|
||||
@@ -208,6 +210,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.
|
||||
*/
|
||||
|
||||
+3
@@ -22,3 +22,6 @@ sealed class ClientException(message: String, val details: String?, cause: Throw
|
||||
fun ClientException.isNetworkError(): Boolean {
|
||||
return this is ClientException.Generic && message?.contains("error sending request for url", ignoreCase = true) == true
|
||||
}
|
||||
|
||||
fun Throwable.isNetworkError(): Boolean =
|
||||
(this as? ClientException)?.isNetworkError() == true
|
||||
|
||||
+36
@@ -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
|
||||
}
|
||||
+1
@@ -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
|
||||
}
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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.scanner
|
||||
|
||||
import io.element.android.libraries.matrix.api.media.MediaSource
|
||||
|
||||
/**
|
||||
* Component used to manually scan media content for potential security risks.
|
||||
*
|
||||
* While the Matrix SDK automatically scans media content we load if a content scanner instance is provided, this interface allows for scanning
|
||||
* some media sources in advance without actually loading their contents, which can be useful for pre-fetching scenarios.
|
||||
*/
|
||||
interface ContentScanner {
|
||||
/**
|
||||
* Manually scans the given [mediaSource] for potential security risks.
|
||||
*
|
||||
* @param mediaSource The media source to scan.
|
||||
* @return A [Result] containing a [Boolean] indicating whether the content is safe (true) or potentially unsafe (false).
|
||||
* If the scan fails, the [Result] will contain an exception.
|
||||
*/
|
||||
suspend fun scan(mediaSource: MediaSource): Result<Boolean>
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* 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.scanner
|
||||
|
||||
/**
|
||||
* Provides the URL of the content scanner service for a given homeserver, if any is set up.
|
||||
*/
|
||||
fun interface ContentScannerUrlProvider {
|
||||
/**
|
||||
* Returns the URL of the content scanner service for the given [homeserver], or `null` if no content scanner is set up.
|
||||
*/
|
||||
suspend fun getContentScannerUrl(homeserver: String): Result<String?>
|
||||
}
|
||||
+15
@@ -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>
|
||||
@@ -216,6 +224,13 @@ interface Timeline : AutoCloseable {
|
||||
|
||||
suspend fun loadReplyDetails(eventId: EventId): InReplyTo
|
||||
|
||||
/**
|
||||
* Returns true if [eventId] is currently loaded in this timeline's window, even if the display
|
||||
* layer does not render it (e.g. filtered or state events). This distinguishes "in the window
|
||||
* but not displayed" from "genuinely outside the loaded window".
|
||||
*/
|
||||
suspend fun isEventLoaded(eventId: EventId): Boolean
|
||||
|
||||
/**
|
||||
* Adds a new pinned event by sending an updated `m.room.pinned_events`
|
||||
* event containing the new event id.
|
||||
|
||||
+15
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user