Skip to content

Commit d7f74b7

Browse files
committed
fix: only navigate to home once during QR login
Signed-off-by: Brandon McAnsh <git@bmcreations.dev>
1 parent dc1b7e1 commit d7f74b7

7 files changed

Lines changed: 117 additions & 133 deletions

File tree

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
package com.getcode.navigation.core
2+
3+
import android.annotation.SuppressLint
4+
import androidx.compose.runtime.Composable
5+
import androidx.compose.runtime.ProvidableCompositionLocal
6+
import androidx.compose.runtime.derivedStateOf
7+
import androidx.compose.runtime.getValue
8+
import androidx.compose.runtime.remember
9+
import androidx.compose.runtime.staticCompositionLocalOf
10+
import cafe.adriel.voyager.core.screen.Screen
11+
import cafe.adriel.voyager.core.stack.StackEvent
12+
import cafe.adriel.voyager.navigator.Navigator
13+
import com.getcode.navigation.screens.AppScreen
14+
import timber.log.Timber
15+
16+
val LocalCodeNavigator: ProvidableCompositionLocal<CodeNavigator> =
17+
staticCompositionLocalOf { NavigatorNull() }
18+
19+
class NavigatorNull : CodeNavigator {
20+
override val lastItem: Screen? = null
21+
override val lastModalItem: Screen? = null
22+
override val sheetStackRoot: Screen? = null
23+
override val lastEvent: StackEvent = StackEvent.Idle
24+
override val isVisible: Boolean = false
25+
override val progress: Float = 0f
26+
27+
override var screensNavigator: Navigator? = null
28+
29+
override fun show(screen: Screen) = Unit
30+
31+
override fun hide() = Unit
32+
override fun <T> hideWithResult(result: T) = Unit
33+
34+
override fun push(item: Screen) = Unit
35+
36+
override fun push(items: List<Screen>) = Unit
37+
38+
override fun replace(item: Screen) = Unit
39+
40+
override fun replaceAll(item: Screen, inSheet: Boolean) = Unit
41+
42+
override fun replaceAll(items: List<Screen>, inSheet: Boolean) = Unit
43+
44+
override fun pop(): Boolean = false
45+
override fun <T> popWithResult(result: T) = false
46+
47+
override fun popAll() = Unit
48+
49+
override fun popUntil(predicate: (Screen) -> Boolean): Boolean = false
50+
51+
@Composable
52+
override fun saveableState(
53+
key: String,
54+
screen: Screen?,
55+
content: @Composable () -> Unit
56+
) {
57+
content()
58+
}
59+
60+
}
61+
62+
interface CodeNavigator {
63+
val lastItem: Screen?
64+
val lastModalItem: Screen?
65+
val sheetStackRoot: Screen?
66+
val lastEvent: StackEvent
67+
val isVisible: Boolean
68+
val progress: Float
69+
var screensNavigator: Navigator?
70+
fun show(screen: Screen)
71+
fun hide()
72+
fun <T> hideWithResult(result: T)
73+
infix fun push(item: Screen)
74+
75+
infix fun push(items: List<Screen>)
76+
77+
infix fun replace(item: Screen)
78+
79+
fun replaceAll(item: Screen, inSheet: Boolean = false)
80+
81+
fun replaceAll(items: List<Screen>, inSheet: Boolean = false)
82+
83+
fun pop(): Boolean
84+
fun <T> popWithResult(result: T): Boolean
85+
86+
fun popAll()
87+
88+
infix fun popUntil(predicate: (Screen) -> Boolean): Boolean
89+
90+
@SuppressLint("ComposableNaming")
91+
@Composable
92+
fun saveableState(
93+
key: String,
94+
screen: Screen?,
95+
content: @Composable () -> Unit
96+
)
97+
}

app/src/main/java/com/getcode/navigation/core/Navigator.kt renamed to app/src/main/java/com/getcode/navigation/core/CombinedNavigator.kt

Lines changed: 2 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -1,103 +1,15 @@
11
package com.getcode.navigation.core
22

3-
import android.annotation.SuppressLint
43
import androidx.compose.runtime.Composable
5-
import androidx.compose.runtime.ProvidableCompositionLocal
64
import androidx.compose.runtime.derivedStateOf
75
import androidx.compose.runtime.getValue
86
import androidx.compose.runtime.remember
9-
import androidx.compose.runtime.staticCompositionLocalOf
107
import cafe.adriel.voyager.core.screen.Screen
11-
import cafe.adriel.voyager.core.stack.Stack
128
import cafe.adriel.voyager.core.stack.StackEvent
139
import cafe.adriel.voyager.navigator.Navigator
1410
import com.getcode.navigation.screens.AppScreen
15-
import com.getcode.navigation.screens.ModalContent
1611
import timber.log.Timber
1712

