diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/GetPollsUseCase.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/GetPollsUseCase.kt new file mode 100644 index 0000000000..fa8c6d0aa6 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/GetPollsUseCase.kt @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.roomprofile.polls + +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.emptyFlow +import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.flow.map +import javax.inject.Inject + +class GetPollsUseCase @Inject constructor() { + + fun execute(filter: RoomPollsFilter): Flow> { + // TODO unmock and add unit tests + return when (filter) { + RoomPollsFilter.ACTIVE -> getActivePolls() + RoomPollsFilter.ENDED -> emptyFlow() + }.map { it.sortedByDescending { poll -> poll.creationTimestamp } } + } + + private fun getActivePolls(): Flow> { + return flowOf( + listOf( + PollSummary.ActivePoll( + id = "id1", + // 2022/06/28 UTC+1 + creationTimestamp = 1656367200000, + title = "Which charity would you like to support?" + ), + PollSummary.ActivePoll( + id = "id2", + // 2022/06/26 UTC+1 + creationTimestamp = 1656194400000, + title = "Which sport should the pupils do this year?" + ), + PollSummary.ActivePoll( + id = "id3", + // 2022/06/24 UTC+1 + creationTimestamp = 1656021600000, + title = "What type of food should we have at the party?" + ), + PollSummary.ActivePoll( + id = "id4", + // 2022/06/22 UTC+1 + creationTimestamp = 1655848800000, + title = "What film should we show at the end of the year party?" + ), + ) + ) + } +} diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsAction.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsAction.kt index 9d87f13f14..27753b6d16 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsAction.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsAction.kt @@ -18,4 +18,6 @@ package im.vector.app.features.roomprofile.polls import im.vector.app.core.platform.VectorViewModelAction -sealed class RoomPollsAction : VectorViewModelAction +sealed interface RoomPollsAction : VectorViewModelAction { + data class SetFilter(val filter: RoomPollsFilter) : RoomPollsAction +} diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFilter.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFilter.kt new file mode 100644 index 0000000000..68ebb13f7d --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFilter.kt @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.roomprofile.polls + +enum class RoomPollsFilter { + ACTIVE, + ENDED, +} diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModel.kt index 42278ff976..27ba6679d8 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModel.kt @@ -23,9 +23,13 @@ import dagger.assisted.AssistedInject import im.vector.app.core.di.MavericksAssistedViewModelFactory import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.platform.VectorViewModel +import kotlinx.coroutines.Job +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach class RoomPollsViewModel @AssistedInject constructor( @Assisted initialState: RoomPollsViewState, + private val getPollsUseCase: GetPollsUseCase, ) : VectorViewModel(initialState) { @AssistedFactory @@ -35,7 +39,24 @@ class RoomPollsViewModel @AssistedInject constructor( companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() + private var pollsCollectionJob: Job? = null + + // TODO add unit tests override fun handle(action: RoomPollsAction) { - // do nothing for now + when (action) { + is RoomPollsAction.SetFilter -> handleSetFilter(action.filter) + } + } + + override fun onCleared() { + pollsCollectionJob = null + super.onCleared() + } + + private fun handleSetFilter(filter: RoomPollsFilter) { + pollsCollectionJob?.cancel() + pollsCollectionJob = getPollsUseCase.execute(filter) + .onEach { setState { copy(polls = it) } } + .launchIn(viewModelScope) } } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt index 10518d4b18..ed851a045d 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt @@ -24,9 +24,12 @@ import com.airbnb.mvrx.parentFragmentViewModel import com.airbnb.mvrx.withState import dagger.hilt.android.AndroidEntryPoint import im.vector.app.core.extensions.cleanup +import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.FragmentRoomPollsListBinding import im.vector.app.features.roomprofile.polls.PollSummary +import im.vector.app.features.roomprofile.polls.RoomPollsAction +import im.vector.app.features.roomprofile.polls.RoomPollsFilter import im.vector.app.features.roomprofile.polls.RoomPollsViewModel import javax.inject.Inject @@ -51,7 +54,7 @@ class RoomActivePollsFragment : private fun setupList() { roomActivePollsController.listener = this - views.activePollsList.adapter = roomActivePollsController.adapter + views.activePollsList.configureWith(roomActivePollsController) } override fun onDestroyView() { @@ -64,6 +67,11 @@ class RoomActivePollsFragment : roomActivePollsController.listener = null } + override fun onResume() { + super.onResume() + viewModel.handle(RoomPollsAction.SetFilter(RoomPollsFilter.ACTIVE)) + } + override fun invalidate() = withState(viewModel) { viewState -> renderList(viewState.polls.filterIsInstance(PollSummary.ActivePoll::class.java)) } diff --git a/vector/src/main/res/layout/fragment_room_polls_list.xml b/vector/src/main/res/layout/fragment_room_polls_list.xml index 39add6a298..1aa6625ae5 100644 --- a/vector/src/main/res/layout/fragment_room_polls_list.xml +++ b/vector/src/main/res/layout/fragment_room_polls_list.xml @@ -8,8 +8,9 @@