Skip to content

Commit

Permalink
Merge pull request element-hq#7886 from vector-im/feature/mna/past-po…
Browse files Browse the repository at this point in the history
…lls-ui

[Poll] Render past polls list of a room (PSG-1029)
  • Loading branch information
mnaturel authored Jan 6, 2023
2 parents b7076a1 + 85cfa43 commit f856142
Show file tree
Hide file tree
Showing 17 changed files with 385 additions and 196 deletions.
1 change: 1 addition & 0 deletions changelog.d/7864.wip
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
[Poll] Render active polls list of a room
[Poll] Render past polls list of a room
2 changes: 2 additions & 0 deletions library/ui-strings/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3193,6 +3193,8 @@
<string name="closed_poll_option_description">Results are only revealed when you end the poll</string>
<string name="room_polls_active">Active polls</string>
<string name="room_polls_active_no_item">There are no active polls in this room</string>
<string name="room_polls_ended">Past polls</string>
<string name="room_polls_ended_no_item">There are no past polls in this room</string>

<!-- Location -->
<string name="location_activity_title_static_sharing">Share location</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,50 +16,99 @@

package im.vector.app.features.roomprofile.polls

import im.vector.app.features.home.room.detail.timeline.item.PollOptionViewState
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: RoomPollsFilterType): Flow<List<PollSummary>> {
fun execute(): Flow<List<PollSummary>> {
// TODO unmock and add unit tests
return when (filter) {
RoomPollsFilterType.ACTIVE -> getActivePolls()
RoomPollsFilterType.ENDED -> emptyFlow()
}.map { it.sortedByDescending { poll -> poll.creationTimestamp } }
return flowOf(getActivePolls() + getEndedPolls())
.map { it.sortedByDescending { poll -> poll.creationTimestamp } }
}

private fun getActivePolls(): Flow<List<PollSummary.ActivePoll>> {
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?"
private fun getActivePolls(): List<PollSummary.ActivePoll> {
return 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?"
),
)
}

private fun getEndedPolls(): List<PollSummary.EndedPoll> {
return listOf(
PollSummary.EndedPoll(
id = "id1-ended",
// 2022/06/28 UTC+1
creationTimestamp = 1656367200000,
title = "Which charity would you like to support?",
totalVotes = 22,
winnerOptions = listOf(
PollOptionViewState.PollEnded(
optionId = "id1",
optionAnswer = "Cancer research",
voteCount = 13,
votePercentage = 13 / 22.0,
isWinner = true,
)
),
PollSummary.ActivePoll(
id = "id3",
// 2022/06/24 UTC+1
creationTimestamp = 1656021600000,
title = "What type of food should we have at the party?"
),
PollSummary.EndedPoll(
id = "id2-ended",
// 2022/06/26 UTC+1
creationTimestamp = 1656194400000,
title = "Where should we do the offsite?",
totalVotes = 92,
winnerOptions = listOf(
PollOptionViewState.PollEnded(
optionId = "id1",
optionAnswer = "Hawaii",
voteCount = 43,
votePercentage = 43 / 92.0,
isWinner = true,
)
),
PollSummary.ActivePoll(
id = "id4",
// 2022/06/22 UTC+1
creationTimestamp = 1655848800000,
title = "What film should we show at the end of the year party?"
),
PollSummary.EndedPoll(
id = "id3-ended",
// 2022/06/24 UTC+1
creationTimestamp = 1656021600000,
title = "What type of food should we have at the party?",
totalVotes = 22,
winnerOptions = listOf(
PollOptionViewState.PollEnded(
optionId = "id1",
optionAnswer = "Brazilian",
voteCount = 13,
votePercentage = 13 / 22.0,
isWinner = true,
)
),
)
),
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,24 @@

package im.vector.app.features.roomprofile.polls

import im.vector.app.features.home.room.detail.timeline.item.PollOptionViewState

sealed interface PollSummary {
val id: String
val creationTimestamp: Long
val title: String

data class ActivePoll(
val id: String,
val creationTimestamp: Long,
val title: String,
override val id: String,
override val creationTimestamp: Long,
override val title: String,
) : PollSummary

data class EndedPoll(
override val id: String,
override val creationTimestamp: Long,
override val title: String,
val totalVotes: Int,
val winnerOptions: List<PollOptionViewState.PollEnded>,
) : PollSummary
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,4 @@ package im.vector.app.features.roomprofile.polls

import im.vector.app.core.platform.VectorViewModelAction

sealed interface RoomPollsAction : VectorViewModelAction {
data class SetFilter(val filter: RoomPollsFilterType) : RoomPollsAction
}
sealed interface RoomPollsAction : VectorViewModelAction
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ class RoomPollsFragment : VectorBaseFragment<FragmentRoomPollsBinding>() {

tabLayoutMediator = TabLayoutMediator(views.roomPollsTabs, views.roomPollsViewPager) { tab, position ->
when (position) {
0 -> tab.text = getString(R.string.room_polls_active)
RoomPollsType.ACTIVE.ordinal -> tab.text = getString(R.string.room_polls_active)
RoomPollsType.ENDED.ordinal -> tab.text = getString(R.string.room_polls_ended)
}
}.also { it.attach() }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,20 @@ package im.vector.app.features.roomprofile.polls
import androidx.fragment.app.Fragment
import androidx.viewpager2.adapter.FragmentStateAdapter
import im.vector.app.features.roomprofile.polls.active.RoomActivePollsFragment
import im.vector.app.features.roomprofile.polls.ended.RoomEndedPollsFragment

class RoomPollsPagerAdapter(
private val fragment: Fragment
) : FragmentStateAdapter(fragment) {

override fun getItemCount() = 1
override fun getItemCount() = RoomPollsType.values().size

override fun createFragment(position: Int): Fragment {
return instantiateFragment(RoomActivePollsFragment::class.java.name)
return when (position) {
RoomPollsType.ACTIVE.ordinal -> instantiateFragment(RoomActivePollsFragment::class.java.name)
RoomPollsType.ENDED.ordinal -> instantiateFragment(RoomEndedPollsFragment::class.java.name)
else -> throw IllegalArgumentException("position should be between 0 and ${itemCount - 1}, while it was $position")
}
}

private fun instantiateFragment(fragmentName: String): Fragment {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

package im.vector.app.features.roomprofile.polls

enum class RoomPollsFilterType {
enum class RoomPollsType {
ACTIVE,
ENDED,
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,13 @@

package im.vector.app.features.roomprofile.polls

import androidx.annotation.VisibleForTesting
import com.airbnb.mvrx.MavericksViewModelFactory
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
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

Expand All @@ -40,24 +38,17 @@ class RoomPollsViewModel @AssistedInject constructor(

companion object : MavericksViewModelFactory<RoomPollsViewModel, RoomPollsViewState> by hiltMavericksViewModelFactory()

@VisibleForTesting
var pollsCollectionJob: Job? = null

override fun handle(action: RoomPollsAction) {
when (action) {
is RoomPollsAction.SetFilter -> handleSetFilter(action.filter)
}
}

override fun onCleared() {
pollsCollectionJob = null
super.onCleared()
init {
observePolls()
}

private fun handleSetFilter(filter: RoomPollsFilterType) {
pollsCollectionJob?.cancel()
pollsCollectionJob = getPollsUseCase.execute(filter)
private fun observePolls() {
getPollsUseCase.execute()
.onEach { setState { copy(polls = it) } }
.launchIn(viewModelScope)
}

override fun handle(action: RoomPollsAction) {
// do nothing for now
}
}

This file was deleted.

Loading

0 comments on commit f856142

Please sign in to comment.