Files
chatroom/resources/js/chat-room/vip-presence.js
T
pllx f17f171f4b fix: 修复迁移遗留的按钮无响应、头像框层级及构建错误
迁移收尾修复:
- heartbeat.js: 移除 export { } 中重复的 startHeartbeat/stopHeartbeat(已通过 export function 导出)
- scripts.blade.php: 移除 JS 注释中的 {{ }} 避免 Blade 编译为 e() 导致 PHP 解析错误
- preferences-status.js: 补全 6 个缺失的 window.* 赋值(toggleBlockMenu/toggleFeatureMenu 等),
  实现迁移中丢失的 updateDailyStatus/clearDailyStatus,修复 handleFeatureLocalClear 清屏回调
- toolbar.js: 补全 window.runFeatureShortcut 赋值

头像框样式修复(chat-decorations.css):
- z-index 互换:头像降至 1,框升至 3,使框边缘可遮挡头像外围
- 使用 CSS mask(radial-gradient)挖环形替代旧 ::before 实心圆遮挡方案
- clip-path: circle(50%) 硬裁剪确保圆形,不受 chat.css border-radius: 2px 覆盖
- 特异性提升至 .user-item .avatar-frame-wrapper .user-head

新 Vite 模块(从 Blade 迁移):
- chat-state.js / message-renderer.js / user-list.js / chat-events.js
- composer.js(重写)/ heartbeat.js / admin-commands.js
- vip-presence.js / chat-decorations.css
2026-04-27 09:19:49 +00:00

105 lines
3.5 KiB
JavaScript

// 会员进退场豪华横幅模块,从 Blade 内联脚本迁移至 Vite 管理。
import { escapeHtml } from "./html.js";
/**
* 转义会员横幅文本,避免横幅层被注入 HTML。
*/
function escapePresenceText(text) {
return escapeHtml(String(text ?? "")).replace(/\n/g, "<br>");
}
/**
* 根据不同的会员横幅风格返回渐变与光影配置。
*/
function getVipPresenceStyleConfig(style, color) {
const fallback = color || "#f59e0b";
const map = {
aurora: {
gradient: `linear-gradient(135deg, #f59e0b, #fbbf24, #fef3c7)`,
glow: `rgba(251, 191, 36, 0.4)`,
accent: "#78350f",
},
storm: {
gradient: `linear-gradient(135deg, #0ea5e9, #7dd3fc, #f0f9ff)`,
glow: `rgba(125, 211, 252, 0.4)`,
accent: "#0369a1",
},
royal: {
gradient: `linear-gradient(135deg, #d97706, #fcd34d, #fffbeb)`,
glow: `rgba(252, 211, 77, 0.4)`,
accent: "#92400e",
},
cosmic: {
gradient: `linear-gradient(135deg, #db2777, #f472b6, #fdf2f8)`,
glow: `rgba(244, 114, 182, 0.4)`,
accent: "#9d174d",
},
farewell: {
gradient: `linear-gradient(135deg, #ea580c, #fb923c, #fff7ed)`,
glow: `rgba(251, 146, 60, 0.4)`,
accent: "#9a3412",
},
};
return map[style] || map.aurora;
}
/**
* 显示会员进退场豪华横幅。
*
* @param {Record<string, any>} payload 携带 presence_text / presence_type / presence_icon 等字段的消息载荷
* @returns {void}
*/
function showVipPresenceBanner(payload) {
if (!payload || !payload.presence_text) {
return;
}
const existing = document.getElementById("vip-presence-banner");
if (existing) {
existing.remove();
}
const styleConfig = getVipPresenceStyleConfig(
payload.presence_banner_style,
payload.presence_color,
);
const bannerTypeLabel =
payload.presence_type === "leave"
? "离场提示"
: payload.presence_type === "purchase"
? "开通喜报"
: "闪耀登场";
const banner = document.createElement("div");
banner.id = "vip-presence-banner";
banner.className = "vip-presence-banner";
banner.innerHTML = `
<div class="vip-presence-banner__glow" style="background:${styleConfig.glow};"></div>
<div class="vip-presence-banner__card" style="background:${styleConfig.gradient}; border-color:${payload.presence_color || "#fff"};">
<div class="vip-presence-banner__meta">
<span class="vip-presence-banner__icon">${escapeHtml(payload.presence_icon || "👑")}</span>
<span class="vip-presence-banner__level">${escapeHtml(payload.presence_level_name || "尊贵会员")}</span>
<span class="vip-presence-banner__type">${bannerTypeLabel}</span>
</div>
<div class="vip-presence-banner__text" style="color:${styleConfig.accent};">
${escapePresenceText(payload.presence_text)}
</div>
</div>
`;
document.body.appendChild(banner);
setTimeout(() => {
banner.classList.add("is-leaving");
setTimeout(() => banner.remove(), 700);
}, 4200);
}
// 挂载到 window 供 Blade 脚本及其他模块使用。
window.showVipPresenceBanner = showVipPresenceBanner;
export { showVipPresenceBanner, getVipPresenceStyleConfig, escapePresenceText };