Highlight best-version subscriptions on mobile cards

This commit is contained in:
jxxghp
2026-08-03 22:26:04 +08:00
parent 47b9633a86
commit 102abf7df9
2 changed files with 27 additions and 31 deletions
+21 -22
View File
@@ -100,6 +100,9 @@ const compactStateDisplay = computed(() => {
if (subscribeState.value === 'P') { if (subscribeState.value === 'P') {
return { color: 'info', icon: 'mdi-timer-sand', label: t('subscribe.cardStatePending') } return { color: 'info', icon: 'mdi-timer-sand', label: t('subscribe.cardStatePending') }
} }
if (isBestVersion.value) {
return { color: 'success', icon: 'mdi-shimmer', label: t('subscribe.subscribing') }
}
return { color: 'primary', icon: 'mdi-rss', label: t('subscribe.subscribing') } return { color: 'primary', icon: 'mdi-rss', label: t('subscribe.subscribing') }
}) })
@@ -440,6 +443,7 @@ function handleCardClick() {
:class="{ :class="{
'subscribe-card-paused': subscribeState === 'S', 'subscribe-card-paused': subscribeState === 'S',
'subscribe-card-pending-tint': subscribeState === 'P', 'subscribe-card-pending-tint': subscribeState === 'P',
'subscribe-card-best-version-tint': display.xs.value && isBestVersion && subscribeState === 'R',
'cursor-move': props.sortable, 'cursor-move': props.sortable,
}" }"
min-height="150" min-height="150"
@@ -517,13 +521,6 @@ function handleCardClick() {
</div> </div>
<div class="subscribe-card-mobile-title"> <div class="subscribe-card-mobile-title">
<span
v-if="bestVersionBadge && imageLoaded"
class="best-version-badge subscribe-card-mobile-best-version-badge"
:class="{ 'best-version-badge-full': bestVersionBadge.full }"
>
<VIcon :icon="bestVersionBadge.icon" color="white" size="14" />
</span>
<div class="subscribe-card-mobile-title-text"> <div class="subscribe-card-mobile-title-text">
<span>{{ props.media?.name }}</span> <span>{{ props.media?.name }}</span>
<span <span
@@ -790,9 +787,6 @@ function handleCardClick() {
.subscribe-card-mobile-title { .subscribe-card-mobile-title {
position: absolute; position: absolute;
z-index: 2; z-index: 2;
display: flex;
align-items: flex-start;
gap: 0.375rem;
color: white; color: white;
font-size: 1rem; font-size: 1rem;
font-weight: 650; font-weight: 650;
@@ -805,23 +799,12 @@ function handleCardClick() {
.subscribe-card-mobile-title-text { .subscribe-card-mobile-title-text {
display: -webkit-box; display: -webkit-box;
min-inline-size: 0;
max-block-size: 3.9em; max-block-size: 3.9em;
overflow: hidden; overflow: hidden;
flex: 1 1 auto;
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
-webkit-line-clamp: 3; -webkit-line-clamp: 3;
} }
.best-version-badge.subscribe-card-mobile-best-version-badge {
position: static;
z-index: auto;
block-size: 1.25rem;
flex: 0 0 1.25rem;
inline-size: 1.25rem;
margin-block-start: 0.05rem;
}
.subscribe-card-mobile-season { .subscribe-card-mobile-season {
margin-inline-start: 0.25rem; margin-inline-start: 0.25rem;
color: rgba(255, 255, 255, 0.66); color: rgba(255, 255, 255, 0.66);
@@ -926,7 +909,7 @@ function handleCardClick() {
} }
/** /**
* 洗版标识:桌面端左上角使用 24x24 圆形徽标,移动端缩小后放在标题前 * 洗版标识:桌面端左上角使用 24x24 圆形徽标。
* 分集:深色半透底 + 模糊 * 分集:深色半透底 + 模糊
* 全集:磨砂玻璃半透白底 + 大模糊 * 全集:磨砂玻璃半透白底 + 大模糊
*/ */
@@ -971,5 +954,21 @@ function handleCardClick() {
inset 0 0 0 1px rgba(var(--v-theme-info), 0.28), inset 0 0 0 1px rgba(var(--v-theme-info), 0.28),
inset 0 -4rem 5rem rgba(var(--v-theme-info), 0.08); inset 0 -4rem 5rem rgba(var(--v-theme-info), 0.08);
} }
.subscribe-card-best-version-tint {
position: relative;
}
.subscribe-card-best-version-tint::after {
position: absolute;
z-index: 3;
border-radius: inherit;
box-shadow:
inset 0 0 0 1px rgba(var(--v-theme-success), 0.34),
inset 0 -4rem 5rem rgba(var(--v-theme-success), 0.12);
content: '';
inset: 0;
pointer-events: none;
}
} }
</style> </style>
@@ -191,6 +191,7 @@ describe('SubscribeCard display and progress', () => {
expect(progress.querySelector('.v-progress-linear__buffer')).toHaveStyle({ width: expectedWash ? '80%' : '0%' }) expect(progress.querySelector('.v-progress-linear__buffer')).toHaveStyle({ width: expectedWash ? '80%' : '0%' })
expect(Boolean(container.querySelector('.best-version-badge'))).toBe(expectedWash) expect(Boolean(container.querySelector('.best-version-badge'))).toBe(expectedWash)
expect(Boolean(container.querySelector('.best-version-badge-full'))).toBe(expectedFull) expect(Boolean(container.querySelector('.best-version-badge-full'))).toBe(expectedFull)
expect(container.querySelector('.subscribe-card')).not.toHaveClass('subscribe-card-best-version-tint')
}, },
) )
@@ -217,23 +218,19 @@ describe('SubscribeCard display and progress', () => {
expect(document.querySelector('.subscribe-card-mobile-body')).not.toHaveTextContent('卡片测试媒体') expect(document.querySelector('.subscribe-card-mobile-body')).not.toHaveTextContent('卡片测试媒体')
expect(document.querySelector('.subscribe-card-mobile-season')).toHaveTextContent('S01') expect(document.querySelector('.subscribe-card-mobile-season')).toHaveTextContent('S01')
expect(document.querySelector('.subscribe-card-mobile-title-text')).toHaveTextContent('卡片测试媒体S01') expect(document.querySelector('.subscribe-card-mobile-title-text')).toHaveTextContent('卡片测试媒体S01')
const image = container.querySelector<HTMLImageElement>('img') expect(document.querySelector('.subscribe-card-mobile-best-version-badge')).not.toBeInTheDocument()
expect(image).not.toBeNull() expect(container.querySelector('.subscribe-card')).toHaveClass('subscribe-card-pending-tint')
await fireEvent.load(image as HTMLImageElement) expect(container.querySelector('.subscribe-card')).not.toHaveClass('subscribe-card-best-version-tint')
expect(document.querySelector('.subscribe-card-mobile-title')).toContainElement(
document.querySelector('.subscribe-card-mobile-best-version-badge'),
)
expect(document.querySelector('.subscribe-card-mobile-image-meta')).not.toHaveClass(
'subscribe-card-mobile-image-meta--with-badge',
)
await rerender({ media: { ...media, state: 'S' } }) await rerender({ media: { ...media, state: 'S' } })
expect(screen.getByLabelText('已暂停')).toBeInTheDocument() expect(screen.getByLabelText('已暂停')).toBeInTheDocument()
expect(screen.getByText(lastUpdateText)).toBeInTheDocument() expect(screen.getByText(lastUpdateText)).toBeInTheDocument()
expect(container.querySelector('.subscribe-card')).not.toHaveClass('subscribe-card-best-version-tint')
await rerender({ media: { ...media, state: 'R' } }) await rerender({ media: { ...media, state: 'R' } })
expect(screen.getByLabelText('订阅中')).toBeInTheDocument() expect(screen.getByLabelText('订阅中')).toBeInTheDocument()
expect(screen.getByText(lastUpdateText)).toBeInTheDocument() expect(screen.getByText(lastUpdateText)).toBeInTheDocument()
expect(container.querySelector('.subscribe-card')).toHaveClass('subscribe-card-best-version-tint')
}) })
it('synchronizes desktop P, S, and R state from updated media props', async () => { it('synchronizes desktop P, S, and R state from updated media props', async () => {