diff --git a/ToDo.md b/ToDo.md index f2a0783..088b5ec 100644 --- a/ToDo.md +++ b/ToDo.md @@ -1,9 +1,9 @@ [ ] Improove: In the preview page, add full header. -[ ] Improove: Split header into two parts: static top and dynamic bottom. [ ] Improove: In the preview page, add possibility select custom color for each target. -[ ] Strategy: Add quiz game to guess the logo or flags and invert Done: +[v] Strategy: Add quiz game to guess the logo or flags and invert +[v] Improove: Split header into two parts: static top and dynamic bottom. [v] Improove: To the tiny card add the color chooser. It should be one circle that display current color, on click it should open color picker. [v] Strategy: Add differents base/collections of images: Flags, [v] Strategy: WebApp, PWA diff --git a/public/icons/danger-triangle.svg b/public/icons/danger-triangle.svg new file mode 100644 index 0000000..cafb954 --- /dev/null +++ b/public/icons/danger-triangle.svg @@ -0,0 +1,6 @@ + + diff --git a/src/components/QuizSettings.svelte b/src/components/QuizSettings.svelte new file mode 100644 index 0000000..7cd442d --- /dev/null +++ b/src/components/QuizSettings.svelte @@ -0,0 +1,374 @@ + + +{#if showSettings} +
+{/if} + +{#if showResetConfirmation} + +{/if} + + diff --git a/src/pages/FlagQuiz.svelte b/src/pages/FlagQuiz.svelte index c6d278e..fc33fa9 100644 --- a/src/pages/FlagQuiz.svelte +++ b/src/pages/FlagQuiz.svelte @@ -4,7 +4,7 @@ import Footer from '../components/Footer.svelte'; import InlineSvg from '../components/InlineSvg.svelte'; import Achievements from '../components/Achievements.svelte'; - import AchievementButton from '../components/AchievementButton.svelte'; + import QuizSettings from '../components/QuizSettings.svelte'; // Game data let flags = []; @@ -27,6 +27,12 @@ let showCountryInfo = false; let showResultCountryInfo = false; + // Auto-advance timer variables + let autoAdvanceTimer = null; + let timerProgress = 0; + let timerDuration = 2000; // 2 seconds + let timerStartTime = 0; + // Scoring let score = { correct: 0, total: 0, skipped: 0 }; let gameStats = { correct: 0, wrong: 0, total: 0, skipped: 0 }; @@ -197,6 +203,9 @@ showCountryInfo = false; showResultCountryInfo = false; + // Cancel any active auto-advance timer + cancelAutoAdvanceTimer(); + // Randomly choose question type questionType = Math.random() < 0.5 ? 'flag-to-country' : 'country-to-flag'; @@ -348,9 +357,7 @@ // Auto-advance to next question with different delays if auto mode is on if (autoAdvance) { const delay = isCorrect ? 2000 : 4000; // Double delay for wrong answers - setTimeout(() => { - generateQuestion(); - }, delay); + startAutoAdvanceTimer(delay); } } function skipQuestion() { if (gameState !== 'question') return; @@ -377,6 +384,38 @@ generateQuestion(); } + function startAutoAdvanceTimer(duration) { + timerDuration = duration; + timerProgress = 0; + timerStartTime = Date.now(); + + // Clear any existing timer + if (autoAdvanceTimer) { + clearInterval(autoAdvanceTimer); + } + + // Update progress every 50ms for smooth animation + autoAdvanceTimer = setInterval(() => { + const elapsed = Date.now() - timerStartTime; + timerProgress = Math.min((elapsed / duration) * 100, 100); + + if (timerProgress >= 100) { + clearInterval(autoAdvanceTimer); + autoAdvanceTimer = null; + timerProgress = 0; + generateQuestion(); + } + }, 50); + } + + function cancelAutoAdvanceTimer() { + if (autoAdvanceTimer) { + clearInterval(autoAdvanceTimer); + autoAdvanceTimer = null; + timerProgress = 0; + } + } + function resetGame() { score = { correct: 0, total: 0, skipped: 0 }; generateQuestion(); @@ -396,23 +435,23 @@ showSettings = !showSettings; } - function handleOverlayClick(event) { - if (event.target === event.currentTarget) { - toggleSettings(); - } + function handleSettingsChange(event) { + const { autoAdvance: newAutoAdvance, focusWrongAnswers: newFocusWrong, reduceCorrectAnswers: newReduceCorrect, soundEnabled: newSoundEnabled } = event.detail; + autoAdvance = newAutoAdvance; + focusWrongAnswers = newFocusWrong; + reduceCorrectAnswers = newReduceCorrect; + soundEnabled = newSoundEnabled; } - function handleOverlayKeydown(event) { - if (event.key === 'Escape') { - toggleSettings(); - } + function handleSettingsToggle(event) { + showSettings = event.detail; } - function resetAllStats() { - showResetConfirmation = true; + function handleResetConfirmation(event) { + showResetConfirmation = event.detail; } - function confirmReset() { + function handleResetStats() { // Reset game statistics gameStats = { correct: 0, wrong: 0, total: 0, skipped: 0 }; score = { correct: 0, total: 0, skipped: 0 }; @@ -427,16 +466,12 @@ correctAnswers = new Map(); localStorage.removeItem('flagQuizCorrectAnswers'); - // Reset achievements + // Reset achievements if component is available if (achievementsComponent) { - localStorage.removeItem('flagQuizAchievements'); - // Reinitialize achievements component - achievementsComponent.loadAchievements(); - updateAchievementCount(); + achievementsComponent.resetAllAchievements(); } showResetConfirmation = false; - showSettings = false; } function cancelReset() { @@ -535,115 +570,21 @@