diff --git a/ui/src/lib/i18n/en.ts b/ui/src/lib/i18n/en.ts index 71e07b4..db0cad9 100644 --- a/ui/src/lib/i18n/en.ts +++ b/ui/src/lib/i18n/en.ts @@ -257,6 +257,7 @@ export const en = { 'invitations.with': 'With {names}', 'invitations.accept': 'Accept', 'invitations.decline': 'Decline', + 'invitations.declineConfirm': 'Decline invitation?', 'invitations.cancel': 'Cancel', 'invitations.waiting': 'Waiting for replies', @@ -264,10 +265,10 @@ export const en = { 'new.withFriends': 'Play with friends', 'new.pickFriends': 'Choose who to invite', 'new.searchFriends': 'Search friends', - 'new.gameType': 'Game type', + 'new.gameType': 'Variant', 'new.invite': 'Send invitation', 'new.moveTime': 'Move time', - 'new.hintsPerPlayer': 'Hints per player', + 'new.hintsPerPlayer': 'Hints', 'new.multipleWordsPerTurn': 'Multiple words per turn', 'new.start': 'Start game', 'new.invited': 'Invitation sent.', diff --git a/ui/src/lib/i18n/ru.ts b/ui/src/lib/i18n/ru.ts index 122260f..4321efd 100644 --- a/ui/src/lib/i18n/ru.ts +++ b/ui/src/lib/i18n/ru.ts @@ -258,6 +258,7 @@ export const ru: Record = { 'invitations.with': 'С {names}', 'invitations.accept': 'Принять', 'invitations.decline': 'Отклонить', + 'invitations.declineConfirm': 'Отклонить приглашение?', 'invitations.cancel': 'Отменить', 'invitations.waiting': 'Ожидаем ответы', @@ -265,10 +266,10 @@ export const ru: Record = { 'new.withFriends': 'Игра с друзьями', 'new.pickFriends': 'Кого пригласить', 'new.searchFriends': 'Поиск друзей', - 'new.gameType': 'Тип игры', + 'new.gameType': 'Вариант', 'new.invite': 'Отправить приглашение', 'new.moveTime': 'Время на ход', - 'new.hintsPerPlayer': 'Подсказок на игрока', + 'new.hintsPerPlayer': 'Подсказки', 'new.multipleWordsPerTurn': 'Несколько слов за ход', 'new.start': 'Начать игру', 'new.invited': 'Приглашение отправлено.', diff --git a/ui/src/screens/Lobby.svelte b/ui/src/screens/Lobby.svelte index c8c5f73..b06ba42 100644 --- a/ui/src/screens/Lobby.svelte +++ b/ui/src/screens/Lobby.svelte @@ -3,17 +3,19 @@ import { SvelteMap, SvelteSet } from 'svelte/reactivity'; import Screen from '../components/Screen.svelte'; import TabBar from '../components/TabBar.svelte'; + import Modal from '../components/Modal.svelte'; import { app, handleError, refreshFeedbackBadge, seedChatUnread } from '../lib/app.svelte'; import { connection } from '../lib/connection.svelte'; import { gateway } from '../lib/gateway'; import { navigate } from '../lib/router.svelte'; - import { t, type MessageKey } from '../lib/i18n/index.svelte'; + import { t } from '../lib/i18n/index.svelte'; import { resultBadge } from '../lib/result'; import { badgeKind } from '../lib/unread'; import { getLobby, setLobby } from '../lib/lobbycache'; import { preloadGames } from '../lib/preload'; import { gamePhase, groupGames, orderedSeats, scoreStanding, shouldBlink, type LobbyPhase } from '../lib/lobbysort'; import type { AccountRef, GameView, Invitation } from '../lib/model'; + import { VARIANT_FLAG, VARIANT_RULES } from '../lib/variants'; let games = $state([]); let invitations = $state([]); @@ -209,11 +211,14 @@ } } - const variantKey: Record = { - scrabble_en: 'new.english', - scrabble_ru: 'new.russian', - erudit_ru: 'new.erudit', - }; + // The invitation pending a decline confirmation: the ❌ opens a modal (mirroring the + // in-game resign confirmation) rather than declining on the first tap. + let declineTarget = $state(null); + function confirmDecline() { + const inv = declineTarget; + declineTarget = null; + if (inv) declineInvite(inv); + } @@ -230,16 +235,23 @@ {t('invitations.waiting')} {:else} {t('invitations.from', { name: inv.inviter.displayName })} - {t(variantKey[inv.variant] ?? 'new.english')} + + {#if VARIANT_FLAG[inv.variant]} + {VARIANT_FLAG[inv.variant]} + {:else} + + {/if} + {t(VARIANT_RULES[inv.variant])} + {/if} {#if !inv.multipleWordsPerTurn}{t('game.oneWordRule')}{/if} {#if inv.inviter.accountId === myId} - + {:else} - - + + {/if} @@ -308,6 +320,15 @@ {/if} + {#if declineTarget} + (declineTarget = null)}> +
+ + +
+
+ {/if} + {#snippet tabbar()}