Files
chatroom/resources/js/chat-room/chat-state.js
T
2026-04-30 09:40:50 +08:00

224 lines
8.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 聊天室共享运行时状态,桥接 Blade 闭包作用域与 Vite 模块。
// 所有需要跨模块共享的可变状态集中在此管理,通过 window.chatState 访问。
export const BLOCKABLE_SYSTEM_SENDERS = ["钓鱼播报", "猜成语", "星海小博士", "百家乐", "跑马", "神秘箱子"];
export const BLOCKED_SYSTEM_SENDERS_STORAGE_KEY = "chat_blocked_system_senders";
export const CHAT_SOUND_MUTED_STORAGE_KEY = "chat_sound_muted";
export const PUBLIC_MESSAGE_NODE_LIMIT = 600;
export const PRIVATE_MESSAGE_NODE_LIMIT = 300;
export const CHAT_MESSAGE_FLUSH_BATCH_SIZE = 8;
export const ROOMS_ONLINE_STATUS_CACHE_TTL = 10000;
export const HEARTBEAT_INTERVAL = 60 * 1000;
export const SYSTEM_USERS = ["钓鱼播报", "星海小博士", "系统传音", "系统公告", "送花播报", "座驾播报", "系统", "欢迎", "系统播报", "神秘箱子"];
// 消息动作文字映射表:情绪型(着/地,放"对"之前)和动作型(了,替换"对X说"
export const ACTION_TEXT_MAP = {
"微笑": { type: "emotion", word: "微笑着" },
"大笑": { type: "emotion", word: "大笑着" },
"愤怒": { type: "emotion", word: "愤怒地" },
"哭泣": { type: "emotion", word: "哭泣着" },
"害羞": { type: "emotion", word: "害羞地" },
"鄙视": { type: "emotion", word: "鄙视地" },
"得意": { type: "emotion", word: "得意地" },
"疑惑": { type: "emotion", word: "疑惑地" },
"同情": { type: "emotion", word: "同情地" },
"无奈": { type: "emotion", word: "无奈地" },
"拳打": { type: "verb", word: "拳打了" },
"飞吻": { type: "verb", word: "飞吻了" },
"偷看": { type: "verb", word: "偷看了" },
};
// ── DOM 引用(惰性获取,避免模块加载时 DOM 未就绪)──
function getContainer() { return document.getElementById("chat-messages-container"); }
function getContainer2() { return document.getElementById("chat-messages-container2"); }
function getUserList() { return document.getElementById("online-users-list"); }
function getToUserSelect() { return document.getElementById("to_user"); }
function getOnlineCount() { return document.getElementById("online-count"); }
function getOnlineCountBottom() { return document.getElementById("online-count-bottom"); }
// ── 可变状态 ──
let onlineUsers = {};
let autoScroll = true;
let maxMsgId = 0;
let pendingChatMessages = [];
let chatMessageFlushTimer = null;
let userListRenderTimer = null;
let userFilterRenderTimer = null;
let userBadgeRotationTick = 0;
let lastAutosaveNode = null;
let roomsRefreshTimer = null;
let roomsOnlineStatusCache = null;
let roomsOnlineStatusCacheAt = 0;
let isMutedUntil = 0;
let imeComposing = false;
let isSending = false;
let sendStartedAt = 0;
let leaveRequestInFlight = false;
let heartbeatFailCount = 0;
const MAX_HEARTBEAT_FAILS = 3;
// 偏好状态
let blockedSystemSenders = new Set();
let initialChatPreferences = null;
// ── 访问器 ──
function getOnlineUsers() { return onlineUsers; }
function setOnlineUsers(v) {
onlineUsers = v;
window.onlineUsers = onlineUsers;
}
function getAutoScroll() { return autoScroll; }
function setAutoScroll(v) { autoScroll = Boolean(v); }
function getMaxMsgId() { return maxMsgId; }
function setMaxMsgId(v) { if (v > maxMsgId) maxMsgId = v; }
function getBlockedSystemSenders() { return blockedSystemSenders; }
function setBlockedSystemSenders(v) { blockedSystemSenders = v; }
function getIsMutedUntil() { return isMutedUntil; }
function setIsMutedUntil(v) { isMutedUntil = v; }
// ── 构建聊天状态对象 ──
const chatState = {
// 常量
BLOCKABLE_SYSTEM_SENDERS,
BLOCKED_SYSTEM_SENDERS_STORAGE_KEY,
CHAT_SOUND_MUTED_STORAGE_KEY,
PUBLIC_MESSAGE_NODE_LIMIT,
PRIVATE_MESSAGE_NODE_LIMIT,
CHAT_MESSAGE_FLUSH_BATCH_SIZE,
ROOMS_ONLINE_STATUS_CACHE_TTL,
HEARTBEAT_INTERVAL,
SYSTEM_USERS,
ACTION_TEXT_MAP,
MAX_HEARTBEAT_FAILS,
// DOM 引用
get container() { return getContainer(); },
get container2() { return getContainer2(); },
get userList() { return getUserList(); },
get toUserSelect() { return getToUserSelect(); },
get onlineCount() { return getOnlineCount(); },
get onlineCountBottom() { return getOnlineCountBottom(); },
// 在线用户
get onlineUsers() { return onlineUsers; },
set onlineUsers(v) {
onlineUsers = v;
window.onlineUsers = onlineUsers;
},
// 自动滚屏
get autoScroll() { return autoScroll; },
set autoScroll(v) { autoScroll = Boolean(v); },
// 最大消息 ID
get maxMsgId() { return maxMsgId; },
set maxMsgId(v) { maxMsgId = v; },
trackMaxMsgId(v) { if (v > maxMsgId) maxMsgId = v; },
// 消息队列
get pendingChatMessages() { return pendingChatMessages; },
set pendingChatMessages(v) { pendingChatMessages = v; },
get chatMessageFlushTimer() { return chatMessageFlushTimer; },
set chatMessageFlushTimer(v) { chatMessageFlushTimer = v; },
// 用户列表渲染
get userListRenderTimer() { return userListRenderTimer; },
set userListRenderTimer(v) { userListRenderTimer = v; },
get userFilterRenderTimer() { return userFilterRenderTimer; },
set userFilterRenderTimer(v) { userFilterRenderTimer = v; },
get userBadgeRotationTick() { return userBadgeRotationTick; },
set userBadgeRotationTick(v) { userBadgeRotationTick = v; },
// 存点节点
get lastAutosaveNode() { return lastAutosaveNode; },
set lastAutosaveNode(v) { lastAutosaveNode = v; },
// 房间在线状态缓存
get roomsRefreshTimer() { return roomsRefreshTimer; },
set roomsRefreshTimer(v) { roomsRefreshTimer = v; },
get roomsOnlineStatusCache() { return roomsOnlineStatusCache; },
set roomsOnlineStatusCache(v) { roomsOnlineStatusCache = v; },
get roomsOnlineStatusCacheAt() { return roomsOnlineStatusCacheAt; },
set roomsOnlineStatusCacheAt(v) { roomsOnlineStatusCacheAt = v; },
// 禁言
get isMutedUntil() { return isMutedUntil; },
set isMutedUntil(v) { isMutedUntil = v; },
// 发送锁
get imeComposing() { return imeComposing; },
set imeComposing(v) { imeComposing = v; },
get isSending() { return isSending; },
set isSending(v) { isSending = v; },
get sendStartedAt() { return sendStartedAt; },
set sendStartedAt(v) { sendStartedAt = v; },
// 退出房间
get leaveRequestInFlight() { return leaveRequestInFlight; },
set leaveRequestInFlight(v) { leaveRequestInFlight = v; },
// 心跳计数
get heartbeatFailCount() { return heartbeatFailCount; },
set heartbeatFailCount(v) { heartbeatFailCount = v; },
// 偏好
get blockedSystemSenders() { return blockedSystemSenders; },
set blockedSystemSenders(v) { blockedSystemSenders = v; },
get initialChatPreferences() { return initialChatPreferences; },
set initialChatPreferences(v) { initialChatPreferences = v; },
// 重置所有状态(用于测试或强制同步)
reset() {
onlineUsers = {};
window.onlineUsers = onlineUsers;
autoScroll = true;
maxMsgId = 0;
pendingChatMessages = [];
chatMessageFlushTimer = null;
userListRenderTimer = null;
userFilterRenderTimer = null;
userBadgeRotationTick = 0;
lastAutosaveNode = null;
roomsRefreshTimer = null;
roomsOnlineStatusCache = null;
roomsOnlineStatusCacheAt = 0;
isMutedUntil = 0;
imeComposing = false;
isSending = false;
sendStartedAt = 0;
leaveRequestInFlight = false;
heartbeatFailCount = 0;
blockedSystemSenders = new Set();
},
};
// 挂载到 window 供 Blade 脚本及其他模块使用
window.chatState = chatState;
// 向后兼容 Blade 中已暴露的 window 接口
export function hydrateOnlineUserPayload(username, payload) {
const nextPayload = { ...(onlineUsers[username] || {}) };
// 清除旧状态字段
delete nextPayload.daily_status_key;
delete nextPayload.daily_status_label;
delete nextPayload.daily_status_icon;
delete nextPayload.daily_status_group;
delete nextPayload.daily_status_expires_at;
onlineUsers[username] = { ...nextPayload, ...payload };
window.onlineUsers = onlineUsers;
}
window.hydrateOnlineUserPayload = hydrateOnlineUserPayload;
export function renderUserList() {
// 占位:实际渲染逻辑由 user-list.js 挂载到 window.chatState.renderUserList
if (typeof window.renderUserList === "function") {
window.renderUserList();
}
}
export { onlineUsers, autoScroll, maxMsgId };