// 猜成语游戏前端模块 // 监听 IdiomGameStarted / IdiomGameAnswered 事件,提供答题弹窗功能 function csrf() { return document.querySelector('meta[name="csrf-token"]')?.content ?? ""; } let currentRoundId = 0; let currentRoomId = 0; /** * 收到猜成语出题事件时,在聊天窗口显示提示消息。 */ function handleIdiomGameStarted(e) { const { round_id, hint, reward_gold, reward_exp, message } = e.detail || {}; if (!round_id || !hint) return; currentRoundId = round_id; currentRoomId = window.chatContext?.roomId || 0; // 追加一条聊天室消息(由 MessageSent 事件负责渲染,不重复添加) // 这里只存储当前回合信息 console.log(`猜成语开始:${hint},奖励 ${reward_gold}金/${reward_exp}经验`); } /** * 收到猜成语结果事件。 */ function handleIdiomGameAnswered(e) { const { answer, winner_username, reward_gold, reward_exp, round_id } = e.detail || {}; if (!answer) return; currentRoundId = 0; // 关闭当前用户的答题弹窗(如果开着的话) const answerModal = document.getElementById("idiom-answer-modal"); if (answerModal && answerModal.style.display !== "none") { answerModal.style.display = "none"; } // ── 分屏文字提示 ── // 回答者 → 包厢(chat-messages-container2) // 其他人 → 公屏(chat-messages-container) const now = new Date(); const timeStr = now.getHours().toString().padStart(2, "0") + ":" + now.getMinutes().toString().padStart(2, "0") + ":" + now.getSeconds().toString().padStart(2, "0"); const div = document.createElement("div"); div.className = "msg-line"; div.innerHTML = `🎉 恭喜 ${winner_username} 率先答对成语「${answer}」,获得 ${reward_gold} 金币、${reward_exp} 经验!(${timeStr})`; const isWinner = winner_username === (window.chatContext?.username || ""); if (isWinner) { // 回答者 → 包厢 const say2 = document.getElementById("chat-messages-container2"); if (say2) { say2.appendChild(div.cloneNode(true)); say2.scrollTop = say2.scrollHeight; } } else { // 其他人 → 公屏 const say1 = document.getElementById("chat-messages-container"); if (say1) { say1.appendChild(div); say1.scrollTop = say1.scrollHeight; } } // ── Toast 通知(所有用户都能看到) ── window.chatToast?.show({ title: "🧩 猜成语", message: `${winner_username} 答对了「${answer}」,获得 ${reward_gold}💰 + ${reward_exp}⭐!`, icon: "🎉", color: "#16a34a", duration: 6000, }); // ── 标记所有对应 round_id 的【答题】按钮为已答 ── document.querySelectorAll(`[data-idiom-answer-btn="${round_id}"]`).forEach((btn) => { btn.dataset.idiomAnswered = "1"; btn.textContent = "✅ 已答"; btn.style.background = "#9ca3af"; btn.style.cursor = "default"; btn.style.opacity = "0.6"; }); } /** * 打开答题弹窗。 */ function openIdiomAnswerModal(roundId, hint, rewardGold, rewardExp) { currentRoundId = roundId; currentRoomId = window.chatContext?.roomId || 0; const modal = document.getElementById("idiom-answer-modal"); if (!modal) return; const hintEl = document.getElementById("idiom-answer-hint"); const rewardEl = document.getElementById("idiom-answer-reward"); if (hintEl) hintEl.textContent = hint; if (rewardEl) rewardEl.textContent = `🎁 答对奖励:${rewardGold} 金币 + ${rewardExp} 经验`; modal.style.display = "flex"; const input = document.getElementById("idiom-answer-input"); if (input) { input.value = ""; input.focus(); input.disabled = false; } const submitBtn = document.getElementById("idiom-answer-submit"); if (submitBtn) { submitBtn.disabled = false; submitBtn.textContent = "提交答案"; } const feedbackEl = document.getElementById("idiom-answer-feedback"); if (feedbackEl) feedbackEl.textContent = ""; } /** * 关闭答题弹窗。 */ function closeIdiomAnswerModal() { const modal = document.getElementById("idiom-answer-modal"); if (modal) modal.style.display = "none"; } /** * 提交答案。 */ async function submitIdiomAnswer() { const input = document.getElementById("idiom-answer-input"); const feedbackEl = document.getElementById("idiom-answer-feedback"); const submitBtn = document.getElementById("idiom-answer-submit"); if (!input || !feedbackEl || !submitBtn) return; const answer = input.value.trim(); if (!answer) { feedbackEl.textContent = "请输入成语答案"; feedbackEl.style.color = "#ef4444"; return; } submitBtn.disabled = true; submitBtn.textContent = "提交中..."; try { const response = await fetch("/idiom-quiz/answer", { method: "POST", headers: { "X-CSRF-TOKEN": csrf(), "Content-Type": "application/json", "Accept": "application/json", }, body: JSON.stringify({ round_id: currentRoundId, answer: answer, room_id: currentRoomId, }), }); const data = await response.json(); if (data.status === "success") { feedbackEl.textContent = data.message || "🎉 回答正确!"; feedbackEl.style.color = "#16a34a"; input.disabled = true; // 延迟关闭弹窗 setTimeout(() => { closeIdiomAnswerModal(); }, 2000); } else { feedbackEl.textContent = data.message || "答案不正确"; feedbackEl.style.color = "#ef4444"; submitBtn.disabled = false; submitBtn.textContent = "提交答案"; input.focus(); input.select(); } } catch (error) { feedbackEl.textContent = "网络错误,请稍后重试"; feedbackEl.style.color = "#ef4444"; submitBtn.disabled = false; submitBtn.textContent = "提交答案"; } } // ── 事件绑定 ── export function bindIdiomQuizControls() { // 已经绑定的不再重复绑定 if (document.getElementById("idiom-answer-modal")?.dataset?.idiomBound) return; const modal = document.getElementById("idiom-answer-modal"); if (modal) modal.dataset.idiomBound = "1"; // 关闭按钮 document.addEventListener("click", (e) => { const closeBtn = e.target.closest("[data-idiom-answer-close]"); if (closeBtn) { closeIdiomAnswerModal(); return; } // 点击遮罩层关闭 const overlay = e.target.closest("#idiom-answer-modal"); if (overlay && e.target === overlay) { closeIdiomAnswerModal(); } }); // 提交按钮 document.addEventListener("click", (e) => { const submitBtn = e.target.closest("[data-idiom-answer-submit]"); if (submitBtn) { e.preventDefault(); submitIdiomAnswer(); } }); // 输入框 Enter 提交 document.addEventListener("keydown", (e) => { const input = e.target.closest("#idiom-answer-input"); if (input && e.key === "Enter" && !e.shiftKey) { e.preventDefault(); submitIdiomAnswer(); } }); // 聊天消息中的【答题】按钮点击 document.addEventListener("click", (e) => { const btn = e.target.closest("[data-idiom-answer-btn]"); if (!btn) return; // 已答完的按钮不可点击 if (btn.dataset.idiomAnswered === "1") { window.chatToast?.show({ title: "🧩 猜成语", message: "这道题已被答过了,等下一题吧!", icon: "😅", color: "#9ca3af", duration: 3000, }); return; } const roundId = parseInt(btn.dataset.idiomAnswerBtn || "0", 10); const hint = btn.dataset.idiomHint || ""; const rewardGold = parseInt(btn.dataset.idiomGold || "0", 10); const rewardExp = parseInt(btn.dataset.idiomExp || "0", 10); if (roundId > 0) { openIdiomAnswerModal(roundId, hint, rewardGold, rewardExp); } }); // ── 猜成语结果消息中的用户名可点击 → 打开用户名片 // 注:单击/双击已由 right-panel.js 的全局 [data-chat-message-user] 事件委托统一处理 } // ── 挂载到 window ── window.openIdiomAnswerModal = openIdiomAnswerModal; window.closeIdiomAnswerModal = closeIdiomAnswerModal; window.submitIdiomAnswer = submitIdiomAnswer; window.handleIdiomGameStarted = handleIdiomGameStarted; window.handleIdiomGameAnswered = handleIdiomGameAnswered;