Merge pull request #1554 from vector-im/feature/fga/init_pin_unlock

[Pin code] : setup the feature
This commit is contained in:
ganfra 2023-10-13 12:38:41 +02:00 committed by GitHub
commit 5d0eb3d693
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
33 changed files with 881 additions and 32 deletions

View file

@ -16,6 +16,12 @@
package io.element.android.appnav
import android.content.Context
import android.content.ContextWrapper
import androidx.activity.ComponentActivity
import androidx.activity.compose.BackHandler
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalContext
import com.bumble.appyx.navmodel.backstack.BackStack
import com.bumble.appyx.navmodel.backstack.operation.NewRoot
import com.bumble.appyx.navmodel.backstack.operation.Remove
@ -41,3 +47,18 @@ fun <T : Any> BackStack<T>.removeLast(element: T) {
accept(Remove(lastExpectedNavElement.key))
}
@Composable
fun MoveActivityToBackgroundBackHandler(enabled: Boolean = true) {
fun Context.findActivity(): ComponentActivity? = when (this) {
is ComponentActivity -> this
is ContextWrapper -> baseContext.findActivity()
else -> null
}
val context = LocalContext.current
BackHandler(enabled = enabled) {
context.findActivity()?.moveTaskToBack(false)
}
}

View file

@ -50,6 +50,9 @@ import io.element.android.features.ftue.api.state.FtueState
import io.element.android.features.invitelist.api.InviteListEntryPoint
import io.element.android.features.networkmonitor.api.NetworkMonitor
import io.element.android.features.networkmonitor.api.NetworkStatus
import io.element.android.features.pin.api.PinEntryPoint
import io.element.android.features.pin.api.PinState
import io.element.android.features.pin.api.PinStateService
import io.element.android.features.preferences.api.PreferencesEntryPoint
import io.element.android.features.roomlist.api.RoomListEntryPoint
import io.element.android.features.verifysession.api.VerifySessionEntryPoint
@ -90,6 +93,8 @@ class LoggedInFlowNode @AssistedInject constructor(
private val networkMonitor: NetworkMonitor,
private val notificationDrawerManager: NotificationDrawerManager,
private val ftueState: FtueState,
private val pinEntryPoint: PinEntryPoint,
private val pinStateService: PinStateService,
private val matrixClient: MatrixClient,
snackbarDispatcher: SnackbarDispatcher,
) : BackstackNode<LoggedInFlowNode.NavTarget>(
@ -98,7 +103,7 @@ class LoggedInFlowNode @AssistedInject constructor(
savedStateMap = buildContext.savedStateMap,
),
permanentNavModel = PermanentNavModel(
NavTarget.Permanent,
navTargets = setOf(NavTarget.LoggedInPermanent, NavTarget.LockPermanent),
savedStateMap = buildContext.savedStateMap,
),
buildContext = buildContext,
@ -129,9 +134,19 @@ class LoggedInFlowNode @AssistedInject constructor(
backstack.push(NavTarget.Ftue)
}
},
onStop = {
//Counterpart startSync is done in observeSyncStateAndNetworkStatus method.
onResume = {
coroutineScope.launch {
pinStateService.entersForeground()
}
},
onPause = {
coroutineScope.launch {
pinStateService.entersBackground()
}
},
onStop = {
coroutineScope.launch {
//Counterpart startSync is done in observeSyncStateAndNetworkStatus method.
syncService.stopSync()
}
},
@ -167,7 +182,10 @@ class LoggedInFlowNode @AssistedInject constructor(
sealed interface NavTarget : Parcelable {
@Parcelize
data object Permanent : NavTarget
data object LoggedInPermanent : NavTarget
@Parcelize
data object LockPermanent : NavTarget
@Parcelize
data object RoomList : NavTarget
@ -196,9 +214,12 @@ class LoggedInFlowNode @AssistedInject constructor(
override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node {
return when (navTarget) {
NavTarget.Permanent -> {
NavTarget.LoggedInPermanent -> {
createNode<LoggedInNode>(buildContext)
}
NavTarget.LockPermanent -> {
pinEntryPoint.createNode(this, buildContext)
}
NavTarget.RoomList -> {
val callback = object : RoomListEntryPoint.Callback {
override fun onRoomClicked(roomId: RoomId) {
@ -324,17 +345,24 @@ class LoggedInFlowNode @AssistedInject constructor(
@Composable
override fun View(modifier: Modifier) {
Box(modifier = modifier) {
Children(
navModel = backstack,
modifier = Modifier,
// Animate navigation to settings and to a room
transitionHandler = rememberDefaultTransitionHandler(),
)
val isFtueDisplayed by ftueState.shouldDisplayFlow.collectAsState()
if (!isFtueDisplayed) {
PermanentChild(permanentNavModel = permanentNavModel, navTarget = NavTarget.Permanent)
val pinState by pinStateService.pinState.collectAsState()
when (pinState) {
PinState.Unlocked -> {
Children(
navModel = backstack,
modifier = Modifier,
// Animate navigation to settings and to a room
transitionHandler = rememberDefaultTransitionHandler(),
)
val isFtueDisplayed by ftueState.shouldDisplayFlow.collectAsState()
if (!isFtueDisplayed) {
PermanentChild(permanentNavModel = permanentNavModel, navTarget = NavTarget.LoggedInPermanent)
}
}
PinState.Locked -> {
MoveActivityToBackgroundBackHandler()
PermanentChild(permanentNavModel = permanentNavModel, navTarget = NavTarget.LockPermanent)
}
}
}
}

View file

@ -31,7 +31,10 @@ class LoggedInNode @AssistedInject constructor(
@Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>,
private val loggedInPresenter: LoggedInPresenter,
) : Node(buildContext, plugins = plugins) {
) : Node(
buildContext = buildContext,
plugins = plugins
) {
@Composable
override fun View(modifier: Modifier) {