Skip to content
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

Fix Link default card change ui states #10108

Merged
merged 7 commits into from
Feb 13, 2025

Conversation

toluo-stripe
Copy link
Contributor

@toluo-stripe toluo-stripe commented Feb 7, 2025

Summary

  • Fix selected button flicker when default card is changed
  • Loading bar should be on payment method row, not primary button

Motivation

Payment Method Update Loading State

Default Card Radio Button Flicker

Testing

  • Added tests
  • Modified tests
  • Manually verified

Screenshots

Screen.Recording.2025-02-07.at.5.22.56.PM.mov

Changelog

Copy link
Contributor

github-actions bot commented Feb 7, 2025

Diffuse output:

OLD: identity-example-release-base.apk (signature: V1, V2)
NEW: identity-example-release-pr.apk (signature: V1, V2)

          │          compressed          │         uncompressed         
          ├───────────┬───────────┬──────┼───────────┬───────────┬──────
 APK      │ old       │ new       │ diff │ old       │ new       │ diff 
──────────┼───────────┼───────────┼──────┼───────────┼───────────┼──────
      dex │     2 MiB │     2 MiB │  0 B │   4.1 MiB │   4.1 MiB │  0 B 
     arsc │     1 MiB │     1 MiB │  0 B │     1 MiB │     1 MiB │  0 B 
 manifest │   2.3 KiB │   2.3 KiB │  0 B │     8 KiB │     8 KiB │  0 B 
      res │ 302.6 KiB │ 302.6 KiB │  0 B │ 456.7 KiB │ 456.7 KiB │  0 B 
   native │   6.2 MiB │   6.2 MiB │  0 B │  15.8 MiB │  15.8 MiB │  0 B 
    asset │   7.1 KiB │   7.1 KiB │  0 B │   6.9 KiB │   6.9 KiB │  0 B 
    other │  90.8 KiB │  90.8 KiB │ -2 B │   171 KiB │   171 KiB │  0 B 
──────────┼───────────┼───────────┼──────┼───────────┼───────────┼──────
    total │   9.6 MiB │   9.6 MiB │ -2 B │  21.5 MiB │  21.5 MiB │  0 B 

 DEX     │ old   │ new   │ diff      
─────────┼───────┼───────┼───────────
   files │     1 │     1 │ 0         
 strings │ 19981 │ 19981 │ 0 (+0 -0) 
   types │  6194 │  6194 │ 0 (+0 -0) 
 classes │  4985 │  4985 │ 0 (+0 -0) 
 methods │ 29823 │ 29823 │ 0 (+0 -0) 
  fields │ 17542 │ 17542 │ 0 (+0 -0) 

 ARSC    │ old  │ new  │ diff 
─────────┼──────┼──────┼──────
 configs │  164 │  164 │  0   
 entries │ 3624 │ 3624 │  0
APK
   compressed    │   uncompressed   │                        
──────────┬──────┼───────────┬──────┤                        
 size     │ diff │ size      │ diff │ path                   
──────────┼──────┼───────────┼──────┼────────────────────────
 28.6 KiB │ -3 B │  63.2 KiB │  0 B │ ∆ META-INF/CERT.SF     
 25.4 KiB │ +1 B │  63.1 KiB │  0 B │ ∆ META-INF/MANIFEST.MF 
──────────┼──────┼───────────┼──────┼────────────────────────
   54 KiB │ -2 B │ 126.3 KiB │  0 B │ (total)

@toluo-stripe toluo-stripe changed the title Wallet update states Fix Link default card change ui states Feb 7, 2025
@toluo-stripe toluo-stripe marked this pull request as ready for review February 7, 2025 22:31
@toluo-stripe toluo-stripe requested review from a team as code owners February 7, 2025 22:31
@@ -96,30 +96,34 @@ internal class WalletViewModel @Inject constructor(
}
}

private fun loadPaymentDetails(selectedItemId: String? = null) {
private fun loadPaymentDetails() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the updated function is only used in the init block, should we move

_uiState.update {
    it.setProcessing()
}

out of the function instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

loadPaymentDetails is only used in the init block, so this is fine. The other calls to load use loadPaymentDetailsHelper

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 to James' question here. I think we could move the uiState into the init block.

Then we wouldn't need this function which is only intended to be called by the init block. We could rename loadPaymentDetailsHelper to loadPaymentDetails and call it from anywhere.

My concern with the current approach is that it's not easy to tell why you would want to call loadPaymentDetails vs. loadPaymentDetailsHelper, which could lead to confusion/bugs in the future

dispatcher.scheduler.advanceTimeBy(1.1.seconds)

onWalletPaymentMethodRowLoadingIndicator().assertDoesNotExist()
onWalletPayButton().assertExists()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exist or enabled?

Comment on lines +516 to +520
composeTestRule.waitForIdle()

onWalletPaymentMethodRowLoadingIndicator().assertIsDisplayed()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this introduce flakiness? Should we use waitUntilExists instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think if we have flakiness after waitForIdle, then the screen is not behaving as expected. The loader state is changed on the main thread before kicking of any coroutines to update the card

@@ -392,17 +401,21 @@ class WalletViewModelTest {

viewModel.onSetDefaultClicked(card1)

assertThat(viewModel.uiState.value.cardBeingUpdated).isEqualTo(card1.id)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a better way to simulate processing, maybe test dispatcher?
I don't know. Not a blocker for me.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 to this question.

If the tests are going to continue to rely on the delay, could we at least use a variable for the delay and then reference that variable in the advanceTimeBy call? Otherwise I was having a hard time figuring out why 1.1 seconds was being used here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't think of another way to simulate processing. I'll replace the literals with variable names

Copy link
Collaborator

@amk-stripe amk-stripe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure this is the right fix -- on iOS, it looks like the payment methods are not re-ordered when the default payment method changes. Instead, just the default badge moves. I think that this is a better/smoother UI. Could we do the same thing on Android?

@toluo-stripe toluo-stripe force-pushed the tolu/link/wallet_screen_states branch from 36040cb to a17477d Compare February 11, 2025 21:59
@toluo-stripe
Copy link
Contributor Author

This what it looks like now cc @amk-stripe

Screen.Recording.2025-02-11.at.4.55.46.PM.mov

amk-stripe
amk-stripe previously approved these changes Feb 12, 2025
@@ -392,17 +401,21 @@ class WalletViewModelTest {

viewModel.onSetDefaultClicked(card1)

assertThat(viewModel.uiState.value.cardBeingUpdated).isEqualTo(card1.id)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 to this question.

If the tests are going to continue to rely on the delay, could we at least use a variable for the delay and then reference that variable in the advanceTimeBy call? Otherwise I was having a hard time figuring out why 1.1 seconds was being used here

@@ -96,30 +96,34 @@ internal class WalletViewModel @Inject constructor(
}
}

private fun loadPaymentDetails(selectedItemId: String? = null) {
private fun loadPaymentDetails() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 to James' question here. I think we could move the uiState into the init block.

Then we wouldn't need this function which is only intended to be called by the init block. We could rename loadPaymentDetailsHelper to loadPaymentDetails and call it from anywhere.

My concern with the current approach is that it's not easy to tell why you would want to call loadPaymentDetails vs. loadPaymentDetailsHelper, which could lead to confusion/bugs in the future

amk-stripe
amk-stripe previously approved these changes Feb 12, 2025
@toluo-stripe toluo-stripe merged commit f5bec10 into master Feb 13, 2025
13 checks passed
@toluo-stripe toluo-stripe deleted the tolu/link/wallet_screen_states branch February 13, 2025 19:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants