feat(android): resolve gateway origin on native, skip SW, hide MVP purchases
Make the web SPA behave correctly inside the Capacitor native shell, where the bundle loads from a local origin: - New lib/origin.ts gatewayOrigin(): absolute URLs resolve to VITE_GATEWAY_URL on native (the finished-game export/share URL in Game.svelte and the Wallet site-root link), falling back to the page origin on web. transport.ts already resolved via VITE_GATEWAY_URL and is left as-is. - Skip the PWA service worker on the native channel (the assets are already local; a worker would risk serving stale content across store updates). - Hide the money-purchase UI in the MVP: new distribution.purchasesHidden() folds VITE_PAYMENTS_DISABLED and the Google Play flag. The Wallet "buy" tab shows a neutral, pointer-free note (wallet.purchasesSoon) for the RuStore MVP and keeps the RuStore stub Google-Play-only. A ?nopay mock force mirrors ?gp for the e2e. - Native env types in vite-env.d.ts. Client-only, contour-safe: no wire/proto/schema change; web/VK/Telegram unchanged. Tests: origin + purchasesHidden unit tests, a ?nopay wallet e2e. svelte-check clean, vitest green, web + native vite build clean.
This commit is contained in:
@@ -6,8 +6,9 @@
|
||||
import { normalizeSubtype } from '../lib/platform';
|
||||
import { t, i18n, type MessageKey } from '../lib/i18n/index.svelte';
|
||||
import { executionContext, formatAmount, needsWebSpendWarning, spendableChips, type SpendContext } from '../lib/wallet';
|
||||
import { isGooglePlayBuild } from '../lib/distribution';
|
||||
import { isGooglePlayBuild, purchasesHidden } from '../lib/distribution';
|
||||
import { onExternalLinkClick, openExternalUrl } from '../lib/links';
|
||||
import { gatewayOrigin } from '../lib/origin';
|
||||
import { vkPlatform, vkShowOrderBox } from '../lib/vk';
|
||||
import { telegramOpenInvoice } from '../lib/telegram';
|
||||
import { rewardedReady, showRewarded } from '../lib/ads';
|
||||
@@ -16,8 +17,9 @@
|
||||
|
||||
// The Wallet section: a compact chip balance, the active benefits, and the storefront. The store
|
||||
// splits into "buy chips" (chip packs, funded with money — a provider redirect) and "spend chips"
|
||||
// (values bought with chips — an instant exchange). On the Google Play build the money purchases
|
||||
// are hidden behind a RuStore stub (store policy), while spending already-earned chips still works.
|
||||
// (values bought with chips — an instant exchange). When purchases are hidden — the Google Play
|
||||
// build (behind a RuStore stub, store policy) or the native MVP that defers billing (a neutral
|
||||
// note) — the money purchases disappear while spending already-earned chips still works.
|
||||
|
||||
let wallet = $state<Wallet | null>(null);
|
||||
let catalog = $state<Catalog | null>(null);
|
||||
@@ -38,13 +40,16 @@
|
||||
);
|
||||
|
||||
const gpBuild = isGooglePlayBuild();
|
||||
// Money purchases are hidden in the Google Play build (policy) and in the native MVP that defers
|
||||
// billing; the RuStore-pointer stub shows only for the former (gpBuild).
|
||||
const noPurchases = purchasesHidden();
|
||||
// Money purchases are not permitted inside the VK iOS app (Apple ToS); the pack CTA is shown
|
||||
// muted and taps explain why, rather than hiding the storefront. VK's device family is not on the
|
||||
// client platformSubtype (server-derived) — read it from the signed vk_platform launch param.
|
||||
const purchaseBlocked = context === 'vk' && normalizeSubtype(vkPlatform()) === 'ios';
|
||||
// The "other version" link points at this deployment's own site root (the landing lists every
|
||||
// platform), so it follows prod vs the contour without a hardcoded host.
|
||||
const siteRoot = typeof location !== 'undefined' ? `${location.origin}/` : '/';
|
||||
const siteRoot = `${gatewayOrigin()}/`;
|
||||
|
||||
const values = $derived(catalog?.products.filter((p) => p.kind === 'value') ?? []);
|
||||
const packs = $derived(catalog?.products.filter((p) => p.kind === 'pack') ?? []);
|
||||
@@ -237,8 +242,12 @@
|
||||
>
|
||||
</div>
|
||||
{/if}
|
||||
{#if gpBuild}
|
||||
<p class="stub" data-testid="gp-stub">{t('wallet.gpStub')}</p>
|
||||
{#if noPurchases}
|
||||
{#if gpBuild}
|
||||
<p class="stub" data-testid="gp-stub">{t('wallet.gpStub')}</p>
|
||||
{:else}
|
||||
<p class="stub" data-testid="purchases-hidden">{t('wallet.purchasesSoon')}</p>
|
||||
{/if}
|
||||
{:else}
|
||||
{#each packs as p (p.productId)}
|
||||
<div class="row product" data-testid="product" data-kind="pack" data-pid={p.productId}>
|
||||
|
||||
Reference in New Issue
Block a user