diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeFlowNode.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeFlowNode.kt index 00f285e3f4..b7b05cca87 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeFlowNode.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeFlowNode.kt @@ -269,6 +269,11 @@ class HomeFlowNode( parentNode = this, buildContext = buildContext, inviteData = navTarget.inviteData, + callback = object : DeclineInviteAndBlockEntryPoint.Callback { + override fun onDeclineSuccess() { + backstack.pop() + } + }, ) } is NavTarget.SelectNewOwnersWhenLeavingRoom -> { diff --git a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/DefaultHomeEntryPointTest.kt b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/DefaultHomeEntryPointTest.kt index 8eee8e1ee2..5e8570adec 100644 --- a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/DefaultHomeEntryPointTest.kt +++ b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/DefaultHomeEntryPointTest.kt @@ -11,6 +11,7 @@ package io.element.android.features.home.impl import com.bumble.appyx.core.modality.BuildContext import com.google.common.truth.Truth.assertThat import io.element.android.features.home.api.HomeEntryPoint +import io.element.android.features.invite.test.declineandblock.FakeDeclineInviteAndBlockEntryPoint import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.libraries.matrix.test.FakeMatrixClient @@ -36,7 +37,7 @@ class DefaultHomeEntryPointTest : RobolectricTest() { acceptDeclineInviteView = { _, _, _, _ -> lambdaError() }, directLogoutView = { _ -> lambdaError() }, reportRoomEntryPoint = { _, _, _ -> lambdaError() }, - declineInviteAndBlockUserEntryPoint = { _, _, _ -> lambdaError() }, + declineInviteAndBlockUserEntryPoint = FakeDeclineInviteAndBlockEntryPoint(), changeRoomMemberRolesEntryPoint = { _, _, _, _ -> lambdaError() }, leaveRoomRenderer = { _, _, _ -> lambdaError() }, sessionCoroutineScope = backgroundScope, diff --git a/features/invite/api/src/main/kotlin/io/element/android/features/invite/api/declineandblock/DeclineInviteAndBlockEntryPoint.kt b/features/invite/api/src/main/kotlin/io/element/android/features/invite/api/declineandblock/DeclineInviteAndBlockEntryPoint.kt index 4174d99222..3b9d512d80 100644 --- a/features/invite/api/src/main/kotlin/io/element/android/features/invite/api/declineandblock/DeclineInviteAndBlockEntryPoint.kt +++ b/features/invite/api/src/main/kotlin/io/element/android/features/invite/api/declineandblock/DeclineInviteAndBlockEntryPoint.kt @@ -10,13 +10,19 @@ package io.element.android.features.invite.api.declineandblock import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.node.Node +import com.bumble.appyx.core.plugin.Plugin import io.element.android.features.invite.api.InviteData import io.element.android.libraries.architecture.FeatureEntryPoint -fun interface DeclineInviteAndBlockEntryPoint : FeatureEntryPoint { +interface DeclineInviteAndBlockEntryPoint : FeatureEntryPoint { fun createNode( parentNode: Node, buildContext: BuildContext, inviteData: InviteData, + callback: Callback, ): Node + + interface Callback : Plugin { + fun onDeclineSuccess() + } } diff --git a/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/declineandblock/DeclineAndBlockNode.kt b/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/declineandblock/DeclineAndBlockNode.kt index 2fe5c23088..89a2aaf238 100644 --- a/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/declineandblock/DeclineAndBlockNode.kt +++ b/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/declineandblock/DeclineAndBlockNode.kt @@ -17,7 +17,9 @@ import dev.zacsweers.metro.Assisted import dev.zacsweers.metro.AssistedInject import io.element.android.annotations.ContributesNode import io.element.android.features.invite.api.InviteData +import io.element.android.features.invite.api.declineandblock.DeclineInviteAndBlockEntryPoint import io.element.android.libraries.architecture.NodeInputs +import io.element.android.libraries.architecture.callback import io.element.android.libraries.architecture.inputs import io.element.android.libraries.di.SessionScope @@ -31,6 +33,7 @@ class DeclineAndBlockNode( data class Inputs(val inviteData: InviteData) : NodeInputs private val inviteData = inputs().inviteData + private val callback: DeclineInviteAndBlockEntryPoint.Callback = callback() private val presenter = presenterFactory.create(inviteData) @Composable @@ -39,6 +42,7 @@ class DeclineAndBlockNode( DeclineAndBlockView( state = state, onBackClick = ::navigateUp, + onDeclineSuccess = callback::onDeclineSuccess, modifier = modifier ) } diff --git a/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/declineandblock/DeclineAndBlockView.kt b/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/declineandblock/DeclineAndBlockView.kt index 1d14df024a..841034516e 100644 --- a/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/declineandblock/DeclineAndBlockView.kt +++ b/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/declineandblock/DeclineAndBlockView.kt @@ -46,6 +46,7 @@ import io.element.android.libraries.ui.strings.CommonStrings fun DeclineAndBlockView( state: DeclineAndBlockState, onBackClick: () -> Unit, + onDeclineSuccess: () -> Unit, modifier: Modifier = Modifier, ) { val focusManager = LocalFocusManager.current @@ -53,7 +54,7 @@ fun DeclineAndBlockView( val isDeclining = state.declineAction is AsyncAction.Loading AsyncActionView( async = state.declineAction, - onSuccess = { onBackClick() }, + onSuccess = { onDeclineSuccess() }, errorMessage = { stringResource(CommonStrings.error_unknown) }, onRetry = { state.eventSink(DeclineAndBlockEvents.Decline) }, onErrorDismiss = { state.eventSink(DeclineAndBlockEvents.ClearDeclineAction) } @@ -149,5 +150,6 @@ internal fun DeclineAndBlockViewPreview( DeclineAndBlockView( state = state, onBackClick = {}, + onDeclineSuccess = {}, ) } diff --git a/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/declineandblock/DefaultDeclineAndBlockEntryPoint.kt b/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/declineandblock/DefaultDeclineAndBlockEntryPoint.kt index d6e93fb805..4a5734af45 100644 --- a/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/declineandblock/DefaultDeclineAndBlockEntryPoint.kt +++ b/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/declineandblock/DefaultDeclineAndBlockEntryPoint.kt @@ -22,8 +22,9 @@ class DefaultDeclineAndBlockEntryPoint : DeclineInviteAndBlockEntryPoint { parentNode: Node, buildContext: BuildContext, inviteData: InviteData, + callback: DeclineInviteAndBlockEntryPoint.Callback, ): Node { val inputs = DeclineAndBlockNode.Inputs(inviteData) - return parentNode.createNode(buildContext, plugins = listOf(inputs)) + return parentNode.createNode(buildContext, plugins = listOf(inputs, callback)) } } diff --git a/features/invite/impl/src/test/kotlin/io/element/android/features/invite/impl/declineandblock/DeclineAndBlockViewTest.kt b/features/invite/impl/src/test/kotlin/io/element/android/features/invite/impl/declineandblock/DeclineAndBlockViewTest.kt index 55c31a09d2..5cfb091e82 100644 --- a/features/invite/impl/src/test/kotlin/io/element/android/features/invite/impl/declineandblock/DeclineAndBlockViewTest.kt +++ b/features/invite/impl/src/test/kotlin/io/element/android/features/invite/impl/declineandblock/DeclineAndBlockViewTest.kt @@ -17,6 +17,7 @@ import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performTextInput import androidx.compose.ui.test.v2.runAndroidComposeUiTest import io.element.android.features.invite.impl.R +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.tests.testutils.EnsureNeverCalled import io.element.android.tests.testutils.EventsRecorder @@ -41,6 +42,20 @@ class DeclineAndBlockViewTest : RobolectricTest() { } } + @Test + fun `a successful decline invokes the expected callback`() = runAndroidComposeUiTest { + val eventsRecorder = EventsRecorder(expectEvents = false) + ensureCalledOnce { + setDeclineAndBlockView( + aDeclineAndBlockState( + declineAction = AsyncAction.Success(Unit), + eventSink = eventsRecorder, + ), + onDeclineSuccess = it, + ) + } + } + @Test fun `clicking on decline when enabled emits the expected event`() = runAndroidComposeUiTest { val eventsRecorder = EventsRecorder() @@ -112,11 +127,13 @@ class DeclineAndBlockViewTest : RobolectricTest() { private fun AndroidComposeUiTest.setDeclineAndBlockView( state: DeclineAndBlockState, onBackClick: () -> Unit = EnsureNeverCalled(), + onDeclineSuccess: () -> Unit = EnsureNeverCalled(), ) { setContent { DeclineAndBlockView( state = state, onBackClick = onBackClick, + onDeclineSuccess = onDeclineSuccess, ) } } diff --git a/features/invite/impl/src/test/kotlin/io/element/android/features/invite/impl/declineandblock/DefaultDeclineAndBlockEntryPointTest.kt b/features/invite/impl/src/test/kotlin/io/element/android/features/invite/impl/declineandblock/DefaultDeclineAndBlockEntryPointTest.kt index 13bb13dccf..f09cda2337 100644 --- a/features/invite/impl/src/test/kotlin/io/element/android/features/invite/impl/declineandblock/DefaultDeclineAndBlockEntryPointTest.kt +++ b/features/invite/impl/src/test/kotlin/io/element/android/features/invite/impl/declineandblock/DefaultDeclineAndBlockEntryPointTest.kt @@ -11,7 +11,9 @@ package io.element.android.features.invite.impl.declineandblock import androidx.arch.core.executor.testing.InstantTaskExecutorRule import com.bumble.appyx.core.modality.BuildContext import com.google.common.truth.Truth.assertThat +import io.element.android.features.invite.api.declineandblock.DeclineInviteAndBlockEntryPoint import io.element.android.features.invite.test.anInviteData +import io.element.android.tests.testutils.lambda.lambdaError import io.element.android.tests.testutils.node.TestParentNode import org.junit.Rule import org.junit.Test @@ -31,12 +33,17 @@ class DefaultDeclineAndBlockEntryPointTest { ) } val inviteData = anInviteData() + val callback = object : DeclineInviteAndBlockEntryPoint.Callback { + override fun onDeclineSuccess() = lambdaError() + } val result = entryPoint.createNode( parentNode = parentNode, buildContext = BuildContext.root(null), - inviteData = inviteData + inviteData = inviteData, + callback = callback, ) assertThat(result).isInstanceOf(DeclineAndBlockNode::class.java) assertThat(result.plugins).contains(DeclineAndBlockNode.Inputs(inviteData)) + assertThat(result.plugins).contains(callback) } } diff --git a/features/invite/test/src/main/kotlin/io/element/android/features/invite/test/declineandblock/FakeDeclineInviteAndBlockEntryPoint.kt b/features/invite/test/src/main/kotlin/io/element/android/features/invite/test/declineandblock/FakeDeclineInviteAndBlockEntryPoint.kt index 52d4d17790..19625f1473 100644 --- a/features/invite/test/src/main/kotlin/io/element/android/features/invite/test/declineandblock/FakeDeclineInviteAndBlockEntryPoint.kt +++ b/features/invite/test/src/main/kotlin/io/element/android/features/invite/test/declineandblock/FakeDeclineInviteAndBlockEntryPoint.kt @@ -19,6 +19,7 @@ class FakeDeclineInviteAndBlockEntryPoint : DeclineInviteAndBlockEntryPoint { parentNode: Node, buildContext: BuildContext, inviteData: InviteData, + callback: DeclineInviteAndBlockEntryPoint.Callback, ): Node { lambdaError() } diff --git a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomFlowNode.kt b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomFlowNode.kt index 93f8f53412..493c180731 100644 --- a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomFlowNode.kt +++ b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomFlowNode.kt @@ -69,6 +69,9 @@ class JoinRoomFlowNode( parentNode = this, buildContext = buildContext, inviteData = navTarget.inviteData, + callback = object : DeclineInviteAndBlockEntryPoint.Callback { + override fun onDeclineSuccess() = navigateUp() + }, ) NavTarget.Root -> rootNode(buildContext) } @@ -99,7 +102,7 @@ class JoinRoomFlowNode( acceptDeclineInviteView.Render( state = state.acceptDeclineInviteState, onAcceptInviteSuccess = {}, - onDeclineInviteSuccess = {}, + onDeclineInviteSuccess = { navigateUp() }, modifier = Modifier ) }