迁移管理菜单和钓鱼按钮事件绑定
This commit is contained in:
@@ -10,6 +10,8 @@ export { closeChatImageLightbox, initChatImageLightboxEvents, openChatImageLight
|
|||||||
export { bindMobileDrawerControls } from "./chat-room/mobile-drawer.js";
|
export { bindMobileDrawerControls } from "./chat-room/mobile-drawer.js";
|
||||||
export { bindToolbarControls } from "./chat-room/toolbar.js";
|
export { bindToolbarControls } from "./chat-room/toolbar.js";
|
||||||
export { bindWelcomeMenuControls } from "./chat-room/welcome-menu.js";
|
export { bindWelcomeMenuControls } from "./chat-room/welcome-menu.js";
|
||||||
|
export { bindAdminMenuControls } from "./chat-room/admin-menu.js";
|
||||||
|
export { bindFishingControls } from "./chat-room/fishing.js";
|
||||||
export {
|
export {
|
||||||
BLOCKABLE_SYSTEM_SENDERS,
|
BLOCKABLE_SYSTEM_SENDERS,
|
||||||
BLOCKED_SYSTEM_SENDERS_STORAGE_KEY,
|
BLOCKED_SYSTEM_SENDERS_STORAGE_KEY,
|
||||||
@@ -44,6 +46,8 @@ import { closeChatImageLightbox, initChatImageLightboxEvents, openChatImageLight
|
|||||||
import { bindMobileDrawerControls } from "./chat-room/mobile-drawer.js";
|
import { bindMobileDrawerControls } from "./chat-room/mobile-drawer.js";
|
||||||
import { bindToolbarControls } from "./chat-room/toolbar.js";
|
import { bindToolbarControls } from "./chat-room/toolbar.js";
|
||||||
import { bindWelcomeMenuControls } from "./chat-room/welcome-menu.js";
|
import { bindWelcomeMenuControls } from "./chat-room/welcome-menu.js";
|
||||||
|
import { bindAdminMenuControls } from "./chat-room/admin-menu.js";
|
||||||
|
import { bindFishingControls } from "./chat-room/fishing.js";
|
||||||
import {
|
import {
|
||||||
BLOCKABLE_SYSTEM_SENDERS,
|
BLOCKABLE_SYSTEM_SENDERS,
|
||||||
BLOCKED_SYSTEM_SENDERS_STORAGE_KEY,
|
BLOCKED_SYSTEM_SENDERS_STORAGE_KEY,
|
||||||
@@ -86,6 +90,8 @@ if (typeof window !== "undefined") {
|
|||||||
bindMobileDrawerControls,
|
bindMobileDrawerControls,
|
||||||
bindToolbarControls,
|
bindToolbarControls,
|
||||||
bindWelcomeMenuControls,
|
bindWelcomeMenuControls,
|
||||||
|
bindAdminMenuControls,
|
||||||
|
bindFishingControls,
|
||||||
CHAT_FONT_SIZE_STORAGE_KEY,
|
CHAT_FONT_SIZE_STORAGE_KEY,
|
||||||
restoreChatFontSize,
|
restoreChatFontSize,
|
||||||
closeChatImageLightbox,
|
closeChatImageLightbox,
|
||||||
@@ -127,6 +133,8 @@ if (typeof window !== "undefined") {
|
|||||||
bindChatImageUploadControl();
|
bindChatImageUploadControl();
|
||||||
bindFriendPanelControls();
|
bindFriendPanelControls();
|
||||||
bindToolbarControls();
|
bindToolbarControls();
|
||||||
|
bindAdminMenuControls();
|
||||||
|
bindFishingControls();
|
||||||
bindChatRightPanelControls();
|
bindChatRightPanelControls();
|
||||||
bindMobileDrawerControls();
|
bindMobileDrawerControls();
|
||||||
bindWelcomeMenuControls();
|
bindWelcomeMenuControls();
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
// 聊天室管理菜单事件绑定,替代 input-bar 中的管理类内联 onclick。
|
||||||
|
|
||||||
|
let adminMenuEventsBound = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绑定管理菜单、管理动作与全屏特效选择事件。
|
||||||
|
*
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
export function bindAdminMenuControls() {
|
||||||
|
if (adminMenuEventsBound || typeof document === "undefined") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
adminMenuEventsBound = true;
|
||||||
|
document.addEventListener("click", (event) => {
|
||||||
|
if (!(event.target instanceof Element)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const menuToggle = event.target.closest("[data-chat-admin-menu-toggle]");
|
||||||
|
if (menuToggle) {
|
||||||
|
event.preventDefault();
|
||||||
|
window.toggleAdminMenu?.(event);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const adminAction = event.target.closest("[data-chat-admin-action]");
|
||||||
|
if (adminAction) {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
// 管理菜单只负责入口分发,权限校验和实际动作仍由后端与原有全局函数负责。
|
||||||
|
const action = adminAction.getAttribute("data-chat-admin-action") || "";
|
||||||
|
if (action && typeof window.runAdminAction === "function") {
|
||||||
|
window.runAdminAction(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const effectButton = event.target.closest("[data-chat-admin-effect]");
|
||||||
|
if (effectButton) {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
// 特效按钮只触发管理员发起请求,实际播放仍由 chat:effect 广播和 EffectManager 处理。
|
||||||
|
const effect = effectButton.getAttribute("data-chat-admin-effect") || "";
|
||||||
|
if (effect && typeof window.selectEffect === "function") {
|
||||||
|
window.selectEffect(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.target.closest("[data-chat-admin-menu]")) {
|
||||||
|
event.stopPropagation();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
// 聊天室钓鱼入口事件绑定,先兼容存量全局 startFishing 实现。
|
||||||
|
|
||||||
|
let fishingEventsBound = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绑定钓鱼按钮点击事件。
|
||||||
|
*
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
export function bindFishingControls() {
|
||||||
|
if (fishingEventsBound || typeof document === "undefined") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fishingEventsBound = true;
|
||||||
|
document.addEventListener("click", (event) => {
|
||||||
|
if (!(event.target instanceof Element) || !event.target.closest("[data-chat-fishing-start]")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
// 钓鱼完整流程仍在 fishing-panel.blade.php,当前模块只统一按钮事件入口。
|
||||||
|
if (typeof window.startFishing === "function") {
|
||||||
|
window.startFishing();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -452,7 +452,6 @@
|
|||||||
const btn = document.getElementById('fishing-btn');
|
const btn = document.getElementById('fishing-btn');
|
||||||
btn.textContent = '🎣 钓鱼';
|
btn.textContent = '🎣 钓鱼';
|
||||||
btn.disabled = false;
|
btn.disabled = false;
|
||||||
btn.onclick = startFishing;
|
|
||||||
fishingTimer = null;
|
fishingTimer = null;
|
||||||
fishingReelTimeout = null;
|
fishingReelTimeout = null;
|
||||||
removeBobber();
|
removeBobber();
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ $welcomeMessages = [
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button type="button" id="fishing-btn" onclick="startFishing()"
|
<button type="button" id="fishing-btn" data-chat-fishing-start
|
||||||
style="font-size: 11px; padding: 1px 6px; background: #2563eb; color: #fff; border: none; border-radius: 2px; cursor: pointer;">🎣
|
style="font-size: 11px; padding: 1px 6px; background: #2563eb; color: #fff; border: none; border-radius: 2px; cursor: pointer;">🎣
|
||||||
钓鱼</button>
|
钓鱼</button>
|
||||||
|
|
||||||
@@ -244,16 +244,16 @@ $welcomeMessages = [
|
|||||||
|
|
||||||
@if (! empty($hasRoomManagementPermission))
|
@if (! empty($hasRoomManagementPermission))
|
||||||
<div style="position:relative;display:inline-block;" id="admin-btn-wrap">
|
<div style="position:relative;display:inline-block;" id="admin-btn-wrap">
|
||||||
<button type="button" onclick="toggleAdminMenu(event)"
|
<button type="button" data-chat-admin-menu-toggle
|
||||||
style="font-size:11px;padding:1px 6px;background:linear-gradient(135deg,#b45309,#d97706);color:#fff;border:none;border-radius:2px;cursor:pointer;font-weight:bold;">
|
style="font-size:11px;padding:1px 6px;background:linear-gradient(135deg,#b45309,#d97706);color:#fff;border:none;border-radius:2px;cursor:pointer;font-weight:bold;">
|
||||||
🛠 管理
|
🛠 管理
|
||||||
</button>
|
</button>
|
||||||
<div id="admin-menu"
|
<div id="admin-menu" data-chat-admin-menu
|
||||||
style="display:none;position:absolute;bottom:calc(100% + 6px);left:0;z-index:10020;min-width:244px;max-width:min(80vw,288px);max-height:min(62vh,460px);overflow-y:auto;padding:10px;background:#fffaf0;border:1px solid #fdba74;border-radius:10px;box-shadow:0 10px 24px rgba(15,23,42,.18);">
|
style="display:none;position:absolute;bottom:calc(100% + 6px);left:0;z-index:10020;min-width:244px;max-width:min(80vw,288px);max-height:min(62vh,460px);overflow-y:auto;padding:10px;background:#fffaf0;border:1px solid #fdba74;border-radius:10px;box-shadow:0 10px 24px rgba(15,23,42,.18);">
|
||||||
@if ($canSetAnnouncement)
|
@if ($canSetAnnouncement)
|
||||||
<div style="font-size:10px;color:#9a3412;padding:0 2px 6px;">房间管理</div>
|
<div style="font-size:10px;color:#9a3412;padding:0 2px 6px;">房间管理</div>
|
||||||
<div style="display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px;">
|
<div style="display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px;">
|
||||||
<button type="button" onclick="runAdminAction('announcement')"
|
<button type="button" data-chat-admin-action="announcement"
|
||||||
style="font-size:11px;padding:6px 8px;background:#fff;color:#047857;border:1px solid #86efac;border-radius:6px;cursor:pointer;">🪧 设公告</button>
|
style="font-size:11px;padding:6px 8px;background:#fff;color:#047857;border:1px solid #86efac;border-radius:6px;cursor:pointer;">🪧 设公告</button>
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
@@ -262,23 +262,23 @@ $welcomeMessages = [
|
|||||||
<div style="font-size:10px;color:#9a3412;padding:10px 2px 6px;">聊天室管理</div>
|
<div style="font-size:10px;color:#9a3412;padding:10px 2px 6px;">聊天室管理</div>
|
||||||
<div style="display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px;">
|
<div style="display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px;">
|
||||||
@if ($canPublicBroadcast)
|
@if ($canPublicBroadcast)
|
||||||
<button type="button" onclick="runAdminAction('announce-message')"
|
<button type="button" data-chat-admin-action="announce-message"
|
||||||
style="font-size:11px;padding:6px 8px;background:#fff;color:#7c3aed;border:1px solid #c4b5fd;border-radius:6px;cursor:pointer;">📢 公屏</button>
|
style="font-size:11px;padding:6px 8px;background:#fff;color:#7c3aed;border:1px solid #c4b5fd;border-radius:6px;cursor:pointer;">📢 公屏</button>
|
||||||
@endif
|
@endif
|
||||||
@if ($canClearScreen)
|
@if ($canClearScreen)
|
||||||
<button type="button" onclick="runAdminAction('admin-clear')"
|
<button type="button" data-chat-admin-action="admin-clear"
|
||||||
style="font-size:11px;padding:6px 8px;background:#fff;color:#dc2626;border:1px solid #fca5a5;border-radius:6px;cursor:pointer;">🧹 清屏</button>
|
style="font-size:11px;padding:6px 8px;background:#fff;color:#dc2626;border:1px solid #fca5a5;border-radius:6px;cursor:pointer;">🧹 清屏</button>
|
||||||
@endif
|
@endif
|
||||||
@if ($canSendRedPacket)
|
@if ($canSendRedPacket)
|
||||||
<button type="button" onclick="runAdminAction('red-packet')"
|
<button type="button" data-chat-admin-action="red-packet"
|
||||||
style="font-size:11px;padding:6px 8px;background:#fff;color:#b91c1c;border:1px solid #fdba74;border-radius:6px;cursor:pointer;">🧧 礼包</button>
|
style="font-size:11px;padding:6px 8px;background:#fff;color:#b91c1c;border:1px solid #fdba74;border-radius:6px;cursor:pointer;">🧧 礼包</button>
|
||||||
@endif
|
@endif
|
||||||
@if ($canManageLossCover)
|
@if ($canManageLossCover)
|
||||||
<button type="button" onclick="runAdminAction('loss-cover')"
|
<button type="button" data-chat-admin-action="loss-cover"
|
||||||
style="font-size:11px;padding:6px 8px;background:#fff;color:#15803d;border:1px solid #86efac;border-radius:6px;cursor:pointer;">🎁 买单活动</button>
|
style="font-size:11px;padding:6px 8px;background:#fff;color:#15803d;border:1px solid #86efac;border-radius:6px;cursor:pointer;">🎁 买单活动</button>
|
||||||
@endif
|
@endif
|
||||||
@if (Auth::id() === 1)
|
@if (Auth::id() === 1)
|
||||||
<button type="button" onclick="runAdminAction('refresh-all')"
|
<button type="button" data-chat-admin-action="refresh-all"
|
||||||
style="font-size:11px;padding:6px 8px;background:#fff;color:#0f766e;border:1px solid #99f6e4;border-radius:6px;cursor:pointer;">♻️ 刷新全员</button>
|
style="font-size:11px;padding:6px 8px;background:#fff;color:#0f766e;border:1px solid #99f6e4;border-radius:6px;cursor:pointer;">♻️ 刷新全员</button>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
@@ -287,25 +287,25 @@ $welcomeMessages = [
|
|||||||
@if ($canTriggerFullscreenEffect)
|
@if ($canTriggerFullscreenEffect)
|
||||||
<div style="font-size:10px;color:#9a3412;padding:10px 2px 6px;">全屏特效</div>
|
<div style="font-size:10px;color:#9a3412;padding:10px 2px 6px;">全屏特效</div>
|
||||||
<div style="display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px;">
|
<div style="display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px;">
|
||||||
<button type="button" onclick="selectEffect('fireworks')"
|
<button type="button" data-chat-admin-effect="fireworks"
|
||||||
style="font-size:11px;padding:6px 8px;background:#fff;color:#ea580c;border:1px solid #fdba74;border-radius:6px;cursor:pointer;">🎆 烟花</button>
|
style="font-size:11px;padding:6px 8px;background:#fff;color:#ea580c;border:1px solid #fdba74;border-radius:6px;cursor:pointer;">🎆 烟花</button>
|
||||||
<button type="button" onclick="selectEffect('rain')"
|
<button type="button" data-chat-admin-effect="rain"
|
||||||
style="font-size:11px;padding:6px 8px;background:#fff;color:#2563eb;border:1px solid #93c5fd;border-radius:6px;cursor:pointer;">🌧️ 下雨</button>
|
style="font-size:11px;padding:6px 8px;background:#fff;color:#2563eb;border:1px solid #93c5fd;border-radius:6px;cursor:pointer;">🌧️ 下雨</button>
|
||||||
<button type="button" onclick="selectEffect('lightning')"
|
<button type="button" data-chat-admin-effect="lightning"
|
||||||
style="font-size:11px;padding:6px 8px;background:#fff;color:#7c3aed;border:1px solid #c4b5fd;border-radius:6px;cursor:pointer;">⚡ 雷电</button>
|
style="font-size:11px;padding:6px 8px;background:#fff;color:#7c3aed;border:1px solid #c4b5fd;border-radius:6px;cursor:pointer;">⚡ 雷电</button>
|
||||||
<button type="button" onclick="selectEffect('snow')"
|
<button type="button" data-chat-admin-effect="snow"
|
||||||
style="font-size:11px;padding:6px 8px;background:#fff;color:#0891b2;border:1px solid #bae6fd;border-radius:6px;cursor:pointer;">❄️ 下雪</button>
|
style="font-size:11px;padding:6px 8px;background:#fff;color:#0891b2;border:1px solid #bae6fd;border-radius:6px;cursor:pointer;">❄️ 下雪</button>
|
||||||
<button type="button" onclick="selectEffect('sakura')"
|
<button type="button" data-chat-admin-effect="sakura"
|
||||||
style="font-size:11px;padding:6px 8px;background:#fff;color:#db2777;border:1px solid #f9a8d4;border-radius:6px;cursor:pointer;">🌸 樱花飘落</button>
|
style="font-size:11px;padding:6px 8px;background:#fff;color:#db2777;border:1px solid #f9a8d4;border-radius:6px;cursor:pointer;">🌸 樱花飘落</button>
|
||||||
<button type="button" onclick="selectEffect('meteors')"
|
<button type="button" data-chat-admin-effect="meteors"
|
||||||
style="font-size:11px;padding:6px 8px;background:#fff;color:#2563eb;border:1px solid #bfdbfe;border-radius:6px;cursor:pointer;">🌠 流星</button>
|
style="font-size:11px;padding:6px 8px;background:#fff;color:#2563eb;border:1px solid #bfdbfe;border-radius:6px;cursor:pointer;">🌠 流星</button>
|
||||||
<button type="button" onclick="selectEffect('gold-rain')"
|
<button type="button" data-chat-admin-effect="gold-rain"
|
||||||
style="font-size:11px;padding:6px 8px;background:#fff;color:#ca8a04;border:1px solid #fde68a;border-radius:6px;cursor:pointer;">🪙 金币雨</button>
|
style="font-size:11px;padding:6px 8px;background:#fff;color:#ca8a04;border:1px solid #fde68a;border-radius:6px;cursor:pointer;">🪙 金币雨</button>
|
||||||
<button type="button" onclick="selectEffect('hearts')"
|
<button type="button" data-chat-admin-effect="hearts"
|
||||||
style="font-size:11px;padding:6px 8px;background:#fff;color:#e11d48;border:1px solid #fda4af;border-radius:6px;cursor:pointer;">💖 爱心飘落</button>
|
style="font-size:11px;padding:6px 8px;background:#fff;color:#e11d48;border:1px solid #fda4af;border-radius:6px;cursor:pointer;">💖 爱心飘落</button>
|
||||||
<button type="button" onclick="selectEffect('confetti')"
|
<button type="button" data-chat-admin-effect="confetti"
|
||||||
style="font-size:11px;padding:6px 8px;background:#fff;color:#7c3aed;border:1px solid #ddd6fe;border-radius:6px;cursor:pointer;">🎊 彩带庆典</button>
|
style="font-size:11px;padding:6px 8px;background:#fff;color:#7c3aed;border:1px solid #ddd6fe;border-radius:6px;cursor:pointer;">🎊 彩带庆典</button>
|
||||||
<button type="button" onclick="selectEffect('fireflies')"
|
<button type="button" data-chat-admin-effect="fireflies"
|
||||||
style="font-size:11px;padding:6px 8px;background:#fff;color:#15803d;border:1px solid #bbf7d0;border-radius:6px;cursor:pointer;">✨ 萤火虫</button>
|
style="font-size:11px;padding:6px 8px;background:#fff;color:#15803d;border:1px solid #bbf7d0;border-radius:6px;cursor:pointer;">✨ 萤火虫</button>
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|||||||
@@ -412,7 +412,7 @@ class ChatControllerTest extends TestCase
|
|||||||
|
|
||||||
$response->assertOk();
|
$response->assertOk();
|
||||||
$response->assertSee('🛠 管理', false);
|
$response->assertSee('🛠 管理', false);
|
||||||
$response->assertSee("runAdminAction('refresh-all')", false);
|
$response->assertSee('data-chat-admin-action="refresh-all"', false);
|
||||||
$response->assertSee('♻️ 刷新全员', false);
|
$response->assertSee('♻️ 刷新全员', false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user