Release v1.14.0 — monetization launch (E5-E8) #237

Merged
developer merged 54 commits from development into master 2026-07-10 10:11:02 +00:00
3 changed files with 20 additions and 2 deletions
Showing only changes of commit f48ebf2151 - Show all commits
+1
View File
@@ -243,6 +243,7 @@ export const en = {
'wallet.empty': 'The store is empty for now', 'wallet.empty': 'The store is empty for now',
'wallet.buy': 'Buy', 'wallet.buy': 'Buy',
'wallet.offer': 'Public offer', 'wallet.offer': 'Public offer',
'wallet.platformNoBuy': 'Purchases are not available on this platform',
'wallet.gpStub': 'To buy chips, install the RuStore build.', 'wallet.gpStub': 'To buy chips, install the RuStore build.',
'wallet.cur.RUB': '₽', 'wallet.cur.RUB': '₽',
'wallet.cur.VOTE': 'votes', 'wallet.cur.VOTE': 'votes',
+1
View File
@@ -243,6 +243,7 @@ export const ru: Record<MessageKey, string> = {
'wallet.empty': 'Магазин пока пуст', 'wallet.empty': 'Магазин пока пуст',
'wallet.buy': 'Купить', 'wallet.buy': 'Купить',
'wallet.offer': 'Публичная оферта', 'wallet.offer': 'Публичная оферта',
'wallet.platformNoBuy': 'На данной платформе покупки невозможны',
'wallet.gpStub': 'Чтобы покупать фишки, установите версию из RuStore.', 'wallet.gpStub': 'Чтобы покупать фишки, установите версию из RuStore.',
'wallet.cur.RUB': '₽', 'wallet.cur.RUB': '₽',
'wallet.cur.VOTE': 'голосов', 'wallet.cur.VOTE': 'голосов',
+18 -2
View File
@@ -1,8 +1,9 @@
<script lang="ts"> <script lang="ts">
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import Modal from '../components/Modal.svelte'; import Modal from '../components/Modal.svelte';
import { app, handleError } from '../lib/app.svelte'; import { app, handleError, showToast } from '../lib/app.svelte';
import { gateway } from '../lib/gateway'; import { gateway } from '../lib/gateway';
import { platformSubtype } from '../lib/platform';
import { t, i18n, type MessageKey } from '../lib/i18n/index.svelte'; import { t, i18n, type MessageKey } from '../lib/i18n/index.svelte';
import { executionContext, formatAmount, needsWebSpendWarning, type SpendContext } from '../lib/wallet'; import { executionContext, formatAmount, needsWebSpendWarning, type SpendContext } from '../lib/wallet';
import { isGooglePlayBuild } from '../lib/distribution'; import { isGooglePlayBuild } from '../lib/distribution';
@@ -25,6 +26,9 @@
const context: SpendContext = executionContext(); const context: SpendContext = executionContext();
const gpBuild = isGooglePlayBuild(); const gpBuild = isGooglePlayBuild();
// 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.
const purchaseBlocked = context === 'vk' && platformSubtype() === 'ios';
const values = $derived(catalog?.products.filter((p) => p.kind === 'value') ?? []); const values = $derived(catalog?.products.filter((p) => p.kind === 'value') ?? []);
const packs = $derived(catalog?.products.filter((p) => p.kind === 'pack') ?? []); const packs = $derived(catalog?.products.filter((p) => p.kind === 'pack') ?? []);
@@ -162,7 +166,16 @@
<div class="row product" data-testid="product" data-kind="pack" data-pid={p.productId}> <div class="row product" data-testid="product" data-kind="pack" data-pid={p.productId}>
<span class="name">{p.title}</span> <span class="name">{p.title}</span>
<span class="price">{formatAmount(p.moneyAmount, p.moneyCurrency)}&nbsp;{currencyLabel(p.moneyCurrency)}</span> <span class="price">{formatAmount(p.moneyAmount, p.moneyCurrency)}&nbsp;{currencyLabel(p.moneyCurrency)}</span>
<button class="buy" data-testid="buy-pack" disabled={busy} onclick={() => onOrder(p)}>{t('wallet.buy')}</button> <button
class="buy"
class:blocked={purchaseBlocked}
data-testid="buy-pack"
disabled={busy}
onclick={() => {
if (purchaseBlocked) showToast(t('wallet.platformNoBuy'));
else void onOrder(p);
}}>{t('wallet.buy')}</button
>
</div> </div>
{/each} {/each}
{#if packs.length > 0} {#if packs.length > 0}
@@ -244,6 +257,9 @@
opacity: 0.5; opacity: 0.5;
cursor: default; cursor: default;
} }
.buy.blocked {
opacity: 0.5;
}
.empty, .empty,
.stub { .stub {
margin: 0; margin: 0;