mirror of
https://github.com/shadoll/sLogos.git
synced 2025-12-20 03:26:59 +00:00
Refactor CapitalsQuiz and FlagQuiz to utilize shared logic for achievements and settings management, enhancing code consistency and maintainability.
This commit is contained in:
@@ -1,4 +1,9 @@
|
|||||||
<script>
|
<script>
|
||||||
|
import { updateAchievementCount as sharedUpdateAchievementCount } from '../quizLogic/quizAchievements.js';
|
||||||
|
import { saveSettings as sharedSaveSettings, loadSettings as sharedLoadSettings } from '../quizLogic/quizSettings.js';
|
||||||
|
import { loadGlobalStats as sharedLoadGlobalStats, updateGlobalStats as sharedUpdateGlobalStats } from '../quizLogic/quizGlobalStats.js';
|
||||||
|
import { saveSessionState as sharedSaveSessionState, loadSessionState as sharedLoadSessionState, clearSessionState as sharedClearSessionState } from '../quizLogic/quizSession.js';
|
||||||
|
import { playCorrectSound as sharedPlayCorrectSound, playWrongSound as sharedPlayWrongSound } from '../quizLogic/quizSound.js';
|
||||||
import { quizInfo } from '../quizInfo/CapitalsQuizInfo.js';
|
import { quizInfo } from '../quizInfo/CapitalsQuizInfo.js';
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
import Header from "../components/Header.svelte";
|
import Header from "../components/Header.svelte";
|
||||||
@@ -87,21 +92,18 @@
|
|||||||
|
|
||||||
// Update achievement count when achievements component is available
|
// Update achievement count when achievements component is available
|
||||||
$: if (achievementsComponent) {
|
$: if (achievementsComponent) {
|
||||||
updateAchievementCount();
|
achievementCount = sharedUpdateAchievementCount(achievementsComponent);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save settings when they change (after initial load)
|
// Save settings when they change (after initial load)
|
||||||
$: if (settingsLoaded && typeof reduceCorrectAnswers !== "undefined") {
|
$: if (settingsLoaded && typeof reduceCorrectAnswers !== "undefined") {
|
||||||
localStorage.setItem(
|
sharedSaveSettings("capitalsQuizSettings", {
|
||||||
"capitalsQuizSettings",
|
autoAdvance,
|
||||||
JSON.stringify({
|
focusWrongAnswers,
|
||||||
autoAdvance,
|
reduceCorrectAnswers,
|
||||||
focusWrongAnswers,
|
soundEnabled,
|
||||||
reduceCorrectAnswers,
|
sessionLength,
|
||||||
soundEnabled,
|
});
|
||||||
sessionLength,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load game stats from localStorage
|
// Load game stats from localStorage
|
||||||
@@ -162,31 +164,23 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Load settings
|
// Load settings
|
||||||
const savedSettings = localStorage.getItem("capitalsQuizSettings");
|
const loadedSettings = sharedLoadSettings("capitalsQuizSettings", {
|
||||||
if (savedSettings) {
|
autoAdvance,
|
||||||
try {
|
focusWrongAnswers,
|
||||||
const settings = JSON.parse(savedSettings);
|
reduceCorrectAnswers,
|
||||||
autoAdvance =
|
soundEnabled,
|
||||||
settings.autoAdvance !== undefined ? settings.autoAdvance : true;
|
sessionLength,
|
||||||
focusWrongAnswers =
|
});
|
||||||
settings.focusWrongAnswers !== undefined
|
if (loadedSettings) {
|
||||||
? settings.focusWrongAnswers
|
autoAdvance = loadedSettings.autoAdvance;
|
||||||
: false;
|
focusWrongAnswers = loadedSettings.focusWrongAnswers;
|
||||||
reduceCorrectAnswers =
|
reduceCorrectAnswers = loadedSettings.reduceCorrectAnswers;
|
||||||
settings.reduceCorrectAnswers !== undefined
|
soundEnabled = loadedSettings.soundEnabled;
|
||||||
? settings.reduceCorrectAnswers
|
sessionLength = loadedSettings.sessionLength;
|
||||||
: false;
|
|
||||||
soundEnabled =
|
|
||||||
settings.soundEnabled !== undefined ? settings.soundEnabled : true;
|
|
||||||
sessionLength =
|
|
||||||
settings.sessionLength !== undefined ? settings.sessionLength : 10;
|
|
||||||
} catch (e) {
|
|
||||||
console.error("Error loading settings:", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load global stats and update them
|
// Load global stats and update them
|
||||||
loadGlobalStats();
|
sharedLoadGlobalStats("globalQuizStats");
|
||||||
}
|
}
|
||||||
|
|
||||||
await loadFlags();
|
await loadFlags();
|
||||||
@@ -255,50 +249,37 @@
|
|||||||
sessionStartTime,
|
sessionStartTime,
|
||||||
questionKey,
|
questionKey,
|
||||||
};
|
};
|
||||||
localStorage.setItem("capitalsQuizSessionState", JSON.stringify(sessionState));
|
sharedSaveSessionState("capitalsQuizSessionState", sessionState);
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadSessionState() {
|
function loadSessionState() {
|
||||||
const savedState = localStorage.getItem("capitalsQuizSessionState");
|
const loadedSession = sharedLoadSessionState("capitalsQuizSessionState", null);
|
||||||
if (savedState) {
|
if (loadedSession) {
|
||||||
try {
|
// Restore session
|
||||||
const state = JSON.parse(savedState);
|
sessionInProgress = loadedSession.sessionInProgress;
|
||||||
if (state.sessionInProgress) {
|
currentSessionQuestions = loadedSession.currentSessionQuestions || 0;
|
||||||
// Restore session
|
sessionStats = loadedSession.sessionStats || {
|
||||||
sessionInProgress = state.sessionInProgress;
|
correct: 0,
|
||||||
currentSessionQuestions = state.currentSessionQuestions || 0;
|
wrong: 0,
|
||||||
sessionStats = state.sessionStats || {
|
skipped: 0,
|
||||||
correct: 0,
|
total: 0,
|
||||||
wrong: 0,
|
sessionLength,
|
||||||
skipped: 0,
|
};
|
||||||
total: 0,
|
score = loadedSession.score || { correct: 0, total: 0, skipped: 0 };
|
||||||
sessionLength,
|
currentQuestion = loadedSession.currentQuestion;
|
||||||
};
|
selectedAnswer = loadedSession.selectedAnswer;
|
||||||
score = state.score || { correct: 0, total: 0, skipped: 0 };
|
showResult = loadedSession.showResult || false;
|
||||||
currentQuestion = state.currentQuestion;
|
gameState = loadedSession.gameState || "question";
|
||||||
selectedAnswer = state.selectedAnswer;
|
quizSubpage = "quiz";
|
||||||
showResult = state.showResult || false;
|
sessionStartTime = loadedSession.sessionStartTime;
|
||||||
gameState = state.gameState || "question";
|
questionKey = loadedSession.questionKey || 0;
|
||||||
quizSubpage = "quiz";
|
|
||||||
sessionStartTime = state.sessionStartTime;
|
|
||||||
questionKey = state.questionKey || 0;
|
|
||||||
|
|
||||||
// Mark that session was restored from reload
|
// Mark that session was restored from reload
|
||||||
sessionRestoredFromReload = true;
|
sessionRestoredFromReload = true;
|
||||||
|
|
||||||
// If we don't have a current question, generate one
|
// If we don't have a current question, generate one
|
||||||
if (!currentQuestion) {
|
if (!currentQuestion) {
|
||||||
generateQuestion();
|
generateQuestion();
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// No active session, show welcome page
|
|
||||||
quizSubpage = "welcome";
|
|
||||||
gameState = "welcome";
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.error("Error loading session state:", e);
|
|
||||||
quizSubpage = "welcome";
|
|
||||||
gameState = "welcome";
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// No saved state, show welcome page
|
// No saved state, show welcome page
|
||||||
@@ -308,7 +289,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function clearSessionState() {
|
function clearSessionState() {
|
||||||
localStorage.removeItem("capitalsQuizSessionState");
|
sharedClearSessionState("capitalsQuizSessionState");
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateQuestion() {
|
function generateQuestion() {
|
||||||
@@ -676,10 +657,6 @@
|
|||||||
localStorage.setItem("capitalsQuizStats", JSON.stringify(gameStats));
|
localStorage.setItem("capitalsQuizStats", JSON.stringify(gameStats));
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveSettings() {
|
|
||||||
const settings = { autoAdvance };
|
|
||||||
localStorage.setItem("capitalsQuizSettings", JSON.stringify(settings));
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleSettings() {
|
function toggleSettings() {
|
||||||
showSettings = !showSettings;
|
showSettings = !showSettings;
|
||||||
@@ -736,7 +713,7 @@
|
|||||||
|
|
||||||
// Reset achievements if component is available
|
// Reset achievements if component is available
|
||||||
if (achievementsComponent) {
|
if (achievementsComponent) {
|
||||||
achievementsComponent.resetAllAchievements();
|
achievementsComponent.resetConsecutiveSkips();
|
||||||
}
|
}
|
||||||
|
|
||||||
showResetConfirmation = false;
|
showResetConfirmation = false;
|
||||||
@@ -799,134 +776,27 @@
|
|||||||
return `/images/flags/${flag.path}`;
|
return `/images/flags/${flag.path}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateAchievementCount() {
|
|
||||||
if (achievementsComponent) {
|
|
||||||
achievementCount = achievementsComponent.getAchievementCount();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleAchievementsUnlocked() {
|
function handleAchievementsUnlocked() {
|
||||||
updateAchievementCount();
|
achievementCount = sharedUpdateAchievementCount(achievementsComponent);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Global statistics functions
|
// Global statistics functions
|
||||||
function loadGlobalStats() {
|
function loadGlobalStats() {
|
||||||
const savedGlobalStats = localStorage.getItem("globalQuizStats");
|
sharedLoadGlobalStats("globalQuizStats");
|
||||||
if (savedGlobalStats) {
|
|
||||||
try {
|
|
||||||
const globalStats = JSON.parse(savedGlobalStats);
|
|
||||||
console.log("Loaded global stats:", globalStats);
|
|
||||||
} catch (e) {
|
|
||||||
console.error("Error loading global stats:", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateGlobalStats(isCorrect, isSkipped = false) {
|
function updateGlobalStats(isCorrect, isSkipped = false) {
|
||||||
let globalStats = {};
|
sharedUpdateGlobalStats("globalQuizStats", "capitalsQuiz", isCorrect, isSkipped);
|
||||||
|
|
||||||
// Load existing global stats
|
|
||||||
const savedGlobalStats = localStorage.getItem("globalQuizStats");
|
|
||||||
if (savedGlobalStats) {
|
|
||||||
try {
|
|
||||||
globalStats = JSON.parse(savedGlobalStats);
|
|
||||||
} catch (e) {
|
|
||||||
console.error("Error parsing global stats:", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize stats structure if it doesn't exist
|
|
||||||
if (!globalStats.capitalsQuiz) {
|
|
||||||
globalStats.capitalsQuiz = { correct: 0, wrong: 0, total: 0, skipped: 0 };
|
|
||||||
}
|
|
||||||
if (!globalStats.overall) {
|
|
||||||
globalStats.overall = { correct: 0, wrong: 0, total: 0, skipped: 0 };
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update capitals quiz stats
|
|
||||||
globalStats.capitalsQuiz.total++;
|
|
||||||
globalStats.overall.total++;
|
|
||||||
|
|
||||||
if (isSkipped) {
|
|
||||||
globalStats.capitalsQuiz.skipped++;
|
|
||||||
globalStats.overall.skipped++;
|
|
||||||
} else if (isCorrect) {
|
|
||||||
globalStats.capitalsQuiz.correct++;
|
|
||||||
globalStats.overall.correct++;
|
|
||||||
} else {
|
|
||||||
globalStats.capitalsQuiz.wrong++;
|
|
||||||
globalStats.overall.wrong++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save updated global stats
|
|
||||||
localStorage.setItem("globalQuizStats", JSON.stringify(globalStats));
|
|
||||||
console.log("Updated global stats:", globalStats);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sound functions
|
// Sound functions
|
||||||
function playCorrectSound() {
|
function playCorrectSound() {
|
||||||
if (!soundEnabled) return;
|
sharedPlayCorrectSound(soundEnabled);
|
||||||
|
|
||||||
try {
|
|
||||||
const audioContext = new (window.AudioContext ||
|
|
||||||
window.webkitAudioContext)();
|
|
||||||
const oscillator = audioContext.createOscillator();
|
|
||||||
const gainNode = audioContext.createGain();
|
|
||||||
|
|
||||||
oscillator.connect(gainNode);
|
|
||||||
gainNode.connect(audioContext.destination);
|
|
||||||
|
|
||||||
// Pleasant ascending tone for correct answer
|
|
||||||
oscillator.frequency.setValueAtTime(523.25, audioContext.currentTime); // C5
|
|
||||||
oscillator.frequency.setValueAtTime(
|
|
||||||
659.25,
|
|
||||||
audioContext.currentTime + 0.1,
|
|
||||||
); // E5
|
|
||||||
oscillator.frequency.setValueAtTime(
|
|
||||||
783.99,
|
|
||||||
audioContext.currentTime + 0.2,
|
|
||||||
); // G5
|
|
||||||
|
|
||||||
gainNode.gain.setValueAtTime(0.3, audioContext.currentTime);
|
|
||||||
gainNode.gain.exponentialRampToValueAtTime(
|
|
||||||
0.001,
|
|
||||||
audioContext.currentTime + 0.4,
|
|
||||||
);
|
|
||||||
|
|
||||||
oscillator.start(audioContext.currentTime);
|
|
||||||
oscillator.stop(audioContext.currentTime + 0.4);
|
|
||||||
} catch (e) {
|
|
||||||
console.log("Audio not supported:", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function playWrongSound() {
|
function playWrongSound() {
|
||||||
if (!soundEnabled) return;
|
sharedPlayWrongSound(soundEnabled);
|
||||||
|
|
||||||
try {
|
|
||||||
const audioContext = new (window.AudioContext ||
|
|
||||||
window.webkitAudioContext)();
|
|
||||||
const oscillator = audioContext.createOscillator();
|
|
||||||
const gainNode = audioContext.createGain();
|
|
||||||
|
|
||||||
oscillator.connect(gainNode);
|
|
||||||
gainNode.connect(audioContext.destination);
|
|
||||||
|
|
||||||
// Descending tone for wrong answer
|
|
||||||
oscillator.frequency.setValueAtTime(400, audioContext.currentTime); // Lower frequency
|
|
||||||
oscillator.frequency.setValueAtTime(300, audioContext.currentTime + 0.15);
|
|
||||||
|
|
||||||
gainNode.gain.setValueAtTime(0.3, audioContext.currentTime);
|
|
||||||
gainNode.gain.exponentialRampToValueAtTime(
|
|
||||||
0.001,
|
|
||||||
audioContext.currentTime + 0.3,
|
|
||||||
);
|
|
||||||
|
|
||||||
oscillator.start(audioContext.currentTime);
|
|
||||||
oscillator.stop(audioContext.currentTime + 0.3);
|
|
||||||
} catch (e) {
|
|
||||||
console.log("Audio not supported:", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
<script>
|
<script>
|
||||||
|
import { updateAchievementCount as sharedUpdateAchievementCount } from '../quizLogic/quizAchievements.js';
|
||||||
|
import { saveSettings as sharedSaveSettings } from '../quizLogic/quizSettings.js';
|
||||||
import { quizInfo } from '../quizInfo/FlagQuizInfo.js';
|
import { quizInfo } from '../quizInfo/FlagQuizInfo.js';
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
import Header from "../components/Header.svelte";
|
import Header from "../components/Header.svelte";
|
||||||
@@ -87,21 +89,18 @@ import { quizInfo } from '../quizInfo/FlagQuizInfo.js';
|
|||||||
|
|
||||||
// Update achievement count when achievements component is available
|
// Update achievement count when achievements component is available
|
||||||
$: if (achievementsComponent) {
|
$: if (achievementsComponent) {
|
||||||
updateAchievementCount();
|
achievementCount = sharedUpdateAchievementCount(achievementsComponent);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save settings when they change (after initial load)
|
// Save settings when they change (after initial load)
|
||||||
$: if (settingsLoaded && typeof reduceCorrectAnswers !== "undefined") {
|
$: if (settingsLoaded && typeof reduceCorrectAnswers !== "undefined") {
|
||||||
localStorage.setItem(
|
sharedSaveSettings("flagQuizSettings", {
|
||||||
"flagQuizSettings",
|
autoAdvance,
|
||||||
JSON.stringify({
|
focusWrongAnswers,
|
||||||
autoAdvance,
|
reduceCorrectAnswers,
|
||||||
focusWrongAnswers,
|
soundEnabled,
|
||||||
reduceCorrectAnswers,
|
sessionLength,
|
||||||
soundEnabled,
|
});
|
||||||
sessionLength,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load game stats from localStorage
|
// Load game stats from localStorage
|
||||||
@@ -670,10 +669,6 @@ import { quizInfo } from '../quizInfo/FlagQuizInfo.js';
|
|||||||
localStorage.setItem("flagQuizStats", JSON.stringify(gameStats));
|
localStorage.setItem("flagQuizStats", JSON.stringify(gameStats));
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveSettings() {
|
|
||||||
const settings = { autoAdvance };
|
|
||||||
localStorage.setItem("flagQuizSettings", JSON.stringify(settings));
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleSettings() {
|
function toggleSettings() {
|
||||||
showSettings = !showSettings;
|
showSettings = !showSettings;
|
||||||
@@ -730,7 +725,7 @@ import { quizInfo } from '../quizInfo/FlagQuizInfo.js';
|
|||||||
|
|
||||||
// Reset achievements if component is available
|
// Reset achievements if component is available
|
||||||
if (achievementsComponent) {
|
if (achievementsComponent) {
|
||||||
achievementsComponent.resetAllAchievements();
|
achievementsComponent.resetConsecutiveSkips();
|
||||||
}
|
}
|
||||||
|
|
||||||
showResetConfirmation = false;
|
showResetConfirmation = false;
|
||||||
@@ -789,14 +784,9 @@ import { quizInfo } from '../quizInfo/FlagQuizInfo.js';
|
|||||||
return `/images/flags/${flag.path}`;
|
return `/images/flags/${flag.path}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateAchievementCount() {
|
|
||||||
if (achievementsComponent) {
|
|
||||||
achievementCount = achievementsComponent.getAchievementCount();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleAchievementsUnlocked() {
|
function handleAchievementsUnlocked() {
|
||||||
updateAchievementCount();
|
achievementCount = sharedUpdateAchievementCount(achievementsComponent);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Global statistics functions
|
// Global statistics functions
|
||||||
|
|||||||
Reference in New Issue
Block a user