diff --git a/src/components/cards/SubscribeCard.vue b/src/components/cards/SubscribeCard.vue index 695d5ded..cf0784b7 100644 --- a/src/components/cards/SubscribeCard.vue +++ b/src/components/cards/SubscribeCard.vue @@ -146,7 +146,10 @@ const executionStateDisplay = computed(() => { return { ...display, label: t(`subscribe.execution.state.${displayState}`), - error: execution.error, + // 兼容旧后端残留的等待原因:恢复搜索后不再把旧提示带入 tooltip。 + error: ['matching', 'searching', 'preparing', 'submitting', 'running'].includes(displayState) + ? undefined + : execution.error, } }) @@ -1106,8 +1109,10 @@ function handleCardClick() { text-overflow: ellipsis; } +/* 状态与集数共用单行槽位,小屏空间不足时允许省略而不挤压操作按钮。 */ .subscribe-card-mobile-progress-text { - flex-shrink: 0; + min-inline-size: 0; + flex-shrink: 1; } .subscribe-card-mobile-menu { diff --git a/src/components/cards/__tests__/SubscribeCard.spec.ts b/src/components/cards/__tests__/SubscribeCard.spec.ts index b07612f2..3e51c346 100644 --- a/src/components/cards/__tests__/SubscribeCard.spec.ts +++ b/src/components/cards/__tests__/SubscribeCard.spec.ts @@ -1,6 +1,8 @@ import { formatDateDifference } from '@/@core/utils/formatters' import type { Subscribe } from '@/api/types' import SubscribeCard from '@/components/cards/SubscribeCard.vue' +import zhCN from '@/locales/zh-CN' +import zhTW from '@/locales/zh-TW' import { fireEvent, screen, waitFor } from '@testing-library/vue' import { createSubscribe } from '@tests/support/factories/subscribe' import { @@ -12,6 +14,7 @@ import { import { server } from '@tests/support/msw/server' import { renderWithProviders } from '@tests/support/render' import { beforeEach, describe, expect, it, vi } from 'vitest' +import { createI18n } from 'vue-i18n' const mocks = vi.hoisted(() => ({ confirm: vi.fn(), @@ -350,7 +353,7 @@ describe('SubscribeCard display and progress', () => { expect(container.querySelector('.subscribe-card')).not.toHaveClass('subscribe-card-paused') }) - it.each([480, 1024])('shows governed execution state and safe failure detail at %ipx', async width => { + it.each([375, 480, 1024])('shows governed execution state and safe failure detail at %ipx', async width => { setViewport(width) await renderCard({ execution_status: { @@ -364,13 +367,29 @@ describe('SubscribeCard display and progress', () => { }, }) - expect(screen.getByText('站点暂时忙,稍后继续')).toBeInTheDocument() + expect(screen.getByText('等待站点')).toBeInTheDocument() const status = screen.getByTitle('站点暂时忙,系统会自动继续搜索') expect(status).toBeInTheDocument() await fireEvent.mouseEnter(status) await waitFor(() => expect(screen.getByRole('tooltip')).toHaveTextContent('站点暂时忙,系统会自动继续搜索')) }) + it.each([375, 1024])('clears old waiting detail when search resumes at %ipx', async width => { + setViewport(width) + await renderCard({ + execution_status: { + can_cancel: true, + error: '站点暂时忙,系统会自动继续搜索', + phase: 'searching', + state: 'running', + updated_at: new Date().toISOString(), + }, + }) + + expect(screen.getByText('搜索中')).toBeInTheDocument() + expect(screen.queryByTitle('站点暂时忙,系统会自动继续搜索')).not.toBeInTheDocument() + }) + it.each([480, 1024])('shows a skipped execution as a non-error terminal state at %ipx', async width => { setViewport(width) await renderCard({ @@ -382,7 +401,7 @@ describe('SubscribeCard display and progress', () => { }, }) - expect(screen.getByText('这次未搜索')).toBeInTheDocument() + expect(screen.getByText('已跳过')).toBeInTheDocument() if (width < 600) { expect(document.querySelector('[data-subscribe-state-icon="mdi-skip-next-circle-outline"]')).toBeInTheDocument() } @@ -461,7 +480,7 @@ describe('SubscribeCard display and progress', () => { type: '电视剧', }) - expect(screen.queryByText('已安排,稍后开始')).not.toBeInTheDocument() + expect(screen.queryByText('待搜索')).not.toBeInTheDocument() expect(screen.getByText('6 / 10')).toBeInTheDocument() if (width >= 600) expect(screen.getByText(formatDateDifference(media.last_update))).toBeInTheDocument() }) @@ -710,3 +729,12 @@ describe('SubscribeCard item operations', () => { }, ) }) + +describe('SubscribeCard compact execution vocabulary', () => { + it.each([zhCN, zhTW])('keeps every Chinese state within four characters', locale => { + const i18n = createI18n({ legacy: false, locale: 'test', messages: { test: locale } }) + for (const state of Object.keys(locale.subscribe.execution.state)) { + expect([...i18n.global.t(`subscribe.execution.state.${state}`)].length).toBeLessThanOrEqual(4) + } + }) +}) diff --git a/src/locales/en-US.ts b/src/locales/en-US.ts index 03b84e10..02b93b0f 100644 --- a/src/locales/en-US.ts +++ b/src/locales/en-US.ts @@ -1421,17 +1421,17 @@ export default { cancelRequested: 'Stopping this search', cancelFailed: 'Unable to stop the search right now. Try again shortly.', state: { - queued: 'Starting soon', - scheduled: 'Scheduled to start shortly', - running: 'In progress', - matching: 'Preparing the search', + queued: 'Queued', + scheduled: 'Scheduled', + running: 'Processing', + matching: 'Preparing', searching: 'Searching', - waiting_subscription: 'Continuing after the current task', - waiting_site_budget: 'Site is busy; continuing shortly', - preparing: 'Resource found; preparing download', - submitting: 'Submitting download', - skipped: 'Not searched this time', - failed: 'Search did not finish', + waiting_subscription: 'Task pending', + waiting_site_budget: 'Site pending', + preparing: 'Ready', + submitting: 'Submitting', + skipped: 'Skipped', + failed: 'Search failed', cancelling: 'Stopping', cancelled: 'Stopped', completed: 'Search complete', diff --git a/src/locales/zh-CN.ts b/src/locales/zh-CN.ts index 3a5a932d..1c9f70dc 100644 --- a/src/locales/zh-CN.ts +++ b/src/locales/zh-CN.ts @@ -1401,18 +1401,18 @@ export default { cancelRequested: '正在停止这次搜索', cancelFailed: '暂时无法停止,请稍后重试', state: { - queued: '即将开始', - scheduled: '已安排,稍后开始', - running: '正在处理', - matching: '正在准备搜索', - searching: '正在搜索', - waiting_subscription: '当前任务结束后继续', - waiting_site_budget: '站点暂时忙,稍后继续', - preparing: '找到资源,准备下载', - submitting: '正在提交下载', - skipped: '这次未搜索', - failed: '搜索没有完成', - cancelling: '正在停止', + queued: '排队中', + scheduled: '待搜索', + running: '处理中', + matching: '准备中', + searching: '搜索中', + waiting_subscription: '等待任务', + waiting_site_budget: '等待站点', + preparing: '待下载', + submitting: '提交中', + skipped: '已跳过', + failed: '搜索失败', + cancelling: '停止中', cancelled: '已停止', completed: '搜索完成', }, diff --git a/src/locales/zh-TW.ts b/src/locales/zh-TW.ts index c8cb9a9c..20a6772b 100644 --- a/src/locales/zh-TW.ts +++ b/src/locales/zh-TW.ts @@ -1399,18 +1399,18 @@ export default { cancelRequested: '正在停止這次搜索', cancelFailed: '暫時無法停止,請稍後重試', state: { - queued: '即將開始', - scheduled: '已安排,稍後開始', - running: '正在處理', - matching: '正在準備搜索', - searching: '正在搜索', - waiting_subscription: '目前任務結束後繼續', - waiting_site_budget: '站點暫時忙,稍後繼續', - preparing: '找到資源,準備下載', - submitting: '正在提交下載', - skipped: '這次未搜索', - failed: '搜索沒有完成', - cancelling: '正在停止', + queued: '排隊中', + scheduled: '待搜尋', + running: '處理中', + matching: '準備中', + searching: '搜尋中', + waiting_subscription: '等待任務', + waiting_site_budget: '等待站點', + preparing: '待下載', + submitting: '提交中', + skipped: '已略過', + failed: '搜尋失敗', + cancelling: '停止中', cancelled: '已停止', completed: '搜索完成', }, diff --git a/src/views/subscribe/__tests__/SubscribeListView.spec.ts b/src/views/subscribe/__tests__/SubscribeListView.spec.ts index 451a6929..86ed642b 100644 --- a/src/views/subscribe/__tests__/SubscribeListView.spec.ts +++ b/src/views/subscribe/__tests__/SubscribeListView.spec.ts @@ -385,7 +385,7 @@ describe('SubscribeListView loading and filtering', () => { server.use(cancelSubscriptionExecutionBatchHandler(batch.batch_id, { success: true }, 200, cancelRequested)) await renderList({ batchResponse: [batch], listResponse: [movie(1, 'Own movie')] }) - expect(await screen.findByText('正在搜索')).toBeInTheDocument() + expect(await screen.findByText('搜索中')).toBeInTheDocument() expect(screen.getByText('1/3')).toBeInTheDocument() await fireEvent.click(screen.getByTitle('停止这次搜索')) @@ -845,7 +845,7 @@ describe('SubscribeListView loading and filtering', () => { }) expect(await screen.findByText('跳过批次订阅')).toBeInTheDocument() - expect(await screen.findByText('这次未搜索')).toBeInTheDocument() + expect(await screen.findByText('已跳过')).toBeInTheDocument() expect(await screen.findByText('2/3')).toBeInTheDocument() }) @@ -856,7 +856,7 @@ describe('SubscribeListView loading and filtering', () => { }) expect(await screen.findByText('后台自动搜索订阅')).toBeInTheDocument() - expect(screen.queryByText('已安排,稍后开始')).not.toBeInTheDocument() + expect(screen.queryByText('待搜索')).not.toBeInTheDocument() expect(document.querySelector('.subscribe-execution-banner')).not.toBeInTheDocument() })