3306a016a0
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 12s
CI / integration (pull_request) Successful in 28s
CI / ui (pull_request) Successful in 1m11s
CI / conformance (pull_request) Successful in 10s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m46s
Carry the caller's per-tier active-game caps and each game's kind on the wire (Profile.game_limits + GameView.kind, additive FBS + gateway transcode + client codec, committed regen). The New Game screen counts the player's active games per kind from the lobby and locks a capped start: an outline button with a lock that opens a funnel modal instead of a game -- a sign-in prompt for a guest, a "finish a current game first" notice for a signed-in account (native Telegram popup, in-app modal elsewhere). The lock lifts via the existing profile refetch after a guest->durable upgrade. Remove the lobby's old at_game_limit New-Game tab disable + notice: the flag (now the random-kind cap) conflicted with the per-kind lock -- it hid the screen where the lock lives and wrongly blocked an unfulfilled kind. The New Game tab is always enabled; the per-kind start lock is the only gate. The at_game_limit wire field stays (unused by the client) for a later cleanup. Tests: client lock logic + codec kind/game_limits roundtrip + gateway transcode encode + native popup builders (unit); a mock e2e for the lock badge and the modal.
40 lines
2.2 KiB
TypeScript
40 lines
2.2 KiB
TypeScript
// Pure builder for the Telegram native popup (showPopup) used by the deep-link info modals
|
|
// (StaleInviteModal / WelcomeRedeemModal) inside the Mini App. Kept free of the SDK and the DOM so
|
|
// it unit-tests in the node environment; the showPopup transport wrapper lives in telegram.ts and
|
|
// the wiring (native inside Telegram, the in-app Modal elsewhere) in the modal components.
|
|
|
|
import type { TelegramPopupParams } from './telegram';
|
|
|
|
/** BOT_BUTTON_ID is the showPopup button id that means "open the bot chat". */
|
|
export const BOT_BUTTON_ID = 'bot';
|
|
|
|
/** LOGIN_BUTTON_ID is the game-limit popup button that opens the sign-in funnel. */
|
|
export const LOGIN_BUTTON_ID = 'login';
|
|
|
|
/** gameLimitGuestPopup builds the native popup that nudges a guest to sign in when a New-Game start
|
|
* is capped for guests: a cancel button and a login button (the sign-in funnel). */
|
|
export function gameLimitGuestPopup(title: string, message: string, cancelText: string, loginText: string): TelegramPopupParams {
|
|
return { title, message, buttons: [{ id: 'cancel', text: cancelText }, { id: LOGIN_BUTTON_ID, text: loginText }] };
|
|
}
|
|
|
|
/** gameLimitDurablePopup builds the native notice shown to a durable account at its per-kind cap:
|
|
* an OK button only (finish a current game first). */
|
|
export function gameLimitDurablePopup(title: string, message: string, okText: string): TelegramPopupParams {
|
|
return { title, message, buttons: [{ id: 'ok', text: okText }] };
|
|
}
|
|
|
|
/**
|
|
* botInfoPopup builds the native popup for a deep-link info modal: the message with the `{bot}`
|
|
* token replaced by the `@username` as plain text (a native popup has no inline link, unlike the
|
|
* in-app Modal), plus an "open bot" button when a username is known and a closing OK button. With
|
|
* no username it is the message (token removed) and OK only.
|
|
*/
|
|
export function botInfoPopup(title: string, message: string, username: string, okText: string): TelegramPopupParams {
|
|
const handle = username ? `@${username}` : '';
|
|
const text = (username ? message.replace('{bot}', handle) : message.replace('{bot}', '').replace(' ', ' ')).trim();
|
|
const buttons = username
|
|
? [{ id: BOT_BUTTON_ID, text: handle }, { id: 'ok', text: okText }]
|
|
: [{ id: 'ok', text: okText }];
|
|
return { title, message: text, buttons };
|
|
}
|