Files
yattee/Yattee/Models/Player/QueueSource.swift
2026-02-08 18:33:56 +01:00

89 lines
3.0 KiB
Swift

//
// QueueSource.swift
// Yattee
//
// Tracks the origin of queued videos for continuation loading.
//
import Foundation
/// Tracks the origin of queued videos for continuation loading.
enum QueueSource: Codable, Equatable, Hashable, Sendable {
/// Videos from a channel's video list.
case channel(channelID: String, source: ContentSource, continuation: String?)
/// Videos from a playlist.
case playlist(playlistID: String, continuation: String?)
/// Videos from search results.
case search(query: String, continuation: String?)
/// Videos from subscriptions feed.
case subscriptions(continuation: String?)
/// Manually added individual videos (no continuation).
case manual
/// Videos from a media browser folder (WebDAV/SMB/local folder).
/// Folder contents are loaded upfront, so no continuation is needed.
case mediaBrowser(sourceID: UUID, folderPath: String)
/// Whether this source supports loading more items.
var supportsContinuation: Bool {
switch self {
case .channel(_, _, let continuation),
.playlist(_, let continuation),
.search(_, let continuation),
.subscriptions(let continuation):
return continuation != nil
case .manual, .mediaBrowser:
return false
}
}
/// The continuation token, if available.
var continuation: String? {
switch self {
case .channel(_, _, let continuation),
.playlist(_, let continuation),
.search(_, let continuation),
.subscriptions(let continuation):
return continuation
case .manual, .mediaBrowser:
return nil
}
}
/// Returns a new QueueSource with an updated continuation token.
func withContinuation(_ newContinuation: String?) -> QueueSource {
switch self {
case .channel(let channelID, let source, _):
return .channel(channelID: channelID, source: source, continuation: newContinuation)
case .playlist(let playlistID, _):
return .playlist(playlistID: playlistID, continuation: newContinuation)
case .search(let query, _):
return .search(query: query, continuation: newContinuation)
case .subscriptions:
return .subscriptions(continuation: newContinuation)
case .manual:
return .manual
case .mediaBrowser:
return self // No continuation for media browser
}
}
/// The content source for this queue source, used for instance selection.
/// Returns nil for sources that don't use API-based continuation (manual, mediaBrowser).
var contentSource: ContentSource? {
switch self {
case .channel(_, let source, _):
return source
case .playlist, .search, .subscriptions:
// Playlists, search, and subscriptions are YouTube content
return .global(provider: ContentSource.youtubeProvider)
case .manual, .mediaBrowser:
return nil
}
}
}