diff --git a/www/html/Game/public/js/play.js b/www/html/Game/public/js/play.js index e022751..9caa15d 100644 --- a/www/html/Game/public/js/play.js +++ b/www/html/Game/public/js/play.js @@ -1850,6 +1850,10 @@ /** quiz_carry: epoch ให้หยิบตัวเลือกได้ · epoch ปิดรอบตอบ (ตั้งที่ Admin แท็บหยิบมาวาง) */ let quizCarryOptionRevealAt = 0; let quizCarryAnswerCloseAt = 0; + /** หมดเวลาตอบรอบนี้แล้ว — โชว์ TIME'S UP ~3s แล้วเรียก quizCarryAfterRoundResolved */ + let quizCarryAnswerTimeupAwaitNext = false; + let quizCarryAnswerRoundTimeupAutoT = null; + let quizCarryAnswerRoundTimeupAdvanceAt = 0; let quizCarryCarryTimingMs = { carryReadMs: 3000, carryAnswerMs: 5000 }; /** พรีวิว (รวม editor embed): จำนวนข้อที่เล่นก่อนโอเวอร์เลย์จบ — 0 = ไม่จบอัตโนมัติ */ let quizCarrySessionLength = 0; @@ -6742,6 +6746,11 @@ if (!isQuizCarry() || !quizCarryCurrent) return; const phaseEl = document.getElementById('quiz-game-phase-label'); if (!phaseEl) return; + if (quizCarryAnswerTimeupAwaitNext && quizCarryAnswerRoundTimeupAdvanceAt > 0) { + const sec = Math.max(0, Math.ceil((quizCarryAnswerRoundTimeupAdvanceAt - Date.now()) / 1000)); + phaseEl.textContent = 'หมดเวลาตอบ — ไปข้อถัดไปใน ' + sec + ' วิ…'; + return; + } const now = Date.now(); if (quizCarryOptionRevealAt > 0 && now < quizCarryOptionRevealAt) { const remain = Math.max(0, Math.ceil((quizCarryOptionRevealAt - now) / 1000)); @@ -6762,6 +6771,7 @@ if (!isQuizCarry() || !mapData || !quizCarryCurrent) return; if (quizCarryEmbedCountdownEndAt > Date.now()) return; if (quizCarryEmbedPendingQuestion) return; + if (quizCarryAnswerTimeupAwaitNext) return; if (!quizCarryAnswerCloseAt || quizCarryAnswerCloseAt <= 0) return; if (Date.now() < quizCarryAnswerCloseAt) return; quizCarryAnswerCloseAt = 0; @@ -6773,7 +6783,9 @@ o.botPath = []; }); renderPlayQuizScoreboard(playLiveQuizScores); - quizCarryAfterRoundResolved(); + quizCarryAnswerTimeupAwaitNext = true; + showQuizCarryAnswerRoundTimeupOverlay(); + updateQuizCarryCarryPhaseHud(); } function resetQuizCarryEmbedCountdownOverlayInners() { @@ -7045,6 +7057,21 @@ cancelEmbedPreviewLobbyReturnTimer(); } + function cancelQuizCarryAnswerRoundTimeupAuto() { + if (quizCarryAnswerRoundTimeupAutoT != null) { + clearTimeout(quizCarryAnswerRoundTimeupAutoT); + quizCarryAnswerRoundTimeupAutoT = null; + } + quizCarryAnswerRoundTimeupAdvanceAt = 0; + } + + function quizCarrySetAnswerRoundTimeupVisualActive(on) { + try { + if (on) document.documentElement.classList.add('quiz-carry-answer-timeup-active'); + else document.documentElement.classList.remove('quiz-carry-answer-timeup-active'); + } catch (e) { /* ignore */ } + } + /** หลังภาพ result-complete / gameover (editor embed + preview): รอ 5s แล้วไปล็อบบี้ห้องพรีวิว */ function scheduleEmbedPreviewReturnToLobbyAfterResultEnd() { cancelEmbedPreviewLobbyReturnTimer(); @@ -7094,6 +7121,7 @@ /** Embed editor: หลัง timeup บนโต๊ะ — รอ 5 วิ แล้วโชว์ result-complete / result-gameover (ใช้ร่วม quiz_carry + crown) */ function scheduleEmbedDeskResultAfterDelay(okResolver) { + cancelQuizCarryAnswerRoundTimeupAuto(); cancelQuizCarryResultEndAfterTimeup(); hideQuizCarryResultEndLayer(); const resolve = typeof okResolver === 'function' ? okResolver : function () { return !!okResolver; }; @@ -7112,9 +7140,16 @@ } function hideQuizCarryTimeupOnDeskLayer() { + cancelQuizCarryAnswerRoundTimeupAuto(); cancelQuizCarryResultEndAfterTimeup(); + quizCarrySetAnswerRoundTimeupVisualActive(false); const el = document.getElementById('quiz-carry-timeup-desk-layer'); - if (!el) return; + if (!el) { + quizCarryAnswerTimeupAwaitNext = false; + return; + } + el.classList.remove('qc-timeup-desk--interactive'); + quizCarryAnswerTimeupAwaitNext = false; const anchor = el.querySelector('.qc-timeup-desk-anchor') || el.querySelector('.qc-timeup-desk-inner'); if (anchor) { anchor.style.left = ''; @@ -7126,9 +7161,44 @@ el.setAttribute('aria-hidden', 'true'); } + /** หมดเวลาตอบ (carryAnswerMs) — โชว์ TIME'S UP บนโซนคำถาม ~3s แล้วไปข้อถัดไป (ไม่ใช่ flow 5s → result ของ embed จบภารกิจ) */ + function showQuizCarryAnswerRoundTimeupOverlay() { + if (!isQuizCarry()) return; + cancelQuizCarryAnswerRoundTimeupAuto(); + const el = document.getElementById('quiz-carry-timeup-desk-layer'); + if (!el) return; + const img = document.getElementById('quiz-carry-timeup-txt-img'); + if (img) { + img.onerror = null; + img.src = BASE + '/img/quiz-carry/timeup-txt.png?v=' + String(Date.now()); + } + quizCarrySetAnswerRoundTimeupVisualActive(true); + quizCarryAnswerRoundTimeupAdvanceAt = Date.now() + 3000; + el.classList.add('qc-timeup-desk--interactive'); + el.classList.remove('is-hidden'); + el.setAttribute('aria-hidden', 'false'); + try { + syncQuizCarryTimeupDeskLayerPosition(); + } catch (e) { /* ignore */ } + quizCarryAnswerRoundTimeupAutoT = setTimeout(function () { + quizCarryAnswerRoundTimeupAutoT = null; + dismissQuizCarryAnswerRoundTimeupAndContinue(); + }, 3000); + } + + function dismissQuizCarryAnswerRoundTimeupAndContinue() { + if (!quizCarryAnswerTimeupAwaitNext) return; + cancelQuizCarryAnswerRoundTimeupAuto(); + quizCarryAnswerTimeupAwaitNext = false; + hideQuizCarryTimeupOnDeskLayer(); + quizCarryAfterRoundResolved(); + } + /** หลังกดรับหลักฐาน (embed preview) — แสดง timeup กลางแคนวาส (Jumper mnptfts2 = img/Jumper/result-timeup.png) แยกจากป๊อปสรุปคะแนน * @param {function():boolean} [embedResultOkFn] — ถ้าไม่ส่ง = ใช้คะแนน quiz_carry (คนตอบถูก); ส่งเมื่อ crown เพื่อเลือก complete vs gameover */ function showQuizCarryTimeupOnDeskLayer(embedResultOkFn) { + cancelQuizCarryAnswerRoundTimeupAuto(); + quizCarrySetAnswerRoundTimeupVisualActive(false); const el = document.getElementById('quiz-carry-timeup-desk-layer'); if (!el) return; // Last Light (Gauntlet Crown): skip TIME'S UP desk graphic; keep embed 5s → result flow. @@ -7608,6 +7678,7 @@ quizCarryEmbedCountdownEndAt = 0; quizCarryOptionRevealAt = 0; quizCarryAnswerCloseAt = 0; + quizCarryAnswerTimeupAwaitNext = false; quizCarryRoundsCompleted = 0; quizCarrySessionEnded = false; hideQuizCarryEmbedCountdownOverlay(); diff --git a/www/html/Game/public/js/version.js b/www/html/Game/public/js/version.js index ad5a230..0f6b7eb 100644 --- a/www/html/Game/public/js/version.js +++ b/www/html/Game/public/js/version.js @@ -1,6 +1,6 @@ // ทุกครั้งที่มีการเพิ่มหรือเปลี่ยน ให้เพิ่ม v +0.0001 // หลังแก้ค่าแล้วต้อง copy ไป path ที่ Nginx ชี้ (หรือรัน copy-frogger-files-only.sh) ถึงจะเห็นบนเว็บ -window.APP_VERSION = '0.0292'; +window.APP_VERSION = '0.0295'; document.addEventListener('DOMContentLoaded', function () { var t = document.querySelector('.version-tag'); if (t) t.textContent = 'v ' + window.APP_VERSION; diff --git a/www/html/Game/public/play.html b/www/html/Game/public/play.html index 4d6a154..3a85bbd 100644 --- a/www/html/Game/public/play.html +++ b/www/html/Game/public/play.html @@ -135,6 +135,16 @@ pointer-events: none; box-sizing: border-box; } + /* หมดเวลาตอบรอบคำถาม — กด «ข้อถัดไป» ได้ (กัน pointer ทะลุไปเกม) */ + #quiz-carry-timeup-desk-layer.qc-timeup-desk--interactive { + pointer-events: auto; + } + #quiz-carry-timeup-desk-layer.qc-timeup-desk--interactive .qc-timeup-dim { + pointer-events: auto; + } + #quiz-carry-timeup-desk-layer.qc-timeup-desk--interactive .qc-timeup-desk-anchor { + pointer-events: auto; + } #quiz-carry-timeup-desk-layer.is-hidden { display: none !important; } @@ -158,6 +168,18 @@ overflow: visible; pointer-events: none; } + /* หมดเวลาตอบรอบคำถาม — ซ่อนข้อความคำถามใต้ TIME'S UP */ + html.quiz-carry-answer-timeup-active #quiz-map-question-text, + html.quiz-carry-answer-timeup-active #quiz-map-question-kicker, + html.quiz-carry-answer-timeup-active .quiz-map-q-feedback-icon, + html.quiz-carry-answer-timeup-active #quiz-map-q-feedback-score-wrap, + html.quiz-carry-answer-timeup-active #quiz-game-question, + html.quiz-carry-answer-timeup-active #quiz-carry-embed-q-strip, + html.quiz-carry-answer-timeup-active #quiz-carry-embed-q-strip-text { + visibility: hidden !important; + opacity: 0 !important; + pointer-events: none !important; + } .qc-timeup-txt-img { width: min(94%, 520px); max-width: 100%; @@ -1848,13 +1870,13 @@ width: 0; height: 0; } - /* quiz_carry: TIME ชิดซ้ายกลางแนวตั้ง — แถวบน: SCORE + โปรไฟล์ */ + /* quiz_carry: TIME ชิดซ้ายกลางแนวตั้ง — แถวบน: SCORE + โปรไฟล์ (แผง SCORE อย่ายืด 1fr แล้วชิดซ้าย = ช่องว่างยาวถึงโปรไฟล์) */ #play-cyber-hud.play-cyber-hud--gauntlet-crown-strip.play-cyber-hud--score-flush-left { padding-left: env(safe-area-inset-left, 0px); display: grid; grid-template-columns: minmax(4.5rem, 17vw) minmax(0, 1fr) auto; grid-template-rows: auto 1fr; - column-gap: clamp(8px, 1.5vw, 16px); + column-gap: clamp(2px, 0.55vw, 8px); row-gap: 0.35rem; align-items: start; box-sizing: border-box; @@ -1877,11 +1899,11 @@ grid-area: unset; grid-column: 2; grid-row: 1; - justify-self: stretch; + justify-self: end; align-self: start; - width: 100%; + width: max-content; + max-width: 100%; min-width: 0; - max-width: none; margin-left: 0; margin-right: 0; } @@ -1889,7 +1911,7 @@ grid-area: unset; grid-column: 3; grid-row: 1; - justify-self: end; + justify-self: start; align-self: start; } #play-cyber-hud.play-cyber-hud--gauntlet-crown-strip.play-cyber-hud--score-flush-left .play-cyber-time-block { @@ -3002,8 +3024,8 @@ - - + +
v —