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

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; 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]"); const trigger = event.target.closest("[data-chat-block-menu-toggle]");
if (trigger) { if (trigger) {
event.preventDefault(); event.preventDefault();
@@ -160,18 +160,17 @@ $welcomeMessages = [
</div> </div>
<div style="position:relative;display:inline-block;" id="feature-btn-wrap"> <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;"> 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> </button>
<div id="feature-menu" <div id="feature-menu" data-chat-feature-menu
onclick="event.stopPropagation()"
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);"> 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="font-size:10px;color:#4338ca;padding:0 2px 8px;">常用操作</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="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> 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;"> 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-icon">{{ $activeDailyStatus['icon'] ?? '🙂' }}</span>
<span id="daily-status-shortcut-label">{{ $activeDailyStatus['label'] ?? '状态' }}</span> <span id="daily-status-shortcut-label">{{ $activeDailyStatus['label'] ?? '状态' }}</span>
@@ -179,44 +178,42 @@ $welcomeMessages = [
</div> </div>
<div style="font-size:10px;color:#4338ca;padding:10px 2px 8px;">快捷入口</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;"> <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> 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> 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> 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> 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> 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> 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> 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> 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> 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>
</div> </div>
<div id="daily-status-editor-overlay" <div id="daily-status-editor-overlay" data-chat-daily-status-overlay
onclick="closeDailyStatusEditor()"
style="display:none;position:fixed;inset:0;z-index:10030;background:rgba(15,23,42,.45);backdrop-filter:blur(2px);"> 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" <div id="daily-status-editor" data-chat-daily-status-editor
onclick="event.stopPropagation()"
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);"> 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="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="min-width:0;">
<div style="font-size:20px;font-weight:bold;color:#312e81;line-height:1.15;">设个状态</div> <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 style="font-size:11px;color:#6366f1;margin-top:2px;">朋友当天内可见,次日自动失效</div>
</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;"> style="flex:none;font-size:11px;padding:5px 10px;background:#fff7ed;color:#c2410c;border:1px solid #fdba74;border-radius:999px;cursor:pointer;">
♻️ 清除状态 ♻️ 清除状态
</button> </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> style="width:28px;height:28px;border:none;border-radius:999px;background:#e0e7ff;color:#4338ca;font-size:18px;cursor:pointer;line-height:1;">×</button>
</div> </div>
@@ -233,7 +230,7 @@ $welcomeMessages = [
data-status-label="{{ $item['label'] }}" data-status-label="{{ $item['label'] }}"
data-status-icon="{{ $item['icon'] }}" data-status-icon="{{ $item['icon'] }}"
data-status-active="{{ $currentDailyStatusKey === $item['key'] ? '1' : '0' }}" 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;"> 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: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> <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 = $this->actingAs($user)->get(route('chat.room', $room->id));
$response->assertOk(); $response->assertOk();
$response->assertSee('toggleFeatureMenu(event)', false); $response->assertSee('data-chat-feature-menu-toggle', false);
$response->assertSee('功能'); $response->assertSee('功能');
$response->assertSee('设个状态', false); $response->assertSee('设个状态', false);
$response->assertSee('runFeatureShortcut(\'shop\')', false); $response->assertSee('data-chat-daily-status-open', false);
$response->assertSee('runFeatureShortcut(\'vip\')', false); $response->assertSee('data-chat-feature-shortcut="shop"', false);
$response->assertSee('runFeatureShortcut(\'game\')', false); $response->assertSee('data-chat-feature-shortcut="vip"', false);
$response->assertSee('runFeatureShortcut(\'avatar\')', false); $response->assertSee('data-chat-feature-shortcut="game"', false);
$response->assertSee('runFeatureShortcut(\'bank\')', false); $response->assertSee('data-chat-feature-shortcut="avatar"', false);
$response->assertSee('runFeatureShortcut(\'marriage\')', false); $response->assertSee('data-chat-feature-shortcut="bank"', false);
$response->assertSee('runFeatureShortcut(\'friend\')', false); $response->assertSee('data-chat-feature-shortcut="marriage"', false);
$response->assertSee('runFeatureShortcut(\'settings\')', false); $response->assertSee('data-chat-feature-shortcut="friend"', false);
$response->assertSee('data-chat-feature-shortcut="settings"', false);
$response->assertSee('本地清屏', false); $response->assertSee('本地清屏', false);
$response->assertDontSee('onclick="toggleFeatureMenu(event)"', false);
$response->assertDontSee('onclick="localClearScreen()"', false); $response->assertDontSee('onclick="localClearScreen()"', false);
} }