diff --git a/www/html/Admin/admin.css b/www/html/Admin/admin.css index 324f39d..abb71a4 100644 --- a/www/html/Admin/admin.css +++ b/www/html/Admin/admin.css @@ -725,6 +725,10 @@ code { margin-top: 0.35rem; } +.quiz-round-q-fieldset .quiz-round-q-label { + max-width: 280px; +} + .quiz-admin-questions-list { display: flex; flex-direction: column; diff --git a/www/html/Admin/admin.js b/www/html/Admin/admin.js index 93cc1c3..4df7df7 100644 --- a/www/html/Admin/admin.js +++ b/www/html/Admin/admin.js @@ -187,6 +187,13 @@ el('quiz-answer-sec').value = String(Math.round((data.answerMs || 5000) / 1000)); var bMs = data.betweenMs != null ? data.betweenMs : 3500; el('quiz-between-sec').value = String(Math.max(0, Math.round(bMs / 1000))); + var rqIn = el('quiz-round-q-count'); + if (rqIn) { + var rq = data.quizRoundQuestionCount != null ? parseInt(data.quizRoundQuestionCount, 10) : 10; + if (Number.isNaN(rq) || rq < 1) rq = 10; + rq = Math.min(50, rq); + rqIn.value = String(rq); + } renderQuizAdminQuestions(data.questions); if (data.quizMapPanelTheme && typeof data.quizMapPanelTheme === 'object') { quizTfFillFormFromTheme(data.quizMapPanelTheme); @@ -210,6 +217,11 @@ ansS = Math.min(300, ansS); betS = Math.min(120, betS); + var roundQEl = el('quiz-round-q-count'); + var roundQ = roundQEl ? parseInt(roundQEl.value, 10) : 10; + if (Number.isNaN(roundQ) || roundQ < 1) roundQ = 10; + roundQ = Math.min(50, roundQ); + var questions = []; document.querySelectorAll('#quiz-admin-questions-list .quiz-admin-q-row').forEach(function (row) { var inp = row.querySelector('.quiz-admin-q-text'); @@ -223,6 +235,7 @@ readMs: readS * 1000, answerMs: ansS * 1000, betweenMs: betS * 1000, + quizRoundQuestionCount: roundQ, questions: questions, quizMapPanelTheme: quizTfBuildThemeForSave(), }).then(function () { diff --git a/www/html/Admin/api/game-quiz-settings.php b/www/html/Admin/api/game-quiz-settings.php index e430610..e5541f1 100644 --- a/www/html/Admin/api/game-quiz-settings.php +++ b/www/html/Admin/api/game-quiz-settings.php @@ -52,7 +52,7 @@ function merge_quiz_settings_disk_from_put(string $rawBody): bool if ($hadFileButInvalidJson) { return false; } - $mergeKeys = ['readMs', 'answerMs', 'betweenMs', 'carryReadMs', 'carryAnswerMs', 'carrySessionLength', 'carryMapPanelTheme', 'quizMapPanelTheme', 'carryEmbedCountdownTheme', 'carryChoicePlaqueTheme', 'carryChoicePlaqueThemes', 'carryChoicePlaqueMapScale', 'carryWalkSpeedMultForMapId', 'carryWalkSpeedMult', 'questions', 'carryQuestions', 'battleQuizMcq']; + $mergeKeys = ['readMs', 'answerMs', 'betweenMs', 'carryReadMs', 'carryAnswerMs', 'carrySessionLength', 'carryMapPanelTheme', 'quizMapPanelTheme', 'carryEmbedCountdownTheme', 'carryChoicePlaqueTheme', 'carryChoicePlaqueThemes', 'carryChoicePlaqueMapScale', 'carryWalkSpeedMultForMapId', 'carryWalkSpeedMult', 'quizRoundQuestionCount', 'questions', 'carryQuestions', 'battleQuizMcq']; foreach ($mergeKeys as $k) { if (array_key_exists($k, $patch)) { $base[$k] = $patch[$k]; @@ -106,7 +106,7 @@ function overlay_quiz_settings_from_disk(string $nodeBody): string $j['carryEmbedCountdownTheme'] = $disk['carryEmbedCountdownTheme']; } /* ไม่ทับ carryChoicePlaqueThemes / carryChoicePlaqueTheme จากดิสก์ — ใช้ค่าจาก Node (อ่านไฟล์เดียวกันกับ disk merge) เพื่อกันทับด้วย JSON เก่าที่ไม่มี plaqueImageUrl ทำให้ช่อง URL ใน Admin ว่างหลังรีเฟรช */ - foreach (['carryReadMs', 'carryAnswerMs', 'carrySessionLength', 'carryChoicePlaqueMapScale', 'carryWalkSpeedMultForMapId', 'carryWalkSpeedMult'] as $ck) { + foreach (['carryReadMs', 'carryAnswerMs', 'carrySessionLength', 'carryChoicePlaqueMapScale', 'carryWalkSpeedMultForMapId', 'carryWalkSpeedMult', 'quizRoundQuestionCount'] as $ck) { if (array_key_exists($ck, $disk)) { $j[$ck] = $disk[$ck]; } diff --git a/www/html/Admin/index.html b/www/html/Admin/index.html index 614df71..5e72df4 100644 --- a/www/html/Admin/index.html +++ b/www/html/Admin/index.html @@ -145,7 +145,7 @@