Do some renaming now that user can select multiple answers per poll

This commit is contained in:
Benoit Marty
2026-08-31 15:45:14 +02:00
parent 0ad3ab1d9d
commit 012c5a1f81
12 changed files with 35 additions and 35 deletions
@@ -52,7 +52,7 @@ sealed interface TimelineEvent {
*/ */
sealed interface TimelineItemPollEvent : TimelineItemEvent sealed interface TimelineItemPollEvent : TimelineItemEvent
data class SelectPollAnswer( data class SendPollResponse(
val pollStartId: EventId, val pollStartId: EventId,
val answerIds: List<String> val answerIds: List<String>
) : TimelineItemPollEvent ) : TimelineItemPollEvent
@@ -201,12 +201,12 @@ class TimelinePresenter(
newEventState.value = NewEventState.None newEventState.value = NewEventState.None
} }
} }
is TimelineEvent.SelectPollAnswer -> sessionCoroutineScope.launch { is TimelineEvent.SendPollResponse -> sessionCoroutineScope.launch {
timelineController.invokeOnCurrentTimeline { timelineController.invokeOnCurrentTimeline {
sendPollResponseAction.execute( sendPollResponseAction.execute(
timeline = this, timeline = this,
pollStartId = event.pollStartId, pollStartId = event.pollStartId,
answerIds = event.answerIds answerIds = event.answerIds,
).onFailure { error -> ).onFailure { error ->
Timber.tag(tag).e(error, "Failed to send poll response") Timber.tag(tag).e(error, "Failed to send poll response")
} }
@@ -26,8 +26,8 @@ fun TimelineItemPollView(
eventSink: (TimelineEvent.TimelineItemPollEvent) -> Unit, eventSink: (TimelineEvent.TimelineItemPollEvent) -> Unit,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
fun onSelectAnswer(pollStartId: EventId, answerIds: List<String>) { fun onSendPollResponse(pollStartId: EventId, answerIds: List<String>) {
eventSink(TimelineEvent.SelectPollAnswer(pollStartId, answerIds)) eventSink(TimelineEvent.SendPollResponse(pollStartId, answerIds))
} }
fun onEndPoll(pollStartId: EventId) { fun onEndPoll(pollStartId: EventId) {
@@ -48,7 +48,7 @@ fun TimelineItemPollView(
isPollEnded = content.isEnded, isPollEnded = content.isEnded,
isPollEditable = content.isEditable, isPollEditable = content.isEditable,
isMine = content.isMine, isMine = content.isMine,
onSelectAnswer = ::onSelectAnswer, onSendPollResponse = ::onSendPollResponse,
onEditPoll = ::onEditPoll, onEditPoll = ::onEditPoll,
onEndPoll = ::onEndPoll, onEndPoll = ::onEndPoll,
modifier = modifier, modifier = modifier,
@@ -951,14 +951,14 @@ class TimelinePresenterTest {
} }
@Test @Test
fun `present - PollAnswerSelected event`() = runTest { fun `present - SendPollResponse event`() = runTest {
val sendPollResponseAction = FakeSendPollResponseAction() val sendPollResponseAction = FakeSendPollResponseAction()
val presenter = createTimelinePresenter( val presenter = createTimelinePresenter(
sendPollResponseAction = sendPollResponseAction, sendPollResponseAction = sendPollResponseAction,
) )
presenter.test { presenter.test {
val initialState = awaitFirstItem() val initialState = awaitFirstItem()
initialState.eventSink.invoke(TimelineEvent.SelectPollAnswer(AN_EVENT_ID, listOf("anAnswerId"))) initialState.eventSink.invoke(TimelineEvent.SendPollResponse(AN_EVENT_ID, listOf("anAnswerId")))
} }
delay(1) delay(1)
sendPollResponseAction.verifyExecutionCount(1) sendPollResponseAction.verifyExecutionCount(1)
@@ -50,7 +50,7 @@ class TimelineItemPollViewTest : RobolectricTest() {
matcher = hasText(answer.text), matcher = hasText(answer.text),
useUnmergedTree = true, useUnmergedTree = true,
).performClick() ).performClick()
eventsRecorder.assertSingle(TimelineEvent.SelectPollAnswer(content.eventId!!, listOf(answer.id))) eventsRecorder.assertSingle(TimelineEvent.SendPollResponse(content.eventId!!, listOf(answer.id)))
} }
@Test @Test
@@ -12,17 +12,17 @@ import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.timeline.Timeline import io.element.android.libraries.matrix.api.timeline.Timeline
/** /**
* Sends the current user's answer to a poll, wrapping the timeline call so the analytics are captured in one place. * Sends the current user's answer(s) to a poll, wrapping the timeline call so the analytics are captured in one place.
*/ */
interface SendPollResponseAction { interface SendPollResponseAction {
/** /**
* @param timeline the timeline the poll lives in. * @param timeline the timeline the poll lives in.
* @param pollStartId the poll start event being answered. * @param pollStartId the poll start event being answered.
* @param answerId the id of the chosen answer. * @param answerIds the ids of the chosen answers.
*/ */
suspend fun execute( suspend fun execute(
timeline: Timeline, timeline: Timeline,
pollStartId: EventId, pollStartId: EventId,
answerIds: List<String> answerIds: List<String>,
): Result<Unit> ): Result<Unit>
} }
@@ -40,7 +40,7 @@ import kotlinx.collections.immutable.ImmutableList
@Composable @Composable
fun PollContentView( fun PollContentView(
state: PollContentState, state: PollContentState,
onSelectAnswer: (pollStartId: EventId, answerIds: List<String>) -> Unit, onSendPollResponse: (pollStartId: EventId, answerIds: List<String>) -> Unit,
onEditPoll: (pollStartId: EventId) -> Unit, onEditPoll: (pollStartId: EventId) -> Unit,
onEndPoll: (pollStartId: EventId) -> Unit, onEndPoll: (pollStartId: EventId) -> Unit,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
@@ -56,7 +56,7 @@ fun PollContentView(
isPollEnded = state.isPollEnded, isPollEnded = state.isPollEnded,
isMine = state.isMine, isMine = state.isMine,
onEditPoll = onEditPoll, onEditPoll = onEditPoll,
onSelectAnswer = onSelectAnswer, onSendPollResponse = onSendPollResponse,
onEndPoll = onEndPoll, onEndPoll = onEndPoll,
modifier = modifier, modifier = modifier,
) )
@@ -73,7 +73,7 @@ fun PollContentView(
isPollEditable: Boolean, isPollEditable: Boolean,
isPollEnded: Boolean, isPollEnded: Boolean,
isMine: Boolean, isMine: Boolean,
onSelectAnswer: (pollStartId: EventId, answerIds: List<String>) -> Unit, onSendPollResponse: (pollStartId: EventId, answerIds: List<String>) -> Unit,
onEditPoll: (pollStartId: EventId) -> Unit, onEditPoll: (pollStartId: EventId) -> Unit,
onEndPoll: (pollStartId: EventId) -> Unit, onEndPoll: (pollStartId: EventId) -> Unit,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
@@ -92,10 +92,10 @@ fun PollContentView(
}.filter { it.isSelected }.map { it.answer.id } }.filter { it.isSelected }.map { it.answer.id }
// Only send the response if the selection count is within the limit // Only send the response if the selection count is within the limit
if (newSelections.size <= maxSelections.toInt()) { if (newSelections.size <= maxSelections.toInt()) {
onSelectAnswer(it, newSelections) onSendPollResponse(it, newSelections)
} }
} else { } else {
onSelectAnswer(it, listOf(pollAnswer.id)) onSendPollResponse(it, listOf(pollAnswer.id))
} }
} }
} }
@@ -238,7 +238,7 @@ internal fun PollContentViewUndisclosedPreview() = ElementPreview {
isPollEnded = false, isPollEnded = false,
isPollEditable = false, isPollEditable = false,
isMine = false, isMine = false,
onSelectAnswer = { _, _ -> }, onSendPollResponse = { _, _ -> },
onEditPoll = {}, onEditPoll = {},
onEndPoll = {}, onEndPoll = {},
) )
@@ -257,7 +257,7 @@ internal fun PollContentViewDisclosedPreview() = ElementPreview {
isPollEnded = false, isPollEnded = false,
isPollEditable = false, isPollEditable = false,
isMine = false, isMine = false,
onSelectAnswer = { _, _ -> }, onSendPollResponse = { _, _ -> },
onEditPoll = {}, onEditPoll = {},
onEndPoll = {}, onEndPoll = {},
) )
@@ -276,7 +276,7 @@ internal fun PollContentViewMultipleSelectionPreview() = ElementPreview {
isPollEnded = false, isPollEnded = false,
isPollEditable = false, isPollEditable = false,
isMine = false, isMine = false,
onSelectAnswer = { _, _ -> }, onSendPollResponse = { _, _ -> },
onEditPoll = {}, onEditPoll = {},
onEndPoll = {}, onEndPoll = {},
) )
@@ -295,7 +295,7 @@ internal fun PollContentViewEndedPreview() = ElementPreview {
isPollEnded = true, isPollEnded = true,
isPollEditable = false, isPollEditable = false,
isMine = false, isMine = false,
onSelectAnswer = { _, _ -> }, onSendPollResponse = { _, _ -> },
onEditPoll = {}, onEditPoll = {},
onEndPoll = {}, onEndPoll = {},
) )
@@ -314,7 +314,7 @@ internal fun PollContentViewCreatorEditablePreview() = ElementPreview {
isPollEnded = false, isPollEnded = false,
isPollEditable = true, isPollEditable = true,
isMine = true, isMine = true,
onSelectAnswer = { _, _ -> }, onSendPollResponse = { _, _ -> },
onEditPoll = {}, onEditPoll = {},
onEndPoll = {}, onEndPoll = {},
) )
@@ -333,7 +333,7 @@ internal fun PollContentViewCreatorPreview() = ElementPreview {
isPollEnded = false, isPollEnded = false,
isPollEditable = false, isPollEditable = false,
isMine = true, isMine = true,
onSelectAnswer = { _, _ -> }, onSendPollResponse = { _, _ -> },
onEditPoll = {}, onEditPoll = {},
onEndPoll = {}, onEndPoll = {},
) )
@@ -352,7 +352,7 @@ internal fun PollContentViewCreatorEndedPreview() = ElementPreview {
isPollEnded = true, isPollEnded = true,
isPollEditable = false, isPollEditable = false,
isMine = true, isMine = true,
onSelectAnswer = { _, _ -> }, onSendPollResponse = { _, _ -> },
onEditPoll = {}, onEditPoll = {},
onEndPoll = {}, onEndPoll = {},
) )
@@ -13,7 +13,7 @@ import io.element.android.libraries.matrix.api.core.EventId
sealed interface PollHistoryEvent { sealed interface PollHistoryEvent {
data object LoadMore : PollHistoryEvent data object LoadMore : PollHistoryEvent
data class SelectPollAnswer(val pollStartId: EventId, val answerIds: List<String>) : PollHistoryEvent data class SendPollResponse(val pollStartId: EventId, val answerIds: List<String>) : PollHistoryEvent
data class EndPoll(val pollStartId: EventId) : PollHistoryEvent data class EndPoll(val pollStartId: EventId) : PollHistoryEvent
data class SelectFilter(val filter: PollHistoryFilter) : PollHistoryEvent data class SelectFilter(val filter: PollHistoryFilter) : PollHistoryEvent
} }
@@ -69,7 +69,7 @@ class PollHistoryPresenter(
is PollHistoryEvent.LoadMore -> { is PollHistoryEvent.LoadMore -> {
coroutineScope.loadMore(timeline) coroutineScope.loadMore(timeline)
} }
is PollHistoryEvent.SelectPollAnswer -> sessionCoroutineScope.launch { is PollHistoryEvent.SendPollResponse -> sessionCoroutineScope.launch {
sendPollResponseAction.execute( sendPollResponseAction.execute(
timeline = timeline, timeline = timeline,
pollStartId = event.pollStartId, pollStartId = event.pollStartId,
@@ -65,8 +65,8 @@ fun PollHistoryView(
state.eventSink(PollHistoryEvent.LoadMore) state.eventSink(PollHistoryEvent.LoadMore)
} }
fun onSelectAnswer(pollStartId: EventId, answerIds: List<String>) { fun onSendPollResponse(pollStartId: EventId, answerIds: List<String>) {
state.eventSink(PollHistoryEvent.SelectPollAnswer(pollStartId, answerIds)) state.eventSink(PollHistoryEvent.SendPollResponse(pollStartId, answerIds))
} }
fun onEndPoll(pollStartId: EventId) { fun onEndPoll(pollStartId: EventId) {
@@ -114,7 +114,7 @@ fun PollHistoryView(
pollHistoryItems = pollHistoryItems, pollHistoryItems = pollHistoryItems,
hasMoreToLoad = state.hasMoreToLoad, hasMoreToLoad = state.hasMoreToLoad,
isLoading = state.isLoading, isLoading = state.isLoading,
onSelectAnswer = ::onSelectAnswer, onSendPollResponse = ::onSendPollResponse,
onEditPoll = onEditPoll, onEditPoll = onEditPoll,
onEndPoll = ::onEndPoll, onEndPoll = ::onEndPoll,
onLoadMore = ::onLoadMore, onLoadMore = ::onLoadMore,
@@ -151,7 +151,7 @@ private fun PollHistoryList(
pollHistoryItems: ImmutableList<PollHistoryItem>, pollHistoryItems: ImmutableList<PollHistoryItem>,
hasMoreToLoad: Boolean, hasMoreToLoad: Boolean,
isLoading: Boolean, isLoading: Boolean,
onSelectAnswer: (pollStartId: EventId, answerIds: List<String>) -> Unit, onSendPollResponse: (pollStartId: EventId, answerIds: List<String>) -> Unit,
onEditPoll: (pollStartId: EventId) -> Unit, onEditPoll: (pollStartId: EventId) -> Unit,
onEndPoll: (pollStartId: EventId) -> Unit, onEndPoll: (pollStartId: EventId) -> Unit,
onLoadMore: () -> Unit, onLoadMore: () -> Unit,
@@ -166,7 +166,7 @@ private fun PollHistoryList(
items(pollHistoryItems) { pollHistoryItem -> items(pollHistoryItems) { pollHistoryItem ->
PollHistoryItemRow( PollHistoryItemRow(
pollHistoryItem = pollHistoryItem, pollHistoryItem = pollHistoryItem,
onSelectAnswer = onSelectAnswer, onSendPollResponse = onSendPollResponse,
onEditPoll = onEditPoll, onEditPoll = onEditPoll,
onEndPoll = onEndPoll, onEndPoll = onEndPoll,
modifier = Modifier.padding(vertical = 8.dp, horizontal = 16.dp) modifier = Modifier.padding(vertical = 8.dp, horizontal = 16.dp)
@@ -222,7 +222,7 @@ private fun LoadMoreButton(isLoading: Boolean, onClick: () -> Unit) {
@Composable @Composable
private fun PollHistoryItemRow( private fun PollHistoryItemRow(
pollHistoryItem: PollHistoryItem, pollHistoryItem: PollHistoryItem,
onSelectAnswer: (pollStartId: EventId, answerIds: List<String>) -> Unit, onSendPollResponse: (pollStartId: EventId, answerIds: List<String>) -> Unit,
onEditPoll: (pollStartId: EventId) -> Unit, onEditPoll: (pollStartId: EventId) -> Unit,
onEndPoll: (pollStartId: EventId) -> Unit, onEndPoll: (pollStartId: EventId) -> Unit,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
@@ -244,7 +244,7 @@ private fun PollHistoryItemRow(
Spacer(modifier = Modifier.height(4.dp)) Spacer(modifier = Modifier.height(4.dp))
PollContentView( PollContentView(
state = pollHistoryItem.state, state = pollHistoryItem.state,
onSelectAnswer = onSelectAnswer, onSendPollResponse = onSendPollResponse,
onEditPoll = onEditPoll, onEditPoll = onEditPoll,
onEndPoll = onEndPoll, onEndPoll = onEndPoll,
) )
@@ -117,7 +117,7 @@ class PollHistoryPresenterTest {
state.eventSink(PollHistoryEvent.EndPoll(AN_EVENT_ID)) state.eventSink(PollHistoryEvent.EndPoll(AN_EVENT_ID))
runCurrent() runCurrent()
endPollAction.verifyExecutionCount(1) endPollAction.verifyExecutionCount(1)
state.eventSink(PollHistoryEvent.SelectPollAnswer(AN_EVENT_ID, listOf("answer"))) state.eventSink(PollHistoryEvent.SendPollResponse(AN_EVENT_ID, listOf("answer")))
runCurrent() runCurrent()
sendPollResponseAction.verifyExecutionCount(1) sendPollResponseAction.verifyExecutionCount(1)
cancelAndConsumeRemainingEvents() cancelAndConsumeRemainingEvents()
@@ -133,7 +133,7 @@ class PollHistoryViewTest : RobolectricTest() {
useUnmergedTree = true, useUnmergedTree = true,
).performClick() ).performClick()
eventsRecorder.assertSingle( eventsRecorder.assertSingle(
PollHistoryEvent.SelectPollAnswer(eventId, listOf(answer.id)) PollHistoryEvent.SendPollResponse(eventId, listOf(answer.id))
) )
} }