Add VIP presence themes and custom greetings
This commit is contained in:
@@ -68,6 +68,89 @@
|
||||
let autoScroll = true;
|
||||
let _maxMsgId = 0; // 记录当前收到的最大消息 ID
|
||||
|
||||
/**
|
||||
* 转义会员横幅文本,避免横幅层被注入 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, ${fallback}, #fde68a, #fff7ed)`,
|
||||
glow: `${fallback}66`,
|
||||
accent: '#fff7ed',
|
||||
},
|
||||
storm: {
|
||||
gradient: `linear-gradient(135deg, #1e3a8a, ${fallback}, #dbeafe)`,
|
||||
glow: '#60a5fa88',
|
||||
accent: '#dbeafe',
|
||||
},
|
||||
royal: {
|
||||
gradient: `linear-gradient(135deg, #111827, ${fallback}, #fbbf24)`,
|
||||
glow: '#fbbf2488',
|
||||
accent: '#fef3c7',
|
||||
},
|
||||
cosmic: {
|
||||
gradient: `linear-gradient(135deg, #312e81, ${fallback}, #ec4899)`,
|
||||
glow: '#c084fc99',
|
||||
accent: '#f5d0fe',
|
||||
},
|
||||
farewell: {
|
||||
gradient: `linear-gradient(135deg, #334155, ${fallback}, #94a3b8)`,
|
||||
glow: '#cbd5e188',
|
||||
accent: '#f8fafc',
|
||||
},
|
||||
};
|
||||
|
||||
return map[style] || map.aurora;
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示会员进退场豪华横幅。
|
||||
*/
|
||||
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 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">${payload.presence_type === 'leave' ? '离场提示' : '闪耀登场'}</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.showVipPresenceBanner = showVipPresenceBanner;
|
||||
|
||||
// ── Tab 切换 ──────────────────────────────────────
|
||||
let _roomsRefreshTimer = null;
|
||||
|
||||
@@ -539,6 +622,31 @@
|
||||
|
||||
html = `${iconImg} ${parsedContent}`;
|
||||
}
|
||||
// 会员专属进退场播报:更醒目的卡片化样式,同时由外层额外触发豪华横幅。
|
||||
else if (msg.action === 'vip_presence') {
|
||||
div.style.cssText =
|
||||
'background:linear-gradient(135deg, rgba(15,23,42,.96), rgba(30,41,59,.9)); border:1px solid rgba(255,255,255,.14); border-radius:12px; padding:10px 12px; margin:6px 0; box-shadow:0 10px 26px rgba(15,23,42,.22);';
|
||||
const icon = escapeHtml(msg.presence_icon || '👑');
|
||||
const levelName = escapeHtml(msg.presence_level_name || '尊贵会员');
|
||||
const typeLabel = msg.presence_type === 'leave' ? '华丽离场' : '荣耀入场';
|
||||
const accent = msg.presence_color || '#f59e0b';
|
||||
const safeText = escapePresenceText(msg.presence_text || '');
|
||||
|
||||
html = `
|
||||
<div style="display:flex;align-items:center;gap:10px;">
|
||||
<div style="width:42px;height:42px;border-radius:14px;background:radial-gradient(circle at top, ${accent}, #111827);display:flex;align-items:center;justify-content:center;font-size:22px;box-shadow:0 0 22px ${accent}55;">${icon}</div>
|
||||
<div style="min-width:0;flex:1;">
|
||||
<div style="display:flex;align-items:center;gap:8px;flex-wrap:wrap;">
|
||||
<span style="font-size:12px;font-weight:800;letter-spacing:.08em;color:${accent};text-transform:uppercase;">${typeLabel}</span>
|
||||
<span style="font-size:12px;color:#e2e8f0;">${levelName}</span>
|
||||
<span style="font-size:11px;color:#94a3b8;">(${timeStr})</span>
|
||||
</div>
|
||||
<div style="margin-top:4px;font-size:14px;line-height:1.6;color:#f8fafc;">${safeText}</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
timeStrOverride = true;
|
||||
}
|
||||
// 贾妖语 —— 蓝色左边框渐变样式,比 系统公告 低调
|
||||
else if (msg.action === '欢迎') {
|
||||
div.style.cssText =
|
||||
@@ -759,6 +867,11 @@
|
||||
return;
|
||||
}
|
||||
appendMessage(msg);
|
||||
|
||||
if (msg.action === 'vip_presence') {
|
||||
showVipPresenceBanner(msg);
|
||||
}
|
||||
|
||||
// 若消息携带 toast_notification 字段且当前用户是接收者,弹右下角小卡片
|
||||
if (msg.toast_notification && msg.to_user === window.chatContext.username) {
|
||||
const t = msg.toast_notification;
|
||||
|
||||
Reference in New Issue
Block a user