Skip to content

Commit eeacfa2

Browse files
committed
Flow base logic revamp to avoid overlapping parameters + session expiration support
1 parent c379888 commit eeacfa2

22 files changed

+725
-420
lines changed

app/src/main/java/com/sap/cdc/bitsnbytes/cdc/IdentityServiceRepository.kt

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,9 @@ import com.sap.cdc.android.sdk.auth.provider.WebAuthenticationProvider
1212
import com.sap.cdc.android.sdk.auth.session.Session
1313
import com.sap.cdc.android.sdk.auth.session.SessionSecureLevel
1414
import com.sap.cdc.android.sdk.core.SiteConfig
15+
import com.sap.cdc.android.sdk.screensets.WebBridgeJS
1516
import com.sap.cdc.bitsnbytes.social.FacebookAuthenticationProvider
1617
import com.sap.cdc.bitsnbytes.social.GoogleAuthenticationProvider
17-
import com.sap.cdc.bitsnbytes.social.LineAuthenticationProvider
18-
import com.sap.cdc.bitsnbytes.social.WeChatAuthenticationProvider
19-
import com.sap.cdc.android.sdk.screensets.WebBridgeJS
2018

2119
/**
2220
* Created by Tal Mirmelshtein on 10/06/2024
@@ -142,7 +140,7 @@ class IdentityServiceRepository private constructor(context: Context) {
142140
* Initiate cdc SDK credentials login.
143141
*/
144142
suspend fun login(email: String, password: String): IAuthResponse {
145-
val params = mutableMapOf("loginID" to email, "password" to password)
143+
val params = mutableMapOf("loginID" to email, "password" to password, "sessionExpiration" to "30")
146144
return authenticationService.authenticate().login(params)
147145
}
148146

app/src/main/java/com/sap/cdc/bitsnbytes/ui/activity/MainActivity.kt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ import androidx.compose.ui.Modifier
99
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
1010
import androidx.fragment.app.FragmentActivity
1111
import androidx.lifecycle.lifecycleScope
12+
import com.sap.cdc.android.sdk.CDCDebuggable
13+
import com.sap.cdc.android.sdk.CDCMessageEventBus
14+
import com.sap.cdc.android.sdk.SessionEvent
15+
import com.sap.cdc.bitsnbytes.ui.route.NavigationCoordinator
16+
import com.sap.cdc.bitsnbytes.ui.route.ProfileScreenRoute
1217
import com.sap.cdc.bitsnbytes.ui.theme.AppTheme
1318
import com.sap.cdc.bitsnbytes.ui.view.flow.HomeScaffoldView
1419
import kotlinx.coroutines.launch
@@ -40,6 +45,22 @@ class MainActivity : FragmentActivity() {
4045
}
4146
}
4247
}
48+
49+
CDCMessageEventBus.subscribeToSessionEvents {
50+
when (it) {
51+
is SessionEvent.ExpiredSession -> {
52+
CDCDebuggable.log("MainActivity", "Invalidate session event received from bus.")
53+
NavigationCoordinator.INSTANCE.popToRootAndNavigate(
54+
toRoute = ProfileScreenRoute.Welcome.route,
55+
rootRoute = ProfileScreenRoute.Welcome.route
56+
)
57+
}
58+
59+
is SessionEvent.VerifySession -> {
60+
// Verify session
61+
}
62+
}
63+
}
4364
}
4465
}
4566

app/src/main/java/com/sap/cdc/bitsnbytes/ui/route/NavigationCoordinator.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,10 @@ class NavigationCoordinator private constructor() {
3737
* Navigate to new route.
3838
*/
3939
fun navigate(route: String) {
40-
currentNavController?.navigate(route)
40+
currentNavController?.navigate(route) {
41+
launchSingleTop = true
42+
restoreState = true
43+
}
4144
// Update back stack custom state.
4245
_backNav.value = currentNavController?.previousBackStackEntry != null
4346
}

app/src/main/java/com/sap/cdc/bitsnbytes/ui/route/NavigationHosts.kt

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,16 @@ import com.sap.cdc.bitsnbytes.ui.view.flow.RegisterView
2424
import com.sap.cdc.bitsnbytes.ui.view.flow.ScreenSetView
2525
import com.sap.cdc.bitsnbytes.ui.view.flow.SignInView
2626
import com.sap.cdc.bitsnbytes.ui.view.flow.WelcomeView
27-
import com.sap.cdc.bitsnbytes.ui.viewmodel.AboutMeViewModel
2827
import com.sap.cdc.bitsnbytes.ui.viewmodel.EmailRegisterViewModel
2928
import com.sap.cdc.bitsnbytes.ui.viewmodel.EmailSignInViewModel
3029
import com.sap.cdc.bitsnbytes.ui.viewmodel.LinkAccountViewModel
3130
import com.sap.cdc.bitsnbytes.ui.viewmodel.LoginOptionsViewModel
32-
import com.sap.cdc.bitsnbytes.ui.viewmodel.MyProfileViewModel
3331
import com.sap.cdc.bitsnbytes.ui.viewmodel.OtpSignInViewModel
3432
import com.sap.cdc.bitsnbytes.ui.viewmodel.OtpVerifyViewModel
3533
import com.sap.cdc.bitsnbytes.ui.viewmodel.PendingRegistrationViewModel
3634
import com.sap.cdc.bitsnbytes.ui.viewmodel.RegisterViewModel
3735
import com.sap.cdc.bitsnbytes.ui.viewmodel.ScreenSetViewModel
3836
import com.sap.cdc.bitsnbytes.ui.viewmodel.SignInViewModel
39-
import com.sap.cdc.bitsnbytes.ui.viewmodel.WelcomeViewModel
4037
import kotlinx.serialization.json.Json
4138

4239
/**
@@ -107,7 +104,7 @@ fun ProfileNavHost() {
107104
}
108105
) {
109106
composable(ProfileScreenRoute.Welcome.route) {
110-
WelcomeView(viewModel = WelcomeViewModel(LocalContext.current))
107+
WelcomeView()
111108
}
112109
composable(ProfileScreenRoute.SignIn.route) {
113110
SignInView(viewModel = SignInViewModel(LocalContext.current))
@@ -142,10 +139,10 @@ fun ProfileNavHost() {
142139
)
143140
}
144141
composable(ProfileScreenRoute.MyProfile.route) {
145-
MyProfileView(viewModel = MyProfileViewModel(LocalContext.current))
142+
MyProfileView()
146143
}
147144
composable(ProfileScreenRoute.AboutMe.route) {
148-
AboutMeView(viewModel = AboutMeViewModel(LocalContext.current))
145+
AboutMeView()
149146
}
150147
composable(ScreenSetsRoute.ScreenSetRegistrationLoginLogin.route) {
151148
ScreenSetView(

app/src/main/java/com/sap/cdc/bitsnbytes/ui/view/custom/LoadingStateColumn.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import androidx.compose.foundation.layout.Box
55
import androidx.compose.foundation.layout.Column
66
import androidx.compose.foundation.layout.fillMaxHeight
77
import androidx.compose.foundation.layout.fillMaxWidth
8+
import androidx.compose.foundation.layout.imePadding
89
import androidx.compose.runtime.Composable
910
import androidx.compose.ui.Alignment
1011
import androidx.compose.ui.Modifier
@@ -18,6 +19,7 @@ fun LoadingStateColumn(
1819
content: @Composable () -> Unit
1920
) {
2021
Box(
22+
modifier = Modifier.background(Color.White).imePadding(),
2123
contentAlignment = Alignment.TopCenter,
2224
) {
2325
Column(

app/src/main/java/com/sap/cdc/bitsnbytes/ui/view/flow/AboutMeView.kt

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,18 @@ import androidx.compose.runtime.setValue
1818
import androidx.compose.ui.Alignment
1919
import androidx.compose.ui.Modifier
2020
import androidx.compose.ui.graphics.Color
21+
import androidx.compose.ui.platform.LocalContext
2122
import androidx.compose.ui.tooling.preview.Preview
2223
import androidx.compose.ui.unit.dp
24+
import androidx.lifecycle.viewmodel.compose.viewModel
2325
import com.sap.cdc.bitsnbytes.ui.theme.AppTheme
2426
import com.sap.cdc.bitsnbytes.ui.view.custom.ActionOutlineInverseButton
2527
import com.sap.cdc.bitsnbytes.ui.view.custom.IndeterminateLinearIndicator
2628
import com.sap.cdc.bitsnbytes.ui.view.custom.SimpleErrorMessages
2729
import com.sap.cdc.bitsnbytes.ui.view.custom.TitledText
2830
import com.sap.cdc.bitsnbytes.ui.view.custom.UpdatableEditBox
29-
import com.sap.cdc.bitsnbytes.ui.viewmodel.AboutMeViewModelPreview
30-
import com.sap.cdc.bitsnbytes.ui.viewmodel.IAboutMeViewModel
31+
import com.sap.cdc.bitsnbytes.ui.viewmodel.AccountViewModel
32+
import com.sap.cdc.bitsnbytes.ui.viewmodel.factory.CustomViewModelFactory
3133

3234

3335
/**
@@ -39,7 +41,10 @@ import com.sap.cdc.bitsnbytes.ui.viewmodel.IAboutMeViewModel
3941
*/
4042

4143
@Composable
42-
fun AboutMeView(viewModel: IAboutMeViewModel) {
44+
fun AboutMeView() {
45+
val viewModel: AccountViewModel = viewModel(
46+
factory = CustomViewModelFactory(LocalContext.current)
47+
)
4348

4449
var loading by remember { mutableStateOf(false) }
4550
var setError by remember { mutableStateOf("") }
@@ -136,7 +141,7 @@ fun AboutMeView(viewModel: IAboutMeViewModel) {
136141
@Composable
137142
fun AboutMeViewPreview() {
138143
AppTheme {
139-
AboutMeView(viewModel = AboutMeViewModelPreview())
144+
AboutMeView()
140145
}
141146
}
142147

app/src/main/java/com/sap/cdc/bitsnbytes/ui/view/flow/EmailRegisterView.kt

Lines changed: 94 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
package com.sap.cdc.bitsnbytes.ui.view.flow
22

3-
import androidx.compose.foundation.layout.Column
3+
import androidx.compose.animation.core.tween
44
import androidx.compose.foundation.layout.fillMaxWidth
55
import androidx.compose.foundation.layout.padding
66
import androidx.compose.foundation.rememberScrollState
77
import androidx.compose.foundation.verticalScroll
88
import androidx.compose.material3.Text
99
import androidx.compose.runtime.Composable
10+
import androidx.compose.runtime.LaunchedEffect
1011
import androidx.compose.runtime.derivedStateOf
1112
import androidx.compose.runtime.getValue
1213
import androidx.compose.runtime.mutableStateOf
@@ -70,7 +71,9 @@ fun EmailRegisterView(viewModel: IEmailRegisterViewModel) {
7071
// UI elements.
7172

7273
LoadingStateColumn(
73-
modifier = Modifier.verticalScroll(rememberScrollState()),
74+
modifier = Modifier
75+
.verticalScroll(rememberScrollState())
76+
.padding(48.dp),
7477
loading = loading
7578
) {
7679

@@ -80,106 +83,103 @@ fun EmailRegisterView(viewModel: IEmailRegisterViewModel) {
8083
Text("Please fill out the listed inputs", fontSize = 16.sp, fontWeight = FontWeight.Light)
8184
MediumVerticalSpacer()
8285

83-
Column(
84-
modifier = Modifier
85-
.padding(start = 48.dp, end = 48.dp)
86-
) {
87-
// Name Input.
88-
SmallVerticalSpacer()
89-
OutlineTitleAndEditTextField(
90-
titleText = "Name: *",
91-
inputText = name,
92-
placeholderText = "Name placeholder",
93-
onValueChange = {
94-
name = it
95-
},
96-
focusManager = focusManager
97-
)
98-
99-
// Email input.
100-
SmallVerticalSpacer()
101-
OutlineTitleAndEditTextField(
102-
titleText = "Email: *",
103-
inputText = email,
104-
placeholderText = "Email placeholder",
105-
onValueChange = {
106-
email = it
107-
},
108-
focusManager = focusManager
109-
)
110-
111-
// Password input.
112-
SmallVerticalSpacer()
113-
OutlineTitleAndEditPasswordTextField(
114-
titleText = "Password: *",
115-
inputText = password,
116-
placeholderText = "",
117-
passwordVisible = passwordVisible,
118-
onValueChange = {
119-
password = it
120-
},
121-
onEyeClick = { passwordVisible = it },
122-
focusManager = focusManager
123-
)
12486

125-
// Confirm password input.
126-
SmallVerticalSpacer()
127-
OutlineTitleAndEditPasswordTextField(
128-
titleText = "Confirm password: *",
129-
inputText = confirmPassword,
130-
placeholderText = "",
131-
passwordVisible = passwordVisible,
132-
onValueChange = {
133-
confirmPassword = it
134-
},
135-
onEyeClick = { passwordVisible = it },
136-
focusManager = focusManager
137-
)
138-
139-
if (isNotMatching.value) {
140-
PasswordNotMatchingError()
141-
}
87+
// Name Input.
88+
SmallVerticalSpacer()
89+
OutlineTitleAndEditTextField(
90+
titleText = "Name: *",
91+
inputText = name,
92+
placeholderText = "Name placeholder",
93+
onValueChange = {
94+
name = it
95+
},
96+
focusManager = focusManager
97+
)
98+
99+
// Email input.
100+
SmallVerticalSpacer()
101+
OutlineTitleAndEditTextField(
102+
titleText = "Email: *",
103+
inputText = email,
104+
placeholderText = "Email placeholder",
105+
onValueChange = {
106+
email = it
107+
},
108+
focusManager = focusManager
109+
)
110+
111+
// Password input.
112+
SmallVerticalSpacer()
113+
OutlineTitleAndEditPasswordTextField(
114+
titleText = "Password: *",
115+
inputText = password,
116+
placeholderText = "",
117+
passwordVisible = passwordVisible,
118+
onValueChange = {
119+
password = it
120+
},
121+
onEyeClick = { passwordVisible = it },
122+
focusManager = focusManager
123+
)
124+
125+
// Confirm password input.
126+
SmallVerticalSpacer()
127+
OutlineTitleAndEditPasswordTextField(
128+
titleText = "Confirm password: *",
129+
inputText = confirmPassword,
130+
placeholderText = "",
131+
passwordVisible = passwordVisible,
132+
onValueChange = {
133+
confirmPassword = it
134+
},
135+
onEyeClick = { passwordVisible = it },
136+
focusManager = focusManager
137+
)
138+
139+
if (isNotMatching.value) {
140+
PasswordNotMatchingError()
141+
}
142142

143-
MediumVerticalSpacer()
144-
Text(
145-
"By clicking on \"register\", you conform that you have read and agree to the privacy policy and terms of use.",
146-
)
143+
MediumVerticalSpacer()
144+
Text(
145+
"By clicking on \"register\", you conform that you have read and agree to the privacy policy and terms of use.",
146+
)
147147

148-
MediumVerticalSpacer()
149-
ActionOutlineButton(
150-
modifier = Modifier
151-
.fillMaxWidth(),
152-
text = "Register",
153-
onClick = {
154-
registerError = ""
155-
loading = true
156-
// Credentials registration.
157-
viewModel.register(
158-
email = email,
159-
password = password,
160-
name = name,
161-
onLogin = {
162-
loading = false
163-
NavigationCoordinator.INSTANCE.navigate(ProfileScreenRoute.MyProfile.route)
164-
},
165-
onFailedWith = { error ->
166-
loading = false
167-
if (error != null) {
168-
// Need to display error information.
169-
registerError = error.errorDetails!!
170-
}
148+
MediumVerticalSpacer()
149+
ActionOutlineButton(
150+
modifier = Modifier
151+
.fillMaxWidth(),
152+
text = "Register",
153+
onClick = {
154+
registerError = ""
155+
loading = true
156+
// Credentials registration.
157+
viewModel.register(
158+
email = email,
159+
password = password,
160+
name = name,
161+
onLogin = {
162+
loading = false
163+
NavigationCoordinator.INSTANCE.navigate(ProfileScreenRoute.MyProfile.route)
164+
},
165+
onFailedWith = { error ->
166+
loading = false
167+
if (error != null) {
168+
// Need to display error information.
169+
registerError = error.errorDetails!!
171170
}
172-
)
173-
}
174-
)
175-
176-
if (registerError.isNotEmpty()) {
177-
SimpleErrorMessages(
178-
text = registerError
171+
}
179172
)
180173
}
174+
)
175+
176+
if (registerError.isNotEmpty()) {
177+
SimpleErrorMessages(
178+
text = registerError
179+
)
181180
}
182181
}
182+
183183
}
184184

185185

0 commit comments

Comments
 (0)