[DO NOT MERGE] Special release 2.7.24 — 2.7.23 + backported fixes - #451
Closed
ianrumac wants to merge 7 commits into
Closed
[DO NOT MERGE] Special release 2.7.24 — 2.7.23 + backported fixes#451ianrumac wants to merge 7 commits into
ianrumac wants to merge 7 commits into
Conversation
…ll events Superwall-Android never wrote presentation_id into outgoing paywall event payloads (paywall_page_view, paywall_open, paywall_close, etc.), which breaks any dashboard funnel that correlates a set of page views into one paywall session. Confirmed on live ClickHouse data: the field is 100% empty on Android across every SDK version, vs 0% empty on iOS. - PaywallCloseReason: add a `description` extension mirroring iOS's camelCase close-reason strings (systemLogic, forNextPaywall, webViewFailedToLoad, manualClose, none). - PaywallInfo: add `presentationId`, and serialize it alongside the already-modeled-but-never-emitted close_reason/cache_key/build_id in eventParams(). - Paywall: add a transient `presentationId` field, threaded through getInfo(). - PaywallRequestManager.updatePaywall: mint a fresh UUID presentationId on every getPaywall() call that results in a presentation (fresh fetch, in-flight-task reuse, and content-cache hit), so repeat presentations of a cached paywall get distinct, correlatable IDs. Trade-off: PaywallLoad.Complete/PaywallProductsLoad.* events track before updatePaywall runs, so they won't carry presentation_id — same existing timing gap as experiment_id/variant_id/presentation_source_type. paywall_open/paywall_page_view/paywall_close all fire after updatePaywall and reliably get a stable ID.
Translated paywalls rendered in the default language first, then visibly
re-rendered once the template_variables message delivered deviceLocale to
paywall.js (that message is gated on product/billing loading, so it can
take seconds). The web runtime now reads window.__SW_DEVICE_PRELOAD__ at
boot and seeds its locale from it, so inject that global before any page
JavaScript runs:
- Add DevicePreloadScript, a pure builder that serializes the payload
with kotlinx.serialization so hostile locale strings cannot break out
of the script, producing exactly:
window.__SW_DEVICE_PRELOAD__ = {"deviceLocale":"en_US"};
- Install it via WebViewCompat.addDocumentStartJavaScript (androidx.webkit,
new dependency) when the WebView supports DOCUMENT_START_SCRIPT, and
fall back to evaluateJavascript in WebViewClient.onPageStarted on older
WebView versions.
- The locale comes from PaywallViewState.locale, which is the same
DeviceHelper.locale value later sent as deviceLocale in
template_variables, so the later message is a visual no-op.
- Unit-test the builder (exact output, quote escaping, longer and
non-ASCII locales) and add a CHANGELOG entry.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01775Up1AYfMgNQybxjnoDSg
The test asserted externalAccountId equals sha256-of-user-123 but never stubbed storage.read(AppUserId), so userId fell back to the generated anonymous alias. Stub the stored app user ID like the sibling test does. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UL13jCN87cPLKtmZnTYUrb
The document-start script path required adding androidx.webkit as a new dependency for every SDK user. It bought little: the paywall runtime reads window.__SW_DEVICE_PRELOAD__ when its network-fetched bundle boots, so an evaluateJavascript from onPageStarted lands well before that — and since the web runtime now seeds exclusively from the preload global, a missed injection just means today's behavior (wait for template_variables), never a wrong translation. This matches how the SDK already injects JS (plain evaluateJavascript, like the selection/zoom scripts), just hooked at page start rather than template delivery, which would be too late. DevicePreloadScript and its tests are unchanged; the script is now built lazily in the hook so it always uses the freshest locale. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01775Up1AYfMgNQybxjnoDSg
Bump SUPERWALL_VERSION to 2.7.24 and stamp the changelog: this release is 2.7.23 plus the fixes backported from develop (translation first-paint, Play Store user ID hashing, presentation_id/close_reason/cache_key/build_id on paywall events), without the 2.8.0 changes (Billing 9, custom store products, minSdk 23). Also add a `publish` input to the Build, Test & Publish workflow so a manual workflow_dispatch on a non-main branch can opt into the full publish/tag/release flow, which was previously gated to pushes on main. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QQGVCTwCQwWYFVHCHosoFg
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This branch is cut from the
2.7.23tag, not fromdevelop/main. It exists to be tagged and released directly as2.7.24via a manual workflow run — it is a review vehicle only. Merging it intodevelopwould downgradeversion.envfrom 2.8.0 to 2.7.24 and conflict with the 2.8.0 changelog (GitHub already flags it as conflicting). Close this PR without merging once 2.7.24 is released.What this is
A special patch release for users who want the latest fixes but are not ready for the 2.8.0 upgrade (Play Billing 9, custom store products, minSdk 23). It is
2.7.23+ the unreleased fixes cherry-picked fromdevelop:paywall_open,paywall_page_view,paywall_close, …) now emitpresentation_id, plus the previously-missingclose_reason,cache_key, andbuild_idfields, matching iOS.externalAccountIdattached to Play Store purchases was computed from an internal object reference instead of the user ID.onPageStartedeval, no androidx.webkit dependency), so translated paywalls render in the user's language on first paint.Plus release prep:
version.env→ 2.7.24, a stamped## 2.7.24changelog section, and apublishinput on the Build, Test & Publish workflow so a manualworkflow_dispatchon a non-main branch can opt into the full publish/tag/release flow.How to release
Actions → Build, Test & Publish → Run workflow → branch
claude/backport-2-7-24-release-2m3hxs→ check publish → Run. This publishes to Maven Central, tags2.7.24, and creates the GitHub release with the changelog section as notes.Checklist
develop— remaining diffs are 2.8.0-only features, as intendedCHANGELOG.mdhas a2.7.24section (no 2.8.0 section on this branch — it's the 2.7.x lineage)🤖 Generated with Claude Code
https://claude.ai/code/session_01QQGVCTwCQwWYFVHCHosoFg