diff --git a/resources/js/chat-room.js b/resources/js/chat-room.js index 2c547b1..3d528a0 100644 --- a/resources/js/chat-room.js +++ b/resources/js/chat-room.js @@ -214,14 +214,19 @@ export { CHAT_SOUND_MUTED_STORAGE_KEY, bindBlockMenuControls, bindSoundMuteControl, + closeDailyStatusEditor, + closeFeatureMenu, isSoundMuted, loadBlockedSystemSenders, normalizeChatPreferences, normalizeDailyStatus, + openDailyStatusEditor, parseDailyStatusExpiry, persistBlockedSystemSenders, setSoundMuted, shouldMigrateLocalChatPreferences, + toggleBlockMenu, + toggleFeatureMenu, } from "./chat-room/preferences-status.js"; export { bindChatRightPanelControls } from "./chat-room/right-panel.js"; export { @@ -400,14 +405,19 @@ import { CHAT_SOUND_MUTED_STORAGE_KEY, bindBlockMenuControls, bindSoundMuteControl, + closeDailyStatusEditor, + closeFeatureMenu, isSoundMuted, loadBlockedSystemSenders, normalizeChatPreferences, normalizeDailyStatus, + openDailyStatusEditor, parseDailyStatusExpiry, persistBlockedSystemSenders, setSoundMuted, shouldMigrateLocalChatPreferences, + toggleBlockMenu, + toggleFeatureMenu, } from "./chat-room/preferences-status.js"; import { bindChatRightPanelControls } from "./chat-room/right-panel.js"; import { @@ -622,14 +632,19 @@ if (typeof window !== "undefined") { CHAT_SOUND_MUTED_STORAGE_KEY, bindBlockMenuControls, bindSoundMuteControl, + closeDailyStatusEditor, + closeFeatureMenu, isSoundMuted, loadBlockedSystemSenders, normalizeChatPreferences, normalizeDailyStatus, + openDailyStatusEditor, parseDailyStatusExpiry, persistBlockedSystemSenders, setSoundMuted, shouldMigrateLocalChatPreferences, + toggleBlockMenu, + toggleFeatureMenu, bindChatRightPanelControls, bindRoomStatusControls, normalizeRoomStatus, diff --git a/resources/js/chat-room/preferences-status.js b/resources/js/chat-room/preferences-status.js index d2d31e7..1c00456 100644 --- a/resources/js/chat-room/preferences-status.js +++ b/resources/js/chat-room/preferences-status.js @@ -171,6 +171,117 @@ export function bindSoundMuteControl(onChange) { }); } +/** + * 设置浮层显示状态。 + * + * @param {string} elementId 元素 ID + * @param {boolean} visible 是否显示 + * @returns {HTMLElement|null} + */ +function setPanelVisible(elementId, visible) { + const panel = document.getElementById(elementId); + + if (panel) { + panel.style.display = visible ? "block" : "none"; + } + + return panel; +} + +/** + * 关闭一组会互斥显示的聊天室浮层。 + * + * @param {string[]} panelIds 浮层 ID 列表 + * @returns {void} + */ +function closePanels(panelIds) { + panelIds.forEach((panelId) => setPanelVisible(panelId, false)); +} + +/** + * 关闭功能快捷菜单。 + * + * @returns {void} + */ +export function closeFeatureMenu() { + setPanelVisible("feature-menu", false); +} + +/** + * 切换功能快捷菜单显示状态,并关闭其他互斥浮层。 + * + * @param {Event|null} event 点击事件 + * @param {() => void} beforeToggle 切换前同步回调 + * @returns {void} + */ +export function toggleFeatureMenu(event = null, beforeToggle = undefined) { + event?.stopPropagation?.(); + + const menu = document.getElementById("feature-menu"); + + if (!menu) { + return; + } + + closePanels(["welcome-menu", "admin-menu", "block-menu", "daily-status-editor-overlay"]); + + if (typeof beforeToggle === "function") { + beforeToggle(); + } + + menu.style.display = menu.style.display === "none" ? "block" : "none"; +} + +/** + * 打开每日状态编辑器。 + * + * @param {() => void} beforeOpen 打开前同步回调 + * @returns {void} + */ +export function openDailyStatusEditor(beforeOpen = undefined) { + closeFeatureMenu(); + + if (typeof beforeOpen === "function") { + beforeOpen(); + } + + setPanelVisible("daily-status-editor-overlay", true); +} + +/** + * 关闭每日状态编辑器。 + * + * @returns {void} + */ +export function closeDailyStatusEditor() { + setPanelVisible("daily-status-editor-overlay", false); +} + +/** + * 切换系统播报屏蔽菜单显示状态,并关闭其他互斥浮层。 + * + * @param {Event|null} event 点击事件 + * @param {() => void} beforeToggle 切换前同步回调 + * @returns {void} + */ +export function toggleBlockMenu(event = null, beforeToggle = undefined) { + event?.stopPropagation?.(); + + const menu = document.getElementById("block-menu"); + + if (!menu) { + return; + } + + closePanels(["welcome-menu", "admin-menu", "feature-menu", "daily-status-editor-overlay"]); + + if (typeof beforeToggle === "function") { + beforeToggle(); + } + + menu.style.display = menu.style.display === "none" ? "block" : "none"; +} + /** * 绑定功能菜单、每日状态编辑与系统播报屏蔽的统一事件代理。 * diff --git a/resources/views/chat/partials/scripts.blade.php b/resources/views/chat/partials/scripts.blade.php index e8764b1..b2be1eb 100644 --- a/resources/views/chat/partials/scripts.blade.php +++ b/resources/views/chat/partials/scripts.blade.php @@ -311,8 +311,12 @@ * 关闭功能菜单。 */ function closeFeatureMenu() { - const menu = document.getElementById('feature-menu'); + if (window.ChatRoomTools?.closeFeatureMenu) { + window.ChatRoomTools.closeFeatureMenu(); + return; + } + const menu = document.getElementById('feature-menu'); if (menu) { menu.style.display = 'none'; } @@ -324,33 +328,24 @@ * @param {Event} event 点击事件 */ function toggleFeatureMenu(event) { - event.stopPropagation(); + if (window.ChatRoomTools?.toggleFeatureMenu) { + window.ChatRoomTools.toggleFeatureMenu(event, syncDailyStatusUi); + return; + } + event?.stopPropagation?.(); const menu = document.getElementById('feature-menu'); - const welcomeMenu = document.getElementById('welcome-menu'); - const adminMenu = document.getElementById('admin-menu'); - const blockMenu = document.getElementById('block-menu'); - const editorOverlay = document.getElementById('daily-status-editor-overlay'); if (!menu) { return; } - if (welcomeMenu) { - welcomeMenu.style.display = 'none'; - } - - if (adminMenu) { - adminMenu.style.display = 'none'; - } - - if (blockMenu) { - blockMenu.style.display = 'none'; - } - - if (editorOverlay) { - editorOverlay.style.display = 'none'; - } + ['welcome-menu', 'admin-menu', 'block-menu', 'daily-status-editor-overlay'].forEach((id) => { + const panel = document.getElementById(id); + if (panel) { + panel.style.display = 'none'; + } + }); syncDailyStatusUi(); menu.style.display = menu.style.display === 'none' ? 'block' : 'none'; @@ -360,11 +355,15 @@ * 打开状态编辑窗口。 */ function openDailyStatusEditor() { - const overlay = document.getElementById('daily-status-editor-overlay'); + if (window.ChatRoomTools?.openDailyStatusEditor) { + window.ChatRoomTools.openDailyStatusEditor(syncDailyStatusUi); + return; + } closeFeatureMenu(); syncDailyStatusUi(); + const overlay = document.getElementById('daily-status-editor-overlay'); if (overlay) { overlay.style.display = 'block'; } @@ -374,8 +373,12 @@ * 关闭状态编辑窗口。 */ function closeDailyStatusEditor() { - const overlay = document.getElementById('daily-status-editor-overlay'); + if (window.ChatRoomTools?.closeDailyStatusEditor) { + window.ChatRoomTools.closeDailyStatusEditor(); + return; + } + const overlay = document.getElementById('daily-status-editor-overlay'); if (overlay) { overlay.style.display = 'none'; } @@ -1247,32 +1250,24 @@ * @param {Event} event 点击事件 */ function toggleBlockMenu(event) { - event.stopPropagation(); + if (window.ChatRoomTools?.toggleBlockMenu) { + window.ChatRoomTools.toggleBlockMenu(event, syncBlockedSystemSenderCheckboxes); + return; + } + + event?.stopPropagation?.(); const menu = document.getElementById('block-menu'); - const welcomeMenu = document.getElementById('welcome-menu'); - const adminMenu = document.getElementById('admin-menu'); - const featureMenu = document.getElementById('feature-menu'); - const dailyStatusEditor = document.getElementById('daily-status-editor-overlay'); if (!menu) { return; } - if (welcomeMenu) { - welcomeMenu.style.display = 'none'; - } - - if (adminMenu) { - adminMenu.style.display = 'none'; - } - - if (featureMenu) { - featureMenu.style.display = 'none'; - } - - if (dailyStatusEditor) { - dailyStatusEditor.style.display = 'none'; - } + ['welcome-menu', 'admin-menu', 'feature-menu', 'daily-status-editor-overlay'].forEach((id) => { + const panel = document.getElementById(id); + if (panel) { + panel.style.display = 'none'; + } + }); syncBlockedSystemSenderCheckboxes(); menu.style.display = menu.style.display === 'none' ? 'block' : 'none';