diff --git a/Apple TV/SearchView.swift b/Apple TV/SearchView.swift index c2d50b7e..f3314661 100644 --- a/Apple TV/SearchView.swift +++ b/Apple TV/SearchView.swift @@ -1,22 +1,28 @@ +import Defaults import Siesta import SwiftUI struct SearchView: View { - @State private var query = "" + @Default(.searchQuery) var query @ObservedObject private var store = Store<[Video]>() var body: some View { VideosView(videos: store.collection) .searchable(text: $query) + .onAppear { + queryChanged(new: query) + } .onChange(of: query) { newQuery in - queryChanged(query, newQuery) + queryChanged(old: query, new: newQuery) } } - func queryChanged(_ old: String, _ new: String) { - let oldResource = resource(old) - oldResource.removeObservers(ownedBy: store) + func queryChanged(old: String? = nil, new: String) { + if old != nil { + let oldResource = resource(old!) + oldResource.removeObservers(ownedBy: store) + } let resource = resource(new) resource.addObserver(store) diff --git a/Apple TV/TrendingView.swift b/Apple TV/TrendingView.swift index 218ac14b..206092a9 100644 --- a/Apple TV/TrendingView.swift +++ b/Apple TV/TrendingView.swift @@ -2,8 +2,6 @@ import Siesta import SwiftUI struct TrendingView: View { - @EnvironmentObject private var state: AppState - @State private var category: TrendingCategory = .default @State private var country: Country = .pl @State private var selectingCountry = false diff --git a/Apple TV/VideoListRow.swift b/Apple TV/VideoListRowView.swift similarity index 98% rename from Apple TV/VideoListRow.swift rename to Apple TV/VideoListRowView.swift index 45beb38b..87db1827 100644 --- a/Apple TV/VideoListRow.swift +++ b/Apple TV/VideoListRowView.swift @@ -2,7 +2,7 @@ import SwiftUI import URLImage import URLImageStore -struct VideoListRow: View { +struct VideoListRowView: View { @Environment(\.isFocused) private var focused: Bool var video: Video diff --git a/Apple TV/VideosCellsView.swift b/Apple TV/VideosCellsView.swift index 7f6e16f4..c3d8eadc 100644 --- a/Apple TV/VideosCellsView.swift +++ b/Apple TV/VideosCellsView.swift @@ -1,8 +1,6 @@ import SwiftUI struct VideosCellsView: View { - @EnvironmentObject private var state: AppState - @State private var columns: Int init(videos: [Video], columns: Int = 3) { diff --git a/Apple TV/VideosListView.swift b/Apple TV/VideosListView.swift index e5901a68..92d2ddf0 100644 --- a/Apple TV/VideosListView.swift +++ b/Apple TV/VideosListView.swift @@ -2,8 +2,6 @@ import Defaults import SwiftUI struct VideosListView: View { - @EnvironmentObject private var state: AppState - @Default(.tabSelection) var tabSelection var videos: [Video] @@ -12,7 +10,7 @@ struct VideosListView: View { Section { List { ForEach(videos) { video in - VideoListRow(video: video) + VideoListRowView(video: video) .contextMenu { if tabSelection == .channel { closeChannelButton(name: video.author) @@ -29,15 +27,14 @@ struct VideosListView: View { func openChannelButton(from video: Video) -> some View { Button("\(video.author) Channel") { - state.openChannel(from: video) + Defaults[.openChannel] = Channel.from(video: video) tabSelection = .channel } } func closeChannelButton(name: String) -> some View { Button("Close \(name) Channel") { - tabSelection = .popular - state.closeChannel() + Defaults.reset(.openChannel) } } diff --git a/Model/AppState.swift b/Model/AppState.swift deleted file mode 100644 index 3e24d896..00000000 --- a/Model/AppState.swift +++ /dev/null @@ -1,20 +0,0 @@ -import AVFoundation -import Foundation - -final class AppState: ObservableObject { - @Published var showingChannel = false - @Published var channelID: String = "" - @Published var channel: String = "" - - func openChannel(from video: Video) { - channel = video.author - channelID = video.channelID - showingChannel = true - } - - func closeChannel() { - showingChannel = false - channel = "" - channelID = "" - } -} diff --git a/Model/Channel.swift b/Model/Channel.swift new file mode 100644 index 00000000..374a762e --- /dev/null +++ b/Model/Channel.swift @@ -0,0 +1,12 @@ +import AVFoundation +import Defaults +import Foundation + +struct Channel: Codable, Defaults.Serializable { + var id: String + var name: String + + static func from(video: Video) -> Channel { + Channel(id: video.channelID, name: video.author) + } +} diff --git a/Pearvidious.xcodeproj/project.pbxproj b/Pearvidious.xcodeproj/project.pbxproj index b55cf8b8..6d94bc6b 100644 --- a/Pearvidious.xcodeproj/project.pbxproj +++ b/Pearvidious.xcodeproj/project.pbxproj @@ -51,8 +51,8 @@ 377FC7DF267A082200A6BBAF /* VideosListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37AAF29926740A01007FC770 /* VideosListView.swift */; }; 377FC7E0267A082600A6BBAF /* ChannelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37AAF2892673AB89007FC770 /* ChannelView.swift */; }; 377FC7E1267A082600A6BBAF /* ChannelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37AAF2892673AB89007FC770 /* ChannelView.swift */; }; - 377FC7E2267A084A00A6BBAF /* VideoListRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37D4B18B26717B3800C925CA /* VideoListRow.swift */; }; - 377FC7E3267A084A00A6BBAF /* VideoListRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37D4B18B26717B3800C925CA /* VideoListRow.swift */; }; + 377FC7E2267A084A00A6BBAF /* VideoListRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37D4B18B26717B3800C925CA /* VideoListRowView.swift */; }; + 377FC7E3267A084A00A6BBAF /* VideoListRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37D4B18B26717B3800C925CA /* VideoListRowView.swift */; }; 377FC7E4267A084E00A6BBAF /* SearchView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37AAF27F26737550007FC770 /* SearchView.swift */; }; 377FC7E5267A084E00A6BBAF /* SearchView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37AAF27F26737550007FC770 /* SearchView.swift */; }; 377FC7E6267A085600A6BBAF /* PlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37D4B1822671681B00C925CA /* PlayerView.swift */; }; @@ -77,9 +77,9 @@ 37AAF27E26737323007FC770 /* PopularVideosView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37AAF27D26737323007FC770 /* PopularVideosView.swift */; }; 37AAF28026737550007FC770 /* SearchView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37AAF27F26737550007FC770 /* SearchView.swift */; }; 37AAF28A2673AB89007FC770 /* ChannelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37AAF2892673AB89007FC770 /* ChannelView.swift */; }; - 37AAF29026740715007FC770 /* AppState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37AAF28F26740715007FC770 /* AppState.swift */; }; - 37AAF29126740715007FC770 /* AppState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37AAF28F26740715007FC770 /* AppState.swift */; }; - 37AAF29226740715007FC770 /* AppState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37AAF28F26740715007FC770 /* AppState.swift */; }; + 37AAF29026740715007FC770 /* Channel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37AAF28F26740715007FC770 /* Channel.swift */; }; + 37AAF29126740715007FC770 /* Channel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37AAF28F26740715007FC770 /* Channel.swift */; }; + 37AAF29226740715007FC770 /* Channel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37AAF28F26740715007FC770 /* Channel.swift */; }; 37AAF2942674086B007FC770 /* TabSelection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37AAF2932674086B007FC770 /* TabSelection.swift */; }; 37AAF2952674086B007FC770 /* TabSelection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37AAF2932674086B007FC770 /* TabSelection.swift */; }; 37AAF2962674086B007FC770 /* TabSelection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37AAF2932674086B007FC770 /* TabSelection.swift */; }; @@ -127,7 +127,7 @@ 37D4B1812671653A00C925CA /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37D4B0C32671614700C925CA /* ContentView.swift */; }; 37D4B1842671684E00C925CA /* PlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37D4B1822671681B00C925CA /* PlayerView.swift */; }; 37D4B1862671691600C925CA /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 37D4B0C42671614800C925CA /* Assets.xcassets */; }; - 37D4B18E26717B3800C925CA /* VideoListRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37D4B18B26717B3800C925CA /* VideoListRow.swift */; }; + 37D4B18E26717B3800C925CA /* VideoListRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37D4B18B26717B3800C925CA /* VideoListRowView.swift */; }; 37D4B19126717C6900C925CA /* Alamofire in Frameworks */ = {isa = PBXBuildFile; productRef = 37D4B19026717C6900C925CA /* Alamofire */; }; 37D4B19726717E1500C925CA /* Video.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37D4B19626717E1500C925CA /* Video.swift */; }; 37D4B19826717E1500C925CA /* Video.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37D4B19626717E1500C925CA /* Video.swift */; }; @@ -192,7 +192,7 @@ 37AAF27D26737323007FC770 /* PopularVideosView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PopularVideosView.swift; sourceTree = ""; }; 37AAF27F26737550007FC770 /* SearchView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchView.swift; sourceTree = ""; }; 37AAF2892673AB89007FC770 /* ChannelView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChannelView.swift; sourceTree = ""; }; - 37AAF28F26740715007FC770 /* AppState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppState.swift; sourceTree = ""; }; + 37AAF28F26740715007FC770 /* Channel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Channel.swift; sourceTree = ""; }; 37AAF2932674086B007FC770 /* TabSelection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabSelection.swift; sourceTree = ""; }; 37AAF29926740A01007FC770 /* VideosListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideosListView.swift; sourceTree = ""; }; 37AAF29F26741C97007FC770 /* SubscriptionsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionsView.swift; sourceTree = ""; }; @@ -218,7 +218,7 @@ 37D4B171267164B000C925CA /* Tests Apple TV.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Tests Apple TV.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 37D4B175267164B000C925CA /* PearvidiousUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PearvidiousUITests.swift; sourceTree = ""; }; 37D4B1822671681B00C925CA /* PlayerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerView.swift; sourceTree = ""; }; - 37D4B18B26717B3800C925CA /* VideoListRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoListRow.swift; sourceTree = ""; }; + 37D4B18B26717B3800C925CA /* VideoListRowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoListRowView.swift; sourceTree = ""; }; 37D4B19626717E1500C925CA /* Video.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Video.swift; sourceTree = ""; }; 37D4B1AE26729DEB00C925CA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 37EAD86A267B9C5600D9E01B /* SponsorBlockAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SponsorBlockAPI.swift; sourceTree = ""; }; @@ -300,8 +300,8 @@ 37C7A9022679058300E721B4 /* Extensions */ = { isa = PBXGroup; children = ( - 376578842685429C00D4EA09 /* CaseIterable+Next.swift */, 379775922689365600DD52A8 /* Array+Next.swift */, + 376578842685429C00D4EA09 /* CaseIterable+Next.swift */, ); path = Extensions; sourceTree = ""; @@ -327,10 +327,10 @@ 37D4B0C32671614700C925CA /* ContentView.swift */, 37141672267A8E10006CA35D /* Country.swift */, 372915E52687E3B900F5A35B /* Defaults.swift */, + 372915E92687EBA500F5A35B /* ListingLayout.swift */, 37D4B0C22671614700C925CA /* PearvidiousApp.swift */, 37AAF2932674086B007FC770 /* TabSelection.swift */, 37D4B0C42671614800C925CA /* Assets.xcassets */, - 372915E92687EBA500F5A35B /* ListingLayout.swift */, ); path = Shared; sourceTree = ""; @@ -378,7 +378,7 @@ 3705B17F267B4DFB00704544 /* TrendingCountrySelectionView.swift */, 3714166E267A8ACC006CA35D /* TrendingView.swift */, 37F4AE752682908700BD60EA /* VideoCellView.swift */, - 37D4B18B26717B3800C925CA /* VideoListRow.swift */, + 37D4B18B26717B3800C925CA /* VideoListRowView.swift */, 37F4AE7126828F0900BD60EA /* VideosCellsView.swift */, 37AAF29926740A01007FC770 /* VideosListView.swift */, 371231832683E62F0000B307 /* VideosView.swift */, @@ -400,8 +400,8 @@ 37D4B1B72672CFE300C925CA /* Model */ = { isa = PBXGroup; children = ( - 37AAF28F26740715007FC770 /* AppState.swift */, 37CEE4BC2677B670005A1EFE /* AudioVideoStream.swift */, + 37AAF28F26740715007FC770 /* Channel.swift */, 37977582268922F600DD52A8 /* InvidiousAPI.swift */, 37B767DA2677C3CA0098BAA8 /* PlayerState.swift */, 376578882685471400D4EA09 /* Playlist.swift */, @@ -687,8 +687,8 @@ 37CEE4B52677B628005A1EFE /* StreamType.swift in Sources */, 37C7A1DC267CE9D90010EAD6 /* Profile.swift in Sources */, 3714166F267A8ACC006CA35D /* TrendingView.swift in Sources */, - 377FC7E3267A084A00A6BBAF /* VideoListRow.swift in Sources */, - 37AAF29026740715007FC770 /* AppState.swift in Sources */, + 377FC7E3267A084A00A6BBAF /* VideoListRowView.swift in Sources */, + 37AAF29026740715007FC770 /* Channel.swift in Sources */, 37AAF2942674086B007FC770 /* TabSelection.swift in Sources */, 377FC7E9267A085D00A6BBAF /* PlayerViewController.swift in Sources */, 377FC7E5267A084E00A6BBAF /* SearchView.swift in Sources */, @@ -727,9 +727,9 @@ 37EAD870267B9ED100D9E01B /* Segment.swift in Sources */, 37CEE4B62677B628005A1EFE /* StreamType.swift in Sources */, 37141670267A8ACC006CA35D /* TrendingView.swift in Sources */, - 377FC7E2267A084A00A6BBAF /* VideoListRow.swift in Sources */, + 377FC7E2267A084A00A6BBAF /* VideoListRowView.swift in Sources */, 3765788A2685471400D4EA09 /* Playlist.swift in Sources */, - 37AAF29126740715007FC770 /* AppState.swift in Sources */, + 37AAF29126740715007FC770 /* Channel.swift in Sources */, 37AAF2952674086B007FC770 /* TabSelection.swift in Sources */, 372915E72687E3B900F5A35B /* Defaults.swift in Sources */, 376578922685490700D4EA09 /* PlaylistsView.swift in Sources */, @@ -788,13 +788,13 @@ 37D4B1802671650A00C925CA /* PearvidiousApp.swift in Sources */, 371231852683E7820000B307 /* VideosView.swift in Sources */, 37141671267A8ACC006CA35D /* TrendingView.swift in Sources */, - 37AAF29226740715007FC770 /* AppState.swift in Sources */, + 37AAF29226740715007FC770 /* Channel.swift in Sources */, 37EAD86D267B9C5600D9E01B /* SponsorBlockAPI.swift in Sources */, 3765788B2685471400D4EA09 /* Playlist.swift in Sources */, 37C7A1DE267CE9D90010EAD6 /* Profile.swift in Sources */, 3741B5302676213400125C5E /* PlayerViewController.swift in Sources */, 37B767DD2677C3CA0098BAA8 /* PlayerState.swift in Sources */, - 37D4B18E26717B3800C925CA /* VideoListRow.swift in Sources */, + 37D4B18E26717B3800C925CA /* VideoListRowView.swift in Sources */, 37AAF27E26737323007FC770 /* PopularVideosView.swift in Sources */, 37AAF29A26740A01007FC770 /* VideosListView.swift in Sources */, 37AAF2962674086B007FC770 /* TabSelection.swift in Sources */, diff --git a/Shared/ContentView.swift b/Shared/ContentView.swift index a4f71ec8..4f372f7a 100644 --- a/Shared/ContentView.swift +++ b/Shared/ContentView.swift @@ -2,7 +2,7 @@ import Defaults import SwiftUI struct ContentView: View { - @StateObject private var state = AppState() + @Default(.openChannel) var channel @StateObject private var profile = Profile() var body: some View { @@ -16,9 +16,9 @@ struct ContentView: View { .tabItem { Text("Popular") } .tag(TabSelection.popular) - if !state.channelID.isEmpty { - ChannelView(id: state.channelID) - .tabItem { Text("\(state.channel) Channel") } + if channel != nil { + ChannelView(id: channel!.id) + .tabItem { Text("\(channel!.name) Channel") } .tag(TabSelection.channel) } @@ -34,9 +34,8 @@ struct ContentView: View { .tabItem { Image(systemName: "magnifyingglass") } .tag(TabSelection.search) } + .environmentObject(profile) } - .environmentObject(state) - .environmentObject(profile) } var tabSelection: Binding { diff --git a/Shared/Defaults.swift b/Shared/Defaults.swift index 4b423009..9a465c78 100644 --- a/Shared/Defaults.swift +++ b/Shared/Defaults.swift @@ -3,4 +3,6 @@ import Defaults extension Defaults.Keys { static let layout = Key("listingLayout", default: .cells) static let tabSelection = Key("tabSelection", default: .subscriptions) + static let searchQuery = Key("searchQuery", default: "") + static let openChannel = Key("openChannel") }