优化商店个性装扮体验
This commit is contained in:
@@ -24,6 +24,238 @@
|
||||
@version 2.0.0
|
||||
--}}
|
||||
|
||||
{{-- 个人装扮样式(消息气泡 / 昵称颜色 / 头像框) --}}
|
||||
<style>
|
||||
/* ========== 消息气泡装扮:在原版逐行消息基础上增加纹理、角标和轻量动效 ========== */
|
||||
.msg-line[class*="msg-bubble--"] {
|
||||
position: relative;
|
||||
isolation: isolate;
|
||||
min-height: 24px;
|
||||
margin: 4px 0;
|
||||
padding: 5px 12px 5px 14px;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
border: 1px solid rgba(51, 102, 153, .16);
|
||||
background: rgba(255, 255, 255, .72);
|
||||
box-shadow: 0 1px 4px rgba(51, 102, 153, .12);
|
||||
}
|
||||
|
||||
.msg-line[class*="msg-bubble--"]::before,
|
||||
.msg-line[class*="msg-bubble--"]::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.msg-line[class*="msg-bubble--"] > * {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.msg-bubble--golden {
|
||||
border-color: rgba(217, 119, 6, .32) !important;
|
||||
background:
|
||||
linear-gradient(90deg, rgba(245, 158, 11, .32) 0 4px, transparent 4px),
|
||||
radial-gradient(circle at 28px 8px, rgba(255, 255, 255, .85), transparent 10px),
|
||||
linear-gradient(135deg, #fff8df 0%, #fffdf5 56%, #fff1c2 100%) !important;
|
||||
box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .78), 0 2px 8px rgba(217, 119, 6, .18);
|
||||
}
|
||||
|
||||
.msg-bubble--golden::after {
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: -36px;
|
||||
width: 36px;
|
||||
background: linear-gradient(100deg, transparent, rgba(255, 255, 255, .72), transparent);
|
||||
animation: msg-bubble-shine 3.6s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.msg-bubble--sakura {
|
||||
border-color: rgba(244, 114, 182, .32) !important;
|
||||
background:
|
||||
radial-gradient(circle at 18px 10px, rgba(244, 114, 182, .42) 0 2px, transparent 3px),
|
||||
radial-gradient(circle at 44px 20px, rgba(251, 207, 232, .86) 0 3px, transparent 4px),
|
||||
linear-gradient(135deg, #fff7fb 0%, #fff 48%, #ffe4f1 100%) !important;
|
||||
box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .78), 0 2px 8px rgba(244, 114, 182, .14);
|
||||
}
|
||||
|
||||
.msg-bubble--star {
|
||||
border-color: rgba(79, 70, 229, .32) !important;
|
||||
background:
|
||||
radial-gradient(circle at 20px 9px, rgba(255, 255, 255, .9) 0 1px, transparent 2px),
|
||||
radial-gradient(circle at 76px 20px, rgba(99, 102, 241, .36) 0 2px, transparent 3px),
|
||||
linear-gradient(135deg, #eef2ff 0%, #f8fbff 54%, #dbeafe 100%) !important;
|
||||
box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .8), 0 2px 10px rgba(79, 70, 229, .16);
|
||||
}
|
||||
|
||||
.msg-bubble--star::before {
|
||||
right: 10px;
|
||||
top: 5px;
|
||||
width: 42px;
|
||||
height: 16px;
|
||||
background: radial-gradient(circle, rgba(67, 56, 202, .42) 0 1px, transparent 2px);
|
||||
background-size: 11px 8px;
|
||||
opacity: .72;
|
||||
}
|
||||
|
||||
.msg-bubble--rainbow {
|
||||
border-color: rgba(59, 130, 246, .22) !important;
|
||||
background:
|
||||
linear-gradient(#ffffffd9, #ffffffd9) padding-box,
|
||||
linear-gradient(120deg, rgba(239, 68, 68, .16), rgba(245, 158, 11, .16), rgba(34, 197, 94, .16), rgba(59, 130, 246, .16), rgba(168, 85, 247, .16)) border-box !important;
|
||||
box-shadow: 0 2px 10px rgba(59, 130, 246, .14);
|
||||
}
|
||||
|
||||
.msg-bubble--rainbow::before {
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
height: 3px;
|
||||
background: linear-gradient(90deg, #ef4444, #f59e0b, #22c55e, #3b82f6, #a855f7, #ef4444);
|
||||
background-size: 180% 100%;
|
||||
animation: msg-bubble-rainbow 4.2s linear infinite;
|
||||
}
|
||||
|
||||
.msg-bubble--crown {
|
||||
border-color: rgba(180, 83, 9, .34) !important;
|
||||
background:
|
||||
linear-gradient(90deg, rgba(180, 83, 9, .24) 0 4px, transparent 4px),
|
||||
radial-gradient(circle at right 12px top 8px, rgba(251, 191, 36, .36), transparent 18px),
|
||||
linear-gradient(135deg, #fff7d6 0%, #fffdfa 46%, #fde68a 100%) !important;
|
||||
box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .82), 0 3px 12px rgba(180, 83, 9, .22);
|
||||
}
|
||||
|
||||
.msg-bubble--crown::after {
|
||||
content: "♛";
|
||||
top: 2px;
|
||||
right: 8px;
|
||||
z-index: 0;
|
||||
color: rgba(180, 83, 9, .26);
|
||||
font-size: 18px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
@keyframes msg-bubble-shine {
|
||||
0%, 62% { transform: translateX(0); opacity: 0; }
|
||||
72% { opacity: .82; }
|
||||
100% { transform: translateX(280px); opacity: 0; }
|
||||
}
|
||||
|
||||
@keyframes msg-bubble-rainbow {
|
||||
from { background-position: 0% 50%; }
|
||||
to { background-position: 180% 50%; }
|
||||
}
|
||||
|
||||
/* ========== 昵称颜色 ========== */
|
||||
.msg-name--golden { color: #fbbf24 !important; font-weight: 700; }
|
||||
.msg-name--rainbow {
|
||||
background: linear-gradient(90deg, #ef4444, #f59e0b, #22c55e, #3b82f6, #a855f7);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
font-weight: 700;
|
||||
}
|
||||
.msg-name--glow {
|
||||
color: #e2e8f0 !important;
|
||||
text-shadow: 0 0 6px #818cf8, 0 0 14px #6366f1;
|
||||
}
|
||||
.msg-name--flame {
|
||||
color: #f97316 !important;
|
||||
font-weight: 700;
|
||||
animation: name-flame 1.5s ease-in-out infinite;
|
||||
}
|
||||
@keyframes name-flame {
|
||||
0%, 100% { text-shadow: 0 0 4px #ef4444; }
|
||||
50% { text-shadow: 0 0 10px #fbbf24, 0 0 16px #ef4444; }
|
||||
}
|
||||
|
||||
/* ========== 头像框 ========== */
|
||||
.avatar-frame-wrapper {
|
||||
position: relative;
|
||||
display: inline-grid;
|
||||
place-items: center;
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
flex: 0 0 44px;
|
||||
line-height: 0;
|
||||
}
|
||||
|
||||
.avatar-frame-wrapper .user-head {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.avatar-frame {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
border-radius: 50%;
|
||||
pointer-events: none;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.avatar-frame::before,
|
||||
.avatar-frame::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.avatar-frame--silver {
|
||||
background: conic-gradient(from 25deg, #ffffff, #94a3b8, #e2e8f0, #64748b, #ffffff);
|
||||
box-shadow: 0 0 0 1px rgba(148, 163, 184, .38), 0 2px 8px rgba(100, 116, 139, .24);
|
||||
}
|
||||
|
||||
.avatar-frame--silver::before,
|
||||
.avatar-frame--gold::before,
|
||||
.avatar-frame--star::before,
|
||||
.avatar-frame--dragon::before {
|
||||
inset: 4px;
|
||||
border-radius: 50%;
|
||||
background: #eaf3ff;
|
||||
}
|
||||
|
||||
.avatar-frame--gold {
|
||||
background: conic-gradient(from -20deg, #fff7ad, #f59e0b, #fff1a6, #b45309, #fff7ad);
|
||||
box-shadow: 0 0 0 1px rgba(217, 119, 6, .34), 0 0 12px rgba(245, 158, 11, .38);
|
||||
}
|
||||
|
||||
.avatar-frame--star {
|
||||
background:
|
||||
radial-gradient(circle at 50% 0%, #ffffff 0 2px, transparent 3px),
|
||||
conic-gradient(from 0deg, #fef08a, #818cf8, #ffffff, #fbbf24, #818cf8, #fef08a);
|
||||
box-shadow: 0 0 14px rgba(129, 140, 248, .48);
|
||||
animation: frame-rotate 4s linear infinite;
|
||||
}
|
||||
|
||||
.avatar-frame--star::after {
|
||||
inset: -2px;
|
||||
border-radius: 50%;
|
||||
background: radial-gradient(circle at 50% 0%, rgba(255, 255, 255, .9) 0 2px, transparent 3px);
|
||||
transform-origin: 50% 50%;
|
||||
}
|
||||
|
||||
.avatar-frame--dragon {
|
||||
background:
|
||||
conic-gradient(from 45deg, #7f1d1d, #f59e0b, #ef4444, #991b1b, #f59e0b, #7f1d1d);
|
||||
box-shadow: 0 0 14px rgba(239, 68, 68, .42), 0 0 0 1px rgba(127, 29, 29, .38);
|
||||
}
|
||||
|
||||
.avatar-frame--dragon::after {
|
||||
inset: 5px;
|
||||
border-radius: 50%;
|
||||
border: 1px dashed rgba(254, 202, 202, .82);
|
||||
}
|
||||
|
||||
@keyframes frame-rotate {
|
||||
from { transform: rotate(0deg); }
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
/**
|
||||
* 聊天室前端交互逻辑
|
||||
@@ -1821,9 +2053,25 @@
|
||||
|
||||
// 女生名字使用玫粉色
|
||||
const nameColor = (user.sex == 2) ? 'color:#e91e8c;' : '';
|
||||
// ── 昵称颜色装扮 ──
|
||||
var userNameExtraClass = '';
|
||||
if (user.name_color) {
|
||||
userNameExtraClass = ' msg-name--' + user.name_color.replace(/^msg_name_/, '');
|
||||
}
|
||||
// ── 头像框装扮 ──
|
||||
var avatarHtml = '';
|
||||
if (user.avatar_frame) {
|
||||
var frameClass = 'avatar-frame--' + user.avatar_frame.replace(/^avatar_frame_/, '');
|
||||
avatarHtml = '<span class="avatar-frame-wrapper">' +
|
||||
'<span class="avatar-frame ' + frameClass + '"></span>' +
|
||||
'<img class="user-head" src="' + headImgSrc + '" onerror="this.src=\'/images/headface/1.gif\'">' +
|
||||
'</span>';
|
||||
} else {
|
||||
avatarHtml = '<img class="user-head" src="' + headImgSrc + '" onerror="this.src=\'/images/headface/1.gif\'">';
|
||||
}
|
||||
item.innerHTML = `
|
||||
<img class="user-head" src="${headImgSrc}" onerror="this.src='/images/headface/1.gif'">
|
||||
<span class="user-name" style="${nameColor}">${username}</span>
|
||||
${avatarHtml}
|
||||
<span class="user-name${userNameExtraClass}" style="${nameColor}">${username}</span>
|
||||
<span class="user-badge-slot">${badges}</span>
|
||||
`;
|
||||
|
||||
@@ -1834,6 +2082,7 @@
|
||||
targetContainer.replaceChildren(fragment);
|
||||
refreshRenderedUserBadges(targetContainer);
|
||||
}
|
||||
window._renderUserListToContainer = _renderUserListToContainer;
|
||||
|
||||
function renderUserList() {
|
||||
if (userListRenderTimer) {
|
||||
@@ -2122,9 +2371,20 @@
|
||||
div.dataset.blockKey = blockRuleKey;
|
||||
}
|
||||
|
||||
// ── 消息气泡装扮 ──
|
||||
if (msg.msg_bubble) {
|
||||
var bubbleStyle = msg.msg_bubble.replace(/^msg_bubble_/, '');
|
||||
div.classList.add('msg-bubble--' + bubbleStyle);
|
||||
}
|
||||
|
||||
const timeStr = msg.sent_at || '';
|
||||
let timeStrOverride = false;
|
||||
|
||||
var nameClass = '';
|
||||
if (msg.msg_name_color) {
|
||||
nameClass = ' msg-name--' + msg.msg_name_color.replace(/^msg_name_/, '');
|
||||
}
|
||||
|
||||
// 系统用户名列表(不可被选为聊天对象)
|
||||
const systemUsers = ['钓鱼播报', '星海小博士', '系统传音', '系统公告', '送花播报', '系统', '欢迎', '系统播报', '神秘箱子'];
|
||||
|
||||
@@ -2201,15 +2461,15 @@
|
||||
};
|
||||
|
||||
// 用户名(单击切换发言对象,双击查看资料;事件委托已迁至 Vite right-panel.js)
|
||||
const clickableUser = (uName, color) => {
|
||||
const clickableUser = (uName, color, extraClass = '') => {
|
||||
const safeName = escapeHtml(uName);
|
||||
if (uName === 'AI小班长') {
|
||||
return `<span class="msg-user" data-chat-message-user data-u="${safeName}" style="color: ${color}; cursor: pointer;">${safeName}</span>`;
|
||||
return `<span class="msg-user${extraClass}" data-chat-message-user data-u="${safeName}" style="color: ${color}; cursor: pointer;">${safeName}</span>`;
|
||||
}
|
||||
if (systemUsers.includes(uName) || isGameLabel(uName)) {
|
||||
return `<span class="msg-user" style="color: ${color};">${safeName}</span>`;
|
||||
return `<span class="msg-user${extraClass}" style="color: ${color};">${safeName}</span>`;
|
||||
}
|
||||
return `<span class="msg-user" data-chat-message-user data-u="${safeName}" style="color: ${color}; cursor: pointer;">${safeName}</span>`;
|
||||
return `<span class="msg-user${extraClass}" data-chat-message-user data-u="${safeName}" style="color: ${color}; cursor: pointer;">${safeName}</span>`;
|
||||
};
|
||||
|
||||
// 普通用户(包括 AI小班长)用数据库头像,播报类用特殊喇叭图标
|
||||
@@ -2330,7 +2590,7 @@
|
||||
});
|
||||
|
||||
html =
|
||||
`${headImg}<span style="font-weight: bold;">${clickableUser(msg.from_user, fontColor)}:</span><span class="msg-content" style="color: ${fontColor}">${parsedContent}</span>${giftHtml}`;
|
||||
`${headImg}<span style="font-weight: bold;">${clickableUser(msg.from_user, fontColor, nameClass)}:</span><span class="msg-content" style="color: ${fontColor}">${parsedContent}</span>${giftHtml}`;
|
||||
}
|
||||
} else if (msg.is_secret) {
|
||||
if (msg.from_user === '系统') {
|
||||
@@ -2341,7 +2601,7 @@
|
||||
`<span style="color:#16a34a;font-weight:bold;">📢 系统:</span><span style="color:#15803d;">${msg.content}</span>`;
|
||||
} else {
|
||||
// 普通悄悄话样式(原版:紫色斜体,使用自然语序动作)
|
||||
const fromHtml = clickableUser(msg.from_user, '#cc00cc');
|
||||
const fromHtml = clickableUser(msg.from_user, '#cc00cc', nameClass);
|
||||
const toHtml = clickableUser(msg.to_user, '#cc00cc');
|
||||
const verbStr = msg.action ?
|
||||
buildActionStr(msg.action, fromHtml, toHtml, '悄悄说') :
|
||||
@@ -2351,7 +2611,7 @@
|
||||
}
|
||||
} else if (msg.to_user && msg.to_user !== '大家') {
|
||||
// 对特定对象说话
|
||||
const fromHtml = clickableUser(msg.from_user, '#000099');
|
||||
const fromHtml = clickableUser(msg.from_user, '#000099', nameClass);
|
||||
const toHtml = clickableUser(msg.to_user, '#000099');
|
||||
const verbStr = msg.action ?
|
||||
buildActionStr(msg.action, fromHtml, toHtml) :
|
||||
@@ -2359,7 +2619,7 @@
|
||||
html = `${headImg}${verbStr}<span class="msg-content" style="color: ${fontColor}">${messageBodyHtml}</span>`;
|
||||
} else {
|
||||
// 对大家说话
|
||||
const fromHtml = clickableUser(msg.from_user, '#000099');
|
||||
const fromHtml = clickableUser(msg.from_user, '#000099', nameClass);
|
||||
const verbStr = msg.action ?
|
||||
buildActionStr(msg.action, fromHtml, '大家') :
|
||||
`${fromHtml}对大家说:`;
|
||||
|
||||
Reference in New Issue
Block a user