From 15bfaf7497930e965038d8908f2a7ed61dfdd141 Mon Sep 17 00:00:00 2001 From: Arkadiusz Fal Date: Sat, 26 Jun 2021 13:37:24 +0200 Subject: [PATCH] Simple view display switching --- Apple TV/PlayerViewController.swift | 4 +--- Apple TV/PlaylistsView.swift | 9 ++++++-- Apple TV/PopularVideosView.swift | 5 ----- Apple TV/SearchView.swift | 2 ++ Apple TV/SubscriptionsView.swift | 16 ++++++-------- Apple TV/VideosView.swift | 12 ++++++---- Apple TV/ViewOptionsView.swift | 32 +++++++++++++++++++++++++++ Model/AppState.swift | 2 -- Model/PlayerState.swift | 2 +- Model/Profile.swift | 12 +++++----- Pearvidious.xcodeproj/project.pbxproj | 8 +++++++ Shared/ContentView.swift | 2 ++ 12 files changed, 74 insertions(+), 32 deletions(-) create mode 100644 Apple TV/ViewOptionsView.swift diff --git a/Apple TV/PlayerViewController.swift b/Apple TV/PlayerViewController.swift index cb453c9a..2fa374e4 100644 --- a/Apple TV/PlayerViewController.swift +++ b/Apple TV/PlayerViewController.swift @@ -8,15 +8,13 @@ struct PlayerViewController: UIViewControllerRepresentable { @ObservedObject private var state: PlayerState - @ObservedObject private var profile = Profile() - var video: Video init(video: Video) { self.video = video state = PlayerState(video) - loadStream(video.defaultStreamForProfile(profile), loadBest: profile.defaultStreamResolution == .hd720pFirstThenBest) + loadStream(video.defaultStreamForProfile(state.profile), loadBest: state.profile.defaultStreamResolution == .hd720pFirstThenBest) } fileprivate func loadStream(_ stream: Stream?, loadBest: Bool = false) { diff --git a/Apple TV/PlaylistsView.swift b/Apple TV/PlaylistsView.swift index 22e09a32..d46ccdb1 100644 --- a/Apple TV/PlaylistsView.swift +++ b/Apple TV/PlaylistsView.swift @@ -64,8 +64,13 @@ struct PlaylistsView: View { extension Array where Element: Equatable { func next(after element: Element) -> Element? { - let idx = firstIndex(of: element)! - let next = index(after: idx) + let idx = firstIndex(of: element) + + if idx == nil { + return first + } + + let next = index(after: idx!) return self[next == endIndex ? startIndex : next] } diff --git a/Apple TV/PopularVideosView.swift b/Apple TV/PopularVideosView.swift index 9f579d28..cffda949 100644 --- a/Apple TV/PopularVideosView.swift +++ b/Apple TV/PopularVideosView.swift @@ -7,11 +7,6 @@ struct PopularVideosView: View { var body: some View { VideosView(tabSelection: $tabSelection, videos: videos) - .task { - Task { - provider.load() - } - } } var videos: [Video] { diff --git a/Apple TV/SearchView.swift b/Apple TV/SearchView.swift index 8eb2f1eb..2baa8dc5 100644 --- a/Apple TV/SearchView.swift +++ b/Apple TV/SearchView.swift @@ -2,6 +2,7 @@ import SwiftUI struct SearchView: View { @ObservedObject private var provider = SearchedVideosProvider() + @EnvironmentObject private var profile: Profile @EnvironmentObject private var state: AppState @Binding var tabSelection: TabSelection @@ -11,6 +12,7 @@ struct SearchView: View { var body: some View { VideosView(tabSelection: $tabSelection, videos: videos) .environmentObject(state) + .environmentObject(profile) .searchable(text: $query) } diff --git a/Apple TV/SubscriptionsView.swift b/Apple TV/SubscriptionsView.swift index 9bf18496..dff225ee 100644 --- a/Apple TV/SubscriptionsView.swift +++ b/Apple TV/SubscriptionsView.swift @@ -1,21 +1,19 @@ import SwiftUI struct SubscriptionsView: View { - @ObservedObject private var provider = SubscriptionVideosProvider() - @EnvironmentObject private var state: AppState - @Binding var tabSelection: TabSelection + @ObservedObject private var provider = SubscriptionVideosProvider() + var body: some View { VideosView(tabSelection: $tabSelection, videos: videos) - .task { - Task { - provider.load() - } - } } var videos: [Video] { - provider.videos + if provider.videos.isEmpty { + provider.load() + } + + return provider.videos } } diff --git a/Apple TV/VideosView.swift b/Apple TV/VideosView.swift index 65e95ef4..ec22bb03 100644 --- a/Apple TV/VideosView.swift +++ b/Apple TV/VideosView.swift @@ -1,18 +1,22 @@ import SwiftUI struct VideosView: View { - @EnvironmentObject private var state: AppState + @EnvironmentObject private var profile: Profile @Binding var tabSelection: TabSelection var videos: [Video] + @State private var showingViewOptions = false + var body: some View { - Group { - if state.profile.listing == .list { + Section { + if self.profile.listing == .list { VideosListView(tabSelection: $tabSelection, videos: videos) } else { - VideosCellsView(videos: videos, columns: state.profile.cellsColumns) + VideosCellsView(videos: videos, columns: self.profile.cellsColumns) } } + .fullScreenCover(isPresented: $showingViewOptions) { ViewOptionsView() } + .onPlayPauseCommand { showingViewOptions.toggle() } } } diff --git a/Apple TV/ViewOptionsView.swift b/Apple TV/ViewOptionsView.swift new file mode 100644 index 00000000..fe1e1099 --- /dev/null +++ b/Apple TV/ViewOptionsView.swift @@ -0,0 +1,32 @@ +import SwiftUI + +struct ViewOptionsView: View { + @EnvironmentObject private var profile: Profile + + @Environment(\.presentationMode) private var presentationMode + + var body: some View { + ZStack { + VisualEffectView(effect: UIBlurEffect(style: .dark)) + + VStack { + Spacer() + + ScrollView(.vertical) { + Button(profile.listing == .list ? "Cells" : "List") { + profile.listing = (profile.listing == .list ? .cells : .list) + presentationMode.wrappedValue.dismiss() + } + + Button("Close") { + presentationMode.wrappedValue.dismiss() + } + .frame(width: 800) + } + Spacer() + } + } + .frame(maxWidth: .infinity, maxHeight: .infinity) + .edgesIgnoringSafeArea(.all) + } +} diff --git a/Model/AppState.swift b/Model/AppState.swift index 222dd82a..3e24d896 100644 --- a/Model/AppState.swift +++ b/Model/AppState.swift @@ -6,8 +6,6 @@ final class AppState: ObservableObject { @Published var channelID: String = "" @Published var channel: String = "" - @Published var profile = Profile() - func openChannel(from video: Video) { channel = video.author channelID = video.channelID diff --git a/Model/PlayerState.swift b/Model/PlayerState.swift index 13909ba8..ba5e5fce 100644 --- a/Model/PlayerState.swift +++ b/Model/PlayerState.swift @@ -22,7 +22,7 @@ final class PlayerState: ObservableObject { @Published var currentSegment: Segment? - private var profile = Profile() + private(set) var profile = Profile() @Published private(set) var currentRate: Float = 0.0 static let availablePlaybackRates: [Double] = [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2] diff --git a/Model/Profile.swift b/Model/Profile.swift index 856f731d..38d05756 100644 --- a/Model/Profile.swift +++ b/Model/Profile.swift @@ -1,16 +1,16 @@ import Foundation final class Profile: ObservableObject { - let defaultStreamResolution: DefaultStreamResolution = .hd720pFirstThenBest + var defaultStreamResolution: DefaultStreamResolution = .hd720pFirstThenBest - let skippedSegmentsCategories = [String]() // SponsorBlockSegmentsProvider.categories + var skippedSegmentsCategories = [String]() // SponsorBlockSegmentsProvider.categories - // let sid = "B3_WzklziGu8JKefihLrCsTNavdj73KMiPUBfN5HW2M=" - let sid = "RpoS7YPPK2-QS81jJF9z4KSQAjmzsOnMpn84c73-GQ8=" + // var sid = "B3_WzklziGu8JKefihLrCsTNavdj73KMiPUBfN5HW2M=" + var sid = "RpoS7YPPK2-QS81jJF9z4KSQAjmzsOnMpn84c73-GQ8=" - let listing = VideoListing.cells + @Published var listing = VideoListing.cells - let cellsColumns = 3 + var cellsColumns = 3 } enum VideoListing: String { diff --git a/Pearvidious.xcodeproj/project.pbxproj b/Pearvidious.xcodeproj/project.pbxproj index cbdcfa82..be39b345 100644 --- a/Pearvidious.xcodeproj/project.pbxproj +++ b/Pearvidious.xcodeproj/project.pbxproj @@ -93,6 +93,9 @@ 37B767DC2677C3CA0098BAA8 /* PlayerState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37B767DA2677C3CA0098BAA8 /* PlayerState.swift */; }; 37B767DD2677C3CA0098BAA8 /* PlayerState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37B767DA2677C3CA0098BAA8 /* PlayerState.swift */; }; 37B767E02678C5BF0098BAA8 /* Logging in Frameworks */ = {isa = PBXBuildFile; productRef = 37B767DF2678C5BF0098BAA8 /* Logging */; }; + 37B76E96268747C900CE5671 /* ViewOptionsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37B76E95268747C900CE5671 /* ViewOptionsView.swift */; }; + 37B76E97268747C900CE5671 /* ViewOptionsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37B76E95268747C900CE5671 /* ViewOptionsView.swift */; }; + 37B76E98268747C900CE5671 /* ViewOptionsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37B76E95268747C900CE5671 /* ViewOptionsView.swift */; }; 37C7A1D5267BFD9D0010EAD6 /* SponsorBlockSegment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37C7A1D4267BFD9D0010EAD6 /* SponsorBlockSegment.swift */; }; 37C7A1D6267BFD9D0010EAD6 /* SponsorBlockSegment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37C7A1D4267BFD9D0010EAD6 /* SponsorBlockSegment.swift */; }; 37C7A1D7267BFD9D0010EAD6 /* SponsorBlockSegment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37C7A1D4267BFD9D0010EAD6 /* SponsorBlockSegment.swift */; }; @@ -211,6 +214,7 @@ 37AAF29B26741B5F007FC770 /* SubscriptionVideosProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionVideosProvider.swift; sourceTree = ""; }; 37AAF29F26741C97007FC770 /* SubscriptionsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionsView.swift; sourceTree = ""; }; 37B767DA2677C3CA0098BAA8 /* PlayerState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerState.swift; sourceTree = ""; }; + 37B76E95268747C900CE5671 /* ViewOptionsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewOptionsView.swift; sourceTree = ""; }; 37C7A1D4267BFD9D0010EAD6 /* SponsorBlockSegment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SponsorBlockSegment.swift; sourceTree = ""; }; 37C7A1DB267CE9D90010EAD6 /* Profile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Profile.swift; sourceTree = ""; }; 37C7A9032679059200E721B4 /* AVKeyValueStatus+String.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AVKeyValueStatus+String.swift"; sourceTree = ""; }; @@ -395,6 +399,7 @@ 37F4AE7126828F0900BD60EA /* VideosCellsView.swift */, 37AAF29926740A01007FC770 /* VideosListView.swift */, 371231832683E62F0000B307 /* VideosView.swift */, + 37B76E95268747C900CE5671 /* ViewOptionsView.swift */, 3705B17B267B4D9A00704544 /* VisualEffectView.swift */, 37D4B15E267164AF00C925CA /* Assets.xcassets */, 37D4B1AE26729DEB00C925CA /* Info.plist */, @@ -726,6 +731,7 @@ 3714167B267AA1CF006CA35D /* TrendingCountriesProvider.swift in Sources */, 377FC7DF267A082200A6BBAF /* VideosListView.swift in Sources */, 37D4B19726717E1500C925CA /* Video.swift in Sources */, + 37B76E96268747C900CE5671 /* ViewOptionsView.swift in Sources */, 37D4B0E42671614900C925CA /* PearvidiousApp.swift in Sources */, 37CEE4B92677B63F005A1EFE /* StreamResolution.swift in Sources */, ); @@ -764,6 +770,7 @@ 376578862685429C00D4EA09 /* CaseIterable+Next.swift in Sources */, 37F4AE7326828F0900BD60EA /* VideosCellsView.swift in Sources */, 377FC7E0267A082600A6BBAF /* ChannelView.swift in Sources */, + 37B76E97268747C900CE5671 /* ViewOptionsView.swift in Sources */, 371231862683E7820000B307 /* VideosView.swift in Sources */, 37C7A1D6267BFD9D0010EAD6 /* SponsorBlockSegment.swift in Sources */, 37C7A1DD267CE9D90010EAD6 /* Profile.swift in Sources */, @@ -842,6 +849,7 @@ 3705B184267B4E4900704544 /* TrendingCategory.swift in Sources */, 37AAF2A226741C97007FC770 /* SubscriptionsView.swift in Sources */, 37D4B1812671653A00C925CA /* ContentView.swift in Sources */, + 37B76E98268747C900CE5671 /* ViewOptionsView.swift in Sources */, 37AAF2842673791F007FC770 /* SearchedVideosProvider.swift in Sources */, 37CEE4BB2677B63F005A1EFE /* StreamResolution.swift in Sources */, ); diff --git a/Shared/ContentView.swift b/Shared/ContentView.swift index 14ff3fa9..e0015cc4 100644 --- a/Shared/ContentView.swift +++ b/Shared/ContentView.swift @@ -2,6 +2,7 @@ import SwiftUI struct ContentView: View { @ObservedObject private var state = AppState() + @ObservedObject private var profile = Profile() @SceneStorage("tabSelection") var tabSelection = TabSelection.subscriptions @@ -36,6 +37,7 @@ struct ContentView: View { } } .environmentObject(state) + .environmentObject(profile) } }