18-
val LocalCodeNavigator: ProvidableCompositionLocal<CodeNavigator> =
19-
staticCompositionLocalOf { NavigatorNull() }
20-
21-
class NavigatorNull : CodeNavigator {
22-
override val lastItem: Screen? = null
23-
override val lastModalItem: Screen? = null
24-
override val sheetStackRoot: Screen? = null
25-
override val lastEvent: StackEvent = StackEvent.Idle
26-
override val isVisible: Boolean = false
27-
override val progress: Float = 0f
28-
29-
override var screensNavigator: Navigator? = null
30-
31-
override fun show(screen: Screen) = Unit
32-
33-
override fun hide() = Unit
34-
override fun <T> hideWithResult(result: T) = Unit
35-
36-
override fun push(item: Screen) = Unit
37-
38-
override fun push(items: List<Screen>) = Unit
39-
40-
override fun replace(item: Screen) = Unit
41-
42-
override fun replaceAll(item: Screen, inSheet: Boolean) = Unit
43-
44-
override fun replaceAll(items: List<Screen>, inSheet: Boolean) = Unit
45-
46-
override fun pop(): Boolean = false
47-
override fun <T> popWithResult(result: T) = false
48-
49-
override fun popAll() = Unit
50-
51-
override fun popUntil(predicate: (Screen) -> Boolean): Boolean = false
52-
53-
@Composable
54-
override fun saveableState(
55-
key: String,
56-
screen: Screen?,
57-
content: @Composable () -> Unit
58-
) {
59-
content()
60-
}
61-
62-
}
63-
64-
interface CodeNavigator {
65-
val lastItem: Screen?
66-
val lastModalItem: Screen?
67-
val sheetStackRoot: Screen?
68-
val lastEvent: StackEvent
69-
val isVisible: Boolean
70-
val progress: Float
71-
var screensNavigator: Navigator?
72-
fun show(screen: Screen)
73-
fun hide()
74-
fun <T> hideWithResult(result: T)
75-
infix fun push(item: Screen)
76-
77-
infix fun push(items: List<Screen>)
78-
79-
infix fun replace(item: Screen)
80-
81-
fun replaceAll(item: Screen, inSheet: Boolean = true)
82-
83-
fun replaceAll(items: List<Screen>, inSheet: Boolean = true)
84-
85-
fun pop(): Boolean
86-
fun <T> popWithResult(result: T): Boolean
87-
88-
fun popAll()
89-
90-
infix fun popUntil(predicate: (Screen) -> Boolean): Boolean
91-
92-
@SuppressLint("ComposableNaming")
93-
@Composable
94-
fun saveableState(
95-
key: String,
96-
screen: Screen?,
97-
content: @Composable () -> Unit
98-
)
99-
}
100-
10113
class CombinedNavigator(
10214
var sheetNavigator: BottomSheetNavigator
10315
) : CodeNavigator {
@@ -169,17 +81,10 @@ class CombinedNavigator(
16981
}
17082

17183
override fun replaceAll(item: Screen, inSheet: Boolean) {
172-
if (isVisible && inSheet) {
173-
sheetNavigator.replaceAll(item)
174-
} else {
175-
if (isVisible) {
176-
hide()
177-
}
178-
screensNavigator?.replaceAll(item)
179-
}
84+
replaceAll(listOf(item), inSheet)
18085
}
18186

182-
override fun replaceAll(items: List<Screen>, inSheet: Boolean) {
87+
override fun replaceAll(items: List<Screen>, inSheet: Boolean,) {
18388
if (isVisible && inSheet) {
18489
sheetNavigator.replaceAll(items)
18590
} else {

app/src/main/java/com/getcode/ui/components/AuthCheck.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,8 @@ private fun Flow<DeeplinkResult>.showLogoutConfirmationIfNeeded(
151151
): Flow<DeeplinkResult> = onEach { (type, screens) ->
152152
if (type is DeeplinkHandler.Type.Login) {
153153
val entropy = (screens.first() as? HomeScreen)?.seed
154-
startupLog("showing logout confirm")
155154
if (entropy != null) {
155+
startupLog("showing logout confirm")
156156
showLogoutMessage(
157157
context = context,
158158
entropyB64 = entropy,

app/src/main/java/com/getcode/view/login/SeedDeepLink.kt

Lines changed: 13 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import androidx.compose.runtime.collectAsState
99
import androidx.compose.runtime.getValue
1010
import androidx.compose.runtime.mutableStateOf
1111
import androidx.compose.runtime.remember
12+
import androidx.compose.runtime.saveable.rememberSaveable
1213
import androidx.compose.runtime.setValue
1314
import androidx.compose.ui.Alignment
1415
import androidx.compose.ui.Modifier
@@ -33,6 +34,7 @@ import com.getcode.ui.components.CodeCircularProgressIndicator
3334
import kotlinx.coroutines.CoroutineScope
3435
import kotlinx.coroutines.Dispatchers
3536
import kotlinx.coroutines.launch
37+
import timber.log.Timber
3638

3739
@Preview
3840
@Composable
@@ -44,9 +46,10 @@ fun SeedDeepLink(
4446
val navigator = LocalCodeNavigator.current
4547
val context = LocalContext.current
4648
val authState by SessionManager.authState.collectAsState()
47-
var isMessageShown by remember { mutableStateOf(false) }
4849

49-
fun navigateMain() = navigator.replaceAll(HomeScreen())
50+
fun navigateMain() {
51+
navigator.replaceAll(HomeScreen())
52+
}
5053
fun navigateLogin() = navigator.replace(LoginScreen())
5154

5255
val onNotificationResult: (Boolean) -> Unit = { isGranted ->
@@ -68,33 +71,12 @@ fun SeedDeepLink(
6871
navigateLogin()
6972
}
7073

71-
fun showLogoutMessage(entropyB64: String) {
72-
if (isMessageShown) return
73-
isMessageShown = true
74-
75-
BottomBarManager.showMessage(
76-
BottomBarManager.BottomBarMessage(
77-
title = context.getString(R.string.subtitle_logoutAndLoginConfirmation),
78-
subtitle = "",
79-
positiveText = context.getString(R.string.action_logIn),
80-
negativeText = context.getString(R.string.action_cancel),
81-
isDismissible = false,
82-
onPositive = {
83-
context.getActivity()?.let { activity ->
84-
CoroutineScope(Dispatchers.IO).launch {
85-
viewModel.logout(activity) {
86-
viewModel.performLogin(navigator, entropyB64)
87-
}
88-
89-
}
90-
}
91-
},
92-
onNegative = { navigateLogin() }
93-
)
94-
)
74+
var authHandled by rememberSaveable {
75+
mutableStateOf(false)
9576
}
9677

9778
LaunchedEffect(authState.isAuthenticated) {
79+
if (authHandled) return@LaunchedEffect
9880
seed
9981
?.let { entropyB58 ->
10082
val entropy: ByteArray
@@ -110,17 +92,17 @@ fun SeedDeepLink(
11092
onError()
11193
return@let
11294
}
113-
val isAuthenticated = authState.isAuthenticated ?: return@LaunchedEffect
11495
val isSame = entropy.toList() == authState.entropyB64?.decodeBase64()?.toList()
96+
Timber.d("seed isAuth=${authState.isAuthenticated}, same=$isSame")
11597
if (isSame) {
11698
notificationPermissionCheck(false)
117-
} else if (isAuthenticated) {
118-
showLogoutMessage(entropyB64)
11999
} else {
120-
try {
121-
viewModel.performLogin(navigator, entropyB64)
100+
authHandled = try {
101+
viewModel.performLogin(navigator, entropyB64, deeplink = true)
102+
true
122103
} catch (e: Exception) {
123104
onError()
105+
false
124106
}
125107
}
126108
} ?: run {

app/src/main/java/com/getcode/view/login/SeedInputViewModel.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ class SeedInputViewModel @Inject constructor(
8383
authManager.logout(activity, onComplete)
8484

8585
@SuppressLint("CheckResult")
86-
fun performLogin(navigator: CodeNavigator, entropyB64: String) {
86+
fun performLogin(navigator: CodeNavigator, entropyB64: String, deeplink: Boolean = false) {
8787
authManager.login(entropyB64)
8888
.subscribeOn(Schedulers.computation())
8989
.doOnSubscribe {
@@ -94,7 +94,7 @@ class SeedInputViewModel @Inject constructor(
9494
.doOnSubscribe {
9595
setState(isLoading = false, isSuccess = true, isContinueEnabled = false)
9696
}
97-
.delay(1L, TimeUnit.SECONDS)
97+
.delay(if (deeplink) 0L else 1L, TimeUnit.SECONDS)
9898
)
9999
.observeOn(AndroidSchedulers.mainThread())
100100
.subscribe(

app/src/main/java/com/getcode/view/main/account/withdraw/AccountWithdrawSummaryViewModel.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ class AccountWithdrawSummaryViewModel @Inject constructor(
113113
)
114114
)
115115

116-
navigator.replaceAll(HomeScreen(), inSheet = false)
116+
navigator.replaceAll(HomeScreen())
117117

118118
uiFlow.value = uiFlow.value.copy(isSuccess = true)
119119
}, {

app/src/main/java/com/getcode/view/main/home/HomeScan.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ private fun BillContainer(
323323
modifier = Modifier.fillMaxSize(),
324324
// camera isn't really usable on an emulator so don't fade in wacky
325325
// camera feed
326-
visible = isEmulator || !isCameraReady,
326+
visible = !isCameraReady,
327327
enter = fadeIn(
328328
animationSpec = tween(AnimationUtils.animationTime)
329329
),

0 commit comments

Comments
 (0)