Poll history : use pager to keep scrolling state when switching filter
This commit is contained in:
parent
449c331879
commit
7307e0fb13
6 changed files with 82 additions and 38 deletions
|
|
@ -23,6 +23,5 @@ sealed interface PollHistoryEvents {
|
|||
data object LoadMore : PollHistoryEvents
|
||||
data class PollAnswerSelected(val pollStartId: EventId, val answerId: String) : PollHistoryEvents
|
||||
data class PollEndClicked(val pollStartId: EventId) : PollHistoryEvents
|
||||
data object EditPoll : PollHistoryEvents
|
||||
data class OnFilterSelected(val filter: PollHistoryFilter) : PollHistoryEvents
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ class PollHistoryNode @AssistedInject constructor(
|
|||
PollHistoryView(
|
||||
state = presenter.present(),
|
||||
modifier = modifier,
|
||||
onEditPoll = {},
|
||||
goBack = this::navigateUp,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,6 @@ import io.element.android.libraries.matrix.ui.room.rememberPollHistory
|
|||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
class PollHistoryPresenter @Inject constructor(
|
||||
|
|
@ -82,32 +81,23 @@ class PollHistoryPresenter @Inject constructor(
|
|||
is PollHistoryEvents.PollEndClicked -> appCoroutineScope.launch {
|
||||
endPollAction.execute(pollStartId = event.pollStartId)
|
||||
}
|
||||
PollHistoryEvents.EditPoll -> Unit
|
||||
is PollHistoryEvents.OnFilterSelected -> {
|
||||
activeFilter = event.filter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val currentItems by remember {
|
||||
derivedStateOf {
|
||||
when (activeFilter) {
|
||||
PollHistoryFilter.ONGOING -> pollHistoryItems.ongoing
|
||||
PollHistoryFilter.PAST -> pollHistoryItems.past
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return PollHistoryState(
|
||||
isLoading = isLoading,
|
||||
hasMoreToLoad = paginationState.hasMoreToLoadBackwards,
|
||||
currentItems = currentItems,
|
||||
pollHistoryItems = pollHistoryItems,
|
||||
activeFilter = activeFilter,
|
||||
eventSink = ::handleEvents,
|
||||
)
|
||||
}
|
||||
|
||||
private fun CoroutineScope.loadMore(pollHistory: MatrixTimeline) = launch {
|
||||
Timber.d("LoadMore poll history")
|
||||
pollHistory.paginateBackwards(50, 3)
|
||||
pollHistory.paginateBackwards(200)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,12 +18,21 @@ package io.element.android.features.poll.impl.history
|
|||
|
||||
import io.element.android.features.poll.impl.history.model.PollHistoryFilter
|
||||
import io.element.android.features.poll.impl.history.model.PollHistoryItem
|
||||
import io.element.android.features.poll.impl.history.model.PollHistoryItems
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
||||
data class PollHistoryState(
|
||||
val isLoading: Boolean,
|
||||
val hasMoreToLoad: Boolean,
|
||||
val activeFilter: PollHistoryFilter,
|
||||
val currentItems: ImmutableList<PollHistoryItem>,
|
||||
val pollHistoryItems: PollHistoryItems,
|
||||
val eventSink: (PollHistoryEvents) -> Unit,
|
||||
)
|
||||
) {
|
||||
|
||||
fun pollHistoryForFilter(filter: PollHistoryFilter): ImmutableList<PollHistoryItem> {
|
||||
return when (filter) {
|
||||
PollHistoryFilter.ONGOING -> pollHistoryItems.ongoing
|
||||
PollHistoryFilter.PAST -> pollHistoryItems.past
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import io.element.android.features.poll.api.pollcontent.PollContentState
|
|||
import io.element.android.features.poll.api.pollcontent.aPollContentState
|
||||
import io.element.android.features.poll.impl.history.model.PollHistoryFilter
|
||||
import io.element.android.features.poll.impl.history.model.PollHistoryItem
|
||||
import io.element.android.features.poll.impl.history.model.PollHistoryItems
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
|
|
@ -51,7 +52,9 @@ private fun aPollHistoryState(
|
|||
isLoading = isLoading,
|
||||
hasMoreToLoad = hasMoreToLoad,
|
||||
activeFilter = activeFilter,
|
||||
currentItems = currentItems,
|
||||
pollHistoryItems = PollHistoryItems(
|
||||
ongoing = currentItems,
|
||||
past = currentItems,),
|
||||
eventSink = {},
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package io.element.android.features.poll.impl.history
|
||||
|
||||
import androidx.compose.foundation.BorderStroke
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.consumeWindowInsets
|
||||
|
|
@ -26,11 +27,15 @@ import androidx.compose.foundation.layout.height
|
|||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.foundation.pager.HorizontalPager
|
||||
import androidx.compose.foundation.pager.rememberPagerState
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.SingleChoiceSegmentedButtonRow
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
|
|
@ -50,14 +55,29 @@ import io.element.android.libraries.designsystem.theme.components.Surface
|
|||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
import io.element.android.libraries.designsystem.theme.components.TopAppBar
|
||||
import io.element.android.libraries.matrix.api.core.EventId
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
fun PollHistoryView(
|
||||
state: PollHistoryState,
|
||||
modifier: Modifier = Modifier,
|
||||
onEditPoll: (EventId) -> Unit,
|
||||
goBack: () -> Unit,
|
||||
) {
|
||||
|
||||
fun onLoadMore() {
|
||||
state.eventSink(PollHistoryEvents.LoadMore)
|
||||
}
|
||||
|
||||
fun onAnswerSelected(pollStartId: EventId, answerId: String) {
|
||||
state.eventSink(PollHistoryEvents.PollAnswerSelected(pollStartId, answerId))
|
||||
}
|
||||
|
||||
fun onPollEnd(pollStartId: EventId) {
|
||||
state.eventSink(PollHistoryEvents.PollEndClicked(pollStartId))
|
||||
}
|
||||
|
||||
Scaffold(
|
||||
modifier = modifier,
|
||||
topBar = {
|
||||
|
|
@ -79,6 +99,12 @@ fun PollHistoryView(
|
|||
.padding(padding)
|
||||
.consumeWindowInsets(padding)
|
||||
) {
|
||||
val pagerState = rememberPagerState(state.activeFilter.ordinal, 0f) {
|
||||
PollHistoryFilter.entries.size
|
||||
}
|
||||
LaunchedEffect(state.activeFilter) {
|
||||
pagerState.scrollToPage(state.activeFilter.ordinal)
|
||||
}
|
||||
PollHistoryFilterButtons(
|
||||
activeFilter = state.activeFilter,
|
||||
onFilterSelected = { state.eventSink(PollHistoryEvents.OnFilterSelected(it)) },
|
||||
|
|
@ -86,10 +112,25 @@ fun PollHistoryView(
|
|||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp, vertical = 8.dp),
|
||||
)
|
||||
PollHistoryList(
|
||||
state = state,
|
||||
modifier = Modifier.fillMaxSize()
|
||||
)
|
||||
HorizontalPager(
|
||||
state = pagerState,
|
||||
userScrollEnabled = false,
|
||||
modifier = modifier.fillMaxSize()
|
||||
) { page ->
|
||||
val filter = PollHistoryFilter.entries[page]
|
||||
val pollHistoryItems = state.pollHistoryForFilter(filter)
|
||||
PollHistoryList(
|
||||
pollHistoryItems = pollHistoryItems,
|
||||
hasMoreToLoad = state.hasMoreToLoad,
|
||||
isLoading = state.isLoading,
|
||||
onAnswerSelected = ::onAnswerSelected,
|
||||
onPollEdit = onEditPoll,
|
||||
onPollEnd = ::onPollEnd,
|
||||
onLoadMore = ::onLoadMore,
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -116,36 +157,36 @@ private fun PollHistoryFilterButtons(
|
|||
|
||||
@Composable
|
||||
private fun PollHistoryList(
|
||||
state: PollHistoryState,
|
||||
pollHistoryItems: ImmutableList<PollHistoryItem>,
|
||||
hasMoreToLoad: Boolean,
|
||||
isLoading: Boolean,
|
||||
onAnswerSelected: (pollStartId: EventId, answerId: String) -> Unit,
|
||||
onPollEdit: (pollStartId: EventId) -> Unit,
|
||||
onPollEnd: (pollStartId: EventId) -> Unit,
|
||||
onLoadMore: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val lazyListState = rememberLazyListState()
|
||||
LazyColumn(
|
||||
state = lazyListState,
|
||||
modifier = modifier,
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
items(state.currentItems) { pollHistoryItem ->
|
||||
items(pollHistoryItems) { pollHistoryItem ->
|
||||
PollHistoryItemRow(
|
||||
pollHistoryItem = pollHistoryItem,
|
||||
onAnswerSelected = fun(pollStartId: EventId, answerId: String) {
|
||||
state.eventSink(PollHistoryEvents.PollAnswerSelected(pollStartId, answerId))
|
||||
},
|
||||
onPollEdit = {
|
||||
state.eventSink(PollHistoryEvents.EditPoll)
|
||||
},
|
||||
onPollEnd = {
|
||||
state.eventSink(PollHistoryEvents.PollEndClicked(it))
|
||||
},
|
||||
onAnswerSelected = onAnswerSelected,
|
||||
onPollEdit = onPollEdit,
|
||||
onPollEnd = onPollEnd,
|
||||
modifier = Modifier.padding(vertical = 8.dp, horizontal = 16.dp)
|
||||
)
|
||||
}
|
||||
if (state.hasMoreToLoad) {
|
||||
if (hasMoreToLoad) {
|
||||
item {
|
||||
Button(
|
||||
text = "Load more",
|
||||
showProgress = state.isLoading,
|
||||
onClick = {
|
||||
state.eventSink(PollHistoryEvents.LoadMore)
|
||||
},
|
||||
showProgress = isLoading,
|
||||
onClick = onLoadMore,
|
||||
modifier = Modifier.padding(vertical = 24.dp),
|
||||
)
|
||||
}
|
||||
|
|
@ -190,6 +231,7 @@ internal fun PollHistoryViewPreview(
|
|||
) = ElementPreview {
|
||||
PollHistoryView(
|
||||
state = state,
|
||||
onEditPoll = {},
|
||||
goBack = {},
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue