feat(library): add per-row "Download new" for watched sources
Queuing a watched channel's not-yet-downloaded videos previously meant expanding the source and using its "Download N pending" button. Watched source rows now carry a one-click "Download new" that loads the source's items (even while collapsed) and queues everything not already downloaded or in the queue, using the source's resolved kind/profile. Extracts the shared, tested selectUndownloaded selector (also now backs the expanded panel's pending list) and adds ensureSourceItems to load a collapsed source's items without expanding it.
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import { selectUndownloaded } from '../src/renderer/src/store/librarySelect'
|
||||
import type { MediaItem } from '../src/shared/ipc'
|
||||
|
||||
const item = (over: Partial<MediaItem> & { videoId: string }): MediaItem => ({
|
||||
id: `src:${over.videoId}`,
|
||||
sourceId: 'src',
|
||||
title: over.videoId,
|
||||
url: `https://youtube.com/watch?v=${over.videoId}`,
|
||||
playlistTitle: 'Uploads',
|
||||
playlistIndex: 1,
|
||||
downloaded: false,
|
||||
...over
|
||||
})
|
||||
|
||||
describe('selectUndownloaded', () => {
|
||||
it('keeps items that are neither downloaded nor already queued', () => {
|
||||
const items = [item({ videoId: 'a' }), item({ videoId: 'b' })]
|
||||
const result = selectUndownloaded(items, new Set())
|
||||
expect(result.map((i) => i.videoId)).toEqual(['a', 'b'])
|
||||
})
|
||||
|
||||
it('excludes already-downloaded items', () => {
|
||||
const items = [item({ videoId: 'a', downloaded: true }), item({ videoId: 'b' })]
|
||||
expect(selectUndownloaded(items, new Set()).map((i) => i.videoId)).toEqual(['b'])
|
||||
})
|
||||
|
||||
it('excludes items whose URL already has a queue entry (any status)', () => {
|
||||
const queued = item({ videoId: 'a' })
|
||||
const fresh = item({ videoId: 'b' })
|
||||
const result = selectUndownloaded([queued, fresh], new Set([queued.url]))
|
||||
expect(result.map((i) => i.videoId)).toEqual(['b'])
|
||||
})
|
||||
|
||||
it('returns an empty array when nothing is queueable', () => {
|
||||
const items = [item({ videoId: 'a', downloaded: true })]
|
||||
expect(selectUndownloaded(items, new Set())).toEqual([])
|
||||
})
|
||||
|
||||
it('returns an empty array for no items', () => {
|
||||
expect(selectUndownloaded([], new Set())).toEqual([])
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user