fix: 修复迁移遗留的按钮无响应、头像框层级及构建错误
迁移收尾修复:
- heartbeat.js: 移除 export { } 中重复的 startHeartbeat/stopHeartbeat(已通过 export function 导出)
- scripts.blade.php: 移除 JS 注释中的 {{ }} 避免 Blade 编译为 e() 导致 PHP 解析错误
- preferences-status.js: 补全 6 个缺失的 window.* 赋值(toggleBlockMenu/toggleFeatureMenu 等),
实现迁移中丢失的 updateDailyStatus/clearDailyStatus,修复 handleFeatureLocalClear 清屏回调
- toolbar.js: 补全 window.runFeatureShortcut 赋值
头像框样式修复(chat-decorations.css):
- z-index 互换:头像降至 1,框升至 3,使框边缘可遮挡头像外围
- 使用 CSS mask(radial-gradient)挖环形替代旧 ::before 实心圆遮挡方案
- clip-path: circle(50%) 硬裁剪确保圆形,不受 chat.css border-radius: 2px 覆盖
- 特异性提升至 .user-item .avatar-frame-wrapper .user-head
新 Vite 模块(从 Blade 迁移):
- chat-state.js / message-renderer.js / user-list.js / chat-events.js
- composer.js(重写)/ heartbeat.js / admin-commands.js
- vip-presence.js / chat-decorations.css
This commit is contained in:
@@ -0,0 +1,223 @@
|
||||
// 聊天室共享运行时状态,桥接 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 };
|
||||
Reference in New Issue
Block a user