Feature: add room threads list (#6575)

Add threads list screen for rooms:

- Add `ThreadsListService` to subscribe to thread changes in the room.
- Create `ThreadsListView` and its associated node a presenters (the UI may change).
- Add a menu icon in the room screen to open it.

This is still pending info about unread threads, so several UI components related to it will be hidden.

* Add feature flag and use it to hide the access to this new screen

---------

Co-authored-by: ElementBot <android@element.io>
This commit is contained in:
Jorge Martin Espinosa 2026-04-15 14:14:22 +02:00 committed by GitHub
parent be775d686e
commit 80470b3792
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
35 changed files with 1357 additions and 45 deletions

View file

@ -20,6 +20,7 @@ import io.element.android.libraries.matrix.api.room.knock.KnockRequest
import io.element.android.libraries.matrix.api.room.location.LiveLocationShare
import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevelsValues
import io.element.android.libraries.matrix.api.room.powerlevels.UserRoleChange
import io.element.android.libraries.matrix.api.room.threads.ThreadsListService
import io.element.android.libraries.matrix.api.roomdirectory.RoomVisibility
import io.element.android.libraries.matrix.api.timeline.Timeline
import io.element.android.libraries.matrix.api.widget.MatrixWidgetDriver
@ -44,6 +45,8 @@ interface JoinedRoom : BaseRoom {
*/
val liveTimeline: Timeline
val threadsListService: ThreadsListService
/**
* Create a new timeline.
* @param createTimelineParams contains parameters about how to filter the timeline. Will also configure the date separators.

View file

@ -0,0 +1,34 @@
/*
* 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.room.threads
import androidx.compose.runtime.Immutable
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.toThreadId
import io.element.android.libraries.matrix.api.timeline.item.event.EventContent
import io.element.android.libraries.matrix.api.timeline.item.event.ProfileDetails
@Immutable
data class ThreadListItem(
val rootEvent: ThreadListItemEvent,
val latestEvent: ThreadListItemEvent?,
val numberOfReplies: Long,
) {
val threadId = rootEvent.eventId.toThreadId()
}
@Immutable
data class ThreadListItemEvent(
val eventId: EventId,
val senderId: UserId,
val senderProfile: ProfileDetails,
val isOwn: Boolean,
val content: EventContent?,
val timestamp: Long,
)

View file

@ -0,0 +1,16 @@
/*
* 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.room.threads
sealed interface ThreadListPaginationStatus {
data class Idle(
val hasMoreToLoad: Boolean,
) : ThreadListPaginationStatus
data object Loading : ThreadListPaginationStatus
}

View file

@ -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.room.threads
import kotlinx.coroutines.flow.Flow
interface ThreadsListService {
fun subscribeToItemUpdates(): Flow<List<ThreadListItem>>
fun subscribeToPaginationUpdates(): Flow<ThreadListPaginationStatus>
suspend fun paginate(): Result<Unit>
suspend fun reset(): Result<Unit>
fun destroy()
}