Start migrating Anvil KSP to Metro
This commit is contained in:
parent
d4d57b1e21
commit
b76a71ebf5
703 changed files with 3523 additions and 2820 deletions
|
|
@ -10,14 +10,15 @@ package io.element.android.features.verifysession.impl.incoming
|
|||
import com.bumble.appyx.core.modality.BuildContext
|
||||
import com.bumble.appyx.core.node.Node
|
||||
import com.bumble.appyx.core.plugin.Plugin
|
||||
import com.squareup.anvil.annotations.ContributesBinding
|
||||
import dev.zacsweers.metro.ContributesBinding
|
||||
import io.element.android.features.verifysession.api.IncomingVerificationEntryPoint
|
||||
import io.element.android.libraries.architecture.createNode
|
||||
import io.element.android.libraries.di.AppScope
|
||||
import javax.inject.Inject
|
||||
import dev.zacsweers.metro.AppScope
|
||||
import dev.zacsweers.metro.Inject
|
||||
|
||||
@ContributesBinding(AppScope::class)
|
||||
class DefaultIncomingVerificationEntryPoint @Inject constructor() : IncomingVerificationEntryPoint {
|
||||
@Inject
|
||||
class DefaultIncomingVerificationEntryPoint() : IncomingVerificationEntryPoint {
|
||||
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): IncomingVerificationEntryPoint.NodeBuilder {
|
||||
val plugins = ArrayList<Plugin>()
|
||||
|
||||
|
|
|
|||
|
|
@ -13,15 +13,16 @@ import com.bumble.appyx.core.modality.BuildContext
|
|||
import com.bumble.appyx.core.node.Node
|
||||
import com.bumble.appyx.core.plugin.Plugin
|
||||
import com.bumble.appyx.core.plugin.plugins
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedInject
|
||||
import dev.zacsweers.metro.Assisted
|
||||
import dev.zacsweers.metro.Inject
|
||||
import io.element.android.anvilannotations.ContributesNode
|
||||
import io.element.android.features.verifysession.api.IncomingVerificationEntryPoint
|
||||
import io.element.android.libraries.architecture.inputs
|
||||
import io.element.android.libraries.di.SessionScope
|
||||
|
||||
@ContributesNode(SessionScope::class)
|
||||
class IncomingVerificationNode @AssistedInject constructor(
|
||||
@Inject
|
||||
class IncomingVerificationNode(
|
||||
@Assisted buildContext: BuildContext,
|
||||
@Assisted plugins: List<Plugin>,
|
||||
presenterFactory: IncomingVerificationPresenter.Factory,
|
||||
|
|
|
|||
|
|
@ -17,9 +17,9 @@ import androidx.compose.runtime.getValue
|
|||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import com.freeletics.flowredux.compose.rememberStateAndDispatch
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import dev.zacsweers.metro.Assisted
|
||||
import dev.zacsweers.metro.AssistedFactory
|
||||
import dev.zacsweers.metro.Inject
|
||||
import io.element.android.features.verifysession.impl.incoming.IncomingVerificationState.Step
|
||||
import io.element.android.libraries.architecture.Presenter
|
||||
import io.element.android.libraries.dateformatter.api.DateFormatter
|
||||
|
|
@ -38,7 +38,8 @@ import timber.log.Timber
|
|||
import io.element.android.features.verifysession.impl.incoming.IncomingVerificationStateMachine.Event as StateMachineEvent
|
||||
import io.element.android.features.verifysession.impl.incoming.IncomingVerificationStateMachine.State as StateMachineState
|
||||
|
||||
class IncomingVerificationPresenter @AssistedInject constructor(
|
||||
@Inject
|
||||
class IncomingVerificationPresenter(
|
||||
@Assisted private val verificationRequest: VerificationRequest.Incoming,
|
||||
@Assisted private val navigator: IncomingVerificationNavigator,
|
||||
@SessionCoroutineScope private val sessionCoroutineScope: CoroutineScope,
|
||||
|
|
|
|||
|
|
@ -15,10 +15,11 @@ import io.element.android.features.verifysession.impl.util.logReceivedEvents
|
|||
import io.element.android.libraries.matrix.api.verification.SessionVerificationData
|
||||
import io.element.android.libraries.matrix.api.verification.SessionVerificationService
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import javax.inject.Inject
|
||||
import dev.zacsweers.metro.Inject
|
||||
import com.freeletics.flowredux.dsl.State as MachineState
|
||||
|
||||
class IncomingVerificationStateMachine @Inject constructor(
|
||||
@Inject
|
||||
class IncomingVerificationStateMachine(
|
||||
private val sessionVerificationService: SessionVerificationService,
|
||||
) : FlowReduxStateMachine<IncomingVerificationStateMachine.State, IncomingVerificationStateMachine.Event>(
|
||||
initialState = State.Initial(isCancelled = false)
|
||||
|
|
|
|||
|
|
@ -10,14 +10,15 @@ package io.element.android.features.verifysession.impl.outgoing
|
|||
import com.bumble.appyx.core.modality.BuildContext
|
||||
import com.bumble.appyx.core.node.Node
|
||||
import com.bumble.appyx.core.plugin.Plugin
|
||||
import com.squareup.anvil.annotations.ContributesBinding
|
||||
import dev.zacsweers.metro.ContributesBinding
|
||||
import io.element.android.features.verifysession.api.OutgoingVerificationEntryPoint
|
||||
import io.element.android.libraries.architecture.createNode
|
||||
import io.element.android.libraries.di.AppScope
|
||||
import javax.inject.Inject
|
||||
import dev.zacsweers.metro.AppScope
|
||||
import dev.zacsweers.metro.Inject
|
||||
|
||||
@ContributesBinding(AppScope::class)
|
||||
class DefaultOutgoingVerificationEntryPoint @Inject constructor() : OutgoingVerificationEntryPoint {
|
||||
@Inject
|
||||
class DefaultOutgoingVerificationEntryPoint() : OutgoingVerificationEntryPoint {
|
||||
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): OutgoingVerificationEntryPoint.NodeBuilder {
|
||||
val plugins = ArrayList<Plugin>()
|
||||
|
||||
|
|
|
|||
|
|
@ -13,37 +13,38 @@ import com.bumble.appyx.core.modality.BuildContext
|
|||
import com.bumble.appyx.core.node.Node
|
||||
import com.bumble.appyx.core.plugin.Plugin
|
||||
import com.bumble.appyx.core.plugin.plugins
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedInject
|
||||
import dev.zacsweers.metro.Assisted
|
||||
import dev.zacsweers.metro.Inject
|
||||
import io.element.android.anvilannotations.ContributesNode
|
||||
import io.element.android.features.verifysession.api.OutgoingVerificationEntryPoint
|
||||
import io.element.android.libraries.architecture.inputs
|
||||
import io.element.android.libraries.di.SessionScope
|
||||
|
||||
@ContributesNode(SessionScope::class)
|
||||
class OutgoingVerificationNode @AssistedInject constructor(
|
||||
@Inject
|
||||
class OutgoingVerificationNode(
|
||||
@Assisted buildContext: BuildContext,
|
||||
@Assisted plugins: List<Plugin>,
|
||||
presenterFactory: OutgoingVerificationPresenter.Factory,
|
||||
// presenterFactory: OutgoingVerificationPresenter.Factory,
|
||||
) : Node(buildContext, plugins = plugins) {
|
||||
private val callback = plugins<OutgoingVerificationEntryPoint.Callback>().first()
|
||||
|
||||
private val inputs = inputs<OutgoingVerificationEntryPoint.Params>()
|
||||
|
||||
private val presenter = presenterFactory.create(
|
||||
showDeviceVerifiedScreen = inputs.showDeviceVerifiedScreen,
|
||||
verificationRequest = inputs.verificationRequest,
|
||||
)
|
||||
// private val presenter = presenterFactory.create(
|
||||
// showDeviceVerifiedScreen = inputs.showDeviceVerifiedScreen,
|
||||
// verificationRequest = inputs.verificationRequest,
|
||||
// )
|
||||
|
||||
@Composable
|
||||
override fun View(modifier: Modifier) {
|
||||
val state = presenter.present()
|
||||
OutgoingVerificationView(
|
||||
state = state,
|
||||
modifier = modifier,
|
||||
onLearnMoreClick = callback::onLearnMoreAboutEncryption,
|
||||
onFinish = callback::onDone,
|
||||
onBack = callback::onBack,
|
||||
)
|
||||
// val state = presenter.present()
|
||||
// OutgoingVerificationView(
|
||||
// state = state,
|
||||
// modifier = modifier,
|
||||
// onLearnMoreClick = callback::onLearnMoreAboutEncryption,
|
||||
// onFinish = callback::onDone,
|
||||
// onBack = callback::onBack,
|
||||
// )
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,9 +16,9 @@ import androidx.compose.runtime.derivedStateOf
|
|||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import com.freeletics.flowredux.compose.rememberStateAndDispatch
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import dev.zacsweers.metro.Assisted
|
||||
import dev.zacsweers.metro.AssistedFactory
|
||||
import dev.zacsweers.metro.Inject
|
||||
import io.element.android.libraries.architecture.AsyncData
|
||||
import io.element.android.libraries.architecture.Presenter
|
||||
import io.element.android.libraries.matrix.api.encryption.EncryptionService
|
||||
|
|
@ -34,146 +34,147 @@ import timber.log.Timber
|
|||
import io.element.android.features.verifysession.impl.outgoing.OutgoingVerificationStateMachine.Event as StateMachineEvent
|
||||
import io.element.android.features.verifysession.impl.outgoing.OutgoingVerificationStateMachine.State as StateMachineState
|
||||
|
||||
class OutgoingVerificationPresenter @AssistedInject constructor(
|
||||
@Assisted private val showDeviceVerifiedScreen: Boolean,
|
||||
@Assisted private val verificationRequest: VerificationRequest.Outgoing,
|
||||
private val sessionVerificationService: SessionVerificationService,
|
||||
private val encryptionService: EncryptionService,
|
||||
) : Presenter<OutgoingVerificationState> {
|
||||
@AssistedFactory
|
||||
interface Factory {
|
||||
fun create(
|
||||
verificationRequest: VerificationRequest.Outgoing,
|
||||
showDeviceVerifiedScreen: Boolean,
|
||||
): OutgoingVerificationPresenter
|
||||
}
|
||||
|
||||
private val stateMachine = OutgoingVerificationStateMachine(
|
||||
sessionVerificationService = sessionVerificationService,
|
||||
encryptionService = encryptionService,
|
||||
)
|
||||
|
||||
@Composable
|
||||
override fun present(): OutgoingVerificationState {
|
||||
val stateAndDispatch = stateMachine.rememberStateAndDispatch()
|
||||
|
||||
val sessionVerifiedStatus by sessionVerificationService.sessionVerifiedStatus.collectAsState()
|
||||
val step by remember {
|
||||
derivedStateOf {
|
||||
when (verificationRequest) {
|
||||
is VerificationRequest.Outgoing.CurrentSession -> {
|
||||
when (sessionVerifiedStatus) {
|
||||
SessionVerifiedStatus.Unknown -> OutgoingVerificationState.Step.Loading
|
||||
SessionVerifiedStatus.NotVerified -> {
|
||||
stateAndDispatch.state.value.toVerificationStep()
|
||||
}
|
||||
SessionVerifiedStatus.Verified -> {
|
||||
if (stateAndDispatch.state.value != StateMachineState.Initial || showDeviceVerifiedScreen) {
|
||||
// The user has verified the session, we need to show the success screen
|
||||
OutgoingVerificationState.Step.Completed
|
||||
} else {
|
||||
// Automatic verification, which can happen on freshly created account, in this case, skip the screen
|
||||
OutgoingVerificationState.Step.Exit
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
is VerificationRequest.Outgoing.User -> stateAndDispatch.state.value.toVerificationStep()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Start this after observing state machine
|
||||
LaunchedEffect(Unit) {
|
||||
// Force reset, just in case the service was left in a broken state
|
||||
sessionVerificationService.reset(cancelAnyPendingVerificationAttempt = true)
|
||||
|
||||
observeVerificationService()
|
||||
}
|
||||
|
||||
fun handleEvents(event: OutgoingVerificationViewEvents) {
|
||||
Timber.d("Verification user action: ${event::class.simpleName}")
|
||||
when (event) {
|
||||
// Just relay the event to the state machine
|
||||
OutgoingVerificationViewEvents.RequestVerification -> StateMachineEvent.RequestVerification(verificationRequest)
|
||||
OutgoingVerificationViewEvents.StartSasVerification -> StateMachineEvent.StartSasVerification
|
||||
OutgoingVerificationViewEvents.ConfirmVerification -> StateMachineEvent.AcceptChallenge
|
||||
OutgoingVerificationViewEvents.DeclineVerification -> StateMachineEvent.DeclineChallenge
|
||||
OutgoingVerificationViewEvents.Cancel -> StateMachineEvent.Cancel
|
||||
OutgoingVerificationViewEvents.Reset -> StateMachineEvent.Reset
|
||||
}.let { stateMachineEvent ->
|
||||
stateAndDispatch.dispatchAction(stateMachineEvent)
|
||||
}
|
||||
}
|
||||
return OutgoingVerificationState(
|
||||
step = step,
|
||||
request = verificationRequest,
|
||||
eventSink = ::handleEvents,
|
||||
)
|
||||
}
|
||||
|
||||
private fun StateMachineState?.toVerificationStep(): OutgoingVerificationState.Step =
|
||||
when (val machineState = this) {
|
||||
StateMachineState.Initial, null -> {
|
||||
OutgoingVerificationState.Step.Initial
|
||||
}
|
||||
is StateMachineState.RequestingVerification,
|
||||
is StateMachineState.StartingSasVerification,
|
||||
StateMachineState.SasVerificationStarted -> {
|
||||
OutgoingVerificationState.Step.AwaitingOtherDeviceResponse
|
||||
}
|
||||
|
||||
StateMachineState.VerificationRequestAccepted -> {
|
||||
OutgoingVerificationState.Step.Ready
|
||||
}
|
||||
|
||||
is StateMachineState.Canceled -> {
|
||||
OutgoingVerificationState.Step.Canceled
|
||||
}
|
||||
|
||||
is StateMachineState.Verifying -> {
|
||||
val async = when (machineState) {
|
||||
is StateMachineState.Verifying.Replying -> AsyncData.Loading()
|
||||
else -> AsyncData.Uninitialized
|
||||
}
|
||||
OutgoingVerificationState.Step.Verifying(machineState.data, async)
|
||||
}
|
||||
|
||||
StateMachineState.Completed -> {
|
||||
OutgoingVerificationState.Step.Completed
|
||||
}
|
||||
|
||||
StateMachineState.Exit -> {
|
||||
OutgoingVerificationState.Step.Exit
|
||||
}
|
||||
}
|
||||
|
||||
private fun CoroutineScope.observeVerificationService() {
|
||||
sessionVerificationService.verificationFlowState
|
||||
.onEach { Timber.d("Verification flow state: ${it::class.simpleName}") }
|
||||
.onEach { verificationAttemptState ->
|
||||
when (verificationAttemptState) {
|
||||
VerificationFlowState.Initial -> stateMachine.dispatch(StateMachineEvent.Reset)
|
||||
VerificationFlowState.DidAcceptVerificationRequest -> {
|
||||
stateMachine.dispatch(StateMachineEvent.DidAcceptVerificationRequest)
|
||||
}
|
||||
VerificationFlowState.DidStartSasVerification -> {
|
||||
stateMachine.dispatch(StateMachineEvent.DidStartSasVerification)
|
||||
}
|
||||
is VerificationFlowState.DidReceiveVerificationData -> {
|
||||
stateMachine.dispatch(StateMachineEvent.DidReceiveChallenge(verificationAttemptState.data))
|
||||
}
|
||||
VerificationFlowState.DidFinish -> {
|
||||
stateMachine.dispatch(StateMachineEvent.DidAcceptChallenge)
|
||||
}
|
||||
VerificationFlowState.DidCancel -> {
|
||||
stateMachine.dispatch(StateMachineEvent.DidCancel)
|
||||
}
|
||||
VerificationFlowState.DidFail -> {
|
||||
stateMachine.dispatch(StateMachineEvent.DidFail)
|
||||
}
|
||||
}
|
||||
}
|
||||
.launchIn(this)
|
||||
}
|
||||
}
|
||||
//@Inject
|
||||
//class OutgoingVerificationPresenter(
|
||||
// @Assisted private val showDeviceVerifiedScreen: Boolean,
|
||||
// @Assisted private val verificationRequest: VerificationRequest.Outgoing,
|
||||
// private val sessionVerificationService: SessionVerificationService,
|
||||
// private val encryptionService: EncryptionService,
|
||||
//) : Presenter<OutgoingVerificationState> {
|
||||
// @AssistedFactory
|
||||
// interface Factory {
|
||||
// fun create(
|
||||
// verificationRequest: VerificationRequest.Outgoing,
|
||||
// showDeviceVerifiedScreen: Boolean,
|
||||
// ): OutgoingVerificationPresenter
|
||||
// }
|
||||
//
|
||||
// private val stateMachine = OutgoingVerificationStateMachine(
|
||||
// sessionVerificationService = sessionVerificationService,
|
||||
// encryptionService = encryptionService,
|
||||
// )
|
||||
//
|
||||
// @Composable
|
||||
// override fun present(): OutgoingVerificationState {
|
||||
// val stateAndDispatch = stateMachine.rememberStateAndDispatch()
|
||||
//
|
||||
// val sessionVerifiedStatus by sessionVerificationService.sessionVerifiedStatus.collectAsState()
|
||||
// val step by remember {
|
||||
// derivedStateOf {
|
||||
// when (verificationRequest) {
|
||||
// is VerificationRequest.Outgoing.CurrentSession -> {
|
||||
// when (sessionVerifiedStatus) {
|
||||
// SessionVerifiedStatus.Unknown -> OutgoingVerificationState.Step.Loading
|
||||
// SessionVerifiedStatus.NotVerified -> {
|
||||
// stateAndDispatch.state.value.toVerificationStep()
|
||||
// }
|
||||
// SessionVerifiedStatus.Verified -> {
|
||||
// if (stateAndDispatch.state.value != StateMachineState.Initial || showDeviceVerifiedScreen) {
|
||||
// // The user has verified the session, we need to show the success screen
|
||||
// OutgoingVerificationState.Step.Completed
|
||||
// } else {
|
||||
// // Automatic verification, which can happen on freshly created account, in this case, skip the screen
|
||||
// OutgoingVerificationState.Step.Exit
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// is VerificationRequest.Outgoing.User -> stateAndDispatch.state.value.toVerificationStep()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // Start this after observing state machine
|
||||
// LaunchedEffect(Unit) {
|
||||
// // Force reset, just in case the service was left in a broken state
|
||||
// sessionVerificationService.reset(cancelAnyPendingVerificationAttempt = true)
|
||||
//
|
||||
// observeVerificationService()
|
||||
// }
|
||||
//
|
||||
// fun handleEvents(event: OutgoingVerificationViewEvents) {
|
||||
// Timber.d("Verification user action: ${event::class.simpleName}")
|
||||
// when (event) {
|
||||
// // Just relay the event to the state machine
|
||||
// OutgoingVerificationViewEvents.RequestVerification -> StateMachineEvent.RequestVerification(verificationRequest)
|
||||
// OutgoingVerificationViewEvents.StartSasVerification -> StateMachineEvent.StartSasVerification
|
||||
// OutgoingVerificationViewEvents.ConfirmVerification -> StateMachineEvent.AcceptChallenge
|
||||
// OutgoingVerificationViewEvents.DeclineVerification -> StateMachineEvent.DeclineChallenge
|
||||
// OutgoingVerificationViewEvents.Cancel -> StateMachineEvent.Cancel
|
||||
// OutgoingVerificationViewEvents.Reset -> StateMachineEvent.Reset
|
||||
// }.let { stateMachineEvent ->
|
||||
// stateAndDispatch.dispatchAction(stateMachineEvent)
|
||||
// }
|
||||
// }
|
||||
// return OutgoingVerificationState(
|
||||
// step = step,
|
||||
// request = verificationRequest,
|
||||
// eventSink = ::handleEvents,
|
||||
// )
|
||||
// }
|
||||
//
|
||||
// private fun StateMachineState?.toVerificationStep(): OutgoingVerificationState.Step =
|
||||
// when (val machineState = this) {
|
||||
// StateMachineState.Initial, null -> {
|
||||
// OutgoingVerificationState.Step.Initial
|
||||
// }
|
||||
// is StateMachineState.RequestingVerification,
|
||||
// is StateMachineState.StartingSasVerification,
|
||||
// StateMachineState.SasVerificationStarted -> {
|
||||
// OutgoingVerificationState.Step.AwaitingOtherDeviceResponse
|
||||
// }
|
||||
//
|
||||
// StateMachineState.VerificationRequestAccepted -> {
|
||||
// OutgoingVerificationState.Step.Ready
|
||||
// }
|
||||
//
|
||||
// is StateMachineState.Canceled -> {
|
||||
// OutgoingVerificationState.Step.Canceled
|
||||
// }
|
||||
//
|
||||
// is StateMachineState.Verifying -> {
|
||||
// val async = when (machineState) {
|
||||
// is StateMachineState.Verifying.Replying -> AsyncData.Loading()
|
||||
// else -> AsyncData.Uninitialized
|
||||
// }
|
||||
// OutgoingVerificationState.Step.Verifying(machineState.data, async)
|
||||
// }
|
||||
//
|
||||
// StateMachineState.Completed -> {
|
||||
// OutgoingVerificationState.Step.Completed
|
||||
// }
|
||||
//
|
||||
// StateMachineState.Exit -> {
|
||||
// OutgoingVerificationState.Step.Exit
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private fun CoroutineScope.observeVerificationService() {
|
||||
// sessionVerificationService.verificationFlowState
|
||||
// .onEach { Timber.d("Verification flow state: ${it::class.simpleName}") }
|
||||
// .onEach { verificationAttemptState ->
|
||||
// when (verificationAttemptState) {
|
||||
// VerificationFlowState.Initial -> stateMachine.dispatch(StateMachineEvent.Reset)
|
||||
// VerificationFlowState.DidAcceptVerificationRequest -> {
|
||||
// stateMachine.dispatch(StateMachineEvent.DidAcceptVerificationRequest)
|
||||
// }
|
||||
// VerificationFlowState.DidStartSasVerification -> {
|
||||
// stateMachine.dispatch(StateMachineEvent.DidStartSasVerification)
|
||||
// }
|
||||
// is VerificationFlowState.DidReceiveVerificationData -> {
|
||||
// stateMachine.dispatch(StateMachineEvent.DidReceiveChallenge(verificationAttemptState.data))
|
||||
// }
|
||||
// VerificationFlowState.DidFinish -> {
|
||||
// stateMachine.dispatch(StateMachineEvent.DidAcceptChallenge)
|
||||
// }
|
||||
// VerificationFlowState.DidCancel -> {
|
||||
// stateMachine.dispatch(StateMachineEvent.DidCancel)
|
||||
// }
|
||||
// VerificationFlowState.DidFail -> {
|
||||
// stateMachine.dispatch(StateMachineEvent.DidFail)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// .launchIn(this)
|
||||
// }
|
||||
//}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue