完善猜成语过期与答题记录逻辑
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
// 从 Blade 内联脚本 scripts.blade.php 迁移至 Vite 模块。
|
||||
|
||||
import { escapeHtml, normalizeSafeChatUrl } from "./html.js";
|
||||
import { attachIdiomAnswerButton, removeIdiomAnswerButtons } from "./idiom-quiz.js";
|
||||
import { isExpiredChatImageMessage } from "./message-utils.js";
|
||||
import { normalizeDailyStatus, resolveBlockedSystemSenderKey } from "./preferences-status.js";
|
||||
import { escapePresenceText } from "./vip-presence.js";
|
||||
@@ -49,6 +50,21 @@ function parseBracketUsers(content, color = "#000099") {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 只保留包厢窗口最近几条猜成语答题记录,避免答题历史无限堆积。
|
||||
*/
|
||||
function prunePrivateIdiomResultMessages(targetContainer, maxRecords = 3) {
|
||||
if (!targetContainer) {
|
||||
return;
|
||||
}
|
||||
|
||||
const nodes = Array.from(targetContainer.querySelectorAll('[data-idiom-result="1"]'));
|
||||
while (nodes.length > maxRecords) {
|
||||
const firstNode = nodes.shift();
|
||||
firstNode?.remove();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建聊天消息的内容 HTML。
|
||||
*/
|
||||
@@ -172,6 +188,14 @@ export function appendMessage(msg, renderBatch = null) {
|
||||
const iconImg = `<img src="/images/bugle.png" style="display:inline;width:16px;height:16px;vertical-align:middle;margin-right:2px;mix-blend-mode: multiply;" onerror="this.src='/images/headface/1.gif'">`;
|
||||
const parsedContent = parseBracketUsers(msg.content);
|
||||
html = `${iconImg} ${parsedContent}`;
|
||||
} else if (msg.action === "idiom_result") {
|
||||
div.dataset.idiomResult = "1";
|
||||
const winnerUsername = String(msg.winner_username || "");
|
||||
const winnerHtml = clickableUser(winnerUsername, "#16a34a");
|
||||
const answerText = escapeHtml(String(msg.idiom_answer || ""));
|
||||
const rewardGold = Number.parseInt(String(msg.idiom_result_reward_gold ?? msg.reward_gold ?? 0), 10);
|
||||
const rewardExp = Number.parseInt(String(msg.idiom_result_reward_exp ?? msg.reward_exp ?? 0), 10);
|
||||
html = `<span style="color:#16a34a;font-weight:bold;">🎉 【${winnerHtml}】率先答对成语「${answerText}」,获得 ${rewardGold} 金币、${rewardExp} 经验!</span>`;
|
||||
} else if (msg.action === "vip_presence") {
|
||||
const accent = msg.presence_color || "#f59e0b";
|
||||
div.style.cssText =
|
||||
@@ -300,6 +324,12 @@ export function appendMessage(msg, renderBatch = null) {
|
||||
html += ` <span class="msg-time">(${timeStr})</span>`;
|
||||
}
|
||||
div.innerHTML = html;
|
||||
attachIdiomAnswerButton(div, msg);
|
||||
|
||||
// 历史消息恢复或实时结算时,都立即移除对应回合的旧答题按钮。
|
||||
if (Number.parseInt(String(msg.idiom_game_round_ended_id || "0"), 10) > 0) {
|
||||
removeIdiomAnswerButtons(Number.parseInt(String(msg.idiom_game_round_ended_id), 10));
|
||||
}
|
||||
|
||||
// 命中屏蔽规则时,消息仍保留在 DOM 中,便于取消屏蔽后立即恢复显示。
|
||||
if (shouldHideByBlock) {
|
||||
@@ -325,7 +355,8 @@ export function appendMessage(msg, renderBatch = null) {
|
||||
}
|
||||
|
||||
// 路由规则:公众窗口(say1) — 别人的公聊消息;包厢窗口(say2) — 自己发的 + 悄悄话 + 对自己说的
|
||||
const isRelatedToMe = isMe || msg.is_secret || msg.to_user === window.chatContext?.username;
|
||||
const isIdiomWinnerHistory = msg.action === "idiom_result" && msg.winner_username === window.chatContext?.username;
|
||||
const isRelatedToMe = isMe || msg.is_secret || msg.to_user === window.chatContext?.username || isIdiomWinnerHistory;
|
||||
|
||||
// 存点通知标记
|
||||
const isAutoSave = (msg.from_user === "系统" || msg.from_user === "") &&
|
||||
@@ -343,12 +374,18 @@ export function appendMessage(msg, renderBatch = null) {
|
||||
renderBatch.privateFragment.appendChild(div);
|
||||
renderBatch.shouldPrunePrivate = true;
|
||||
renderBatch.shouldScrollPrivate = renderBatch.shouldScrollPrivate || state.autoScroll;
|
||||
if (msg.action === "idiom_result") {
|
||||
renderBatch.shouldPrunePrivateIdiomResults = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
const container2 = state.container2;
|
||||
if (container2) {
|
||||
container2.appendChild(div);
|
||||
pruneMessageContainer(container2, PRIVATE_MESSAGE_NODE_LIMIT);
|
||||
if (msg.action === "idiom_result") {
|
||||
prunePrivateIdiomResultMessages(container2, 3);
|
||||
}
|
||||
if (state.autoScroll) {
|
||||
container2.scrollTop = container2.scrollHeight;
|
||||
}
|
||||
@@ -398,6 +435,7 @@ export function createChatMessageRenderBatch() {
|
||||
privateFragment: document.createDocumentFragment(),
|
||||
shouldPrunePublic: false,
|
||||
shouldPrunePrivate: false,
|
||||
shouldPrunePrivateIdiomResults: false,
|
||||
shouldScrollPublic: false,
|
||||
shouldScrollPrivate: false,
|
||||
};
|
||||
@@ -429,6 +467,10 @@ export function commitChatMessageRenderBatch(renderBatch) {
|
||||
const container2 = state.container2;
|
||||
if (container2) pruneMessageContainer(container2, PRIVATE_MESSAGE_NODE_LIMIT);
|
||||
}
|
||||
if (renderBatch.shouldPrunePrivateIdiomResults) {
|
||||
const container2 = state.container2;
|
||||
if (container2) prunePrivateIdiomResultMessages(container2, 3);
|
||||
}
|
||||
if (renderBatch.shouldScrollPublic) {
|
||||
const container = state.container;
|
||||
if (container) container.scrollTop = container.scrollHeight;
|
||||
|
||||
Reference in New Issue
Block a user