优化屏蔽,可以保存状态

This commit is contained in:
2026-04-14 22:48:29 +08:00
parent 7255d50966
commit 1a39ddd725
8 changed files with 279 additions and 5 deletions
+115 -4
View File
@@ -38,6 +38,7 @@
const onlineCount = document.getElementById('online-count');
const onlineCountBottom = document.getElementById('online-count-bottom');
const BLOCKED_SYSTEM_SENDERS_STORAGE_KEY = 'chat_blocked_system_senders';
const CHAT_SOUND_MUTED_STORAGE_KEY = 'chat_sound_muted';
const BLOCKABLE_SYSTEM_SENDERS = ['钓鱼播报', '星海小博士', '百家乐', '跑马'];
// ── 消息区:手机端双触发打开用户名片(PC 端靠 ondblclick 内联属性)──
@@ -70,7 +71,26 @@
let onlineUsers = {};
let autoScroll = true;
let _maxMsgId = 0; // 记录当前收到的最大消息 ID
let blockedSystemSenders = new Set(loadBlockedSystemSenders());
const initialChatPreferences = normalizeChatPreferences(window.chatContext?.chatPreferences || {});
let blockedSystemSenders = new Set(initialChatPreferences.blocked_system_senders);
/**
* 规整聊天室偏好对象,过滤非法配置并补齐默认值。
*
* @param {Record<string, any>} raw 原始偏好对象
* @returns {Object}
*/
function normalizeChatPreferences(raw) {
const blocked = Array.isArray(raw?.blocked_system_senders)
? raw.blocked_system_senders.filter(sender => BLOCKABLE_SYSTEM_SENDERS.includes(sender))
: [];
return {
// 默认所有用户都处于“不屏蔽”的开放状态,只有显式勾选的项目才会进入该列表。
blocked_system_senders: Array.from(new Set(blocked)),
sound_muted: Boolean(raw?.sound_muted),
};
}
/**
* localStorage 读取已屏蔽的系统播报发送者列表。
@@ -101,6 +121,77 @@
);
}
/**
* 判断当前禁音开关是否处于打开状态。
*
* @returns {boolean}
*/
function isSoundMuted() {
const muteCheckbox = document.getElementById('sound_muted');
if (muteCheckbox) {
return Boolean(muteCheckbox.checked);
}
return localStorage.getItem(CHAT_SOUND_MUTED_STORAGE_KEY) === '1';
}
/**
* 获取当前聊天室偏好快照。
*
* @returns {Object}
*/
function buildChatPreferencesPayload() {
return {
blocked_system_senders: Array.from(blockedSystemSenders),
sound_muted: isSoundMuted(),
};
}
/**
* 将聊天室偏好写入本地缓存,供刷新前快速恢复与迁移兜底。
*/
function persistChatPreferencesToLocal() {
persistBlockedSystemSenders();
localStorage.setItem(CHAT_SOUND_MUTED_STORAGE_KEY, isSoundMuted() ? '1' : '0');
}
/**
* 将当前聊天室偏好保存到当前登录账号。
*/
async function saveChatPreferences() {
const payload = buildChatPreferencesPayload();
persistChatPreferencesToLocal();
if (!window.chatContext?.chatPreferencesUrl) {
return;
}
try {
const response = await fetch(window.chatContext.chatPreferencesUrl, {
method: 'PUT',
headers: {
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]')?.content ?? '',
'Content-Type': 'application/json',
'Accept': 'application/json',
},
body: JSON.stringify(payload),
});
if (!response.ok) {
throw new Error('save chat preferences failed');
}
const data = await response.json();
if (data?.status === 'success') {
window.chatContext.chatPreferences = normalizeChatPreferences(data.data || payload);
}
} catch (error) {
console.error('聊天室偏好保存失败:', error);
}
}
/**
* 同步屏蔽菜单中的复选框状态。
*/
@@ -237,6 +328,7 @@
persistBlockedSystemSenders();
syncBlockedSystemSenderCheckboxes();
void saveChatPreferences();
}
syncBlockedSystemSenderCheckboxes();
@@ -1589,11 +1681,28 @@
if (saved) {
applyFontSize(saved);
}
// 恢复禁音复选框状态
const muted = localStorage.getItem('chat_sound_muted') === '1';
const storedBlockedSystemSenders = loadBlockedSystemSenders();
const mutedFromLocal = localStorage.getItem(CHAT_SOUND_MUTED_STORAGE_KEY) === '1';
const hasServerPreferences = initialChatPreferences.blocked_system_senders.length > 0 || initialChatPreferences.sound_muted;
const shouldMigrateLocalPreferences = !hasServerPreferences
&& (storedBlockedSystemSenders.length > 0 || mutedFromLocal);
if (shouldMigrateLocalPreferences) {
blockedSystemSenders = new Set(storedBlockedSystemSenders);
}
// 恢复禁音复选框状态;默认一律为未禁音。
const muted = shouldMigrateLocalPreferences ? mutedFromLocal : initialChatPreferences.sound_muted;
const muteChk = document.getElementById('sound_muted');
if (muteChk) muteChk.checked = muted;
syncBlockedSystemSenderCheckboxes();
if (shouldMigrateLocalPreferences) {
void saveChatPreferences();
} else {
persistChatPreferencesToLocal();
}
});
// ── 特效禁音开关 ─────────────────────────────────────────────────
@@ -1604,10 +1713,12 @@
* @param {boolean} muted true = 禁音,false = 开启声音
*/
function toggleSoundMute(muted) {
localStorage.setItem('chat_sound_muted', muted ? '1' : '0');
localStorage.setItem(CHAT_SOUND_MUTED_STORAGE_KEY, muted ? '1' : '0');
if (muted && typeof EffectSounds !== 'undefined') {
EffectSounds.stop(); // 立即停止当前音效
}
void saveChatPreferences();
}
window.toggleSoundMute = toggleSoundMute;