Add KDoc to matrix API knock, threads and permissions interfaces

Document KnockRequest and ThreadsListService along with all their members, and
add the missing @param entries to the already documented RoomPermissions.

For ThreadsListService the docs record what the implementation does with the
subscriptions: subscribeToItemUpdates starts a shared subscription on the first
call and re-emits the whole list, subscribeToPaginationUpdates replays the
current state immediately, and destroy leaves the service unusable.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Benoit Marty
2026-08-13 19:03:48 +02:00
parent 0bd4dc39cd
commit 8a88638667
3 changed files with 71 additions and 0 deletions
@@ -11,20 +11,50 @@ package io.element.android.libraries.matrix.api.room.knock
import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.core.UserId
/**
* A pending request from a user to join a room whose join rule is knock, along with the actions a moderator can take on it.
*
* Instances are snapshots handed out by [io.element.android.libraries.matrix.api.room.JoinedRoom.knockRequestsFlow].
*/
interface KnockRequest { interface KnockRequest {
/** The id of the membership event carrying the request. */
val eventId: EventId val eventId: EventId
/** The user asking to join. */
val userId: UserId val userId: UserId
/** The display name of the user asking to join, or `null` if they have none. */
val displayName: String? val displayName: String?
/** The avatar of the user asking to join, or `null` if they have none. */
val avatarUrl: String? val avatarUrl: String?
/** The message the user attached to their request, or `null` if they sent none. */
val reason: String? val reason: String?
/** When the request was made, in milliseconds since the epoch, or `null` if the server did not provide it. */
val timestamp: Long? val timestamp: Long?
/** Whether a moderator has already marked this request as seen, so that it is no longer highlighted as new. */
val isSeen: Boolean val isSeen: Boolean
/** Accepts the request, which makes the user a member of the room. */
suspend fun accept(): Result<Unit> suspend fun accept(): Result<Unit>
/**
* Declines the request; the user is free to knock again.
*
* @param reason the explanation recorded in the membership event, or `null` for none.
*/
suspend fun decline(reason: String?): Result<Unit> suspend fun decline(reason: String?): Result<Unit>
/**
* Declines the request and bans the user, so that they cannot knock again.
*
* @param reason the explanation recorded in the membership event, or `null` for none.
*/
suspend fun declineAndBan(reason: String?): Result<Unit> suspend fun declineAndBan(reason: String?): Result<Unit>
/** Marks the request as seen, without accepting or declining it. */
suspend fun markAsSeen(): Result<Unit> suspend fun markAsSeen(): Result<Unit>
} }
@@ -59,12 +59,16 @@ interface RoomPermissions : AutoCloseable {
/** /**
* Returns true if the current user is able to send a specific message type * Returns true if the current user is able to send a specific message type
* in the room. * in the room.
*
* @param message the kind of message the caller wants to send.
*/ */
fun canOwnUserSendMessage(message: MessageEventType): Boolean fun canOwnUserSendMessage(message: MessageEventType): Boolean
/** /**
* Returns true if the current user is able to send a specific state event * Returns true if the current user is able to send a specific state event
* type in the room. * type in the room.
*
* @param stateEvent the kind of state event the caller wants to send.
*/ */
fun canOwnUserSendState(stateEvent: StateEventType): Boolean fun canOwnUserSendState(stateEvent: StateEventType): Boolean
@@ -77,48 +81,66 @@ interface RoomPermissions : AutoCloseable {
/** /**
* Returns true if the user with the given userId is able to ban in the * Returns true if the user with the given userId is able to ban in the
* room. * room.
*
* @param userId the member whose ability is checked.
*/ */
fun canUserBan(userId: UserId): Boolean fun canUserBan(userId: UserId): Boolean
/** /**
* Returns true if the user with the given userId is able to invite in the * Returns true if the user with the given userId is able to invite in the
* room. * room.
*
* @param userId the member whose ability is checked.
*/ */
fun canUserInvite(userId: UserId): Boolean fun canUserInvite(userId: UserId): Boolean
/** /**
* Returns true if the user with the given userId is able to kick in the * Returns true if the user with the given userId is able to kick in the
* room. * room.
*
* @param userId the member whose ability is checked.
*/ */
fun canUserKick(userId: UserId): Boolean fun canUserKick(userId: UserId): Boolean
/** /**
* Returns true if the user with the given userId is able to pin or unpin * Returns true if the user with the given userId is able to pin or unpin
* events in the room. * events in the room.
*
* @param userId the member whose ability is checked.
*/ */
fun canUserPinUnpin(userId: UserId): Boolean fun canUserPinUnpin(userId: UserId): Boolean
/** /**
* Returns true if the user with the given userId is able to redact * Returns true if the user with the given userId is able to redact
* messages of other users in the room. * messages of other users in the room.
*
* @param userId the member whose ability is checked.
*/ */
fun canUserRedactOther(userId: UserId): Boolean fun canUserRedactOther(userId: UserId): Boolean
/** /**
* Returns true if the user with the given userId is able to redact * Returns true if the user with the given userId is able to redact
* their own messages in the room. * their own messages in the room.
*
* @param userId the member whose ability is checked.
*/ */
fun canUserRedactOwn(userId: UserId): Boolean fun canUserRedactOwn(userId: UserId): Boolean
/** /**
* Returns true if the user with the given userId is able to send a * Returns true if the user with the given userId is able to send a
* specific message type in the room. * specific message type in the room.
*
* @param userId the member whose ability is checked.
* @param message the kind of message to check.
*/ */
fun canUserSendMessage(userId: UserId, message: MessageEventType): Boolean fun canUserSendMessage(userId: UserId, message: MessageEventType): Boolean
/** /**
* Returns true if the user with the given userId is able to send a * Returns true if the user with the given userId is able to send a
* specific state event type in the room. * specific state event type in the room.
*
* @param userId the member whose ability is checked.
* @param stateEvent the kind of state event to check.
*/ */
fun canUserSendState(userId: UserId, stateEvent: StateEventType): Boolean fun canUserSendState(userId: UserId, stateEvent: StateEventType): Boolean
@@ -127,6 +149,8 @@ interface RoomPermissions : AutoCloseable {
* notification in the room. * notification in the room.
* *
* The call may fail if there is an error in getting the power levels. * The call may fail if there is an error in getting the power levels.
*
* @param userId the member whose ability is checked.
*/ */
fun canUserTriggerRoomNotification(userId: UserId): Boolean fun canUserTriggerRoomNotification(userId: UserId): Boolean
} }
@@ -9,10 +9,27 @@ package io.element.android.libraries.matrix.api.room.threads
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
/**
* Exposes the paginated list of threads of a single room, kept up to date by the SDK.
*
* The list grows through explicit [paginate] calls; [destroy] must be called to release the underlying SDK resources.
*/
interface ThreadsListService { interface ThreadsListService {
/**
* The threads loaded so far, starting empty and re-emitted in full whenever the SDK sends an update.
* The underlying subscription is started on the first call and shared by later ones.
*/
fun subscribeToItemUpdates(): Flow<List<ThreadListItem>> fun subscribeToItemUpdates(): Flow<List<ThreadListItem>>
/** The pagination state of the list, emitting the current value immediately so callers know whether more threads can be loaded. */
fun subscribeToPaginationUpdates(): Flow<ThreadListPaginationStatus> fun subscribeToPaginationUpdates(): Flow<ThreadListPaginationStatus>
/** Loads the next page of threads, which will be reflected in [subscribeToItemUpdates]. */
suspend fun paginate(): Result<Unit> suspend fun paginate(): Result<Unit>
/** Discards the loaded threads and starts the list again from the most recent one. */
suspend fun reset(): Result<Unit> suspend fun reset(): Result<Unit>
/** Releases the SDK resources and stops the item subscription; the service is unusable afterwards. */
fun destroy() fun destroy()
} }