+
+ {#if isCurrent}
+
+ ▶️ Текущая
+
+ {/if}
📂 {set.categories.length} категорий
❓ {getTotalQuestions(set)} вопросов
diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte
index 67c591d..8a04f75 100644
--- a/src/routes/+page.svelte
+++ b/src/routes/+page.svelte
@@ -11,8 +11,17 @@
import GameResult from '$lib/components/GameResult.svelte';
import ConfirmDialog from '$lib/components/ConfirmDialog.svelte';
+ // ---- Локальное состояние UI ----
+
+ // Главное меню — это экран выбора набора, открытый поверх сохранённой
+ // партии. Локальный флаг: состояние игры (и localStorage) при этом НЕ
+ // меняется, прогресс сохраняется.
+ let showMainMenu = $state(false);
+
// ---- Состояние подтверждений ----
- let confirmState = $state<{ kind: 'newGame' | 'changeSet' | null }>({ kind: null });
+ let confirmState = $state<{ kind: 'newGame' | 'switchSet' | null }>({ kind: null });
+ // Какой набор ждёт подтверждения перед сбросом текущей партии.
+ let pendingSetId = $state
(null);
// Сигнал для анимации счёта.
let bumpSignal = $state(0);
@@ -35,7 +44,24 @@
// ---- Действия ведущего ----
function selectSet(id: string) {
+ const currentId = $game.questionSetId;
+
+ // Тот же набор, что уже выбран, — просто продолжаем партию (без сброса).
+ if (currentId !== null && id === currentId) {
+ showMainMenu = false;
+ return;
+ }
+
+ // Другой набор при наличии прогресса — спросим перед сбросом.
+ if (hasProgress) {
+ pendingSetId = id;
+ confirmState = { kind: 'switchSet' };
+ return;
+ }
+
+ // Прогресса нет — спокойно переходим к новому набору.
game.selectQuestionSet(id);
+ showMainMenu = false;
}
function openQuestion(ref: QuestionRef) {
@@ -91,38 +117,61 @@
else game.newGame();
}
- function askChangeSet() {
- if (hasProgress) confirmState = { kind: 'changeSet' };
- else game.changeSet();
+ /** Открыть главное меню, не сбрасывая сохранённую партию. */
+ function openMainMenu() {
+ showMainMenu = true;
+ }
+
+ /** Продолжить текущую партию — закрыть главное меню. */
+ function continueGame() {
+ showMainMenu = false;
}
function confirmAction() {
- if (confirmState.kind === 'newGame') game.newGame();
- else if (confirmState.kind === 'changeSet') game.changeSet();
+ if (confirmState.kind === 'newGame') {
+ game.newGame();
+ } else if (confirmState.kind === 'switchSet') {
+ if (pendingSetId !== null) game.selectQuestionSet(pendingSetId);
+ showMainMenu = false;
+ }
confirmState = { kind: null };
+ pendingSetId = null;
}
function cancelAction() {
confirmState = { kind: null };
+ pendingSetId = null;
}
// Прогресс в процентах для полоски.
const progressPct = $derived(
$totalQuestions > 0 ? Math.round(($playedCount / $totalQuestions) * 100) : 0
);
+
+ // Эффективный экран с учётом локального «главного меню»: когда меню открыто,
+ // показываем выбор набора, не трогая сохранённую партию.
+ const effectiveScreen = $derived(showMainMenu ? 'select' : $screen);
-{#if $screen === 'select'}
-
-{:else if $screen === 'result'}
+{#if effectiveScreen === 'select'}
+
+{:else if effectiveScreen === 'result'}
game.newGame()}
- onChangeSet={() => game.changeSet()}
+ onMainMenu={openMainMenu}
/>
-{:else if $screen === 'board' || $screen === 'question'}
+{:else if effectiveScreen === 'board' || effectiveScreen === 'question'}
{@const set = $currentSet}
{#if set}
-{#if $screen === 'question' && currentQuestionData}
+{#if effectiveScreen === 'question' && currentQuestionData}