Skip to content

CC-628: Refresh Customer Center UI after subscription cancellation#3061

Merged
facumenzella merged 6 commits into
mainfrom
CC-628-customer-center-ui-refresh-after-cancel
Feb 6, 2026
Merged

CC-628: Refresh Customer Center UI after subscription cancellation#3061
facumenzella merged 6 commits into
mainfrom
CC-628-customer-center-ui-refresh-after-cancel

Conversation

@facumenzella

Copy link
Copy Markdown
Member

Summary

Fixes issue where Customer Center UI doesn't update after subscription cancellation.

Changes

  • Add lifecycle-aware refresh when activity resumes after being paused (when user returns from manage subscriptions screen)
  • Add isRefreshing state to CustomerCenterState.Success to show loading indicator during refresh
  • Add refreshCustomerCenter() method that keeps content visible while refreshing (shows subtle loading indicator instead of full loading screen)
  • Match iOS behavior: refresh when returning from manage subscriptions screen
  • Show subtle loading indicator and dim content during refresh (similar to iOS)

Testing

  • Test that Customer Center refreshes when returning from Google Play Store manage subscriptions screen
  • Verify that cancelled subscriptions are shown correctly after cancellation
  • Verify that loading indicator appears during refresh
  • Verify that content is dimmed during refresh

Closes CC-628

- Add lifecycle-aware refresh when activity resumes after being paused
- Add isRefreshing state to show loading indicator during refresh
- Add refreshCustomerCenter() method that keeps content visible while refreshing
- Match iOS behavior: refresh when returning from manage subscriptions screen
- Show subtle loading indicator and dim content during refresh (similar to iOS)
@claude

claude Bot commented Jan 30, 2026

Copy link
Copy Markdown

Code review

No issues found. Checked for bugs and CLAUDE.md compliance.

@skydoves skydoves left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

All looks good 🙌 I just left some suggestions, but it's not very critical :)

facumenzella and others added 2 commits February 3, 2026 11:08
- Use LifecycleResumeEffect instead of DisposableEffect with LifecycleEventObserver
- Add isRefreshing check to prevent race condition
- Remove unused size import
- Remove unnecessary padding from CircularProgressIndicator

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@facumenzella facumenzella requested a review from vegaro February 3, 2026 10:36
@codecov

codecov Bot commented Feb 3, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 79.18%. Comparing base (58aaf4a) to head (8ea9109).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #3061   +/-   ##
=======================================
  Coverage   79.18%   79.18%           
=======================================
  Files         342      342           
  Lines       13680    13680           
  Branches     1841     1841           
=======================================
  Hits        10833    10833           
  Misses       2088     2088           
  Partials      759      759           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

- Move refresh logic from Composable to ViewModel to survive config changes
- Use ON_STOP/ON_START with isChangingConfigurations check to distinguish
  real backgrounding from rotation
- Add error logging when refresh fails

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Use non-deprecated LocalLifecycleOwner import from lifecycle-compose
- Use context.getActivity() to safely handle ContextWrapper
- Add empty line after refreshCustomerCenter() for consistency

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@facumenzella

Copy link
Copy Markdown
Member Author

Addressed all feedback in 3b088dd:

  • Added empty line after refreshCustomerCenter()
  • Using non-deprecated LocalLifecycleOwner from lifecycle-compose
  • Using context.getActivity() for safe ContextWrapper handling

@facumenzella facumenzella added this pull request to the merge queue Feb 6, 2026
Merged via the queue into main with commit 8defaed Feb 6, 2026
26 checks passed
@facumenzella facumenzella deleted the CC-628-customer-center-ui-refresh-after-cancel branch February 6, 2026 13:00
github-merge-queue Bot pushed a commit that referenced this pull request Feb 6, 2026
**This is an automatic release.**

## RevenueCatUI SDK
### Customer Center
#### 🐞 Bugfixes
* CC-628: Refresh Customer Center UI after subscription cancellation
(#3061) via Facundo Menzella (@facumenzella)
### Paywallv2
#### 🐞 Bugfixes
* Improve carousel performance with videos (#3070) via Cesar de la Vega
(@vegaro)

### 🔄 Other Changes
* Make networkName nullable in ad event data types (#3076) via Pol Miro
(@polmiro)
* Remove networkName from AdFailedToLoad event (#3074) via Pol Miro
(@polmiro)

Co-authored-by: revenuecat-ops <ops@revenuecat.com>
github-merge-queue Bot pushed a commit that referenced this pull request Mar 16, 2026
…ions (#3152)

## Summary
- fix Customer Center duplicate reload on foreground by removing
collector re-subscription auto-load and running initial load once in
`init`
- refresh Customer Center after returning from manage subscriptions and
force a stronger refresh via `awaitSyncPurchases()`
- keep existing lifecycle refresh behavior and add a one-time delayed
follow-up refresh guard for post-Play propagation
- remove temporary debug instrumentation logs added during investigation
- add regression tests to verify refresh path uses sync

## Testing
- ./gradlew :ui:revenuecatui:testDefaultsBc8DebugUnitTest --tests
"*CustomerCenterViewModelTests"

Follow-up of #3061
Closes CC-628

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Touches Customer Center lifecycle/refresh behavior; mis-ordering
lifecycle events or refresh gating could cause missed or duplicate
reloads when foregrounding or returning from external subscription
management.
> 
> **Overview**
> Improves Customer Center refresh behavior to better reflect
subscription changes after users leave the app to manage/cancel
subscriptions.
> 
> Adds an `ON_RESUME` lifecycle hook and a one-shot
`shouldRefreshOnResume` flag set when launching external subscription
management, so returning triggers a targeted refresh while avoiding
duplicate refreshes on `ON_START`. Refresh now preserves key
UI/navigation state when updating data, and initial loading via the
state flow is guarded to prevent repeated `loadCustomerCenter()` calls
on re-subscription.
> 
> Updates tests to cover the new resume-driven refresh path and assert
refresh uses `awaitCustomerInfo(CacheFetchPolicy.FETCH_CURRENT)` (not
`awaitSyncPurchases()`), plus a small newline fix in
`MockPurchasesType`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
0bcac84. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants