Skip to content

Commit c95d3dc

Browse files
committed
SDK & APP alignment
1 parent ec97960 commit c95d3dc

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+547
-347
lines changed

app/build.gradle.kts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
import java.io.FileNotFoundException
2-
import java.nio.file.Files
3-
import java.nio.file.StandardCopyOption
4-
51
plugins {
62
alias(libs.plugins.android.application)
73
alias(libs.plugins.kotlin.android)

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ import com.sap.cdc.bitsnbytes.social.GoogleAuthenticationProvider
2323

2424
/**
2525
* Singleton class for interacting with the CDC SDK.
26+
* This approach is the simplest one to assure a single instance of the SDK is used throughout the application.
27+
* Using Kotlin object class is also a valid approach.
2628
*/
2729
class IdentityServiceRepository private constructor(context: Context) {
2830

@@ -71,8 +73,6 @@ class IdentityServiceRepository private constructor(context: Context) {
7173
// Register application specific authentication providers.
7274
registerAuthenticationProvider("facebook", FacebookAuthenticationProvider())
7375
registerAuthenticationProvider("google", GoogleAuthenticationProvider())
74-
// registerAuthenticationProvider("line", LineAuthenticationProvider())
75-
// registerAuthenticationProvider("weChat", WeChatAuthenticationProvider())
7676
}
7777

7878
//region CONFIGURATION
@@ -140,7 +140,8 @@ class IdentityServiceRepository private constructor(context: Context) {
140140
* Initiate cdc SDK credentials login.
141141
*/
142142
suspend fun login(email: String, password: String): IAuthResponse {
143-
val params = mutableMapOf("loginID" to email, "password" to password, "sessionExpiration" to "30")
143+
val params =
144+
mutableMapOf("loginID" to email, "password" to password, "sessionExpiration" to "30")
144145
return authenticationService.authenticate().login(params)
145146
}
146147

app/src/main/java/com/sap/cdc/bitsnbytes/cdc/model/AccountEntity.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ import kotlinx.serialization.Serializable
66
/**
77
* Created by Tal Mirmelshtein on 10/06/2024
88
* Copyright: SAP LTD.
9-
*
9+
*/
10+
11+
/**
1012
* Custom instance of the CDC SDK account schema.
1113
* This class can be extended according to the site schema definition and will be serialized
1214
* accordingly.
@@ -17,6 +19,9 @@ data class AccountEntity(
1719
val profile: ProfileEntity
1820
)
1921

22+
/**
23+
* Custom instance of the CDC SDK profile schema.
24+
*/
2025
@Serializable
2126
data class ProfileEntity(
2227
val email: String,
Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,10 @@
11
package com.sap.cdc.bitsnbytes.extensions
22

3-
import androidx.compose.runtime.Composable
4-
import androidx.compose.ui.graphics.painter.Painter
5-
import androidx.compose.ui.res.painterResource
6-
import com.sap.cdc.bitsnbytes.R
7-
83

94
/**
105
* Helper extension method to split first/last name.
116
*/
127
fun String.splitFullName(): Pair<String?, String?> {
138
val names = this.trim().split(Regex("\\s+"))
149
return names.firstOrNull() to names.lastOrNull()
15-
}
16-
17-
/**
18-
* Helper extension method for composable view to provide the correct painter resource for
19-
* String social provider name.
20-
*/
21-
@Composable
22-
fun String.providerIcon(): Painter {
23-
when (this) {
24-
"line" -> {
25-
return painterResource(id = R.drawable.ic_line)
26-
}
27-
28-
"google" -> {
29-
return painterResource(id = R.drawable.google_v)
30-
}
31-
32-
"facebook" -> {
33-
return painterResource(id = R.drawable.facebook_v)
34-
}
35-
36-
"apple" -> {
37-
return painterResource(id = R.drawable.apple_v)
38-
}
39-
"linkedIn" -> {
40-
return painterResource(id = R.drawable.linkedin_v)
41-
}
42-
43-
else -> {
44-
return painterResource(id = R.drawable.ic_logo)
45-
}
46-
}
4710
}

app/src/main/java/com/sap/cdc/bitsnbytes/social/GoogleAuthenticationProvider.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import androidx.credentials.CredentialManager
88
import androidx.credentials.GetCredentialRequest
99
import androidx.credentials.GetCredentialResponse
1010
import androidx.credentials.exceptions.GetCredentialException
11-
import com.google.android.libraries.identity.googleid.GetGoogleIdOption
1211
import com.google.android.libraries.identity.googleid.GetSignInWithGoogleOption
1312
import com.google.android.libraries.identity.googleid.GoogleIdTokenCredential
1413
import com.sap.cdc.android.sdk.auth.provider.AuthenticatorProviderResult

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import com.sap.cdc.android.sdk.SessionEvent
1515
import com.sap.cdc.bitsnbytes.ui.route.NavigationCoordinator
1616
import com.sap.cdc.bitsnbytes.ui.route.ProfileScreenRoute
1717
import com.sap.cdc.bitsnbytes.ui.theme.AppTheme
18-
import com.sap.cdc.bitsnbytes.ui.view.flow.HomeScaffoldView
18+
import com.sap.cdc.bitsnbytes.ui.view.screens.HomeScaffoldView
1919
import kotlinx.coroutines.launch
2020

2121
/**
@@ -46,6 +46,8 @@ class MainActivity : FragmentActivity() {
4646
}
4747
}
4848

49+
// Subscribe to session events. This is a global event bus for session events.
50+
// If a session event is received, the user will be navigated to the welcome screen.
4951
CDCMessageEventBus.subscribeToSessionEvents {
5052
when (it) {
5153
is SessionEvent.ExpiredSession -> {
@@ -62,6 +64,12 @@ class MainActivity : FragmentActivity() {
6264
}
6365
}
6466
}
67+
68+
override fun onDestroy() {
69+
// Dispose the event bus.
70+
CDCMessageEventBus.dispose()
71+
super.onDestroy()
72+
}
6573
}
6674

6775

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

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -45,16 +45,6 @@ class NavigationCoordinator private constructor() {
4545
_backNav.value = currentNavController?.previousBackStackEntry != null
4646
}
4747

48-
/**
49-
* Pop current route and navigate to new route.
50-
*/
51-
fun popAndNavigate(route: String) {
52-
currentNavController?.popBackStack()
53-
currentNavController?.navigate(route)
54-
// Update back stack custom state.
55-
_backNav.value = currentNavController?.previousBackStackEntry != null
56-
}
57-
5848
/**
5949
* Pop controller backstack until specified root route (including) it and navigate to specified route.
6050
*/

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

Lines changed: 81 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,29 @@ package com.sap.cdc.bitsnbytes.ui.route
33
import androidx.compose.material3.Text
44
import androidx.compose.runtime.Composable
55
import androidx.compose.ui.platform.LocalContext
6+
import androidx.lifecycle.viewmodel.compose.viewModel
67
import androidx.navigation.compose.NavHost
78
import androidx.navigation.compose.composable
89
import androidx.navigation.compose.rememberNavController
910
import com.sap.cdc.android.sdk.auth.ResolvableContext
1011
import com.sap.cdc.bitsnbytes.cdc.IdentityServiceRepository
11-
import com.sap.cdc.bitsnbytes.ui.view.custom.AuthenticationTabView
12-
import com.sap.cdc.bitsnbytes.ui.view.flow.AboutMeView
13-
import com.sap.cdc.bitsnbytes.ui.view.flow.EmailRegisterView
14-
import com.sap.cdc.bitsnbytes.ui.view.flow.EmailSignInView
15-
import com.sap.cdc.bitsnbytes.ui.view.flow.HomeView
16-
import com.sap.cdc.bitsnbytes.ui.view.flow.LinkAccountView
17-
import com.sap.cdc.bitsnbytes.ui.view.flow.LoginOptionsView
18-
import com.sap.cdc.bitsnbytes.ui.view.flow.MyProfileView
19-
import com.sap.cdc.bitsnbytes.ui.view.flow.OTPType
20-
import com.sap.cdc.bitsnbytes.ui.view.flow.OtpSignInView
21-
import com.sap.cdc.bitsnbytes.ui.view.flow.OtpVerifyView
22-
import com.sap.cdc.bitsnbytes.ui.view.flow.PendingRegistrationView
23-
import com.sap.cdc.bitsnbytes.ui.view.flow.RegisterView
24-
import com.sap.cdc.bitsnbytes.ui.view.flow.ScreenSetView
25-
import com.sap.cdc.bitsnbytes.ui.view.flow.SignInView
26-
import com.sap.cdc.bitsnbytes.ui.view.flow.WelcomeView
12+
import com.sap.cdc.bitsnbytes.ui.view.composables.AuthenticationTabView
13+
import com.sap.cdc.bitsnbytes.ui.view.screens.AboutMeView
14+
import com.sap.cdc.bitsnbytes.ui.view.screens.EmailRegisterView
15+
import com.sap.cdc.bitsnbytes.ui.view.screens.EmailSignInView
16+
import com.sap.cdc.bitsnbytes.ui.view.screens.HomeView
17+
import com.sap.cdc.bitsnbytes.ui.view.screens.LinkAccountView
18+
import com.sap.cdc.bitsnbytes.ui.view.screens.LoginOptionsView
19+
import com.sap.cdc.bitsnbytes.ui.view.screens.MyProfileView
20+
import com.sap.cdc.bitsnbytes.ui.view.screens.OTPType
21+
import com.sap.cdc.bitsnbytes.ui.view.screens.OtpSignInView
22+
import com.sap.cdc.bitsnbytes.ui.view.screens.OtpVerifyView
23+
import com.sap.cdc.bitsnbytes.ui.view.screens.PendingRegistrationView
24+
import com.sap.cdc.bitsnbytes.ui.view.screens.RegisterView
25+
import com.sap.cdc.bitsnbytes.ui.view.screens.ScreenSetView
26+
import com.sap.cdc.bitsnbytes.ui.view.screens.SignInView
27+
import com.sap.cdc.bitsnbytes.ui.view.screens.WelcomeView
28+
import com.sap.cdc.bitsnbytes.ui.viewmodel.AccountViewModel
2729
import com.sap.cdc.bitsnbytes.ui.viewmodel.EmailRegisterViewModel
2830
import com.sap.cdc.bitsnbytes.ui.viewmodel.EmailSignInViewModel
2931
import com.sap.cdc.bitsnbytes.ui.viewmodel.LinkAccountViewModel
@@ -34,6 +36,8 @@ import com.sap.cdc.bitsnbytes.ui.viewmodel.PendingRegistrationViewModel
3436
import com.sap.cdc.bitsnbytes.ui.viewmodel.RegisterViewModel
3537
import com.sap.cdc.bitsnbytes.ui.viewmodel.ScreenSetViewModel
3638
import com.sap.cdc.bitsnbytes.ui.viewmodel.SignInViewModel
39+
import com.sap.cdc.bitsnbytes.ui.viewmodel.WelcomeViewModel
40+
import com.sap.cdc.bitsnbytes.ui.viewmodel.factory.CustomViewModelFactory
3741
import kotlinx.serialization.json.Json
3842

3943
/**
@@ -96,88 +100,129 @@ fun ProfileNavHost() {
96100
val profileNavController = rememberNavController()
97101
NavigationCoordinator.INSTANCE.setNavController(profileNavController)
98102

103+
val context = LocalContext.current.applicationContext
104+
val identityServiceRepository = IdentityServiceRepository.getInstance(context)
105+
99106
NavHost(
100107
profileNavController, startDestination =
101-
when (IdentityServiceRepository.getInstance(LocalContext.current).availableSession()) {
108+
when (identityServiceRepository.availableSession()) {
102109
true -> ProfileScreenRoute.MyProfile.route
103110
false -> ProfileScreenRoute.Welcome.route
104111
}
105112
) {
106113
composable(ProfileScreenRoute.Welcome.route) {
107-
WelcomeView()
114+
val viewModel: WelcomeViewModel = viewModel(
115+
factory = CustomViewModelFactory(context)
116+
)
117+
WelcomeView(viewModel)
108118
}
109119
composable(ProfileScreenRoute.SignIn.route) {
110-
SignInView(viewModel = SignInViewModel(LocalContext.current))
120+
val viewModel: SignInViewModel = viewModel(
121+
factory = CustomViewModelFactory(context)
122+
)
123+
SignInView(
124+
viewModel
125+
)
111126
}
112127
composable(ProfileScreenRoute.Register.route) {
113-
RegisterView(viewModel = RegisterViewModel(LocalContext.current))
128+
val viewModel: RegisterViewModel = viewModel(
129+
factory = CustomViewModelFactory(context)
130+
)
131+
RegisterView(viewModel)
114132
}
115133
composable("${ProfileScreenRoute.AuthTabView.route}/{selected}") { backStackEntry ->
116134
val selected = backStackEntry.arguments?.getString("selected")
117-
AuthenticationTabView(selected = selected!!.toInt(),)
135+
AuthenticationTabView(selected = selected!!.toInt())
118136
}
119137
composable(ProfileScreenRoute.EmailSignIn.route) {
120-
EmailSignInView(viewModel = EmailSignInViewModel(LocalContext.current))
138+
val viewModel: EmailSignInViewModel = viewModel(
139+
factory = CustomViewModelFactory(context)
140+
)
141+
EmailSignInView(viewModel)
121142
}
122143
composable(ProfileScreenRoute.EmailRegister.route) {
123-
EmailRegisterView(viewModel = EmailRegisterViewModel(LocalContext.current))
144+
val viewModel: EmailRegisterViewModel = viewModel(
145+
factory = CustomViewModelFactory(context)
146+
)
147+
EmailRegisterView(viewModel)
124148
}
125149
composable("${ProfileScreenRoute.ResolvePendingRegistration.route}/{resolvableContext}") { backStackEntry ->
126150
val resolvableJson = backStackEntry.arguments?.getString("resolvableContext")
127151
val resolvable = Json.decodeFromString<ResolvableContext>(resolvableJson!!)
128-
PendingRegistrationView(
129-
viewModel = PendingRegistrationViewModel(LocalContext.current),
130-
resolvable,
152+
val viewModel: PendingRegistrationViewModel = viewModel(
153+
factory = CustomViewModelFactory(context)
131154
)
155+
PendingRegistrationView(viewModel, resolvable)
132156
}
133157
composable("${ProfileScreenRoute.ResolveLinkAccount.route}/{resolvableContext}") { backStackEntry ->
134158
val resolvableJson = backStackEntry.arguments?.getString("resolvableContext")
135159
val resolvable = Json.decodeFromString<ResolvableContext>(resolvableJson!!)
136-
LinkAccountView(
137-
viewModel = LinkAccountViewModel(LocalContext.current),
138-
resolvable,
160+
val viewModel: LinkAccountViewModel = viewModel(
161+
factory = CustomViewModelFactory(context)
139162
)
163+
LinkAccountView(viewModel, resolvable)
140164
}
141165
composable(ProfileScreenRoute.MyProfile.route) {
142-
MyProfileView()
166+
val viewModel: AccountViewModel = viewModel(
167+
factory = CustomViewModelFactory(context)
168+
)
169+
MyProfileView(viewModel)
143170
}
144171
composable(ProfileScreenRoute.AboutMe.route) {
145-
AboutMeView()
172+
val viewModel: AccountViewModel = viewModel(
173+
factory = CustomViewModelFactory(context)
174+
)
175+
AboutMeView(viewModel)
146176
}
147177
composable(ScreenSetsRoute.ScreenSetRegistrationLoginLogin.route) {
178+
val viewModel: ScreenSetViewModel = viewModel(
179+
factory = CustomViewModelFactory(context)
180+
)
148181
ScreenSetView(
149-
ScreenSetViewModel(LocalContext.current),
182+
viewModel,
150183
"Default-RegistrationLogin",
151184
"gigya-login-screen"
152185
)
153186
}
154187
composable(ScreenSetsRoute.ScreenSetRegistrationLoginRegister.route) {
188+
val viewModel: ScreenSetViewModel = viewModel(
189+
factory = CustomViewModelFactory(context)
190+
)
155191
ScreenSetView(
156-
ScreenSetViewModel(LocalContext.current),
192+
viewModel,
157193
"Default-RegistrationLogin",
158194
"gigya-register-screen"
159195
)
160196
}
161197
composable("${ProfileScreenRoute.OTPSignIn.route}/{type}") { backStackEntry ->
162198
val type = backStackEntry.arguments?.getString("type")
163199
val otpType = OTPType.getByValue(type!!.toInt())
164-
OtpSignInView(viewModel = OtpSignInViewModel(LocalContext.current), otpType = otpType!!)
200+
val viewModel: OtpSignInViewModel = viewModel(
201+
factory = CustomViewModelFactory(context)
202+
)
203+
OtpSignInView(viewModel, otpType = otpType!!)
165204
}
166205
composable("${ProfileScreenRoute.OTPVerify.route}/{resolvableContext}/{type}/{inputField}") { backStackEntry ->
167206
val resolvableJson = backStackEntry.arguments?.getString("resolvableContext")
168207
val input = backStackEntry.arguments?.getString("inputField")
169208
val type = backStackEntry.arguments?.getString("type")
170209
val otpType = OTPType.getByValue(type!!.toInt())
171210
val resolvable = Json.decodeFromString<ResolvableContext>(resolvableJson!!)
211+
val viewModel: OtpVerifyViewModel = viewModel(
212+
factory = CustomViewModelFactory(context)
213+
)
172214
OtpVerifyView(
173-
viewModel = OtpVerifyViewModel(LocalContext.current),
215+
viewModel,
174216
resolvable,
175217
otpType = otpType!!,
176218
inputField = input!!
177219
)
178220
}
179221
composable(ProfileScreenRoute.LoginOptions.route) {
180-
LoginOptionsView(viewModel = LoginOptionsViewModel(LocalContext.current))
222+
val viewModel: LoginOptionsViewModel = viewModel(
223+
factory = CustomViewModelFactory(context)
224+
)
225+
LoginOptionsView(viewModel)
181226
}
182227
}
183228
}

0 commit comments

Comments
 (0)