Add VIP presence themes and custom greetings
This commit is contained in:
@@ -9,3 +9,129 @@
|
||||
--font-sans: 'Instrument Sans', ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji',
|
||||
'Segoe UI Symbol', 'Noto Color Emoji';
|
||||
}
|
||||
|
||||
.vip-presence-banner {
|
||||
position: fixed;
|
||||
inset: 24px 24px auto 24px;
|
||||
z-index: 100000;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
pointer-events: none;
|
||||
animation: vip-presence-enter .55s ease-out both;
|
||||
}
|
||||
|
||||
.vip-presence-banner.is-leaving {
|
||||
animation: vip-presence-leave .65s ease-in both;
|
||||
}
|
||||
|
||||
.vip-presence-banner__glow {
|
||||
position: absolute;
|
||||
inset: 14px auto auto 50%;
|
||||
width: min(72vw, 720px);
|
||||
height: 88px;
|
||||
border-radius: 9999px;
|
||||
filter: blur(34px);
|
||||
transform: translateX(-50%);
|
||||
opacity: .95;
|
||||
}
|
||||
|
||||
.vip-presence-banner__card {
|
||||
position: relative;
|
||||
width: min(92vw, 760px);
|
||||
border: 1px solid rgba(255, 255, 255, .35);
|
||||
border-radius: 28px;
|
||||
padding: 20px 24px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 20px 60px rgba(15, 23, 42, .35);
|
||||
}
|
||||
|
||||
.vip-presence-banner__card::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: linear-gradient(120deg, transparent 0%, rgba(255,255,255,.16) 38%, transparent 72%);
|
||||
transform: translateX(-120%);
|
||||
animation: vip-presence-shine 2.6s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.vip-presence-banner__meta {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.vip-presence-banner__icon {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 42px;
|
||||
height: 42px;
|
||||
border-radius: 16px;
|
||||
background: rgba(15, 23, 42, .22);
|
||||
backdrop-filter: blur(10px);
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.vip-presence-banner__level {
|
||||
font-size: 12px;
|
||||
font-weight: 800;
|
||||
letter-spacing: .12em;
|
||||
text-transform: uppercase;
|
||||
color: rgba(255, 255, 255, .92);
|
||||
}
|
||||
|
||||
.vip-presence-banner__type {
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
padding: 6px 10px;
|
||||
border-radius: 9999px;
|
||||
color: #0f172a;
|
||||
background: rgba(255, 255, 255, .72);
|
||||
}
|
||||
|
||||
.vip-presence-banner__text {
|
||||
position: relative;
|
||||
margin-top: 14px;
|
||||
font-size: clamp(16px, 2vw, 24px);
|
||||
font-weight: 800;
|
||||
line-height: 1.5;
|
||||
text-wrap: balance;
|
||||
text-shadow: 0 2px 18px rgba(15, 23, 42, .22);
|
||||
}
|
||||
|
||||
@keyframes vip-presence-enter {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-22px) scale(.96);
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0) scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes vip-presence-leave {
|
||||
from {
|
||||
opacity: 1;
|
||||
transform: translateY(0) scale(1);
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 0;
|
||||
transform: translateY(-16px) scale(.98);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes vip-presence-shine {
|
||||
0% {
|
||||
transform: translateX(-120%);
|
||||
}
|
||||
|
||||
55%,
|
||||
100% {
|
||||
transform: translateX(140%);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,11 @@
|
||||
duration_days: 30,
|
||||
join_templates: '',
|
||||
leave_templates: '',
|
||||
join_effect: 'none',
|
||||
leave_effect: 'none',
|
||||
join_banner_style: 'aurora',
|
||||
leave_banner_style: 'farewell',
|
||||
allow_custom_messages: true,
|
||||
},
|
||||
|
||||
openCreate() {
|
||||
@@ -42,6 +47,11 @@
|
||||
duration_days: 30,
|
||||
join_templates: '',
|
||||
leave_templates: '',
|
||||
join_effect: 'none',
|
||||
leave_effect: 'none',
|
||||
join_banner_style: 'aurora',
|
||||
leave_banner_style: 'farewell',
|
||||
allow_custom_messages: true,
|
||||
};
|
||||
this.showForm = true;
|
||||
},
|
||||
@@ -59,6 +69,11 @@
|
||||
duration_days: level.duration_days,
|
||||
join_templates: level.join_templates_text,
|
||||
leave_templates: level.leave_templates_text,
|
||||
join_effect: level.join_effect,
|
||||
leave_effect: level.leave_effect,
|
||||
join_banner_style: level.join_banner_style,
|
||||
leave_banner_style: level.leave_banner_style,
|
||||
allow_custom_messages: level.allow_custom_messages,
|
||||
};
|
||||
this.showForm = true;
|
||||
}
|
||||
@@ -112,6 +127,18 @@
|
||||
<span class="text-gray-500">当前会员</span>
|
||||
<span class="font-bold text-indigo-600">{{ $level->users()->count() }} 人</span>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<span class="text-gray-500">进场特效</span>
|
||||
<span class="font-bold text-sky-600">{{ $effectOptions[$level->joinEffectKey()] ?? '无特效' }}</span>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<span class="text-gray-500">离场特效</span>
|
||||
<span class="font-bold text-violet-600">{{ $effectOptions[$level->leaveEffectKey()] ?? '无特效' }}</span>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<span class="text-gray-500">允许自定义</span>
|
||||
<span class="font-bold {{ $level->allow_custom_messages ? 'text-emerald-600' : 'text-gray-400' }}">{{ $level->allow_custom_messages ? '允许' : '关闭' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -127,6 +154,11 @@
|
||||
sort_order: {{ $level->sort_order }},
|
||||
price: {{ $level->price }},
|
||||
duration_days: {{ $level->duration_days }},
|
||||
join_effect: '{{ $level->joinEffectKey() }}',
|
||||
leave_effect: '{{ $level->leaveEffectKey() }}',
|
||||
join_banner_style: '{{ $level->joinBannerStyleKey() }}',
|
||||
leave_banner_style: '{{ $level->leaveBannerStyleKey() }}',
|
||||
allow_custom_messages: {{ $level->allow_custom_messages ? 'true' : 'false' }},
|
||||
join_templates_text: `{{ str_replace('`', '', implode("\n", $level->join_templates_array)) }}`,
|
||||
leave_templates_text: `{{ str_replace('`', '', implode("\n", $level->leave_templates_array)) }}`,
|
||||
requestUrl: '{{ route('admin.vip.update', $level->id) }}'
|
||||
@@ -229,6 +261,47 @@
|
||||
class="w-full border rounded-md p-2 text-sm"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="mt-4 grid grid-cols-2 gap-4">
|
||||
<div>
|
||||
<label class="block text-xs font-bold text-gray-600 mb-1">入场特效</label>
|
||||
<select name="join_effect" x-model="form.join_effect" class="w-full border rounded-md p-2 text-sm">
|
||||
@foreach ($effectOptions as $value => $label)
|
||||
<option value="{{ $value }}">{{ $label }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-xs font-bold text-gray-600 mb-1">离场特效</label>
|
||||
<select name="leave_effect" x-model="form.leave_effect" class="w-full border rounded-md p-2 text-sm">
|
||||
@foreach ($effectOptions as $value => $label)
|
||||
<option value="{{ $value }}">{{ $label }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-xs font-bold text-gray-600 mb-1">入场横幅风格</label>
|
||||
<select name="join_banner_style" x-model="form.join_banner_style" class="w-full border rounded-md p-2 text-sm">
|
||||
@foreach ($bannerStyleOptions as $value => $label)
|
||||
<option value="{{ $value }}">{{ $label }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-xs font-bold text-gray-600 mb-1">离场横幅风格</label>
|
||||
<select name="leave_banner_style" x-model="form.leave_banner_style" class="w-full border rounded-md p-2 text-sm">
|
||||
@foreach ($bannerStyleOptions as $value => $label)
|
||||
<option value="{{ $value }}">{{ $label }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<label class="mt-4 flex items-center gap-3 rounded-xl border border-amber-100 bg-amber-50 px-4 py-3 text-sm text-amber-900">
|
||||
<input type="checkbox" name="allow_custom_messages" value="1" x-model="form.allow_custom_messages"
|
||||
class="rounded border-amber-300 text-amber-600 focus:ring-amber-400">
|
||||
允许该会员等级用户在会员中心自定义欢迎语和离开语
|
||||
</label>
|
||||
|
||||
<div class="flex justify-end space-x-3 pt-4 mt-4 border-t">
|
||||
<button type="button" @click="showForm = false"
|
||||
class="px-4 py-2 border rounded font-medium text-gray-600 hover:bg-gray-50">取消</button>
|
||||
|
||||
@@ -232,16 +232,18 @@
|
||||
});
|
||||
</script>
|
||||
@endif
|
||||
@if (!empty($newbieEffect) || !empty($weekEffect))
|
||||
@if (!empty($newbieEffect) || !empty($weekEffect) || !empty($initialPresenceTheme['presence_effect']))
|
||||
<script>
|
||||
/**
|
||||
* 延迟1秒待页面完成初始化后,自动播放进房附带的特效
|
||||
* 优先级:如果有新人礼包特效,优先播放新人大礼包;如果没有,再播放周卡特效
|
||||
* 延迟1秒待页面完成初始化后,自动播放进房附带的特效。
|
||||
* 优先级:新人礼包特效 -> 会员专属进场特效 -> 周卡特效。
|
||||
*/
|
||||
setTimeout(() => {
|
||||
if (typeof EffectManager !== 'undefined') {
|
||||
@if (!empty($newbieEffect))
|
||||
EffectManager.play('{{ $newbieEffect }}');
|
||||
@elseif (!empty($initialPresenceTheme['presence_effect']))
|
||||
EffectManager.play('{{ $initialPresenceTheme['presence_effect'] }}');
|
||||
@elseif (!empty($weekEffect))
|
||||
EffectManager.play('{{ $weekEffect }}');
|
||||
@endif
|
||||
@@ -249,6 +251,17 @@
|
||||
}, 1000);
|
||||
</script>
|
||||
@endif
|
||||
@if (!empty($initialPresenceTheme))
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
setTimeout(() => {
|
||||
if (typeof window.showVipPresenceBanner === 'function') {
|
||||
window.showVipPresenceBanner(@json($initialPresenceTheme));
|
||||
}
|
||||
}, 700);
|
||||
});
|
||||
</script>
|
||||
@endif
|
||||
|
||||
{{-- 页面初始加载时,若存在挂起的求婚 / 离婚请求,则弹窗 --}}
|
||||
@if (!empty($pendingProposal) || !empty($pendingDivorce))
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -139,6 +139,118 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="bg-white rounded-[2rem] border border-slate-200 shadow-sm overflow-hidden">
|
||||
<div class="bg-[radial-gradient(circle_at_top_left,_rgba(251,191,36,0.24),_transparent_42%),linear-gradient(135deg,#0f172a,#1e293b,#334155)] px-6 py-6 text-white">
|
||||
<div class="flex flex-col gap-2 md:flex-row md:items-end md:justify-between">
|
||||
<div>
|
||||
<p class="text-xs font-bold uppercase tracking-[0.28em] text-amber-300/90">会员进退场主题</p>
|
||||
<h3 class="mt-2 text-2xl font-black">欢迎语、离开语与专属入场仪式</h3>
|
||||
<p class="mt-2 max-w-2xl text-sm text-slate-200">
|
||||
这里可以查看当前会员档位的专属特效和横幅风格;若当前档位允许自定义,你还可以设置自己的欢迎语和离开语。
|
||||
</p>
|
||||
</div>
|
||||
@if ($user->isVip())
|
||||
<div class="rounded-2xl border border-white/10 bg-white/10 px-4 py-3 text-sm text-slate-100">
|
||||
当前档位:<span class="font-extrabold" style="color: {{ $user->vipLevel?->color ?: '#fef3c7' }}">{{ $user->vipName() }}</span>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 gap-6 p-6 lg:grid-cols-[1.2fr,0.8fr]">
|
||||
<div class="space-y-5">
|
||||
<div class="rounded-3xl border border-slate-200 bg-slate-50 p-5">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="flex h-12 w-12 items-center justify-center rounded-2xl bg-slate-900 text-2xl text-white shadow-lg">
|
||||
{{ $user->vipLevel?->icon ?: '✨' }}
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-sm font-bold text-slate-500">当前主题预览</p>
|
||||
<h4 class="text-xl font-black text-slate-900">{{ $user->vipLevel?->name ?? '普通用户' }}</h4>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-5 grid grid-cols-1 gap-3 md:grid-cols-2">
|
||||
<div class="rounded-2xl border border-slate-200 bg-white p-4">
|
||||
<p class="text-xs font-bold uppercase tracking-[0.18em] text-slate-400">入场特效</p>
|
||||
<p class="mt-2 text-lg font-extrabold text-slate-900">{{ $effectOptions[$user->vipLevel?->joinEffectKey() ?? 'none'] ?? '无特效' }}</p>
|
||||
<p class="mt-2 text-sm text-slate-500">横幅风格:{{ $bannerStyleOptions[$user->vipLevel?->joinBannerStyleKey() ?? 'aurora'] ?? '鎏光星幕' }}</p>
|
||||
</div>
|
||||
<div class="rounded-2xl border border-slate-200 bg-white p-4">
|
||||
<p class="text-xs font-bold uppercase tracking-[0.18em] text-slate-400">离场特效</p>
|
||||
<p class="mt-2 text-lg font-extrabold text-slate-900">{{ $effectOptions[$user->vipLevel?->leaveEffectKey() ?? 'none'] ?? '无特效' }}</p>
|
||||
<p class="mt-2 text-sm text-slate-500">横幅风格:{{ $bannerStyleOptions[$user->vipLevel?->leaveBannerStyleKey() ?? 'farewell'] ?? '告别暮光' }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="rounded-3xl border border-amber-100 bg-amber-50/70 p-5">
|
||||
<p class="text-sm font-bold text-amber-700">等级默认语句</p>
|
||||
<div class="mt-4 grid gap-4 md:grid-cols-2">
|
||||
<div class="rounded-2xl bg-white p-4 shadow-sm">
|
||||
<p class="text-xs font-bold uppercase tracking-[0.18em] text-amber-500">默认欢迎语</p>
|
||||
<p class="mt-3 text-sm leading-7 text-slate-700">
|
||||
{{ $user->vipLevel?->join_templates_array[0] ?? '当前档位尚未配置默认欢迎语。' }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="rounded-2xl bg-white p-4 shadow-sm">
|
||||
<p class="text-xs font-bold uppercase tracking-[0.18em] text-amber-500">默认离开语</p>
|
||||
<p class="mt-3 text-sm leading-7 text-slate-700">
|
||||
{{ $user->vipLevel?->leave_templates_array[0] ?? '当前档位尚未配置默认离开语。' }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="rounded-3xl border border-slate-200 bg-white p-5 shadow-sm">
|
||||
<div class="flex items-start justify-between gap-3">
|
||||
<div>
|
||||
<p class="text-sm font-bold text-slate-500">我的个性化设置</p>
|
||||
<h4 class="mt-1 text-xl font-black text-slate-900">自定义欢迎语与离开语</h4>
|
||||
</div>
|
||||
@if ($user->canCustomizeVipPresence())
|
||||
<span class="inline-flex rounded-full bg-emerald-100 px-3 py-1 text-xs font-bold text-emerald-700">已开启</span>
|
||||
@else
|
||||
<span class="inline-flex rounded-full bg-gray-100 px-3 py-1 text-xs font-bold text-gray-500">未开放</span>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
@if ($user->canCustomizeVipPresence())
|
||||
<form action="{{ route('vip.center.presence.update') }}" method="POST" class="mt-5 space-y-4">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
<div>
|
||||
<label class="mb-2 block text-sm font-bold text-slate-700">我的欢迎语</label>
|
||||
<textarea name="custom_join_message" rows="4" maxlength="255"
|
||||
class="w-full rounded-2xl border border-slate-200 bg-slate-50 px-4 py-3 text-sm text-slate-900 outline-none transition focus:border-amber-400 focus:bg-white"
|
||||
placeholder="例:{username} 乘着星舰闪耀登场,今晚全场高光属于 TA!">{{ old('custom_join_message', $user->custom_join_message) }}</textarea>
|
||||
<p class="mt-2 text-xs text-slate-500">支持使用 <span class="font-mono text-slate-700">{username}</span> 占位符自动替换成你的昵称。</p>
|
||||
</div>
|
||||
<div>
|
||||
<label class="mb-2 block text-sm font-bold text-slate-700">我的离开语</label>
|
||||
<textarea name="custom_leave_message" rows="4" maxlength="255"
|
||||
class="w-full rounded-2xl border border-slate-200 bg-slate-50 px-4 py-3 text-sm text-slate-900 outline-none transition focus:border-amber-400 focus:bg-white"
|
||||
placeholder="例:{username} 留下一道流光背影,优雅谢幕,我们下次再见。">{{ old('custom_leave_message', $user->custom_leave_message) }}</textarea>
|
||||
</div>
|
||||
<button type="submit"
|
||||
class="w-full rounded-2xl bg-slate-900 px-5 py-3 text-sm font-bold text-white transition hover:bg-slate-800">
|
||||
保存我的专属语句
|
||||
</button>
|
||||
</form>
|
||||
@elseif ($user->isVip())
|
||||
<div class="mt-5 rounded-2xl border border-dashed border-slate-200 bg-slate-50 px-4 py-5 text-sm leading-7 text-slate-500">
|
||||
当前会员档位暂未开放个人自定义功能,不过你仍会自动使用本等级配置的专属欢迎语、离开语和华丽特效。
|
||||
</div>
|
||||
@else
|
||||
<div class="mt-5 rounded-2xl border border-dashed border-amber-200 bg-amber-50 px-4 py-5 text-sm leading-7 text-amber-800">
|
||||
开通会员后,这里会解锁对应等级的专属进退场主题;若等级允许,还能设置你自己的欢迎语和离开语。
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="bg-white rounded-3xl border border-gray-100 shadow-sm p-6">
|
||||
<div class="flex items-center justify-between gap-4 mb-5">
|
||||
<div>
|
||||
|
||||
Reference in New Issue
Block a user