Compare commits
2
Commits
59a417bd10
...
b21f583fe5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b21f583fe5 | ||
|
|
8c7b1086ff |
@@ -64,8 +64,10 @@ export { bindChatToast } from "./chat-room/toast.js";
|
||||
export { bindChatComposerControls, setChatComposerAction } from "./chat-room/composer.js";
|
||||
export {
|
||||
isExpiredChatImageMessage,
|
||||
isAutoScrollEnabled,
|
||||
localClearScreen,
|
||||
scrollChatToBottom,
|
||||
setAutoScrollEnabled,
|
||||
syncAutoScrollControls,
|
||||
toggleAutoScroll,
|
||||
} from "./chat-room/message-utils.js";
|
||||
@@ -319,8 +321,10 @@ if (typeof window !== "undefined") {
|
||||
bindChatComposerControls,
|
||||
setChatComposerAction,
|
||||
isExpiredChatImageMessage,
|
||||
isAutoScrollEnabled,
|
||||
localClearScreen,
|
||||
scrollChatToBottom,
|
||||
setAutoScrollEnabled,
|
||||
syncAutoScrollControls,
|
||||
toggleAutoScroll,
|
||||
bindInstantHoverTooltip,
|
||||
@@ -592,8 +596,10 @@ if (typeof window !== "undefined") {
|
||||
// ── 静态核心模块 window 挂载 ──
|
||||
window.escapeHtml = escapeHtml;
|
||||
window.isExpiredChatImageMessage = isExpiredChatImageMessage;
|
||||
window.isChatAutoScrollEnabled = isAutoScrollEnabled;
|
||||
window.localClearScreen = localClearScreen;
|
||||
window.normalizeSafeChatUrl = normalizeSafeChatUrl;
|
||||
window.setChatAutoScrollEnabled = setAutoScrollEnabled;
|
||||
window.setAction = setChatComposerAction;
|
||||
window.syncAutoScrollControls = syncAutoScrollControls;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// 聊天室任命/撤销公告监听,负责渲染大卡片和频道内系统提示。
|
||||
|
||||
import { escapeHtml } from "./html.js";
|
||||
import { isAutoScrollEnabled, scrollChatToBottom } from "./message-utils.js";
|
||||
|
||||
const APPOINTMENT_PHRASES = [
|
||||
"望再接再厉,大展宏图,为大家服务!",
|
||||
@@ -132,7 +133,7 @@ function appendAppointmentMessage(container, message) {
|
||||
}
|
||||
|
||||
container.appendChild(message);
|
||||
container.scrollTop = container.scrollHeight;
|
||||
scrollChatToBottom(container, isAutoScrollEnabled);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
import { escapeHtml, normalizeSafeChatUrl } from "./html.js";
|
||||
import { normalizeDailyStatus } from "./preferences-status.js";
|
||||
import { enqueueChatMessage } from "./message-renderer.js";
|
||||
import { isAutoScrollEnabled, scrollChatToBottom } from "./message-utils.js";
|
||||
|
||||
// ── 事件注册标记 ──
|
||||
let chatEventsBound = false;
|
||||
@@ -19,6 +20,16 @@ function getState() {
|
||||
return window.chatState;
|
||||
}
|
||||
|
||||
/**
|
||||
* 在开启自动滚屏时把指定聊天窗格滚动到底部。
|
||||
*
|
||||
* @param {HTMLElement|null|undefined} container 聊天消息容器
|
||||
* @returns {void}
|
||||
*/
|
||||
function scrollWhenEnabled(container) {
|
||||
scrollChatToBottom(container, isAutoScrollEnabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* 启动 WebSocket 初始化(DOMContentLoaded 之后调用)。
|
||||
*/
|
||||
@@ -79,7 +90,7 @@ function handleMutedEvent(e) {
|
||||
: (state?.container);
|
||||
if (targetContainer) {
|
||||
targetContainer.appendChild(div);
|
||||
targetContainer.scrollTop = targetContainer.scrollHeight;
|
||||
scrollWhenEnabled(targetContainer);
|
||||
}
|
||||
|
||||
if (isMe && d.mute_time > 0) {
|
||||
@@ -99,7 +110,7 @@ function handleMutedEvent(e) {
|
||||
const say2 = document.getElementById("say2");
|
||||
if (say2) {
|
||||
say2.appendChild(unmuteDiv);
|
||||
say2.scrollTop = say2.scrollHeight;
|
||||
scrollWhenEnabled(say2);
|
||||
}
|
||||
}, d.mute_time * 60 * 1000);
|
||||
}
|
||||
@@ -148,7 +159,7 @@ function setupScreenClearedListener() {
|
||||
sysDiv.innerHTML = `<span style="color: #dc2626; font-weight: bold;">🧹 管理员 <b>${safeOperator}</b> 已执行全员清屏</span><span class="msg-time">(${timeStr})</span>`;
|
||||
if (say1) {
|
||||
say1.appendChild(sysDiv);
|
||||
say1.scrollTop = say1.scrollHeight;
|
||||
scrollWhenEnabled(say1);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -205,7 +216,7 @@ function setupChangelogPublishedListener() {
|
||||
const say1 = document.getElementById("chat-messages-container");
|
||||
if (say1) {
|
||||
say1.appendChild(sysDiv);
|
||||
say1.scrollTop = say1.scrollHeight;
|
||||
scrollWhenEnabled(say1);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -255,7 +266,7 @@ function setupGomokuInviteListener() {
|
||||
const say1 = document.getElementById("chat-messages-container");
|
||||
if (say1) {
|
||||
say1.appendChild(div);
|
||||
say1.scrollTop = say1.scrollHeight;
|
||||
scrollWhenEnabled(say1);
|
||||
}
|
||||
|
||||
if (!isSelf) {
|
||||
@@ -294,7 +305,7 @@ function setupGomokuInviteListener() {
|
||||
const say1 = document.getElementById("chat-messages-container");
|
||||
if (say1) {
|
||||
say1.appendChild(div);
|
||||
say1.scrollTop = say1.scrollHeight;
|
||||
scrollWhenEnabled(say1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
// 聊天输入区完整逻辑:发送消息、草稿管理、IME 防重、神秘箱子暗号拦截。
|
||||
// 从 Blade 内联脚本 scripts.blade.php 迁移至 Vite 模块。
|
||||
|
||||
import { isAutoScrollEnabled, scrollChatToBottom } from "./message-utils.js";
|
||||
|
||||
let chatComposerEventsBound = false;
|
||||
|
||||
function csrf() {
|
||||
@@ -165,7 +167,7 @@ async function sendMessage(e) {
|
||||
const say2 = document.getElementById("say2");
|
||||
if (say2) {
|
||||
say2.appendChild(muteDiv);
|
||||
say2.scrollTop = say2.scrollHeight;
|
||||
scrollChatToBottom(say2, isAutoScrollEnabled);
|
||||
}
|
||||
if (state) {
|
||||
state.isSending = false;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
// 婚姻弹窗辅助入口,承接从 marriage-modals.blade.php 迁移出的全局函数。
|
||||
|
||||
import { isAutoScrollEnabled, scrollChatToBottom } from "./message-utils.js";
|
||||
|
||||
/**
|
||||
* 向聊天主窗口追加一条婚姻系统公告,允许传入受控 HTML 按钮。
|
||||
*
|
||||
@@ -17,7 +19,7 @@ export function appendSystemMessage(html) {
|
||||
div.style.cssText = "background:linear-gradient(135deg,#fdf4ff,#fce7f3); border-left:3px solid #ec4899; border-radius:6px; padding:5px 12px; margin:3px 0; font-size:13px; line-height:1.6;";
|
||||
div.innerHTML = `<span style="color:#9d174d;">${html}</span>`;
|
||||
container.appendChild(div);
|
||||
container.scrollTop = container.scrollHeight;
|
||||
scrollChatToBottom(container, isAutoScrollEnabled);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -219,7 +219,7 @@ function resolveGameNotificationCardMeta(msg) {
|
||||
|| normalizedContent.startsWith("🏇 比赛开始:")
|
||||
|| normalizedContent.startsWith("🏆 冠军:")
|
||||
|| /^🐎\s*第\s*#?\d+\s*场开赛/u.test(normalizedContent)
|
||||
|| /^🏇\s*第\s*#?\d+\s*场比赛开始/u.test(normalizedContent)
|
||||
|| /^🏇\s*(?:赛马)?第\s*#?\d+\s*场比赛开始/u.test(normalizedContent)
|
||||
|| /^🏆\s*第\s*#?\d+\s*场结束/u.test(normalizedContent)
|
||||
) {
|
||||
return {
|
||||
|
||||
@@ -75,10 +75,46 @@ export function localClearScreen(roomId = window.chatContext?.roomId, maxMessage
|
||||
|
||||
if (publicPane) {
|
||||
publicPane.appendChild(notice);
|
||||
publicPane.scrollTop = publicPane.scrollHeight;
|
||||
scrollChatToBottom(publicPane, isAutoScrollEnabled);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取当前是否允许聊天窗口自动滚屏。
|
||||
*
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export function isAutoScrollEnabled() {
|
||||
const state = window.chatState;
|
||||
|
||||
if (state && typeof state.autoScroll !== "undefined") {
|
||||
return Boolean(state.autoScroll);
|
||||
}
|
||||
|
||||
const checkbox = document.getElementById("auto_scroll");
|
||||
|
||||
return checkbox ? Boolean(checkbox.checked) : true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入自动滚屏状态,并同步页面复选框和状态文字。
|
||||
*
|
||||
* @param {boolean} enabled 是否开启自动滚屏
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export function setAutoScrollEnabled(enabled) {
|
||||
const nextEnabled = Boolean(enabled);
|
||||
const state = window.chatState;
|
||||
|
||||
if (state) {
|
||||
state.autoScroll = nextEnabled;
|
||||
}
|
||||
|
||||
syncAutoScrollControls(nextEnabled);
|
||||
|
||||
return nextEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步自动滚屏复选框与状态文字。
|
||||
*
|
||||
@@ -111,6 +147,8 @@ export function toggleAutoScroll(getCurrent, setCurrent) {
|
||||
|
||||
if (typeof setCurrent === "function") {
|
||||
setCurrent(nextEnabled);
|
||||
} else {
|
||||
setAutoScrollEnabled(nextEnabled);
|
||||
}
|
||||
|
||||
syncAutoScrollControls(nextEnabled);
|
||||
|
||||
@@ -545,14 +545,18 @@ export function resolveBlockedSystemSenderKey(msg) {
|
||||
return "百家乐";
|
||||
}
|
||||
|
||||
// 赛马通知已缩短为“开赛:...”“比赛开始:...”“冠军:...”等格式。
|
||||
// 赛马通知可能来自旧版“跑马”发送者,也可能以系统传音发送紧凑开赛/结束文案。
|
||||
if (
|
||||
fromUser === "跑马" ||
|
||||
isSystemBroadcast && (
|
||||
content.includes("赛马") ||
|
||||
content.includes("跑马") ||
|
||||
content.startsWith("🐎 开赛:") ||
|
||||
content.startsWith("🏇 比赛开始:") ||
|
||||
content.startsWith("🏆 冠军:")
|
||||
content.startsWith("🏆 冠军:") ||
|
||||
/^🐎\s*第\s*#?\d+\s*场开赛/u.test(content) ||
|
||||
/^🏇\s*(?:赛马)?第\s*#?\d+\s*场比赛开始/u.test(content) ||
|
||||
/^🏆\s*第\s*#?\d+\s*场结束/u.test(content)
|
||||
)
|
||||
) {
|
||||
return "跑马";
|
||||
|
||||
Reference in New Issue
Block a user