diff --git a/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryEvents.kt b/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryEvents.kt index d07b6fa24a..edc848da41 100644 --- a/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryEvents.kt +++ b/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryEvents.kt @@ -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 } diff --git a/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryNode.kt b/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryNode.kt index d466a16aef..7107aba344 100644 --- a/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryNode.kt +++ b/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryNode.kt @@ -41,6 +41,7 @@ class PollHistoryNode @AssistedInject constructor( PollHistoryView( state = presenter.present(), modifier = modifier, + onEditPoll = {}, goBack = this::navigateUp, ) } diff --git a/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryPresenter.kt b/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryPresenter.kt index a1f0b81315..ab7392f2db 100644 --- a/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryPresenter.kt +++ b/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryPresenter.kt @@ -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) } } diff --git a/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryState.kt b/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryState.kt index c3b768993f..4d0f351bfd 100644 --- a/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryState.kt +++ b/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryState.kt @@ -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, + val pollHistoryItems: PollHistoryItems, val eventSink: (PollHistoryEvents) -> Unit, -) +) { + + fun pollHistoryForFilter(filter: PollHistoryFilter): ImmutableList { + return when (filter) { + PollHistoryFilter.ONGOING -> pollHistoryItems.ongoing + PollHistoryFilter.PAST -> pollHistoryItems.past + } + } +} diff --git a/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryStateProvider.kt b/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryStateProvider.kt index 24862cd599..6771e034bf 100644 --- a/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryStateProvider.kt +++ b/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryStateProvider.kt @@ -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 = {}, ) diff --git a/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryView.kt b/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryView.kt index 53b3488d46..191aae3b2b 100644 --- a/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryView.kt +++ b/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryView.kt @@ -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, + 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 = {}, ) }