迁移功能菜单和每日状态事件绑定

This commit is contained in:
2026-04-25 03:53:29 +08:00
parent 3e525eaa36
commit ef471ec68b
3 changed files with 120 additions and 30 deletions
@@ -198,6 +198,97 @@ export function bindBlockMenuControls() {
return;
}
const featureMenuTrigger = event.target.closest("[data-chat-feature-menu-toggle]");
if (featureMenuTrigger) {
event.preventDefault();
window.toggleFeatureMenu?.(event);
return;
}
const dailyStatusCloseButton = event.target.closest("[data-chat-daily-status-close]");
if (dailyStatusCloseButton) {
event.preventDefault();
window.closeDailyStatusEditor?.();
return;
}
const dailyStatusClearButton = event.target.closest("[data-chat-daily-status-clear]");
if (dailyStatusClearButton) {
event.preventDefault();
window.clearDailyStatus?.();
return;
}
const dailyStatusItem = event.target.closest("[data-chat-daily-status-select]");
if (dailyStatusItem) {
event.preventDefault();
const statusKey = dailyStatusItem.getAttribute("data-chat-daily-status-select") || "";
if (statusKey && typeof window.updateDailyStatus === "function") {
window.updateDailyStatus(statusKey);
}
return;
}
if (event.target.closest("[data-chat-daily-status-editor]")) {
event.stopPropagation();
return;
}
if (event.target.closest("[data-chat-daily-status-overlay]")) {
window.closeDailyStatusEditor?.();
return;
}
const localClearButton = event.target.closest("[data-chat-feature-local-clear]");
if (localClearButton) {
event.preventDefault();
window.handleFeatureLocalClear?.();
return;
}
const dailyStatusOpenButton = event.target.closest("[data-chat-daily-status-open]");
if (dailyStatusOpenButton) {
event.preventDefault();
window.openDailyStatusEditor?.();
return;
}
const dailySignInButton = event.target.closest("[data-chat-feature-sign-in]");
if (dailySignInButton) {
event.preventDefault();
window.closeFeatureMenu?.();
window.quickDailySignIn?.();
return;
}
const shortcutButton = event.target.closest("[data-chat-feature-shortcut]");
if (shortcutButton) {
event.preventDefault();
const action = shortcutButton.getAttribute("data-chat-feature-shortcut") || "";
if (action && typeof window.runFeatureShortcut === "function") {
window.runFeatureShortcut(action);
}
return;
}
if (event.target.closest("[data-chat-feature-menu]")) {
event.stopPropagation();
return;
}
const trigger = event.target.closest("[data-chat-block-menu-toggle]");
if (trigger) {
event.preventDefault();
@@ -160,18 +160,17 @@ $welcomeMessages = [
</div>
<div style="position:relative;display:inline-block;" id="feature-btn-wrap">
<button type="button" onclick="toggleFeatureMenu(event)"
<button type="button" data-chat-feature-menu-toggle
style="font-size:11px;padding:1px 6px;background:linear-gradient(135deg,#4f46e5,#6366f1);color:#fff;border:none;border-radius:2px;cursor:pointer;font-weight:bold;">
⚙️ 功能
</button>
<div id="feature-menu"
onclick="event.stopPropagation()"
<div id="feature-menu" data-chat-feature-menu
style="display:none;position:absolute;bottom:calc(100% + 6px);left:0;z-index:10020;min-width:236px;padding:10px;background:#eef2ff;border:1px solid #c7d2fe;border-radius:10px;box-shadow:0 10px 24px rgba(15,23,42,.18);">
<div style="font-size:10px;color:#4338ca;padding:0 2px 8px;">常用操作</div>
<div style="display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px;">
<button type="button" onclick="handleFeatureLocalClear()"
<button type="button" data-chat-feature-local-clear
style="font-size:11px;padding:6px 8px;background:#fff;color:#475569;border:1px solid #cbd5e1;border-radius:6px;cursor:pointer;">🧹 清屏</button>
<button type="button" onclick="openDailyStatusEditor()"
<button type="button" data-chat-daily-status-open
style="font-size:11px;padding:6px 8px;background:#fff;color:#4f46e5;border:1px solid #a5b4fc;border-radius:6px;cursor:pointer;">
<span id="daily-status-shortcut-icon">{{ $activeDailyStatus['icon'] ?? '🙂' }}</span>
<span id="daily-status-shortcut-label">{{ $activeDailyStatus['label'] ?? '状态' }}</span>
@@ -179,44 +178,42 @@ $welcomeMessages = [
</div>
<div style="font-size:10px;color:#4338ca;padding:10px 2px 8px;">快捷入口</div>
<div style="display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:6px;">
<button type="button" onclick="closeFeatureMenu();quickDailySignIn()"
<button type="button" data-chat-feature-sign-in
style="font-size:11px;padding:6px 8px;background:#fff;color:#334155;border:1px solid #cbd5e1;border-radius:6px;cursor:pointer;"> 签到</button>
<button type="button" onclick="runFeatureShortcut('shop')"
<button type="button" data-chat-feature-shortcut="shop"
style="font-size:11px;padding:6px 8px;background:#fff;color:#334155;border:1px solid #cbd5e1;border-radius:6px;cursor:pointer;">🛍 商店</button>
<button type="button" onclick="runFeatureShortcut('vip')"
<button type="button" data-chat-feature-shortcut="vip"
style="font-size:11px;padding:6px 8px;background:#fff;color:#334155;border:1px solid #cbd5e1;border-radius:6px;cursor:pointer;">👑 会员</button>
<button type="button" onclick="runFeatureShortcut('game')"
<button type="button" data-chat-feature-shortcut="game"
style="font-size:11px;padding:6px 8px;background:#fff;color:#334155;border:1px solid #cbd5e1;border-radius:6px;cursor:pointer;">🎮 娱乐</button>
<button type="button" onclick="runFeatureShortcut('avatar')"
<button type="button" data-chat-feature-shortcut="avatar"
style="font-size:11px;padding:6px 8px;background:#fff;color:#334155;border:1px solid #cbd5e1;border-radius:6px;cursor:pointer;">🖼 头像</button>
<button type="button" onclick="runFeatureShortcut('bank')"
<button type="button" data-chat-feature-shortcut="bank"
style="font-size:11px;padding:6px 8px;background:#fff;color:#334155;border:1px solid #cbd5e1;border-radius:6px;cursor:pointer;">🏦 银行</button>
<button type="button" onclick="runFeatureShortcut('marriage')"
<button type="button" data-chat-feature-shortcut="marriage"
style="font-size:11px;padding:6px 8px;background:#fff;color:#334155;border:1px solid #cbd5e1;border-radius:6px;cursor:pointer;">💍 婚姻</button>
<button type="button" onclick="runFeatureShortcut('friend')"
<button type="button" data-chat-feature-shortcut="friend"
style="font-size:11px;padding:6px 8px;background:#fff;color:#334155;border:1px solid #cbd5e1;border-radius:6px;cursor:pointer;">👥 好友</button>
<button type="button" onclick="runFeatureShortcut('settings')"
<button type="button" data-chat-feature-shortcut="settings"
style="font-size:11px;padding:6px 8px;background:#fff;color:#334155;border:1px solid #cbd5e1;border-radius:6px;cursor:pointer;">⚙️ 设置</button>
</div>
</div>
</div>
<div id="daily-status-editor-overlay"
onclick="closeDailyStatusEditor()"
<div id="daily-status-editor-overlay" data-chat-daily-status-overlay
style="display:none;position:fixed;inset:0;z-index:10030;background:rgba(15,23,42,.45);backdrop-filter:blur(2px);">
<div id="daily-status-editor"
onclick="event.stopPropagation()"
<div id="daily-status-editor" data-chat-daily-status-editor
style="position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:min(94vw,720px);max-height:min(88vh,720px);overflow-y:auto;padding:10px 12px;background:linear-gradient(180deg,#eef2ff 0%,#f8fafc 100%);border:1px solid #c7d2fe;border-radius:14px;box-shadow:0 18px 40px rgba(15,23,42,.28);">
<div style="display:flex;align-items:center;justify-content:space-between;gap:10px;padding:2px 2px 8px;border-bottom:1px solid #dbeafe;">
<div style="min-width:0;">
<div style="font-size:20px;font-weight:bold;color:#312e81;line-height:1.15;">设个状态</div>
<div style="font-size:11px;color:#6366f1;margin-top:2px;">朋友当天内可见,次日自动失效</div>
</div>
<button type="button" onclick="clearDailyStatus()"
<button type="button" data-chat-daily-status-clear
style="flex:none;font-size:11px;padding:5px 10px;background:#fff7ed;color:#c2410c;border:1px solid #fdba74;border-radius:999px;cursor:pointer;">
♻️ 清除状态
</button>
<button type="button" onclick="closeDailyStatusEditor()"
<button type="button" data-chat-daily-status-close
style="width:28px;height:28px;border:none;border-radius:999px;background:#e0e7ff;color:#4338ca;font-size:18px;cursor:pointer;line-height:1;">×</button>
</div>
@@ -233,7 +230,7 @@ $welcomeMessages = [
data-status-label="{{ $item['label'] }}"
data-status-icon="{{ $item['icon'] }}"
data-status-active="{{ $currentDailyStatusKey === $item['key'] ? '1' : '0' }}"
onclick="updateDailyStatus('{{ $item['key'] }}')"
data-chat-daily-status-select="{{ $item['key'] }}"
style="display:flex;align-items:center;justify-content:center;gap:6px;min-height:52px;padding:7px 8px;background:#ffffffcc;border:1px solid #e5e7eb;border-radius:10px;cursor:pointer;transition:all .15s ease;color:#334155;">
<span style="font-size:20px;line-height:1;flex:none;">{{ $item['icon'] }}</span>
<span style="font-size:12px;line-height:1.2;text-align:left;white-space:normal;word-break:keep-all;">{{ $item['label'] }}</span>
+11 -9
View File
@@ -290,18 +290,20 @@ class ChatControllerTest extends TestCase
$response = $this->actingAs($user)->get(route('chat.room', $room->id));
$response->assertOk();
$response->assertSee('toggleFeatureMenu(event)', false);
$response->assertSee('data-chat-feature-menu-toggle', false);
$response->assertSee('功能');
$response->assertSee('设个状态', false);
$response->assertSee('runFeatureShortcut(\'shop\')', false);
$response->assertSee('runFeatureShortcut(\'vip\')', false);
$response->assertSee('runFeatureShortcut(\'game\')', false);
$response->assertSee('runFeatureShortcut(\'avatar\')', false);
$response->assertSee('runFeatureShortcut(\'bank\')', false);
$response->assertSee('runFeatureShortcut(\'marriage\')', false);
$response->assertSee('runFeatureShortcut(\'friend\')', false);
$response->assertSee('runFeatureShortcut(\'settings\')', false);
$response->assertSee('data-chat-daily-status-open', false);
$response->assertSee('data-chat-feature-shortcut="shop"', false);
$response->assertSee('data-chat-feature-shortcut="vip"', false);
$response->assertSee('data-chat-feature-shortcut="game"', false);
$response->assertSee('data-chat-feature-shortcut="avatar"', false);
$response->assertSee('data-chat-feature-shortcut="bank"', false);
$response->assertSee('data-chat-feature-shortcut="marriage"', false);
$response->assertSee('data-chat-feature-shortcut="friend"', false);
$response->assertSee('data-chat-feature-shortcut="settings"', false);
$response->assertSee('本地清屏', false);
$response->assertDontSee('onclick="toggleFeatureMenu(event)"', false);
$response->assertDontSee('onclick="localClearScreen()"', false);
}