⚠ This page is served via a proxy. Original site: https://github.com
This service does not collect credentials or authentication data.
Skip to content

Conversation

@ianrumac
Copy link
Collaborator

@ianrumac ianrumac commented Feb 6, 2026

Changes in this pull request

Checklist

  • All unit tests pass.
  • All UI tests pass.
  • Demo project builds and runs.
  • I added/updated tests or detailed why my change isn't tested.
  • I added an entry to the CHANGELOG.md for any breaking changes, enhancements, or bug fixes.
  • I have run ktlint in the main directory and fixed any issues.
  • I have updated the SDK documentation as well as the online docs.
  • I have reviewed the contributing guide

Greptile Overview

Greptile Summary

  • Updates paywall purchase UX by setting PaywallLoadingState.LoadingPurchase when a purchase is initiated from the paywall webview.
  • Fixes shimmer view implementation to avoid AppCompat theme requirements and corrects view visibility constant imports.
  • Hardens cache reads by catching ClassCastException and clearing corrupted stored values (Cache + Entitlements).
  • Expands JSON conversion to handle Date / org.json types, but current sanitization may drop these values before conversion.
  • Adds a non-dismiss success path in TransactionManager to set loading state back to Ready after purchase completes.

Confidence Score: 3/5

  • Moderate risk to merge due to UI state regression paths and a converter/sanitizer mismatch.
  • Core changes are small and localized, but the newly introduced LoadingPurchase state is not clearly reset on all internal purchase failure paths, and Converters.sanitizeMap currently filters out the newly supported types so the added conversion logic can be bypassed/dropped silently.
  • superwall/src/main/java/com/superwall/sdk/store/transactions/TransactionManager.kt; superwall/src/main/java/com/superwall/sdk/storage/core_data/Converters.kt

Important Files Changed

Filename Overview
superwall/src/main/java/com/superwall/sdk/Superwall.kt Updates internal paywall purchase flow to set PaywallLoadingState.LoadingPurchase when initiating a purchase from the webview.
superwall/src/main/java/com/superwall/sdk/paywall/view/PaywallShimmerView.kt Fixes visibility constants imports by using android.view.View.GONE/VISIBLE; shimmer visibility still only tracks LoadingURL.
superwall/src/main/java/com/superwall/sdk/paywall/view/ShimmerView.kt Switches ShimmerView base class from AppCompatImageView to ImageView (with @SuppressLint) to allow applicationContext usage without requiring an AppCompat theme.
superwall/src/main/java/com/superwall/sdk/storage/Cache.kt Adds ClassCastException handling for in-memory cache reads to evict corrupted entries and log the error.
superwall/src/main/java/com/superwall/sdk/storage/core_data/Converters.kt Adds JSON conversion support for Date/JSONArray/JSONObject, but sanitizeMap still filters these types out, so they may be dropped before conversion.
superwall/src/main/java/com/superwall/sdk/store/Entitlements.kt Wraps reads of StoredSubscriptionStatus and StoredEntitlementsByProductId in try/catch for ClassCastException and clears corrupted storage entries.
superwall/src/main/java/com/superwall/sdk/store/transactions/TransactionManager.kt Ensures loading state is reset to Ready when an internal purchase succeeds but paywall is not dismissed; internal failure paths still only toggle spinner, risking a stuck LoadingPurchase state introduced in this PR.

Sequence Diagram

sequenceDiagram
    participant Web as Paywall WebView
    participant SW as Superwall.eventDidOccur
    participant PV as PaywallView
    participant TM as TransactionManager
    participant PC as PurchaseController

    Web->>SW: InitiatePurchase(productId, shouldDismiss)
    SW->>PV: updateState(SetLoadingState(LoadingPurchase))
    SW->>TM: purchase(PurchaseSource.Internal(productId, paywallState))
    TM->>TM: prepareToPurchase(...)
    TM->>PC: purchase(activity, productDetails, offerId, basePlanId)

    alt Purchased
        TM->>TM: didPurchase(...)
        alt shouldDismiss && automaticallyDismiss
            TM->>SW: dismiss(paywallCacheKey, Purchased)
        else keep paywall open
            TM->>PV: updateState(SetLoadingState(Ready))
        end
    else Failed
        TM->>TM: trackFailure(...)
        TM->>PV: updateState(ToggleSpinner(hidden=true))
        note over TM,PV: PR adds LoadingPurchase on start,
        note over TM,PV: but failure path may not reset loading state.
    else Cancelled
        TM->>TM: trackCancelled(...)
    else Pending
        TM->>TM: handlePendingTransaction(...)
    end
Loading

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

7 files reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

@greptile-apps
Copy link

greptile-apps bot commented Feb 6, 2026

Additional Comments (2)

superwall/src/main/java/com/superwall/sdk/store/transactions/TransactionManager.kt
Loading state never resets

In the PurchaseResult.Failed branch for internal purchases, you only reset the UI via ToggleSpinner(hidden = true) (line ~357), but this PR also introduced SetLoadingState(LoadingPurchase) on purchase start (Superwall.kt:1281-1283). If the paywall UI is now driven by PaywallLoadingState, a failed purchase will leave the loading state stuck on LoadingPurchase (even if the spinner is hidden), which can keep the shimmer/overlay visible and block interaction.

Fix: in the internal failure path, also call PaywallViewState.Updates.SetLoadingState(PaywallLoadingState.Ready) (or whatever the non-loading state should be) when the purchase fails. This should be done in both the alert and non-alert branches so the UI always recovers.

Prompt To Fix With AI
This is a comment left during a code review.
Path: superwall/src/main/java/com/superwall/sdk/store/transactions/TransactionManager.kt
Line: 600:609

Comment:
**Loading state never resets**

In the `PurchaseResult.Failed` branch for internal purchases, you only reset the UI via `ToggleSpinner(hidden = true)` (line ~357), but this PR also introduced `SetLoadingState(LoadingPurchase)` on purchase start (`Superwall.kt:1281-1283`). If the paywall UI is now driven by `PaywallLoadingState`, a failed purchase will leave the loading state stuck on `LoadingPurchase` (even if the spinner is hidden), which can keep the shimmer/overlay visible and block interaction.

Fix: in the internal failure path, also call `PaywallViewState.Updates.SetLoadingState(PaywallLoadingState.Ready)` (or whatever the non-loading state should be) when the purchase fails. This should be done in both the alert and non-alert branches so the UI always recovers.

How can I resolve this? If you propose a fix, please make it concise.

superwall/src/main/java/com/superwall/sdk/storage/core_data/Converters.kt
sanitizeMap now inconsistent

convertToJsonElement now supports Date, JSONArray, and JSONObject (lines ~83-90), but sanitizeMap still filters these out (line ~51). That means callers using Converters.fromMap() will silently drop these values before conversion, and the new conversion code will never run for those types.

Fix: update sanitizeMap to allow Date, JSONArray, and JSONObject (and/or explicitly document that sanitizeMap is a stricter DB-only filter and ensure callers that need these types don’t go through it).

Prompt To Fix With AI
This is a comment left during a code review.
Path: superwall/src/main/java/com/superwall/sdk/storage/core_data/Converters.kt
Line: 48:54

Comment:
**sanitizeMap now inconsistent**

`convertToJsonElement` now supports `Date`, `JSONArray`, and `JSONObject` (lines ~83-90), but `sanitizeMap` still filters these out (line ~51). That means callers using `Converters.fromMap()` will silently drop these values before conversion, and the new conversion code will never run for those types.

Fix: update `sanitizeMap` to allow `Date`, `JSONArray`, and `JSONObject` (and/or explicitly document that `sanitizeMap` is a stricter DB-only filter and ensure callers that need these types don’t go through it).

How can I resolve this? If you propose a fix, please make it concise.

@ianrumac ianrumac force-pushed the ir/feat/minor-fixes branch from 0b056c1 to 25aba58 Compare February 9, 2026 13:24
@ianrumac ianrumac changed the title Ir/feat/minor fixes Minor fixes Feb 9, 2026
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.

1 participant