Conversation
An app that displays its own dialogs from PLYUIHandler.onAlert must end every branch with proceed() or alert.onDismiss(). proceed() displays the SDK dialog and dismisses the alert; alert.onDismiss() dismisses it with no dialog. Calling neither leaves the paywall action pending, so the Screen stays displayed and stops reacting to taps, close button included. The plugin had no coverage of PLYUIHandler at all — only a grep pattern in the review skill — so the frozen-Screen troubleshooting pointed solely at an unresolved interceptor. Early v5 releases did not wait for the dismissal, which makes this a latent v5 bug a v6 migration surfaces. Mirrors Documentation@15e3faa0. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
| ```kotlin | ||
| Purchasely.uiHandler = object : PLYUIHandler { | ||
| override fun onAlert(alert: PLYAlertMessage, purchaselyView: View, activity: Activity?, proceed: () -> Unit) { | ||
| val context = activity ?: return proceed() // no activity: let the SDK display the alert |
There was a problem hiding this comment.
When activity is null or the presentation view is detached, proceed() cannot display the SDK dialog, so alert.onDismiss() is never triggered. The alert remains pending and blocks the shared action queue, leaving the paywall unresponsive—the exact freeze this example is meant to prevent. Use alert.onDismiss() for this fallback instead. The same unsafe fallback also appears in common-patterns.md, migration-v6.md, and common-issues.md.
Greptile automatically discovered a related ticket stating that a null activity or detached view prevents proceed() from completing the alert, which informed this comment.
Source Used: Linear — Android v6: onAlert without proceed() blocks the actions queue and locks the paywall
Prompt To Fix With AI
This is a comment left during a code review.
Path: purchasely/references/android/api-reference.md
Line: 408
Comment:
**Null fallback blocks actions**
When `activity` is null or the presentation view is detached, `proceed()` cannot display the SDK dialog, so `alert.onDismiss()` is never triggered. The alert remains pending and blocks the shared action queue, leaving the paywall unresponsive—the exact freeze this example is meant to prevent. Use `alert.onDismiss()` for this fallback instead. The same unsafe fallback also appears in `common-patterns.md`, `migration-v6.md`, and `common-issues.md`.
Greptile automatically discovered a related ticket stating that a null activity or detached view prevents `proceed()` from completing the alert, which informed this comment.
**Source Used:** Linear — [Android v6: onAlert without proceed() blocks the actions queue and locks the paywall](https://linear.app/purchasely/issue/MOB-462/android-v6-onalert-without-proceed-blocks-the-actions-queue-and-locks)
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.
Summary
Mirrors Documentation@15e3faa0 into the plugin. An app that displays its own dialogs from
PLYUIHandler.onAlertmust end every branch withproceed()(the SDK displays its dialog and dismisses the alert) oralert.onDismiss()(dismisses it with no dialog). Calling neither leaves the paywall action pending, so the Screen stays displayed and stops reacting to taps, close button included.The plugin had no coverage of
PLYUIHandlerat all — only a grep pattern in the review skill — so its frozen-Screen troubleshooting pointed solely at an unresolved interceptor. Early v5 releases did not wait for the dismissal, which makes this a latent v5 bug that a v6 migration surfaces.Type of change
skills/)What changed
References
references/android/api-reference.md— new UI Handler — Alerts section: theproceed()vsalert.onDismiss()table, why the action stays pending, thePLYAlertMessagebase-class helpers (onDismiss(),getTitleContent(),getContentMessage(),getButtonContent()), and the two rules — dismiss after your dialog closes, never call both.references/android/migration-v6.md— aPLYUIHandlersection plus verification-checklist item 11.references/android/common-patterns.md— a Custom alert dialogs pattern dismissing fromsetOnDismissListener.references/troubleshooting/common-issues.md— §2 "UI Frozen / Paywall Stuck" now splits Cause A (Android UI handler) from Cause B (unresolved interceptor), plus a row in the symptom → likely cause table.references/concepts/paywall-actions.md— an Android anti-pattern, tying the freeze to the same root shape as an unresolved interceptor.Skills
purchasely-review— check 3.3 flags a branch that can skip both calls, both calls made for the same alert, andonDismiss()called before the custom dialog closes. Search patterns now includeuiHandler/setUIHandler(/onAlert(.purchasely-debug— the UI handler as the second Android cause in "UI Frozen After Paywall Action", a new audit step, and a symptom-table row.purchasely-migrate— a UI handler alerts step in the Android workflow (later steps renumbered).purchasely-sdk-expert— a routing-index row forPLYUIHandlerquestions.Scope decisions
SKIPon iOS and the cross-platform bridges) — the single-action-queue behaviour documented upstream is Android-specific. Worth a second opinion if iOS shares it.purchasely-integrateis untouched: it does not generate a UI handler, so a check there would be noise.How was this tested?
Documentation-only change — no manifests, versions, or descriptions touched, so no agentskill.sh re-scan is needed. Verified that the
## UI Handler — AlertsandPLYUIHandleranchor targets exist and that every relative link added (../android/api-reference.md,../../references/android/api-reference.md,../../references/android/migration-v6.md) resolves to a real file. Confirmed the renumbered ordered lists inpurchasely-migrate(1–15) andpurchasely-debug(1–6) are sequential.Checklist
CHANGELOG.mdunder[Unreleased].claude-plugin/plugin.jsonand.claude-plugin/marketplace.jsonare still consistent🤖 Generated with Claude Code