-
Notifications
You must be signed in to change notification settings - Fork 132
[WOOMOB-382] Update Coupons Fetching/Loading Business Logic #14019
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
[WOOMOB-382] Update Coupons Fetching/Loading Business Logic #14019
Conversation
📲 You can test the changes from this Pull Request in WooCommerce-Wear Android by scanning the QR code below to install the corresponding build.
|
📲 You can test the changes from this Pull Request in WooCommerce Android by scanning the QR code below to install the corresponding build.
|
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
private suspend fun WooPosCouponsListViewStateManager.showCachedData( |
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.
Why it needs to be an extension of WooPosCouponsListViewStateManager
?
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.
Also, the naming is a bit confusing. The method itself doesn't show anything and can create it from any coupons, not necessary from cached. Maybe simply createContentViewState
?
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.
Agree, I'll update this.
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.
Fixed in c9d9efb
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.
A few things I noticed:
- The PTR is shown when it's not triggered by the user in a few cases
05-06--15-27.mp4
05-06--15-12.mp4
- On the empty state the PTR is not working properly as it's closed before the remote request comes back
05-06--15-34.mp4
- Not related to the PR - empty state is at the top
Thanks for the review @kidinov! All the issues you mentioned don't feel like issues to me - I mean I implemented the behavior like this intentionally (except the vertical alignment). Wdyt @samiuelson, how does the behavior feel to you? Long story short, the app displays
I added it intentionally, isn't it desired to show we are loading something? Or how do we show that the remote request is in progress?
This is already fixed in one of the other open PRs.
Again, I believe this is desired - we are showing "fullscreen" loading in this state and showing two loading approaches on top of each other feels off, doesn't it? |
Aside from that, it feels off to me (this may not be important at all 😀); more important is that it's at least partially against the guidelines and not consistent with the behavior of the products and variations in the POS
https://m2.material.io/design/platform-guidance/android-swipe-to-refresh.html#usage |
Thanks for sharing these references!
👍 I'll update this one to continue showing the indicator until the request finishes to match material 3 guidelines. Update: This is fixed now.
I believe tapping on retry button doesn't go against the guideline. It's still a refresh gesture or action. Wdyt?
Not showing any indicator when action is in progress and then out of no-where replacing the displayed data or even worse replacing them with network error is very likely against the guidelines as well. (btw we show the PTR indicator on order list and product lists as well when remote request is in progress - I'm not saying that's a reason we should match designs in the POS, just saying that it's not something new in our app and not something users or developers reported AFAIK) It seems that guidelines say we should be showing a horizontal indicator at the top of the list -https://m3.material.io/components/progress-indicators/guidelines#0804b871-234a-44d3-be91-0ec85e161ee5. I think we can consider updating the lists to match this. (AFAIK this doesn't affect product list since it's loaded on POS load.) However, regarding |
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## trunk #14019 +/- ##
============================================
+ Coverage 38.33% 38.34% +0.01%
- Complexity 9540 9545 +5
============================================
Files 2122 2122
Lines 116797 116817 +20
Branches 14986 14989 +3
============================================
+ Hits 44776 44796 +20
Misses 67913 67913
Partials 4108 4108 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
I plan to test this a bit more, but I've updated the behavior as you suggested. Thanks for sharing the examples of the gmail/whatsapp on Slack - those truly don't show any loading indicator when they are updating the cache. I still think we should either show it or we should continue showing the cached data when remote request fails, but we iterate on that later. I'll re-request review after I test all the changes. |
I've rested it and it seems it all works now as you suggested. Would appreciate if you could re-review it, thanks! |
I don't see that they say anything specific about this case, and they allow it to be displayed when data is requested to be refreshed, e.g. this video: mio-staging_mio-design_1579302979877_assets_1OKTKpogOxe023_RcmqB6OBYquG6sRyc7_patterns-swipetorefresh-tap.mp4
But IMO, it's better to display a skeleton, as the primary goal of the PTR is to be a swipe gesture that combines the gesture with the indicator. In this case, it's just the indicator, without the gesture. Another point is the consistency with the rest of the lists - I believe they don't have PTR enabled for the error states at all. That said, if the chosen architecture makes it difficult to implement this, I think it's ok to leave it as it is, since this error state, which hopefully nobody will see anyway
I believe this was already discussed on Slack. We verified that numerous major apps all display cached data without any loading indicators for new data fetching, updating the UI only when the data arrives. In my opinion, this approach is sensible, particularly for our situation where the data does not change frequently. Therefore, in most cases, merchants will begin using the app without seeing for any background processes we may be running
I don't see anywhere that it says that. Both video and text say that:
But nothing like this is happening here. We just sync the data. In the video examples, they show that they have no data to display; therefore, there is a loading indicator. By the way, I completely don't think that we need to introduce a third loading indicator on top of the skeleton and PTR here.
The lists themselves are the same from the user's point of view, and I understand that's the technical approach you've decided on, but it shouldn't truly affect the overall user experience. Overall, if the architecture has limitations on such small things like when to display the PTR or when to show a skeleton, I believe it's possibly not the best choice for this particular case. |
@kidinov Thanks for the reply! I'm a bit confused though - I updated the app to behave as you suggested, do you still see some issues with the current approach? |
…-coupons-before-remote-fetch # Conflicts: # WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/items/coupons/WooPosCouponsViewModel.kt # WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/items/coupons/WooPosCouponsListViewStateManagerTest.kt
Sorry, I didn't test the code yet, just answered you 😀 I missed this comment 😮💨
Testing it now! |
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.
Looks nice, thanks!
The only things I noticed:
- Instead of the skeleton, we show the cached data when there is a retry on the error screen
- I think when it's PTR on the empty screen, we should just show PTR. No need to show two loading indicators, but I guess this is more like NP
- Not sure about that, but it looks like both empty and error screens have a larger margin at the top than at the bottom. I didn't measure that, just how it looks to my eye, so maybe it's not correct
- I think I mentioned this already before, but it looks like we use color for the empty state icon that has not have enough of contrast with the background
05-08--11-32.mp4
05-08--11-30.mp4
Thanks for the re-review @kidinov !
I originally didn't update this since it was consistent with the product list, but looking at it it's not great UX. I've fixed this state on the coupon list - it's still happening on the product list though. When the internet is down, the error arrives so quickly that it's not visible, but on poor internet connection the cached data are shown. Do you think it's worth updating there? If so, could you please update it?
Make sense, however, this feels like a state that would make the code more complicated => more costly to maintain => the value for the user is IMO zero, the value for the company is therefor likely negative.
A couple week ago Wagner mentioned he plans to polish all the error/empty screen and we should ignore them for now.
It seems to be center correctly (340px from top and bottom) - assuming we are centering it within the list not center of the screen.
|
Apologies, but I'm somewhat unclear about that. Update what exactly? We have two ways to address remote request failures while utilizing a local cache:
So in both cases, the retry button cannot show cached data, only a skeleton. Here, it seems that a mix of both was implemented. If we have cached data, we should not show the error screen at all
I won't say that it's zero. For me, small things like that create an impression of a good product where people did their best. However, I agree that it's probably not the case for most people, and the impact is really really low. As per implementation, it largely depends on the selected architectural approach. In the products, this is managed by those lines of code:
Which, in my opinion, isn't very complicated. However, if you find it complicated in your situation, it's perfectly acceptable to leave it as is
👍
👍 |
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.
LGTM. Please go ahead with mering if you feel it's good to go
Interesting, now I'm even more confused 🤔 . How do we decide whether to invalidate the cache after a request failure? What do we display on the UI when a request fails and we continue showing the cached data? (I mean, I'm aware only about the Btw, I have never seen an app which would clear cached data upon a request-failure. It feels like we are trying too be too smart, ending up with worse UX. I think the user can decide whether they are fine continue using the product if the refresh failed. Especially considering the order creation is always remote, so all the calculations are guaranteed to be correct.
Yes, if you don't look at the big picture, I agree handling such cases is simple. It's similar with VM size - at the beginning one might feel like we can put everything there, since it's just 80 lines of code. However, if we continue applying this we end up with 500+ lines of code and the way back is very expensive. In this case, it might be one |
Oh, sorry, I meant that we (now) invalidate it when we do PTR in general, not only when the request fails. We display an error when requests fails.
I am talking about the specific case where all these cases are handled, on the products list and its relativilty simple VM. As the code suggests, it handles all the cases to show either loading state or PTR... we don't need 15 cases for this. |
Ohh I see. The usual practice AFAIK is to clear the cache only when the request succeeds - right before we store the new data into the DB. Either case, since we don't have designs for |
Closes: #WOOMOB-382
Do not merge label - #14015 needs to be merged first.
Description
This PR updates the behavior of the coupons list in the POS.
Testing information
The tests that have been performed
I've tested the above.
Images/gif
Screen.Recording.2025-05-06.at.8.59.33.mov
RELEASE-NOTES.txt
if necessary. Use the "[Internal]" label for non-user-facing changes.Reviewer (or Author, in the case of optional code reviews):
Please make sure these conditions are met before approving the PR, or request changes if the PR needs improvement: