CreatePollEvents -> CreatePollEvent

This commit is contained in:
Benoit Marty
2025-12-03 18:13:18 +01:00
parent 4afeb6210c
commit 32e2cabae4
5 changed files with 76 additions and 76 deletions

View File

@@ -10,15 +10,15 @@ package io.element.android.features.poll.impl.create
import io.element.android.libraries.matrix.api.poll.PollKind
sealed interface CreatePollEvents {
data object Save : CreatePollEvents
data class Delete(val confirmed: Boolean) : CreatePollEvents
data class SetQuestion(val question: String) : CreatePollEvents
data class SetAnswer(val index: Int, val text: String) : CreatePollEvents
data object AddAnswer : CreatePollEvents
data class RemoveAnswer(val index: Int) : CreatePollEvents
data class SetPollKind(val pollKind: PollKind) : CreatePollEvents
data object NavBack : CreatePollEvents
data object ConfirmNavBack : CreatePollEvents
data object HideConfirmation : CreatePollEvents
sealed interface CreatePollEvent {
data object Save : CreatePollEvent
data class Delete(val confirmed: Boolean) : CreatePollEvent
data class SetQuestion(val question: String) : CreatePollEvent
data class SetAnswer(val index: Int, val text: String) : CreatePollEvent
data object AddAnswer : CreatePollEvent
data class RemoveAnswer(val index: Int) : CreatePollEvent
data class SetPollKind(val pollKind: PollKind) : CreatePollEvent
data object NavBack : CreatePollEvent
data object ConfirmNavBack : CreatePollEvent
data object HideConfirmation : CreatePollEvent
}

View File

@@ -97,9 +97,9 @@ class CreatePollPresenter(
val scope = rememberCoroutineScope()
fun handleEvent(event: CreatePollEvents) {
fun handleEvent(event: CreatePollEvent) {
when (event) {
is CreatePollEvents.Save -> scope.launch {
is CreatePollEvent.Save -> scope.launch {
if (canSave) {
repository.savePoll(
existingPollId = when (mode) {
@@ -123,7 +123,7 @@ class CreatePollPresenter(
Timber.d("Cannot create poll")
}
}
is CreatePollEvents.Delete -> {
is CreatePollEvent.Delete -> {
if (mode !is CreatePollMode.EditPoll) {
return
}
@@ -139,25 +139,25 @@ class CreatePollPresenter(
navigateUp()
}
}
is CreatePollEvents.AddAnswer -> {
is CreatePollEvent.AddAnswer -> {
poll = poll.withNewAnswer()
}
is CreatePollEvents.RemoveAnswer -> {
is CreatePollEvent.RemoveAnswer -> {
poll = poll.withAnswerRemoved(event.index)
}
is CreatePollEvents.SetAnswer -> {
is CreatePollEvent.SetAnswer -> {
poll = poll.withAnswerChanged(event.index, event.text)
}
is CreatePollEvents.SetPollKind -> {
is CreatePollEvent.SetPollKind -> {
poll = poll.copy(isDisclosed = event.pollKind.isDisclosed)
}
is CreatePollEvents.SetQuestion -> {
is CreatePollEvent.SetQuestion -> {
poll = poll.copy(question = event.question)
}
is CreatePollEvents.NavBack -> {
is CreatePollEvent.NavBack -> {
navigateUp()
}
CreatePollEvents.ConfirmNavBack -> {
CreatePollEvent.ConfirmNavBack -> {
val shouldConfirm = isDirty
if (shouldConfirm) {
showBackConfirmation = true
@@ -165,7 +165,7 @@ class CreatePollPresenter(
navigateUp()
}
}
is CreatePollEvents.HideConfirmation -> {
is CreatePollEvent.HideConfirmation -> {
showBackConfirmation = false
showDeleteConfirmation = false
}

View File

@@ -20,7 +20,7 @@ data class CreatePollState(
val pollKind: PollKind,
val showBackConfirmation: Boolean,
val showDeleteConfirmation: Boolean,
val eventSink: (CreatePollEvents) -> Unit,
val eventSink: (CreatePollEvent) -> Unit,
) {
enum class Mode {
New,

View File

@@ -62,21 +62,21 @@ fun CreatePollView(
) {
val coroutineScope = rememberCoroutineScope()
val navBack = { state.eventSink(CreatePollEvents.ConfirmNavBack) }
val navBack = { state.eventSink(CreatePollEvent.ConfirmNavBack) }
BackHandler(onBack = navBack)
if (state.showBackConfirmation) {
SaveChangesDialog(
onSaveClick = { state.eventSink(CreatePollEvents.Save) },
onDiscardClick = { state.eventSink(CreatePollEvents.NavBack) },
onDismiss = { state.eventSink(CreatePollEvents.HideConfirmation) },
onSaveClick = { state.eventSink(CreatePollEvent.Save) },
onDiscardClick = { state.eventSink(CreatePollEvent.NavBack) },
onDismiss = { state.eventSink(CreatePollEvent.HideConfirmation) },
)
}
if (state.showDeleteConfirmation) {
ConfirmationDialog(
title = stringResource(id = R.string.screen_edit_poll_delete_confirmation_title),
content = stringResource(id = R.string.screen_edit_poll_delete_confirmation),
onSubmitClick = { state.eventSink(CreatePollEvents.Delete(confirmed = true)) },
onDismiss = { state.eventSink(CreatePollEvents.HideConfirmation) }
onSubmitClick = { state.eventSink(CreatePollEvent.Delete(confirmed = true)) },
onDismiss = { state.eventSink(CreatePollEvent.HideConfirmation) }
)
}
val questionFocusRequester = remember { FocusRequester() }
@@ -91,7 +91,7 @@ fun CreatePollView(
mode = state.mode,
saveEnabled = state.canSave,
onBackClick = navBack,
onSaveClick = { state.eventSink(CreatePollEvents.Save) }
onSaveClick = { state.eventSink(CreatePollEvent.Save) }
)
},
) { paddingValues ->
@@ -112,7 +112,7 @@ fun CreatePollView(
label = stringResource(id = R.string.screen_create_poll_question_desc),
value = state.question,
onValueChange = {
state.eventSink(CreatePollEvents.SetQuestion(it))
state.eventSink(CreatePollEvent.SetQuestion(it))
},
modifier = Modifier
.focusRequester(questionFocusRequester)
@@ -131,7 +131,7 @@ fun CreatePollView(
TextField(
value = answer.text,
onValueChange = {
state.eventSink(CreatePollEvents.SetAnswer(index, it))
state.eventSink(CreatePollEvent.SetAnswer(index, it))
},
modifier = Modifier
.then(if (isLastItem) Modifier.focusRequester(answerFocusRequester) else Modifier)
@@ -145,7 +145,7 @@ fun CreatePollView(
imageVector = CompoundIcons.Delete(),
contentDescription = stringResource(R.string.screen_create_poll_delete_option_a11y, answer.text),
modifier = Modifier.clickable(answer.canDelete) {
state.eventSink(CreatePollEvents.RemoveAnswer(index))
state.eventSink(CreatePollEvent.RemoveAnswer(index))
},
)
},
@@ -161,7 +161,7 @@ fun CreatePollView(
),
style = ListItemStyle.Primary,
onClick = {
state.eventSink(CreatePollEvents.AddAnswer)
state.eventSink(CreatePollEvent.AddAnswer)
coroutineScope.launch(Dispatchers.Main) {
lazyListState.animateScrollToItem(state.answers.size + 1)
answerFocusRequester.requestFocus()
@@ -181,7 +181,7 @@ fun CreatePollView(
),
onClick = {
state.eventSink(
CreatePollEvents.SetPollKind(
CreatePollEvent.SetPollKind(
if (state.pollKind == PollKind.Disclosed) PollKind.Undisclosed else PollKind.Disclosed
)
)
@@ -191,7 +191,7 @@ fun CreatePollView(
ListItem(
headlineContent = { Text(text = stringResource(id = CommonStrings.action_delete_poll)) },
style = ListItemStyle.Destructive,
onClick = { state.eventSink(CreatePollEvents.Delete(confirmed = false)) },
onClick = { state.eventSink(CreatePollEvent.Delete(confirmed = false)) },
)
}
}

View File

@@ -104,15 +104,15 @@ class CreatePollPresenterTest {
val initial = awaitItem()
assertThat(initial.canSave).isFalse()
initial.eventSink(CreatePollEvents.SetQuestion("A question?"))
initial.eventSink(CreatePollEvent.SetQuestion("A question?"))
val questionSet = awaitItem()
assertThat(questionSet.canSave).isFalse()
questionSet.eventSink(CreatePollEvents.SetAnswer(0, "Answer 1"))
questionSet.eventSink(CreatePollEvent.SetAnswer(0, "Answer 1"))
val answer1Set = awaitItem()
assertThat(answer1Set.canSave).isFalse()
answer1Set.eventSink(CreatePollEvents.SetAnswer(1, "Answer 2"))
answer1Set.eventSink(CreatePollEvent.SetAnswer(1, "Answer 2"))
val answer2Set = awaitItem()
assertThat(answer2Set.canSave).isTrue()
}
@@ -133,11 +133,11 @@ class CreatePollPresenterTest {
presenter.present()
}.test {
val initial = awaitItem()
initial.eventSink(CreatePollEvents.SetQuestion("A question?"))
initial.eventSink(CreatePollEvents.SetAnswer(0, "Answer 1"))
initial.eventSink(CreatePollEvents.SetAnswer(1, "Answer 2"))
initial.eventSink(CreatePollEvent.SetQuestion("A question?"))
initial.eventSink(CreatePollEvent.SetAnswer(0, "Answer 1"))
initial.eventSink(CreatePollEvent.SetAnswer(1, "Answer 2"))
skipItems(3)
initial.eventSink(CreatePollEvents.Save)
initial.eventSink(CreatePollEvent.Save)
delay(1) // Wait for the coroutine to finish
createPollResult.assertions().isCalledOnce()
.with(
@@ -182,10 +182,10 @@ class CreatePollPresenterTest {
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
awaitDefaultItem().eventSink(CreatePollEvents.SetQuestion("A question?"))
awaitItem().eventSink(CreatePollEvents.SetAnswer(0, "Answer 1"))
awaitItem().eventSink(CreatePollEvents.SetAnswer(1, "Answer 2"))
awaitItem().eventSink(CreatePollEvents.Save)
awaitDefaultItem().eventSink(CreatePollEvent.SetQuestion("A question?"))
awaitItem().eventSink(CreatePollEvent.SetAnswer(0, "Answer 1"))
awaitItem().eventSink(CreatePollEvent.SetAnswer(1, "Answer 2"))
awaitItem().eventSink(CreatePollEvent.Save)
delay(1) // Wait for the coroutine to finish
createPollResult.assertions().isCalledOnce()
assertThat(fakeAnalyticsService.capturedEvents).isEmpty()
@@ -210,20 +210,20 @@ class CreatePollPresenterTest {
}.test {
awaitDefaultItem()
awaitPollLoaded().apply {
eventSink(CreatePollEvents.SetQuestion("Changed question"))
eventSink(CreatePollEvent.SetQuestion("Changed question"))
}
awaitItem().apply {
eventSink(CreatePollEvents.SetAnswer(0, "Changed answer 1"))
eventSink(CreatePollEvent.SetAnswer(0, "Changed answer 1"))
}
awaitItem().apply {
eventSink(CreatePollEvents.SetAnswer(1, "Changed answer 2"))
eventSink(CreatePollEvent.SetAnswer(1, "Changed answer 2"))
}
awaitPollLoaded(
newQuestion = "Changed question",
newAnswer1 = "Changed answer 1",
newAnswer2 = "Changed answer 2",
).apply {
eventSink(CreatePollEvents.Save)
eventSink(CreatePollEvent.Save)
}
advanceUntilIdle() // Wait for the coroutine to finish
@@ -275,8 +275,8 @@ class CreatePollPresenterTest {
presenter.present()
}.test {
awaitDefaultItem()
awaitPollLoaded().eventSink(CreatePollEvents.SetAnswer(0, "A"))
awaitPollLoaded(newAnswer1 = "A").eventSink(CreatePollEvents.Save)
awaitPollLoaded().eventSink(CreatePollEvent.SetAnswer(0, "A"))
awaitPollLoaded(newAnswer1 = "A").eventSink(CreatePollEvent.Save)
advanceUntilIdle() // Wait for the coroutine to finish
editPollLambda.assertions().isCalledOnce()
assertThat(fakeAnalyticsService.capturedEvents).isEmpty()
@@ -296,12 +296,12 @@ class CreatePollPresenterTest {
val initial = awaitItem()
assertThat(initial.answers.size).isEqualTo(2)
initial.eventSink(CreatePollEvents.AddAnswer)
initial.eventSink(CreatePollEvent.AddAnswer)
val answerAdded = awaitItem()
assertThat(answerAdded.answers.size).isEqualTo(3)
assertThat(answerAdded.answers[2].text).isEmpty()
initial.eventSink(CreatePollEvents.RemoveAnswer(2))
initial.eventSink(CreatePollEvent.RemoveAnswer(2))
val answerRemoved = awaitItem()
assertThat(answerRemoved.answers.size).isEqualTo(2)
}
@@ -314,7 +314,7 @@ class CreatePollPresenterTest {
presenter.present()
}.test {
val initial = awaitItem()
initial.eventSink(CreatePollEvents.SetQuestion("A question?"))
initial.eventSink(CreatePollEvent.SetQuestion("A question?"))
val questionSet = awaitItem()
assertThat(questionSet.question).isEqualTo("A question?")
}
@@ -327,7 +327,7 @@ class CreatePollPresenterTest {
presenter.present()
}.test {
val initial = awaitItem()
initial.eventSink(CreatePollEvents.SetAnswer(0, "This is answer 1"))
initial.eventSink(CreatePollEvent.SetAnswer(0, "This is answer 1"))
val answerSet = awaitItem()
assertThat(answerSet.answers.first().text).isEqualTo("This is answer 1")
}
@@ -340,7 +340,7 @@ class CreatePollPresenterTest {
presenter.present()
}.test {
val initial = awaitItem()
initial.eventSink(CreatePollEvents.SetPollKind(PollKind.Undisclosed))
initial.eventSink(CreatePollEvent.SetPollKind(PollKind.Undisclosed))
val kindSet = awaitItem()
assertThat(kindSet.pollKind).isEqualTo(PollKind.Undisclosed)
}
@@ -355,10 +355,10 @@ class CreatePollPresenterTest {
val initial = awaitItem()
assertThat(initial.canAddAnswer).isTrue()
repeat(17) {
initial.eventSink(CreatePollEvents.AddAnswer)
initial.eventSink(CreatePollEvent.AddAnswer)
assertThat(awaitItem().canAddAnswer).isTrue()
}
initial.eventSink(CreatePollEvents.AddAnswer)
initial.eventSink(CreatePollEvent.AddAnswer)
assertThat(awaitItem().canAddAnswer).isFalse()
}
}
@@ -371,7 +371,7 @@ class CreatePollPresenterTest {
}.test {
val initial = awaitItem()
assertThat(initial.answers.all { it.canDelete }).isFalse()
initial.eventSink(CreatePollEvents.AddAnswer)
initial.eventSink(CreatePollEvent.AddAnswer)
assertThat(awaitItem().answers.all { it.canDelete }).isTrue()
}
}
@@ -383,7 +383,7 @@ class CreatePollPresenterTest {
presenter.present()
}.test {
val initial = awaitItem()
initial.eventSink(CreatePollEvents.SetAnswer(0, "A".repeat(241)))
initial.eventSink(CreatePollEvent.SetAnswer(0, "A".repeat(241)))
assertThat(awaitItem().answers.first().text.length).isEqualTo(240)
}
}
@@ -396,7 +396,7 @@ class CreatePollPresenterTest {
}.test {
val initial = awaitItem()
assertThat(navUpInvocationsCount).isEqualTo(0)
initial.eventSink(CreatePollEvents.NavBack)
initial.eventSink(CreatePollEvent.NavBack)
assertThat(navUpInvocationsCount).isEqualTo(1)
}
}
@@ -410,7 +410,7 @@ class CreatePollPresenterTest {
val initial = awaitItem()
assertThat(navUpInvocationsCount).isEqualTo(0)
assertThat(initial.showBackConfirmation).isFalse()
initial.eventSink(CreatePollEvents.ConfirmNavBack)
initial.eventSink(CreatePollEvent.ConfirmNavBack)
assertThat(navUpInvocationsCount).isEqualTo(1)
}
}
@@ -422,11 +422,11 @@ class CreatePollPresenterTest {
presenter.present()
}.test {
val initial = awaitItem()
initial.eventSink(CreatePollEvents.SetQuestion("Non blank"))
initial.eventSink(CreatePollEvent.SetQuestion("Non blank"))
assertThat(awaitItem().showBackConfirmation).isFalse()
initial.eventSink(CreatePollEvents.ConfirmNavBack)
initial.eventSink(CreatePollEvent.ConfirmNavBack)
assertThat(awaitItem().showBackConfirmation).isTrue()
initial.eventSink(CreatePollEvents.HideConfirmation)
initial.eventSink(CreatePollEvent.HideConfirmation)
assertThat(awaitItem().showBackConfirmation).isFalse()
assertThat(navUpInvocationsCount).isEqualTo(0)
}
@@ -442,7 +442,7 @@ class CreatePollPresenterTest {
val loaded = awaitPollLoaded()
assertThat(navUpInvocationsCount).isEqualTo(0)
assertThat(loaded.showBackConfirmation).isFalse()
loaded.eventSink(CreatePollEvents.ConfirmNavBack)
loaded.eventSink(CreatePollEvent.ConfirmNavBack)
assertThat(navUpInvocationsCount).isEqualTo(1)
}
}
@@ -455,11 +455,11 @@ class CreatePollPresenterTest {
}.test {
awaitDefaultItem()
val loaded = awaitPollLoaded()
loaded.eventSink(CreatePollEvents.SetQuestion("CHANGED"))
loaded.eventSink(CreatePollEvent.SetQuestion("CHANGED"))
assertThat(awaitItem().showBackConfirmation).isFalse()
loaded.eventSink(CreatePollEvents.ConfirmNavBack)
loaded.eventSink(CreatePollEvent.ConfirmNavBack)
assertThat(awaitItem().showBackConfirmation).isTrue()
loaded.eventSink(CreatePollEvents.HideConfirmation)
loaded.eventSink(CreatePollEvent.HideConfirmation)
assertThat(awaitItem().showBackConfirmation).isFalse()
assertThat(navUpInvocationsCount).isEqualTo(0)
}
@@ -474,7 +474,7 @@ class CreatePollPresenterTest {
presenter.present()
}.test {
awaitDefaultItem()
awaitPollLoaded().eventSink(CreatePollEvents.Delete(confirmed = false))
awaitPollLoaded().eventSink(CreatePollEvent.Delete(confirmed = false))
awaitDeleteConfirmation()
assert(redactEventLambda).isNeverCalled()
}
@@ -489,8 +489,8 @@ class CreatePollPresenterTest {
presenter.present()
}.test {
awaitDefaultItem()
awaitPollLoaded().eventSink(CreatePollEvents.Delete(confirmed = false))
awaitDeleteConfirmation().eventSink(CreatePollEvents.HideConfirmation)
awaitPollLoaded().eventSink(CreatePollEvent.Delete(confirmed = false))
awaitDeleteConfirmation().eventSink(CreatePollEvent.HideConfirmation)
awaitPollLoaded().apply {
assertThat(showDeleteConfirmation).isFalse()
}
@@ -507,8 +507,8 @@ class CreatePollPresenterTest {
presenter.present()
}.test {
awaitDefaultItem()
awaitPollLoaded().eventSink(CreatePollEvents.Delete(confirmed = false))
awaitDeleteConfirmation().eventSink(CreatePollEvents.Delete(confirmed = true))
awaitPollLoaded().eventSink(CreatePollEvent.Delete(confirmed = false))
awaitDeleteConfirmation().eventSink(CreatePollEvent.Delete(confirmed = true))
awaitPollLoaded().apply {
assertThat(showDeleteConfirmation).isFalse()
}