-
Notifications
You must be signed in to change notification settings - Fork 263
Migrate sample to compose #173
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
/gemini review |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request successfully migrates the CredentialManager sample app from the traditional View system (Fragments and XML) to Jetpack Compose. The migration is comprehensive, replacing all UI components, navigation, and adapting the logic to a ViewModel-based architecture. The code is now more modern and follows many Compose best practices.
However, there are a few significant areas for improvement. The most critical is the downgrading of several key AndroidX and Kotlin libraries in build.gradle
, which is a regression and should be reverted. Additionally, there are architectural concerns, primarily passing Activity
and Context
instances into ViewModels, which violates MVVM principles and can lead to memory leaks. I've also left comments on improving navigation logic, state handling, and making Compose Previews more robust.
Overall, this is a great step forward for the sample app. Addressing the feedback will make it an even better example of a modern Android application.
Button( | ||
onClick = { | ||
if (activity != null) { | ||
viewModel.signIn(activity, context) | ||
} | ||
}, | ||
shape = RoundedCornerShape(4.dp), | ||
enabled = !isLoading && activity != null, | ||
modifier = Modifier.fillMaxWidth() | ||
) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Passing the Activity
or Context
to the ViewModel (viewModel.signIn(activity, context)
) is a violation of MVVM architecture. ViewModels should not hold references to UI-layer components, as this can lead to memory leaks and makes them difficult to test.
The CredentialManager
API requires an Activity
, so the call to credentialManager.getCredential
should be initiated from the UI layer (e.g., inside this onClick
lambda). The result can then be passed to the ViewModel for processing.
private val _navigationEvent = MutableSharedFlow<NavigationEvent>() | ||
val navigationEvent = _navigationEvent.asSharedFlow() | ||
|
||
fun signIn(activity: Activity, context: Context) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The signIn
function accepts Activity
and Context
parameters. This tightly couples the ViewModel to the Android framework, making it difficult to unit test and potentially causing memory leaks. The responsibility of interacting with framework components like CredentialManager
(which requires an Activity) should be handled in the UI layer (the Composable screen), and only the results (or data) should be passed to the ViewModel for processing.
CredentialManager/app/src/main/java/com/google/credentialmanager/sample/SignUpScreen.kt
Show resolved
Hide resolved
Button( | ||
onClick = { | ||
if (activity != null) { | ||
viewModel.signUpWithPasskey(activity, context) | ||
} | ||
}, | ||
shape = RoundedCornerShape(4.dp), | ||
enabled = !isLoading && activity != null, | ||
modifier = Modifier.fillMaxWidth() | ||
) { | ||
Text("Sign Up with passkey") | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Passing the Activity
and Context
to the ViewModel (viewModel.signUpWithPasskey(activity, context)
) is a violation of MVVM architecture. ViewModels should not hold references to UI-layer components, as this can lead to memory leaks and makes them difficult to test. The CredentialManager
API call should be initiated from the UI layer (e.g., inside this onClick
lambda), and the result can then be passed to the ViewModel for processing.
No description provided.