mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-09-09 09:46:44 +08:00
fix(history): distinguish subtitle and audio records
This commit is contained in:
@@ -4728,6 +4728,10 @@ export default {
|
||||
success: 'Success',
|
||||
failed: 'Failed',
|
||||
},
|
||||
category: {
|
||||
subtitle: 'Subtitle',
|
||||
audio: 'Audio',
|
||||
},
|
||||
deleteStep: {
|
||||
source: 'Source file',
|
||||
destination: 'Media library file',
|
||||
|
||||
@@ -4632,6 +4632,10 @@ export default {
|
||||
success: '成功',
|
||||
failed: '失败',
|
||||
},
|
||||
category: {
|
||||
subtitle: '字幕',
|
||||
audio: '音频',
|
||||
},
|
||||
deleteStep: {
|
||||
source: '源文件',
|
||||
destination: '媒体库文件',
|
||||
|
||||
@@ -4573,6 +4573,10 @@ export default {
|
||||
success: '成功',
|
||||
failed: '失敗',
|
||||
},
|
||||
category: {
|
||||
subtitle: '字幕',
|
||||
audio: '音訊',
|
||||
},
|
||||
deleteStep: {
|
||||
source: '來源檔案',
|
||||
destination: '媒體庫檔案',
|
||||
|
||||
@@ -1388,9 +1388,68 @@ function getHistoryDisplayTitle(item: TransferHistory) {
|
||||
|
||||
// 获取移动端卡片副标题,优先展示二级分类和年份。
|
||||
function getHistorySubtitle(item: TransferHistory) {
|
||||
return [item.category, item.year, item.type === '音乐' ? formatMusicAudioSpecs(item) : ''].filter(Boolean).join(' / ')
|
||||
return [getHistoryCategory(item), item.year, item.type === '音乐' ? formatMusicAudioSpecs(item) : '']
|
||||
.filter(Boolean)
|
||||
.join(' / ')
|
||||
}
|
||||
|
||||
// 附加文件不属于媒体分类,按源文件扩展名显示独立类别,避免与电影/剧集分类混淆。
|
||||
function getHistoryCategory(item: TransferHistory) {
|
||||
const rawExtension = item.src_fileitem?.extension || getFileExtension(item.src)
|
||||
const extension = rawExtension ? `.${rawExtension.replace(/^\./, '').toLowerCase()}` : ''
|
||||
if (subtitleExtensions.has(extension)) return t('transferHistory.category.subtitle')
|
||||
if (audioExtensions.has(extension) && item.type !== '音乐') return t('transferHistory.category.audio')
|
||||
return item.category
|
||||
}
|
||||
|
||||
function getFileExtension(path?: string) {
|
||||
const filename = path?.split(/[\\/]/).at(-1) || ''
|
||||
const dot = filename.lastIndexOf('.')
|
||||
return dot >= 0 ? filename.slice(dot) : ''
|
||||
}
|
||||
|
||||
const subtitleExtensions = new Set(['.srt', '.ass', '.ssa', '.sup'])
|
||||
const audioExtensions = new Set([
|
||||
'.aac',
|
||||
'.ac3',
|
||||
'.amr',
|
||||
'.caf',
|
||||
'.cda',
|
||||
'.dsf',
|
||||
'.dff',
|
||||
'.kar',
|
||||
'.m4a',
|
||||
'.mp1',
|
||||
'.mp2',
|
||||
'.mp3',
|
||||
'.mid',
|
||||
'.mod',
|
||||
'.mka',
|
||||
'.mpc',
|
||||
'.nsf',
|
||||
'.ogg',
|
||||
'.pcm',
|
||||
'.rmi',
|
||||
'.s3m',
|
||||
'.snd',
|
||||
'.spx',
|
||||
'.tak',
|
||||
'.tta',
|
||||
'.vqf',
|
||||
'.wav',
|
||||
'.wma',
|
||||
'.aifc',
|
||||
'.aiff',
|
||||
'.alac',
|
||||
'.adif',
|
||||
'.adts',
|
||||
'.ape',
|
||||
'.flac',
|
||||
'.midi',
|
||||
'.opus',
|
||||
'.sfalc',
|
||||
])
|
||||
|
||||
// 获取存储展示名称,配置缺失时回退到原始存储标识。
|
||||
function getHistoryStorageName(storage?: string) {
|
||||
if (!storage) return t('common.unknown')
|
||||
@@ -1849,7 +1908,7 @@ onUnmounted(() => {
|
||||
<span v-if="item.type === '电视剧'" class="d-block text-high-emphasis min-w-20">
|
||||
{{ item?.seasons }}{{ item?.episodes }}
|
||||
</span>
|
||||
<small>{{ item?.category }}</small>
|
||||
<small>{{ getHistoryCategory(item) }}</small>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -1955,7 +2014,7 @@ onUnmounted(() => {
|
||||
<span v-else class="d-block text-high-emphasis min-w-20">
|
||||
{{ item?.title }}
|
||||
</span>
|
||||
<small>{{ item?.category }}</small>
|
||||
<small>{{ getHistoryCategory(item) }}</small>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -963,6 +963,41 @@ describe('TransferHistoryView', () => {
|
||||
expect(await screen.findByText('华语流行 / 2003 / FLAC · 24-bit · 96 kHz · 2,304 kbps')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('shows subtitle and attached audio as distinct history categories', async () => {
|
||||
mocks.desktop = false
|
||||
const histories = [
|
||||
createHistory(1, '字幕文件', {
|
||||
category: '电影',
|
||||
image: '/subtitle-poster.jpg',
|
||||
src: '/downloads/电影.zh.srt',
|
||||
src_fileitem: { extension: 'srt', size: 100 } as TransferHistory['src_fileitem'],
|
||||
}),
|
||||
createHistory(2, '音频文件', {
|
||||
category: '电影',
|
||||
image: '/audio-poster.jpg',
|
||||
src: '/downloads/电影.commentary.mka',
|
||||
src_fileitem: { extension: 'mka', size: 200 } as TransferHistory['src_fileitem'],
|
||||
}),
|
||||
createHistory(3, '正常媒体', {
|
||||
category: '动作',
|
||||
image: '/movie-poster.jpg',
|
||||
src: '/downloads/电影.mkv',
|
||||
src_fileitem: { extension: 'mkv', size: 300 } as TransferHistory['src_fileitem'],
|
||||
}),
|
||||
]
|
||||
mocks.apiGet.mockImplementation((path: string) => {
|
||||
if (path === 'storage/options') return Promise.resolve(storageResponse())
|
||||
return Promise.resolve(historyResponse(histories))
|
||||
})
|
||||
|
||||
await renderHistory()
|
||||
await fireEvent.click(screen.getByRole('button', { name: '加载下一页' }))
|
||||
|
||||
expect(await screen.findByText('字幕')).toBeInTheDocument()
|
||||
expect(screen.getByText('音频')).toBeInTheDocument()
|
||||
expect(screen.getByText('动作')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('prevents a mobile request invalidated by a route reset from appending stale records', async () => {
|
||||
mocks.desktop = false
|
||||
const oldRequest = createDeferred<ReturnType<typeof historyResponse>>()
|
||||
|
||||
Reference in New Issue
Block a user