mirror of
https://github.com/yattee/yattee.git
synced 2024-12-22 21:43:41 +00:00
Adding/removing videos to/from playlists
This commit is contained in:
parent
31bd2f7fe6
commit
f397b13720
97
Apple TV/AddToPlaylistView.swift
Normal file
97
Apple TV/AddToPlaylistView.swift
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
import Defaults
|
||||||
|
import Siesta
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct AddToPlaylistView: View {
|
||||||
|
@ObservedObject private var store = Store<[Playlist]>()
|
||||||
|
|
||||||
|
@State private var selectedPlaylist: Playlist?
|
||||||
|
|
||||||
|
@Default(.videoIDToAddToPlaylist) private var videoID
|
||||||
|
|
||||||
|
@Environment(\.dismiss) private var dismiss
|
||||||
|
|
||||||
|
var resource: Resource {
|
||||||
|
InvidiousAPI.shared.playlists
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
|
resource.addObserver(store)
|
||||||
|
}
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
HStack {
|
||||||
|
Spacer()
|
||||||
|
|
||||||
|
VStack {
|
||||||
|
Spacer()
|
||||||
|
|
||||||
|
if !resource.isLoading && store.collection.isEmpty {
|
||||||
|
CoverSectionView("You have no Playlists", inline: true) {
|
||||||
|
Text("Open \"Playlists\" tab to create new one")
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
.multilineTextAlignment(.center)
|
||||||
|
}
|
||||||
|
Button("Go back") {
|
||||||
|
dismiss()
|
||||||
|
}
|
||||||
|
.padding()
|
||||||
|
} else if !store.collection.isEmpty {
|
||||||
|
CoverSectionView("Add to Playlist", inline: true) { selectPlaylistButton }
|
||||||
|
|
||||||
|
CoverSectionRowView {
|
||||||
|
Button("Add", action: addToPlaylist)
|
||||||
|
.disabled(currentPlaylist == nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
.frame(maxWidth: 1200)
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
.background(.thinMaterial)
|
||||||
|
.onAppear {
|
||||||
|
resource.loadIfNeeded()?.onSuccess { _ in
|
||||||
|
selectedPlaylist = store.collection.first
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var selectPlaylistButton: some View {
|
||||||
|
Button(currentPlaylist?.title ?? "Select playlist") {
|
||||||
|
guard currentPlaylist != nil else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
self.selectedPlaylist = store.collection.next(after: currentPlaylist!)
|
||||||
|
}
|
||||||
|
.contextMenu {
|
||||||
|
ForEach(store.collection) { playlist in
|
||||||
|
Button(playlist.title) {
|
||||||
|
self.selectedPlaylist = playlist
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var currentPlaylist: Playlist? {
|
||||||
|
selectedPlaylist ?? store.collection.first
|
||||||
|
}
|
||||||
|
|
||||||
|
func addToPlaylist() {
|
||||||
|
guard currentPlaylist != nil else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let resource = InvidiousAPI.shared.playlistVideos(currentPlaylist!.id)
|
||||||
|
let body = ["videoId": videoID]
|
||||||
|
|
||||||
|
resource.request(.post, json: body).onSuccess { _ in
|
||||||
|
Defaults.reset(.videoIDToAddToPlaylist)
|
||||||
|
InvidiousAPI.shared.playlists.load()
|
||||||
|
dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -6,7 +6,6 @@ struct PlaylistsView: View {
|
|||||||
@ObservedObject private var store = Store<[Playlist]>()
|
@ObservedObject private var store = Store<[Playlist]>()
|
||||||
|
|
||||||
@Default(.selectedPlaylistID) private var selectedPlaylistID
|
@Default(.selectedPlaylistID) private var selectedPlaylistID
|
||||||
@State private var selectedPlaylist: Playlist?
|
|
||||||
|
|
||||||
@State private var showingNewPlaylist = false
|
@State private var showingNewPlaylist = false
|
||||||
@State private var createdPlaylist: Playlist?
|
@State private var createdPlaylist: Playlist?
|
||||||
@ -26,18 +25,37 @@ struct PlaylistsView: View {
|
|||||||
Section {
|
Section {
|
||||||
VStack(alignment: .center, spacing: 2) {
|
VStack(alignment: .center, spacing: 2) {
|
||||||
HStack {
|
HStack {
|
||||||
selectPlaylistButton
|
if store.collection.isEmpty {
|
||||||
|
Text("No Playlists")
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
} else {
|
||||||
|
Text("Current Playlist")
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
|
||||||
|
selectPlaylistButton
|
||||||
|
}
|
||||||
|
|
||||||
if currentPlaylist != nil {
|
if currentPlaylist != nil {
|
||||||
editPlaylistButton
|
editPlaylistButton
|
||||||
}
|
}
|
||||||
|
|
||||||
newPlaylistButton
|
newPlaylistButton
|
||||||
|
.padding(.leading, 40)
|
||||||
}
|
}
|
||||||
.scaleEffect(0.85)
|
.scaleEffect(0.85)
|
||||||
|
|
||||||
if currentPlaylist != nil {
|
if currentPlaylist != nil {
|
||||||
VideosView(videos: currentPlaylist!.videos)
|
if currentPlaylist!.videos.isEmpty {
|
||||||
|
Spacer()
|
||||||
|
|
||||||
|
Text("Playlist is empty\n\nTap and hold on a video and then tap \"Add to Playlist\"")
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
.multilineTextAlignment(.center)
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
} else {
|
||||||
|
VideosView(videos: currentPlaylist!.videos)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Spacer()
|
Spacer()
|
||||||
}
|
}
|
||||||
@ -57,7 +75,6 @@ struct PlaylistsView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func selectPlaylist(_ id: String?) {
|
func selectPlaylist(_ id: String?) {
|
||||||
selectedPlaylist = store.collection.first { $0.id == id }
|
|
||||||
selectedPlaylistID = id
|
selectedPlaylistID = id
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,7 +103,7 @@ struct PlaylistsView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var currentPlaylist: Playlist? {
|
var currentPlaylist: Playlist? {
|
||||||
selectedPlaylist ?? store.collection.first
|
store.collection.first { $0.id == selectedPlaylistID } ?? store.collection.first
|
||||||
}
|
}
|
||||||
|
|
||||||
var selectPlaylistButton: some View {
|
var selectPlaylistButton: some View {
|
||||||
@ -111,13 +128,19 @@ struct PlaylistsView: View {
|
|||||||
self.editedPlaylist = self.currentPlaylist
|
self.editedPlaylist = self.currentPlaylist
|
||||||
self.showingEditPlaylist = true
|
self.showingEditPlaylist = true
|
||||||
}) {
|
}) {
|
||||||
Image(systemName: "pencil")
|
HStack(spacing: 8) {
|
||||||
|
Image(systemName: "pencil")
|
||||||
|
Text("Edit")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var newPlaylistButton: some View {
|
var newPlaylistButton: some View {
|
||||||
Button(action: { self.showingNewPlaylist = true }) {
|
Button(action: { self.showingNewPlaylist = true }) {
|
||||||
Image(systemName: "plus")
|
HStack(spacing: 8) {
|
||||||
|
Image(systemName: "plus")
|
||||||
|
Text("New Playlist")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,14 @@ struct TrendingView: View {
|
|||||||
Section {
|
Section {
|
||||||
VStack(alignment: .center, spacing: 2) {
|
VStack(alignment: .center, spacing: 2) {
|
||||||
HStack {
|
HStack {
|
||||||
|
Text("Category")
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
|
||||||
categoryButton
|
categoryButton
|
||||||
|
|
||||||
|
Text("Country")
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
|
||||||
countryFlag
|
countryFlag
|
||||||
countryButton
|
countryButton
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,9 @@ struct VideoContextMenuView: View {
|
|||||||
@Default(.openVideoID) var openVideoID
|
@Default(.openVideoID) var openVideoID
|
||||||
@Default(.showingVideoDetails) var showDetails
|
@Default(.showingVideoDetails) var showDetails
|
||||||
|
|
||||||
|
@Default(.showingAddToPlaylist) var showingAddToPlaylist
|
||||||
|
@Default(.videoIDToAddToPlaylist) var videoIDToAddToPlaylist
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
if tabSelection == .channel {
|
if tabSelection == .channel {
|
||||||
closeChannelButton(from: video)
|
closeChannelButton(from: video)
|
||||||
@ -16,9 +19,12 @@ struct VideoContextMenuView: View {
|
|||||||
openChannelButton(from: video)
|
openChannelButton(from: video)
|
||||||
}
|
}
|
||||||
|
|
||||||
Button("Open video details") {
|
openVideoDetailsButton
|
||||||
openVideoID = video.id
|
|
||||||
showDetails = true
|
if tabSelection == .playlists {
|
||||||
|
removeFromPlaylistButton
|
||||||
|
} else {
|
||||||
|
addToPlaylistButton
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,4 +40,27 @@ struct VideoContextMenuView: View {
|
|||||||
Defaults.reset(.openChannel)
|
Defaults.reset(.openChannel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var openVideoDetailsButton: some View {
|
||||||
|
Button("Open video details") {
|
||||||
|
openVideoID = video.id
|
||||||
|
showDetails = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var addToPlaylistButton: some View {
|
||||||
|
Button("Add to playlist...") {
|
||||||
|
videoIDToAddToPlaylist = video.id
|
||||||
|
showingAddToPlaylist = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var removeFromPlaylistButton: some View {
|
||||||
|
Button("Remove from playlist", role: .destructive) {
|
||||||
|
let resource = InvidiousAPI.shared.playlistVideo(Defaults[.selectedPlaylistID]!, video.indexID!)
|
||||||
|
resource.request(.delete).onSuccess { _ in
|
||||||
|
InvidiousAPI.shared.playlists.load()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ struct VideoDetailsView: View {
|
|||||||
|
|
||||||
HStack {
|
HStack {
|
||||||
NavigationLink(destination: PlayerView(id: video.id)) {
|
NavigationLink(destination: PlayerView(id: video.id)) {
|
||||||
HStack(spacing: 10) {
|
HStack(spacing: 8) {
|
||||||
Image(systemName: "play.rectangle.fill")
|
Image(systemName: "play.rectangle.fill")
|
||||||
|
|
||||||
Text("Play")
|
Text("Play")
|
||||||
|
@ -7,15 +7,20 @@ struct VideosView: View {
|
|||||||
@Default(.layout) var layout
|
@Default(.layout) var layout
|
||||||
@Default(.tabSelection) var tabSelection
|
@Default(.tabSelection) var tabSelection
|
||||||
|
|
||||||
|
@Default(.showingAddToPlaylist) var showingAddToPlaylist
|
||||||
|
|
||||||
var videos: [Video]
|
var videos: [Video]
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
Group {
|
VStack {
|
||||||
if layout == .cells {
|
if layout == .cells {
|
||||||
VideosCellsView(videos: videos, columns: self.profile.cellsColumns)
|
VideosCellsView(videos: videos, columns: self.profile.cellsColumns)
|
||||||
} else {
|
} else {
|
||||||
VideosListView(videos: videos)
|
VideosListView(videos: videos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.fullScreenCover(isPresented: $showingAddToPlaylist) {
|
||||||
|
AddToPlaylistView()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -112,6 +112,14 @@ final class InvidiousAPI: Service {
|
|||||||
resource("/auth/playlists/\(id)")
|
resource("/auth/playlists/\(id)")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func playlistVideos(_ id: String) -> Resource {
|
||||||
|
playlist(id).child("videos")
|
||||||
|
}
|
||||||
|
|
||||||
|
func playlistVideo(_ playlistID: String, _ videoID: String) -> Resource {
|
||||||
|
playlist(playlistID).child("videos").child(videoID)
|
||||||
|
}
|
||||||
|
|
||||||
func search(_ query: SearchQuery) -> Resource {
|
func search(_ query: SearchQuery) -> Resource {
|
||||||
var resource = resource("/search")
|
var resource = resource("/search")
|
||||||
.withParam("q", searchQuery(query.query))
|
.withParam("q", searchQuery(query.query))
|
||||||
|
@ -6,17 +6,20 @@ struct Playlist: Identifiable, Equatable, Hashable {
|
|||||||
var title: String
|
var title: String
|
||||||
var visibility: PlaylistVisibility
|
var visibility: PlaylistVisibility
|
||||||
|
|
||||||
|
var updated: TimeInterval
|
||||||
|
|
||||||
var videos = [Video]()
|
var videos = [Video]()
|
||||||
|
|
||||||
init(_ json: JSON) {
|
init(_ json: JSON) {
|
||||||
id = json["playlistId"].stringValue
|
id = json["playlistId"].stringValue
|
||||||
title = json["title"].stringValue
|
title = json["title"].stringValue
|
||||||
visibility = json["isListed"].boolValue ? .public : .private
|
visibility = json["isListed"].boolValue ? .public : .private
|
||||||
|
updated = json["updated"].doubleValue
|
||||||
videos = json["videos"].arrayValue.map { Video($0) }
|
videos = json["videos"].arrayValue.map { Video($0) }
|
||||||
}
|
}
|
||||||
|
|
||||||
static func == (lhs: Playlist, rhs: Playlist) -> Bool {
|
static func == (lhs: Playlist, rhs: Playlist) -> Bool {
|
||||||
lhs.id == rhs.id && lhs.title == rhs.title && lhs.visibility == rhs.visibility
|
lhs.id == rhs.id && lhs.updated == rhs.updated
|
||||||
}
|
}
|
||||||
|
|
||||||
func hash(into hasher: inout Hasher) {
|
func hash(into hasher: inout Hasher) {
|
||||||
|
8
Model/PlaylistVideo.swift
Normal file
8
Model/PlaylistVideo.swift
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
//
|
||||||
|
// PlaylistVideo.swift
|
||||||
|
// Pearvidious
|
||||||
|
//
|
||||||
|
// Created by Arkadiusz Fal on 09/07/2021.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
@ -15,10 +15,21 @@ struct Video: Identifiable {
|
|||||||
var description: String
|
var description: String
|
||||||
var genre: String
|
var genre: String
|
||||||
|
|
||||||
|
let indexID: String?
|
||||||
|
|
||||||
var streams = [Stream]()
|
var streams = [Stream]()
|
||||||
|
|
||||||
init(_ json: JSON) {
|
init(_ json: JSON) {
|
||||||
id = json["videoId"].stringValue
|
let videoID = json["videoId"].stringValue
|
||||||
|
|
||||||
|
if let id = json["indexId"].string {
|
||||||
|
indexID = id
|
||||||
|
self.id = videoID + id
|
||||||
|
} else {
|
||||||
|
indexID = nil
|
||||||
|
id = videoID
|
||||||
|
}
|
||||||
|
|
||||||
title = json["title"].stringValue
|
title = json["title"].stringValue
|
||||||
author = json["author"].stringValue
|
author = json["author"].stringValue
|
||||||
length = json["lengthSeconds"].doubleValue
|
length = json["lengthSeconds"].doubleValue
|
||||||
|
@ -60,6 +60,9 @@
|
|||||||
373CFAEB26975CBF003CB2C6 /* PlaylistFormView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 373CFAEA26975CBF003CB2C6 /* PlaylistFormView.swift */; };
|
373CFAEB26975CBF003CB2C6 /* PlaylistFormView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 373CFAEA26975CBF003CB2C6 /* PlaylistFormView.swift */; };
|
||||||
373CFAEC26975CBF003CB2C6 /* PlaylistFormView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 373CFAEA26975CBF003CB2C6 /* PlaylistFormView.swift */; };
|
373CFAEC26975CBF003CB2C6 /* PlaylistFormView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 373CFAEA26975CBF003CB2C6 /* PlaylistFormView.swift */; };
|
||||||
373CFAED26975CBF003CB2C6 /* PlaylistFormView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 373CFAEA26975CBF003CB2C6 /* PlaylistFormView.swift */; };
|
373CFAED26975CBF003CB2C6 /* PlaylistFormView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 373CFAEA26975CBF003CB2C6 /* PlaylistFormView.swift */; };
|
||||||
|
373CFAEF2697A78B003CB2C6 /* AddToPlaylistView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 373CFAEE2697A78B003CB2C6 /* AddToPlaylistView.swift */; };
|
||||||
|
373CFAF02697A78B003CB2C6 /* AddToPlaylistView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 373CFAEE2697A78B003CB2C6 /* AddToPlaylistView.swift */; };
|
||||||
|
373CFAF12697A78B003CB2C6 /* AddToPlaylistView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 373CFAEE2697A78B003CB2C6 /* AddToPlaylistView.swift */; };
|
||||||
3741B5302676213400125C5E /* PlayerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3741B52F2676213400125C5E /* PlayerViewController.swift */; };
|
3741B5302676213400125C5E /* PlayerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3741B52F2676213400125C5E /* PlayerViewController.swift */; };
|
||||||
376578852685429C00D4EA09 /* CaseIterable+Next.swift in Sources */ = {isa = PBXBuildFile; fileRef = 376578842685429C00D4EA09 /* CaseIterable+Next.swift */; };
|
376578852685429C00D4EA09 /* CaseIterable+Next.swift in Sources */ = {isa = PBXBuildFile; fileRef = 376578842685429C00D4EA09 /* CaseIterable+Next.swift */; };
|
||||||
376578862685429C00D4EA09 /* CaseIterable+Next.swift in Sources */ = {isa = PBXBuildFile; fileRef = 376578842685429C00D4EA09 /* CaseIterable+Next.swift */; };
|
376578862685429C00D4EA09 /* CaseIterable+Next.swift in Sources */ = {isa = PBXBuildFile; fileRef = 376578842685429C00D4EA09 /* CaseIterable+Next.swift */; };
|
||||||
@ -231,6 +234,7 @@
|
|||||||
373CFADA269663F1003CB2C6 /* Thumbnail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Thumbnail.swift; sourceTree = "<group>"; };
|
373CFADA269663F1003CB2C6 /* Thumbnail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Thumbnail.swift; sourceTree = "<group>"; };
|
||||||
373CFAE226974812003CB2C6 /* PlaylistVisibility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaylistVisibility.swift; sourceTree = "<group>"; };
|
373CFAE226974812003CB2C6 /* PlaylistVisibility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaylistVisibility.swift; sourceTree = "<group>"; };
|
||||||
373CFAEA26975CBF003CB2C6 /* PlaylistFormView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaylistFormView.swift; sourceTree = "<group>"; };
|
373CFAEA26975CBF003CB2C6 /* PlaylistFormView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaylistFormView.swift; sourceTree = "<group>"; };
|
||||||
|
373CFAEE2697A78B003CB2C6 /* AddToPlaylistView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddToPlaylistView.swift; sourceTree = "<group>"; };
|
||||||
3741B52F2676213400125C5E /* PlayerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerViewController.swift; sourceTree = "<group>"; };
|
3741B52F2676213400125C5E /* PlayerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerViewController.swift; sourceTree = "<group>"; };
|
||||||
376578842685429C00D4EA09 /* CaseIterable+Next.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CaseIterable+Next.swift"; sourceTree = "<group>"; };
|
376578842685429C00D4EA09 /* CaseIterable+Next.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CaseIterable+Next.swift"; sourceTree = "<group>"; };
|
||||||
376578882685471400D4EA09 /* Playlist.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Playlist.swift; sourceTree = "<group>"; };
|
376578882685471400D4EA09 /* Playlist.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Playlist.swift; sourceTree = "<group>"; };
|
||||||
@ -420,6 +424,7 @@
|
|||||||
37D4B159267164AE00C925CA /* Apple TV */ = {
|
37D4B159267164AE00C925CA /* Apple TV */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
373CFAEE2697A78B003CB2C6 /* AddToPlaylistView.swift */,
|
||||||
37AAF2892673AB89007FC770 /* ChannelView.swift */,
|
37AAF2892673AB89007FC770 /* ChannelView.swift */,
|
||||||
373CFAC126966159003CB2C6 /* CoverSectionRowView.swift */,
|
373CFAC126966159003CB2C6 /* CoverSectionRowView.swift */,
|
||||||
373CFABD26966115003CB2C6 /* CoverSectionView.swift */,
|
373CFABD26966115003CB2C6 /* CoverSectionView.swift */,
|
||||||
@ -442,8 +447,8 @@
|
|||||||
37F4AE7126828F0900BD60EA /* VideosCellsView.swift */,
|
37F4AE7126828F0900BD60EA /* VideosCellsView.swift */,
|
||||||
37AAF29926740A01007FC770 /* VideosListView.swift */,
|
37AAF29926740A01007FC770 /* VideosListView.swift */,
|
||||||
371231832683E62F0000B307 /* VideosView.swift */,
|
371231832683E62F0000B307 /* VideosView.swift */,
|
||||||
37D4B15E267164AF00C925CA /* Assets.xcassets */,
|
|
||||||
37D4B1AE26729DEB00C925CA /* Info.plist */,
|
37D4B1AE26729DEB00C925CA /* Info.plist */,
|
||||||
|
37D4B15E267164AF00C925CA /* Assets.xcassets */,
|
||||||
);
|
);
|
||||||
path = "Apple TV";
|
path = "Apple TV";
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -757,6 +762,7 @@
|
|||||||
37C7A1DC267CE9D90010EAD6 /* Profile.swift in Sources */,
|
37C7A1DC267CE9D90010EAD6 /* Profile.swift in Sources */,
|
||||||
373CFAC026966149003CB2C6 /* CoverSectionView.swift in Sources */,
|
373CFAC026966149003CB2C6 /* CoverSectionView.swift in Sources */,
|
||||||
3714166F267A8ACC006CA35D /* TrendingView.swift in Sources */,
|
3714166F267A8ACC006CA35D /* TrendingView.swift in Sources */,
|
||||||
|
373CFAEF2697A78B003CB2C6 /* AddToPlaylistView.swift in Sources */,
|
||||||
377FC7E3267A084A00A6BBAF /* VideoListRowView.swift in Sources */,
|
377FC7E3267A084A00A6BBAF /* VideoListRowView.swift in Sources */,
|
||||||
37AAF29026740715007FC770 /* Channel.swift in Sources */,
|
37AAF29026740715007FC770 /* Channel.swift in Sources */,
|
||||||
37AAF2942674086B007FC770 /* TabSelection.swift in Sources */,
|
37AAF2942674086B007FC770 /* TabSelection.swift in Sources */,
|
||||||
@ -843,6 +849,7 @@
|
|||||||
37B17DA1268A1F89006AEE9B /* VideoContextMenuView.swift in Sources */,
|
37B17DA1268A1F89006AEE9B /* VideoContextMenuView.swift in Sources */,
|
||||||
373CFAD4269662AB003CB2C6 /* SearchDate.swift in Sources */,
|
373CFAD4269662AB003CB2C6 /* SearchDate.swift in Sources */,
|
||||||
373CFADC269663F1003CB2C6 /* Thumbnail.swift in Sources */,
|
373CFADC269663F1003CB2C6 /* Thumbnail.swift in Sources */,
|
||||||
|
373CFAF02697A78B003CB2C6 /* AddToPlaylistView.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@ -890,6 +897,7 @@
|
|||||||
3741B5302676213400125C5E /* PlayerViewController.swift in Sources */,
|
3741B5302676213400125C5E /* PlayerViewController.swift in Sources */,
|
||||||
373CFABE26966148003CB2C6 /* CoverSectionView.swift in Sources */,
|
373CFABE26966148003CB2C6 /* CoverSectionView.swift in Sources */,
|
||||||
37B767DD2677C3CA0098BAA8 /* PlayerState.swift in Sources */,
|
37B767DD2677C3CA0098BAA8 /* PlayerState.swift in Sources */,
|
||||||
|
373CFAF12697A78B003CB2C6 /* AddToPlaylistView.swift in Sources */,
|
||||||
37D4B18E26717B3800C925CA /* VideoListRowView.swift in Sources */,
|
37D4B18E26717B3800C925CA /* VideoListRowView.swift in Sources */,
|
||||||
37AAF27E26737323007FC770 /* PopularVideosView.swift in Sources */,
|
37AAF27E26737323007FC770 /* PopularVideosView.swift in Sources */,
|
||||||
37AAF29A26740A01007FC770 /* VideosListView.swift in Sources */,
|
37AAF29A26740A01007FC770 /* VideosListView.swift in Sources */,
|
||||||
|
@ -7,10 +7,12 @@ extension Defaults.Keys {
|
|||||||
static let openChannel = Key<Channel?>("openChannel")
|
static let openChannel = Key<Channel?>("openChannel")
|
||||||
|
|
||||||
static let searchSortOrder = Key<SearchSortOrder>("searchSortOrder", default: .relevance)
|
static let searchSortOrder = Key<SearchSortOrder>("searchSortOrder", default: .relevance)
|
||||||
static let searchDate = Key<SearchDate?>("searchDate", default: nil)
|
static let searchDate = Key<SearchDate?>("searchDate")
|
||||||
static let searchDuration = Key<SearchDuration?>("searchDuration", default: nil)
|
static let searchDuration = Key<SearchDuration?>("searchDuration")
|
||||||
static let openVideoID = Key<String>("videoID", default: "")
|
static let openVideoID = Key<String>("videoID", default: "")
|
||||||
static let showingVideoDetails = Key<Bool>("showingVideoDetails", default: false)
|
static let showingVideoDetails = Key<Bool>("showingVideoDetails", default: false)
|
||||||
|
|
||||||
static let selectedPlaylistID = Key<String?>("selectedPlaylistID")
|
static let selectedPlaylistID = Key<String?>("selectedPlaylistID")
|
||||||
|
static let showingAddToPlaylist = Key<Bool>("showingAddToPlaylist", default: false)
|
||||||
|
static let videoIDToAddToPlaylist = Key<String?>("videoIDToAddToPlaylist")
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user