From 41d5f579f7cdea1f2e2b6b4c3cb257c626ee9032 Mon Sep 17 00:00:00 2001 From: jxxghp Date: Mon, 3 Aug 2026 22:42:15 +0800 Subject: [PATCH] Fix movie wash subscription card visuals --- src/components/cards/SubscribeCard.vue | 25 ++++++++++++++----- .../cards/__tests__/SubscribeCard.spec.ts | 17 +++++++++++++ 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/src/components/cards/SubscribeCard.vue b/src/components/cards/SubscribeCard.vue index db4db6d6..7f179dbb 100644 --- a/src/components/cards/SubscribeCard.vue +++ b/src/components/cards/SubscribeCard.vue @@ -79,8 +79,11 @@ const downloadedEpisode = computed(() => { return Math.min(Math.max(total - (props.media?.lack_episode || 0), 0), total) }) -// 是否为洗版订阅(影响进度条与 tooltip 的展示分支) -const isBestVersion = computed(() => isEnabledFlag(props.media?.best_version) && isTvSubscribe(props.media)) +// 是否开启洗版,供电影和电视剧共用洗版标识与配色。 +const hasBestVersion = computed(() => isEnabledFlag(props.media?.best_version)) + +// 是否为电视剧洗版订阅,仅影响分集进度条与 tooltip 的展示分支。 +const isBestVersion = computed(() => hasBestVersion.value && isTvSubscribe(props.media)) const rightBottomStateDisplay = computed(() => { if (subscribeState.value === 'S') { @@ -100,7 +103,7 @@ const compactStateDisplay = computed(() => { if (subscribeState.value === 'P') { return { color: 'info', icon: 'mdi-timer-sand', label: t('subscribe.cardStatePending') } } - if (isBestVersion.value) { + if (hasBestVersion.value) { return { color: 'success', icon: 'mdi-shimmer', label: t('subscribe.subscribing') } } return { color: 'primary', icon: 'mdi-rss', label: t('subscribe.subscribing') } @@ -108,7 +111,7 @@ const compactStateDisplay = computed(() => { // 洗版徽标:共用 mdi-shimmer 图标,分集 / 全集 由 full 标记区分背景 const bestVersionBadge = computed(() => { - if (!isEnabledFlag(props.media?.best_version)) return null + if (!hasBestVersion.value) return null return { icon: 'mdi-shimmer', full: isEnabledFlag(props.media?.best_version_full), @@ -443,7 +446,7 @@ function handleCardClick() { :class="{ 'subscribe-card-paused': subscribeState === 'S', 'subscribe-card-pending-tint': subscribeState === 'P', - 'subscribe-card-best-version-tint': display.xs.value && isBestVersion && subscribeState === 'R', + 'subscribe-card-best-version-tint': display.xs.value && hasBestVersion && subscribeState === 'R', 'cursor-move': props.sortable, }" min-height="150" @@ -542,7 +545,11 @@ function handleCardClick() { :title="compactStateDisplay.label" :aria-label="compactStateDisplay.label" > - + @@ -940,6 +947,12 @@ function handleCardClick() { min-block-size: 0 !important; } + .subscribe-card-background.subscribe-card-mobile-image-scrim { + background-image: + linear-gradient(180deg, rgba(8, 12, 18, 0.28) 0%, rgba(8, 12, 18, 0) 44%), + linear-gradient(0deg, rgba(8, 12, 18, 0.7) 0%, rgba(8, 12, 18, 0) 72%); + } + .subscribe-card-paused { opacity: 1; } diff --git a/src/components/cards/__tests__/SubscribeCard.spec.ts b/src/components/cards/__tests__/SubscribeCard.spec.ts index ec70d73a..1881c55e 100644 --- a/src/components/cards/__tests__/SubscribeCard.spec.ts +++ b/src/components/cards/__tests__/SubscribeCard.spec.ts @@ -233,6 +233,23 @@ describe('SubscribeCard display and progress', () => { expect(container.querySelector('.subscribe-card')).toHaveClass('subscribe-card-best-version-tint') }) + it('applies mobile wash visuals to movies without episode progress', async () => { + setViewport(480) + const { container } = await renderCard({ + best_version: true, + state: 'R', + total_episode: undefined, + type: '电影', + }) + + expect(container.querySelector('.subscribe-card')).toHaveClass('subscribe-card-best-version-tint') + expect(container.querySelector('[data-subscribe-state-icon="mdi-shimmer"]')).toBeInTheDocument() + expect(container.querySelector('.subscribe-card-mobile-state')).toHaveStyle({ + color: 'rgb(var(--v-theme-success))', + }) + expect(screen.queryByRole('progressbar')).not.toBeInTheDocument() + }) + it('synchronizes desktop P, S, and R state from updated media props', async () => { const { container, media, rerender } = await renderCard({ state: 'P' }) const lastUpdateText = formatDateDifference(media.last_update)