feat(theme-2): sync inbox/announcements/presence/deposit from main

This commit is contained in:
2026-06-18 09:38:33 +08:00
parent ec51b675e3
commit e56029225e
86 changed files with 6828 additions and 928 deletions

View File

@@ -1,23 +1,39 @@
<script setup lang="ts">
import { computed } from 'vue';
import { useRouter } from 'vue-router';
import { useI18n } from 'vue-i18n';
const { t } = useI18n();
const router = useRouter();
const props = withDefaults(
defineProps<{ items: string[]; embedded?: boolean }>(),
defineProps<{ items: string[]; targetId?: string; embedded?: boolean }>(),
{ embedded: false },
);
const detailTo = computed(() =>
props.targetId ? `/announcements/${props.targetId}` : '/announcements',
);
const text = computed(() => {
const list = props.items.filter(Boolean);
if (!list.length) return '';
return list.join('  ◆  ');
});
function goDetail() {
void router.push(detailTo.value);
}
</script>
<template>
<div v-if="text" class="marquee-bar" :class="{ embedded }">
<button
v-if="text"
type="button"
class="marquee-bar"
:class="{ embedded }"
@click="goDetail"
>
<span class="marquee-badge">{{ t('home.announcement_badge') }}</span>
<div class="marquee-viewport">
<div class="marquee-track">
@@ -25,21 +41,26 @@ const text = computed(() => {
<span class="marquee-text" aria-hidden="true">{{ text }}</span>
</div>
</div>
</div>
</button>
</template>
<style scoped>
.marquee-bar {
width: 100%;
display: flex;
align-items: center;
gap: 10px;
margin: -4px -2px 14px;
padding: 10px 12px;
background: #FFFFFF;
border: 1px solid #E5E7EB;
border-radius: 8px;
background: #EFF6FF;
border: 1px solid var(--border);
border-radius: var(--radius-sm);
overflow: hidden;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
text-decoration: none;
color: inherit;
cursor: pointer;
touch-action: manipulation;
-webkit-tap-highlight-color: transparent;
}
.marquee-bar.embedded {
@@ -47,8 +68,8 @@ const text = computed(() => {
padding: 8px 12px;
border: none;
border-radius: 0;
border-bottom: 1px solid #E5E7EB;
background: #F5F7FA;
border-bottom: 1px solid var(--border);
background: #EFF6FF;
}
.marquee-bar.embedded .marquee-badge {
@@ -66,9 +87,9 @@ const text = computed(() => {
font-size: 11px;
font-weight: 800;
letter-spacing: 0.12em;
color: #FFFFFF;
background: #003D6B;
border: 1px solid #003D6B;
color: #fff;
background: var(--primary);
border: none;
border-radius: 4px;
}
@@ -83,6 +104,7 @@ const text = computed(() => {
display: flex;
width: max-content;
animation: marquee-scroll 18s linear infinite;
pointer-events: none;
}
.marquee-text {
@@ -90,7 +112,7 @@ const text = computed(() => {
padding-right: 80px;
font-size: 13px;
font-weight: 600;
color: #003D6B;
color: var(--primary-light);
white-space: nowrap;
}