46 lines
1.4 KiB
TypeScript
46 lines
1.4 KiB
TypeScript
import type { PlaylistMetadata, SelectableVideoMetadata, VideoMetadata } from '../types/media'
|
|
|
|
export function detectMixUrl(url: string): boolean {
|
|
return url.includes('v=') && url.includes('list=')
|
|
}
|
|
|
|
export function stripPlaylistContext(rawUrl: string): string {
|
|
try {
|
|
const url = new URL(rawUrl)
|
|
url.searchParams.delete('list')
|
|
url.searchParams.delete('index')
|
|
url.searchParams.delete('start_radio')
|
|
return url.toString()
|
|
} catch {
|
|
return rawUrl
|
|
.replace(/[?&]list=[^&]+/g, '')
|
|
.replace(/[?&]index=[^&]+/g, '')
|
|
.replace(/[?&]start_radio=[^&]+/g, '')
|
|
.replace('?&', '?')
|
|
.replace(/&&+/g, '&')
|
|
.replace(/[?&]$/, '')
|
|
}
|
|
}
|
|
|
|
export function isLikelyHttpUrl(input: string): boolean {
|
|
return input.startsWith('http://') || input.startsWith('https://')
|
|
}
|
|
|
|
export function normalizeBatchLinks(input: string): string[] {
|
|
return input
|
|
.split('\n')
|
|
.map(line => line.trim())
|
|
.filter(Boolean)
|
|
.filter(isLikelyHttpUrl)
|
|
.filter(link => !link.includes('list=') || detectMixUrl(link))
|
|
.map(link => detectMixUrl(link) ? stripPlaylistContext(link) : link)
|
|
}
|
|
|
|
export function toSelectableEntries(entries: VideoMetadata[]): SelectableVideoMetadata[] {
|
|
return entries.map(entry => ({ ...entry, selected: true }))
|
|
}
|
|
|
|
export function countSelectedEntries(metadata: PlaylistMetadata | null): number {
|
|
return metadata?.entries.filter(entry => entry.selected).length ?? 0
|
|
}
|