屏蔽新增 百家乐 跑马
This commit is contained in:
@@ -133,6 +133,18 @@ $welcomeMessages = [
|
|||||||
onchange="toggleBlockedSystemSender('星海小博士', this.checked)">
|
onchange="toggleBlockedSystemSender('星海小博士', this.checked)">
|
||||||
星海小博士
|
星海小博士
|
||||||
</label>
|
</label>
|
||||||
|
<label
|
||||||
|
style="display:flex;align-items:center;gap:6px;font-size:12px;color:#1e293b;cursor:pointer;padding:4px 2px;">
|
||||||
|
<input type="checkbox" id="block-sender-baccarat"
|
||||||
|
onchange="toggleBlockedSystemSender('百家乐', this.checked)">
|
||||||
|
百家乐
|
||||||
|
</label>
|
||||||
|
<label
|
||||||
|
style="display:flex;align-items:center;gap:6px;font-size:12px;color:#1e293b;cursor:pointer;padding:4px 2px;">
|
||||||
|
<input type="checkbox" id="block-sender-horse-race"
|
||||||
|
onchange="toggleBlockedSystemSender('跑马', this.checked)">
|
||||||
|
跑马
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,7 @@
|
|||||||
const onlineCount = document.getElementById('online-count');
|
const onlineCount = document.getElementById('online-count');
|
||||||
const onlineCountBottom = document.getElementById('online-count-bottom');
|
const onlineCountBottom = document.getElementById('online-count-bottom');
|
||||||
const BLOCKED_SYSTEM_SENDERS_STORAGE_KEY = 'chat_blocked_system_senders';
|
const BLOCKED_SYSTEM_SENDERS_STORAGE_KEY = 'chat_blocked_system_senders';
|
||||||
const BLOCKABLE_SYSTEM_SENDERS = ['钓鱼播报', '星海小博士'];
|
const BLOCKABLE_SYSTEM_SENDERS = ['钓鱼播报', '星海小博士', '百家乐', '跑马'];
|
||||||
|
|
||||||
// ── 消息区:手机端双触发打开用户名片(PC 端靠 ondblclick 内联属性)──
|
// ── 消息区:手机端双触发打开用户名片(PC 端靠 ondblclick 内联属性)──
|
||||||
// span[data-u] 由 clickableUser() 生成,touchend 委托至容器避免每条消息单独绑定
|
// span[data-u] 由 clickableUser() 生成,touchend 委托至容器避免每条消息单独绑定
|
||||||
@@ -107,6 +107,8 @@
|
|||||||
function syncBlockedSystemSenderCheckboxes() {
|
function syncBlockedSystemSenderCheckboxes() {
|
||||||
const fishingCheckbox = document.getElementById('block-sender-fishing');
|
const fishingCheckbox = document.getElementById('block-sender-fishing');
|
||||||
const doctorCheckbox = document.getElementById('block-sender-doctor');
|
const doctorCheckbox = document.getElementById('block-sender-doctor');
|
||||||
|
const baccaratCheckbox = document.getElementById('block-sender-baccarat');
|
||||||
|
const horseRaceCheckbox = document.getElementById('block-sender-horse-race');
|
||||||
|
|
||||||
if (fishingCheckbox) {
|
if (fishingCheckbox) {
|
||||||
fishingCheckbox.checked = blockedSystemSenders.has('钓鱼播报');
|
fishingCheckbox.checked = blockedSystemSenders.has('钓鱼播报');
|
||||||
@@ -115,35 +117,74 @@
|
|||||||
if (doctorCheckbox) {
|
if (doctorCheckbox) {
|
||||||
doctorCheckbox.checked = blockedSystemSenders.has('星海小博士');
|
doctorCheckbox.checked = blockedSystemSenders.has('星海小博士');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (baccaratCheckbox) {
|
||||||
|
baccaratCheckbox.checked = blockedSystemSenders.has('百家乐');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (horseRaceCheckbox) {
|
||||||
|
horseRaceCheckbox.checked = blockedSystemSenders.has('跑马');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断当前消息发送者是否已被用户屏蔽。
|
* 根据消息内容识别其对应的屏蔽规则键。
|
||||||
*
|
*
|
||||||
* @param {string} fromUser 发送者名称
|
* @param {Record<string, any>} msg 消息对象
|
||||||
* @returns {boolean}
|
* @returns {string|null}
|
||||||
*/
|
*/
|
||||||
function isBlockedSystemSender(fromUser) {
|
function resolveBlockedSystemSenderKey(msg) {
|
||||||
return blockedSystemSenders.has(String(fromUser || ''));
|
const fromUser = String(msg?.from_user || '');
|
||||||
|
const content = String(msg?.content || '');
|
||||||
|
|
||||||
|
if (fromUser === '钓鱼播报') {
|
||||||
|
return '钓鱼播报';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fromUser === '星海小博士') {
|
||||||
|
return '星海小博士';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((fromUser === '系统传音' || fromUser === '系统') && content.includes('百家乐')) {
|
||||||
|
return '百家乐';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((fromUser === '系统传音' || fromUser === '系统') && (content.includes('赛马') || content.includes('跑马'))) {
|
||||||
|
return '跑马';
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 从当前已渲染的聊天窗口中移除指定发送者的所有消息。
|
* 批量切换当前已渲染消息的显示状态。
|
||||||
*
|
*
|
||||||
* @param {string} sender 发送者名称
|
* @param {string} blockKey 屏蔽规则键
|
||||||
|
* @param {boolean} hidden true = 隐藏,false = 恢复显示
|
||||||
*/
|
*/
|
||||||
function removeRenderedMessagesBySender(sender) {
|
function setRenderedMessagesVisibilityBySender(blockKey, hidden) {
|
||||||
[container, container2].forEach(targetContainer => {
|
[container, container2].forEach(targetContainer => {
|
||||||
if (!targetContainer) {
|
if (!targetContainer) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
targetContainer.querySelectorAll('[data-from-user]').forEach(node => {
|
targetContainer.querySelectorAll('[data-block-key]').forEach(node => {
|
||||||
if (node.dataset.fromUser === sender) {
|
if (node.dataset.blockKey === blockKey) {
|
||||||
node.remove();
|
if (hidden) {
|
||||||
|
node.dataset.blockHidden = '1';
|
||||||
|
node.style.display = 'none';
|
||||||
|
} else if (node.dataset.blockHidden === '1') {
|
||||||
|
node.removeAttribute('data-block-hidden');
|
||||||
|
node.style.display = '';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (!hidden && autoScroll) {
|
||||||
|
container.scrollTop = container.scrollHeight;
|
||||||
|
container2.scrollTop = container2.scrollHeight;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -176,7 +217,7 @@
|
|||||||
/**
|
/**
|
||||||
* 更新指定系统播报项的屏蔽状态,并在勾选后立即清理当前窗口。
|
* 更新指定系统播报项的屏蔽状态,并在勾选后立即清理当前窗口。
|
||||||
*
|
*
|
||||||
* @param {string} sender 系统播报发送者
|
* @param {string} sender 系统播报发送者/规则键
|
||||||
* @param {boolean} blocked 是否屏蔽
|
* @param {boolean} blocked 是否屏蔽
|
||||||
*/
|
*/
|
||||||
function toggleBlockedSystemSender(sender, blocked) {
|
function toggleBlockedSystemSender(sender, blocked) {
|
||||||
@@ -186,10 +227,12 @@
|
|||||||
|
|
||||||
if (blocked) {
|
if (blocked) {
|
||||||
blockedSystemSenders.add(sender);
|
blockedSystemSenders.add(sender);
|
||||||
// 勾选后立刻移除聊天室窗口内已显示的对应播报内容。
|
// 勾选后立刻隐藏聊天室窗口内已显示的对应播报内容。
|
||||||
removeRenderedMessagesBySender(sender);
|
setRenderedMessagesVisibilityBySender(sender, true);
|
||||||
} else {
|
} else {
|
||||||
blockedSystemSenders.delete(sender);
|
blockedSystemSenders.delete(sender);
|
||||||
|
// 取消勾选后立即恢复先前被隐藏的对应播报内容。
|
||||||
|
setRenderedMessagesVisibilityBySender(sender, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
persistBlockedSystemSenders();
|
persistBlockedSystemSenders();
|
||||||
@@ -799,19 +842,19 @@
|
|||||||
_maxMsgId = msg.id;
|
_maxMsgId = msg.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 用户勾选屏蔽后,历史消息和实时消息统一在这里拦截,不再进入渲染流程。
|
|
||||||
if (isBlockedSystemSender(msg?.from_user)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const isMe = msg.from_user === window.chatContext.username;
|
const isMe = msg.from_user === window.chatContext.username;
|
||||||
const fontColor = msg.font_color || '#000000';
|
const fontColor = msg.font_color || '#000000';
|
||||||
|
const blockRuleKey = resolveBlockedSystemSenderKey(msg);
|
||||||
|
const shouldHideByBlock = blockRuleKey ? blockedSystemSenders.has(blockRuleKey) : false;
|
||||||
|
|
||||||
const div = document.createElement('div');
|
const div = document.createElement('div');
|
||||||
div.className = 'msg-line';
|
div.className = 'msg-line';
|
||||||
if (msg?.from_user) {
|
if (msg?.from_user) {
|
||||||
div.dataset.fromUser = msg.from_user;
|
div.dataset.fromUser = msg.from_user;
|
||||||
}
|
}
|
||||||
|
if (blockRuleKey) {
|
||||||
|
div.dataset.blockKey = blockRuleKey;
|
||||||
|
}
|
||||||
|
|
||||||
const timeStr = msg.sent_at || '';
|
const timeStr = msg.sent_at || '';
|
||||||
let timeStrOverride = false;
|
let timeStrOverride = false;
|
||||||
@@ -1061,6 +1104,12 @@
|
|||||||
}
|
}
|
||||||
div.innerHTML = html;
|
div.innerHTML = html;
|
||||||
|
|
||||||
|
// 命中屏蔽规则时,消息仍保留在 DOM 中,便于取消屏蔽后立即恢复显示。
|
||||||
|
if (shouldHideByBlock) {
|
||||||
|
div.dataset.blockHidden = '1';
|
||||||
|
div.style.display = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
// 后端下发的带有 welcome_user 的也是系统欢迎/离开消息,加上属性标记
|
// 后端下发的带有 welcome_user 的也是系统欢迎/离开消息,加上属性标记
|
||||||
if (msg.welcome_user) {
|
if (msg.welcome_user) {
|
||||||
div.setAttribute('data-system-user', msg.welcome_user);
|
div.setAttribute('data-system-user', msg.welcome_user);
|
||||||
|
|||||||
@@ -74,6 +74,8 @@ class ChatControllerTest extends TestCase
|
|||||||
$response->assertSee('🔕 屏蔽', false);
|
$response->assertSee('🔕 屏蔽', false);
|
||||||
$response->assertSee('钓鱼播报');
|
$response->assertSee('钓鱼播报');
|
||||||
$response->assertSee('星海小博士');
|
$response->assertSee('星海小博士');
|
||||||
|
$response->assertSee('百家乐');
|
||||||
|
$response->assertSee('跑马');
|
||||||
$response->assertSee('chat_blocked_system_senders');
|
$response->assertSee('chat_blocked_system_senders');
|
||||||
$response->assertSee('toggleBlockedSystemSender');
|
$response->assertSee('toggleBlockedSystemSender');
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user