Quickly branch pagination
This commit is contained in:
parent
8f3233e450
commit
9dfd471907
6 changed files with 91 additions and 47 deletions
|
|
@ -8,11 +8,12 @@ import androidx.compose.foundation.interaction.MutableInteractionSource
|
|||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.LazyListState
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.material.ripple.rememberRipple
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
|
|
@ -33,7 +34,14 @@ fun MessagesScreen(roomId: String) {
|
|||
val roomTitle by viewModel.collectAsState(MessagesViewState::roomName)
|
||||
val roomAvatar by viewModel.collectAsState(MessagesViewState::roomAvatar)
|
||||
val timelineItems by viewModel.collectAsState(MessagesViewState::timelineItems)
|
||||
MessagesContent(roomTitle, roomAvatar, timelineItems().orEmpty())
|
||||
val hasMoreToLoad by viewModel.collectAsState(MessagesViewState::hasMoreToLoad)
|
||||
MessagesContent(
|
||||
roomTitle = roomTitle,
|
||||
roomAvatar = roomAvatar,
|
||||
timelineItems = timelineItems().orEmpty(),
|
||||
hasMoreToLoad = hasMoreToLoad,
|
||||
onReachedLoadMore = viewModel::loadMore
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
|
@ -41,6 +49,8 @@ fun MessagesContent(
|
|||
roomTitle: String?,
|
||||
roomAvatar: AvatarData?,
|
||||
timelineItems: List<MatrixTimelineItem>,
|
||||
hasMoreToLoad: Boolean,
|
||||
onReachedLoadMore: () -> Unit,
|
||||
) {
|
||||
LogCompositions(tag = "MessagesScreen", msg = "Content")
|
||||
val lazyListState = rememberLazyListState()
|
||||
|
|
@ -61,7 +71,9 @@ fun MessagesContent(
|
|||
TimelineItems(
|
||||
padding = padding,
|
||||
lazyListState = lazyListState,
|
||||
timelineItems = timelineItems
|
||||
timelineItems = timelineItems,
|
||||
hasMoreToLoad = hasMoreToLoad,
|
||||
onReachedLoadMore = onReachedLoadMore,
|
||||
)
|
||||
}
|
||||
)
|
||||
|
|
@ -71,7 +83,9 @@ fun MessagesContent(
|
|||
fun TimelineItems(
|
||||
padding: PaddingValues,
|
||||
lazyListState: LazyListState,
|
||||
timelineItems: List<MatrixTimelineItem>
|
||||
timelineItems: List<MatrixTimelineItem>,
|
||||
hasMoreToLoad: Boolean,
|
||||
onReachedLoadMore: () -> Unit,
|
||||
) {
|
||||
LazyColumn(
|
||||
modifier = Modifier
|
||||
|
|
@ -82,12 +96,18 @@ fun TimelineItems(
|
|||
verticalArrangement = Arrangement.Bottom,
|
||||
reverseLayout = true
|
||||
) {
|
||||
items(timelineItems) { timelineItem ->
|
||||
itemsIndexed(timelineItems) { index, timelineItem ->
|
||||
TimelineItemRow(timelineItem = timelineItem)
|
||||
}
|
||||
if (hasMoreToLoad) {
|
||||
item {
|
||||
MessagesLoadingMoreIndicator(onReachedLoadMore)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Composable
|
||||
fun TimelineItemRow(
|
||||
timelineItem: MatrixTimelineItem
|
||||
|
|
@ -124,7 +144,7 @@ fun TimelineItemRow(
|
|||
}
|
||||
|
||||
@Composable
|
||||
internal fun MessagesLoadingMoreIndicator() {
|
||||
internal fun MessagesLoadingMoreIndicator(onReachedLoadMore: () -> Unit) {
|
||||
Box(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
|
|
@ -133,6 +153,10 @@ internal fun MessagesLoadingMoreIndicator() {
|
|||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
CircularProgressIndicator(strokeWidth = 2.dp, color = MaterialTheme.colorScheme.primary)
|
||||
LaunchedEffect(Unit) {
|
||||
onReachedLoadMore()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,13 +9,17 @@ import io.element.android.x.features.messages.model.MessagesViewState
|
|||
import io.element.android.x.matrix.MatrixClient
|
||||
import io.element.android.x.matrix.MatrixInstance
|
||||
import io.element.android.x.matrix.room.MatrixRoom
|
||||
import io.element.android.x.matrix.timeline.MatrixTimeline
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
import org.matrix.rustcomponents.sdk.mediaSourceFromUrl
|
||||
|
||||
private const val PAGINATION_COUNT = 50
|
||||
class MessagesViewModel(
|
||||
private val client: MatrixClient,
|
||||
private val room: MatrixRoom,
|
||||
private val timeline: MatrixTimeline,
|
||||
private val initialState: MessagesViewState
|
||||
) :
|
||||
MavericksViewModel<MessagesViewState>(initialState) {
|
||||
|
|
@ -29,7 +33,7 @@ class MessagesViewModel(
|
|||
val matrix = MatrixInstance.getInstance()
|
||||
val client = matrix.activeClient()
|
||||
val room = client.getRoom(state.roomId) ?: return null
|
||||
return MessagesViewModel(client, room, state)
|
||||
return MessagesViewModel(client, room, room.timeline(), state)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -39,7 +43,18 @@ class MessagesViewModel(
|
|||
handleInit()
|
||||
}
|
||||
|
||||
fun loadMore(){
|
||||
viewModelScope.launch {
|
||||
timeline.paginateBackwards(PAGINATION_COUNT)
|
||||
setState { copy(hasMoreToLoad = timeline.hasMoreToLoad) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleInit() {
|
||||
setState {
|
||||
copy(hasMoreToLoad = timeline.hasMoreToLoad)
|
||||
}
|
||||
|
||||
room.syncUpdateFlow()
|
||||
.onEach {
|
||||
val avatarData =
|
||||
|
|
@ -51,7 +66,7 @@ class MessagesViewModel(
|
|||
}
|
||||
}.launchIn(viewModelScope)
|
||||
|
||||
room.timeline().timelineItems()
|
||||
timeline.timelineItems()
|
||||
.execute {
|
||||
copy(timelineItems = it)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,10 +10,15 @@ data class MessagesViewState(
|
|||
val roomId: String,
|
||||
val roomName: String? = null,
|
||||
val roomAvatar: AvatarData? = null,
|
||||
val timelineItems: Async<List<MatrixTimelineItem>> = Uninitialized
|
||||
val timelineItems: Async<List<MatrixTimelineItem>> = Uninitialized,
|
||||
val hasMoreToLoad: Boolean = false,
|
||||
) : MavericksState {
|
||||
|
||||
@Suppress("unused")
|
||||
constructor(roomId: String) : this(roomId = roomId, roomName = null, roomAvatar = null)
|
||||
constructor(roomId: String) : this(
|
||||
roomId = roomId,
|
||||
roomName = null,
|
||||
roomAvatar = null
|
||||
)
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue