diff --git a/Model/FavoritesModel.swift b/Model/FavoritesModel.swift index 993880c0..f7fc60c6 100644 --- a/Model/FavoritesModel.swift +++ b/Model/FavoritesModel.swift @@ -4,11 +4,11 @@ import Foundation struct FavoritesModel { static let shared = FavoritesModel() + @Default(.showFavoritesInHome) var showFavoritesInHome @Default(.favorites) var all - @Default(.visibleSections) var visibleSections var isEnabled: Bool { - visibleSections.contains(.home) + showFavoritesInHome } func contains(_ item: FavoriteItem) -> Bool { diff --git a/Shared/Defaults.swift b/Shared/Defaults.swift index f879a10f..6c7592ea 100644 --- a/Shared/Defaults.swift +++ b/Shared/Defaults.swift @@ -21,7 +21,11 @@ extension Defaults.Keys { static let enableReturnYouTubeDislike = Key("enableReturnYouTubeDislike", default: false) - static let homeHistoryItems = Key("homeHistoryItems", default: 30) + static let showHome = Key("showHome", default: true) + static let showOpenActionsInHome = Key("showOpenActionsInHome", default: true) + static let showOpenActionsToolbarItem = Key("showOpenActionsToolbarItem", default: false) + static let showFavoritesInHome = Key("showFavoritesInHome", default: true) + static let homeHistoryItems = Key("homeHistoryItems", default: 10) static let favorites = Key<[FavoriteItem]>("favorites", default: []) #if !os(tvOS) @@ -169,7 +173,7 @@ extension Defaults.Keys { static let trendingCategory = Key("trendingCategory", default: .default) static let trendingCountry = Key("trendingCountry", default: .us) - static let visibleSections = Key>("visibleSections", default: [.home]) + static let visibleSections = Key>("visibleSections", default: [.subscriptions, .trending, .playlists]) #if os(iOS) static let enterFullscreenInLandscape = Key("enterFullscreenInLandscape", default: UIDevice.current.userInterfaceIdiom == .phone) @@ -234,7 +238,7 @@ enum PlayerSidebarSetting: String, CaseIterable, Defaults.Serializable { } enum VisibleSection: String, CaseIterable, Comparable, Defaults.Serializable { - case home, subscriptions, popular, trending, playlists + case subscriptions, popular, trending, playlists var title: String { rawValue.capitalized.localized() @@ -242,8 +246,6 @@ enum VisibleSection: String, CaseIterable, Comparable, Defaults.Serializable { var tabSelection: TabSelection { switch self { - case .home: - return TabSelection.home case .subscriptions: return TabSelection.subscriptions case .popular: @@ -257,16 +259,14 @@ enum VisibleSection: String, CaseIterable, Comparable, Defaults.Serializable { private var sortOrder: Int { switch self { - case .home: - return 0 case .subscriptions: - return 1 + return 0 case .popular: - return 2 + return 1 case .trending: - return 3 + return 2 case .playlists: - return 4 + return 3 } } diff --git a/Shared/Home/HomeView.swift b/Shared/Home/HomeView.swift index 5157371f..3f6781f0 100644 --- a/Shared/Home/HomeView.swift +++ b/Shared/Home/HomeView.swift @@ -18,43 +18,47 @@ struct HomeView: View { @Default(.favorites) private var favorites #endif @Default(.homeHistoryItems) private var homeHistoryItems + @Default(.showFavoritesInHome) private var showFavoritesInHome + @Default(.showOpenActionsInHome) private var showOpenActionsInHome private var navigation: NavigationModel { .shared } var body: some View { BrowserPlayerControls { ScrollView(.vertical, showsIndicators: false) { - HStack { - #if os(tvOS) - OpenVideosButton(text: "Open Video", imageSystemName: "globe") { - NavigationModel.shared.presentingOpenVideos = true - } - .frame(maxWidth: 600) + if showOpenActionsInHome { + HStack { + #if os(tvOS) + OpenVideosButton(text: "Open Video", imageSystemName: "globe") { + NavigationModel.shared.presentingOpenVideos = true + } + .frame(maxWidth: 600) + #else + OpenVideosButton(text: "Files", imageSystemName: "folder") { + NavigationModel.shared.presentingFileImporter = true + } + OpenVideosButton(text: "Paste", imageSystemName: "doc.on.clipboard.fill") { + OpenVideosModel.shared.openURLsFromClipboard(playbackMode: .playNow) + } + OpenVideosButton(imageSystemName: "ellipsis") { + NavigationModel.shared.presentingOpenVideos = true + } + .frame(maxWidth: 40) + #endif + } + #if os(iOS) + .padding(.top, RefreshControl.navigationBarTitleDisplayMode == .inline ? 15 : 0) #else - OpenVideosButton(text: "Files", imageSystemName: "folder") { - NavigationModel.shared.presentingFileImporter = true - } - OpenVideosButton(text: "Paste", imageSystemName: "doc.on.clipboard.fill") { - OpenVideosModel.shared.openURLsFromClipboard(playbackMode: .playNow) - } - OpenVideosButton(imageSystemName: "ellipsis") { - NavigationModel.shared.presentingOpenVideos = true - } - .frame(maxWidth: 40) + .padding(.top, 15) + #endif + #if os(tvOS) + .padding(.horizontal, 40) + #else + .padding(.horizontal, 15) #endif } - #if os(iOS) - .padding(.top, RefreshControl.navigationBarTitleDisplayMode == .inline ? 15 : 0) - #else - .padding(.top, 15) - #endif - #if os(tvOS) - .padding(.horizontal, 40) - #else - .padding(.horizontal, 15) - #endif - if !accounts.current.isNil { + if !accounts.current.isNil, showFavoritesInHome { #if os(tvOS) ForEach(Defaults[.favorites]) { item in FavoriteItemView(item: item, dragging: $dragging) @@ -75,19 +79,21 @@ struct HomeView: View { #endif } - VStack { - Text("History") + if homeHistoryItems > 0 { + VStack { + Text("History") - #if os(tvOS) - .padding(.horizontal, 40) - #else - .padding(.horizontal, 15) - #endif - .font(.title3.bold()) - .frame(maxWidth: .infinity, alignment: .leading) - .foregroundColor(.secondary) + #if os(tvOS) + .padding(.horizontal, 40) + #else + .padding(.horizontal, 15) + #endif + .font(.title3.bold()) + .frame(maxWidth: .infinity, alignment: .leading) + .foregroundColor(.secondary) - HistoryView(limit: homeHistoryItems) + HistoryView(limit: homeHistoryItems) + } } #if !os(tvOS) diff --git a/Shared/Navigation/AppSidebarNavigation.swift b/Shared/Navigation/AppSidebarNavigation.swift index 6185ed04..b0d6237f 100644 --- a/Shared/Navigation/AppSidebarNavigation.swift +++ b/Shared/Navigation/AppSidebarNavigation.swift @@ -5,6 +5,8 @@ import SwiftUI #endif struct AppSidebarNavigation: View { + @Default(.showOpenActionsToolbarItem) private var showOpenActionsToolbarItem + @EnvironmentObject private var accounts @EnvironmentObject private var navigation @@ -75,10 +77,12 @@ struct AppSidebarNavigation: View { #endif ToolbarItemGroup(placement: openVideosToolbarItemPlacement) { - Button { - navigation.presentingOpenVideos = true - } label: { - Label("Open Videos", systemImage: "play.circle.fill") + if showOpenActionsToolbarItem { + Button { + navigation.presentingOpenVideos = true + } label: { + Label("Open Videos", systemImage: "play.circle.fill") + } } } diff --git a/Shared/Navigation/AppTabNavigation.swift b/Shared/Navigation/AppTabNavigation.swift index 956b4d58..3be28bbe 100644 --- a/Shared/Navigation/AppTabNavigation.swift +++ b/Shared/Navigation/AppTabNavigation.swift @@ -13,36 +13,48 @@ struct AppTabNavigation: View { @EnvironmentObject private var subscriptions @EnvironmentObject private var thumbnailsModel + @Default(.showHome) private var showHome + @Default(.showOpenActionsToolbarItem) private var showOpenActionsToolbarItem @Default(.visibleSections) private var visibleSections let persistenceController = PersistenceController.shared var body: some View { TabView(selection: navigation.tabSelectionBinding) { - if visibleSections.contains(.home) { - homeNavigationView + let tabs = Group { + if showHome { + homeNavigationView + } + + if !accounts.isEmpty { + if subscriptionsVisible { + subscriptionsNavigationView + } + + if visibleSections.contains(.popular), accounts.app.supportsPopular, visibleSections.count < 5 { + popularNavigationView + } + + if visibleSections.contains(.trending) { + trendingNavigationView + } + + if playlistsVisible { + playlistsNavigationView + } + + searchNavigationView + } } - if subscriptionsVisible { - subscriptionsNavigationView - } - - if visibleSections.contains(.popular), accounts.app.supportsPopular, visibleSections.count < 5 { - popularNavigationView - } - - if visibleSections.contains(.trending) { - trendingNavigationView - } - - if playlistsVisible { - playlistsNavigationView - } - - if !accounts.isEmpty { - searchNavigationView + if #available(iOS 16, tvOS 16, *) { + tabs + .toolbar(accounts.isEmpty ? .hidden : .visible, for: .tabBar) + } else { + tabs } } + .id(accounts.current?.id ?? "") .overlay(playlistView) .overlay(channelView) @@ -141,8 +153,10 @@ struct AppTabNavigation: View { } ToolbarItemGroup(placement: .navigationBarTrailing) { - Button(action: { navigation.presentingOpenVideos = true }) { - Label("Open Videos", systemImage: "play.circle.fill") + if showOpenActionsToolbarItem { + Button(action: { navigation.presentingOpenVideos = true }) { + Label("Open Videos", systemImage: "play.circle.fill") + } } AccountsMenuView() } diff --git a/Shared/Navigation/Sidebar.swift b/Shared/Navigation/Sidebar.swift index 59b50c78..b820cb47 100644 --- a/Shared/Navigation/Sidebar.swift +++ b/Shared/Navigation/Sidebar.swift @@ -5,6 +5,7 @@ struct Sidebar: View { @EnvironmentObject private var accounts @EnvironmentObject private var navigation + @Default(.showHome) private var showHome @Default(.visibleSections) private var visibleSections var body: some View { @@ -40,40 +41,40 @@ struct Sidebar: View { var mainNavigationLinks: some View { Section(header: Text("Videos")) { - if visibleSections.contains(.home) { + if showHome { NavigationLink(destination: LazyView(HomeView()), tag: TabSelection.home, selection: $navigation.tabSelection) { Label("Home", systemImage: "house") .accessibility(label: Text("Home")) } .id("favorites") } - if visibleSections.contains(.subscriptions), - accounts.app.supportsSubscriptions && accounts.signedIn - { - NavigationLink(destination: LazyView(SubscriptionsView()), tag: TabSelection.subscriptions, selection: $navigation.tabSelection) { - Label("Subscriptions", systemImage: "star.circle") - .accessibility(label: Text("Subscriptions")) - } - .id("subscriptions") - } - - if visibleSections.contains(.popular), accounts.app.supportsPopular { - NavigationLink(destination: LazyView(PopularView()), tag: TabSelection.popular, selection: $navigation.tabSelection) { - Label("Popular", systemImage: "arrow.up.right.circle") - .accessibility(label: Text("Popular")) - } - .id("popular") - } - - if visibleSections.contains(.trending) { - NavigationLink(destination: LazyView(TrendingView()), tag: TabSelection.trending, selection: $navigation.tabSelection) { - Label("Trending", systemImage: "chart.bar") - .accessibility(label: Text("Trending")) - } - .id("trending") - } - if !accounts.isEmpty { + if visibleSections.contains(.subscriptions), + accounts.app.supportsSubscriptions && accounts.signedIn + { + NavigationLink(destination: LazyView(SubscriptionsView()), tag: TabSelection.subscriptions, selection: $navigation.tabSelection) { + Label("Subscriptions", systemImage: "star.circle") + .accessibility(label: Text("Subscriptions")) + } + .id("subscriptions") + } + + if visibleSections.contains(.popular), accounts.app.supportsPopular { + NavigationLink(destination: LazyView(PopularView()), tag: TabSelection.popular, selection: $navigation.tabSelection) { + Label("Popular", systemImage: "arrow.up.right.circle") + .accessibility(label: Text("Popular")) + } + .id("popular") + } + + if visibleSections.contains(.trending) { + NavigationLink(destination: LazyView(TrendingView()), tag: TabSelection.trending, selection: $navigation.tabSelection) { + Label("Trending", systemImage: "chart.bar") + .accessibility(label: Text("Trending")) + } + .id("trending") + } + NavigationLink(destination: LazyView(SearchView()), tag: TabSelection.search, selection: $navigation.tabSelection) { Label("Search", systemImage: "magnifyingglass") .accessibility(label: Text("Search")) diff --git a/Shared/Search/SearchView.swift b/Shared/Search/SearchView.swift index 5471beba..846f7b5a 100644 --- a/Shared/Search/SearchView.swift +++ b/Shared/Search/SearchView.swift @@ -29,6 +29,7 @@ struct SearchView: View { @Default(.recentlyOpened) private var recentlyOpened @Default(.saveRecents) private var saveRecents + @Default(.showHome) private var showHome private var videos = [Video]() @@ -209,13 +210,11 @@ struct SearchView: View { visibleSections.append(.playlists) } - [VisibleSection.home, .trending].forEach { section in - if preferred.contains(section) { - visibleSections.append(section) - } + if preferred.contains(.trending) { + visibleSections.append(.trending) } - return !visibleSections.isEmpty + return !visibleSections.isEmpty || showHome } private var results: some View { diff --git a/Shared/Settings/BrowsingSettings.swift b/Shared/Settings/BrowsingSettings.swift index 194b6301..e3f7b362 100644 --- a/Shared/Settings/BrowsingSettings.swift +++ b/Shared/Settings/BrowsingSettings.swift @@ -13,12 +13,24 @@ struct BrowsingSettings: View { @Default(.thumbnailsQuality) private var thumbnailsQuality @Default(.channelOnThumbnail) private var channelOnThumbnail @Default(.timeOnThumbnail) private var timeOnThumbnail + @Default(.showHome) private var showHome + @Default(.showFavoritesInHome) private var showFavoritesInHome + @Default(.showOpenActionsInHome) private var showOpenActionsInHome + @Default(.showOpenActionsToolbarItem) private var showOpenActionsToolbarItem + @Default(.homeHistoryItems) private var homeHistoryItems @Default(.visibleSections) private var visibleSections + @EnvironmentObject private var accounts + + @State private var homeHistoryItemsText = "" + var body: some View { Group { #if os(macOS) - sections + VStack(alignment: .leading) { + sections + Spacer() + } #else List { sections @@ -38,14 +50,45 @@ struct BrowsingSettings: View { private var sections: some View { Group { + homeSettings interfaceSettings - thumbnailsSettings - visibleSectionsSettings + if !accounts.isEmpty { + thumbnailsSettings + visibleSectionsSettings + } + } + } + + private var homeSettings: some View { + Section(header: SettingsHeader(text: "Home".localized())) { + #if !os(tvOS) + if !accounts.isEmpty { + Toggle("Show Home", isOn: $showHome) + } + #endif + Toggle("Show Open Videos quick actions", isOn: $showOpenActionsInHome) + if !accounts.isEmpty { + Toggle("Show Favorites", isOn: $showFavoritesInHome) + } + HStack { + TextField("Recent history items", text: $homeHistoryItemsText) + #if !os(macOS) + .keyboardType(.URL) + #endif + .onAppear { + homeHistoryItemsText = String(homeHistoryItems) + } + .onChange(of: homeHistoryItemsText) { newValue in + homeHistoryItems = Int(newValue) ?? 10 + } + } + .multilineTextAlignment(.trailing) } } private var interfaceSettings: some View { Section(header: SettingsHeader(text: "Interface".localized())) { + Toggle("Show Open Videos toolbar button", isOn: $showOpenActionsToolbarItem) #if os(iOS) Toggle("Lock portrait mode", isOn: $lockPortraitWhenBrowsing) .onChange(of: lockPortraitWhenBrowsing) { lock in @@ -57,11 +100,13 @@ struct BrowsingSettings: View { } #endif - #if !os(tvOS) - Toggle("Show account username", isOn: $accountPickerDisplaysUsername) - #endif + if !accounts.isEmpty { + #if !os(tvOS) + Toggle("Show account username", isOn: $accountPickerDisplaysUsername) + #endif - Toggle("Show anonymous accounts", isOn: $accountPickerDisplaysAnonymousAccounts) + Toggle("Show anonymous accounts", isOn: $accountPickerDisplaysAnonymousAccounts) + } } } diff --git a/Shared/Settings/SettingsView.swift b/Shared/Settings/SettingsView.swift index b94c820e..f744c255 100644 --- a/Shared/Settings/SettingsView.swift +++ b/Shared/Settings/SettingsView.swift @@ -34,15 +34,13 @@ struct SettingsView: View { var settings: some View { #if os(macOS) TabView(selection: $selection) { - if !accounts.isEmpty { - Form { - BrowsingSettings() - } - .tabItem { - Label("Browsing", systemImage: "list.and.film") - } - .tag(Optional(Tabs.browsing)) + Form { + BrowsingSettings() } + .tabItem { + Label("Browsing", systemImage: "list.and.film") + } + .tag(Optional(Tabs.browsing)) Form { PlayerSettings() @@ -125,12 +123,10 @@ struct SettingsView: View { } #endif - if !accounts.isEmpty { - NavigationLink { - BrowsingSettings() - } label: { - Label("Browsing", systemImage: "list.and.film") - } + NavigationLink { + BrowsingSettings() + } label: { + Label("Browsing", systemImage: "list.and.film") } NavigationLink { @@ -221,9 +217,9 @@ struct SettingsView: View { private var windowHeight: Double { switch selection { case nil: - return accounts.isEmpty ? 680 : 400 + return accounts.isEmpty ? 680 : 520 case .browsing: - return 400 + return 520 case .player: return 680 case .quality: @@ -233,7 +229,7 @@ struct SettingsView: View { case .sponsorBlock: return 700 case .advanced: - return 650 + return 750 case .help: return 600 } diff --git a/Shared/YatteeApp.swift b/Shared/YatteeApp.swift index abda00ee..e3183697 100644 --- a/Shared/YatteeApp.swift +++ b/Shared/YatteeApp.swift @@ -203,7 +203,7 @@ struct YatteeApp: App { recents.clear() } - var section = Defaults[.visibleSections].min()?.tabSelection + var section = Defaults[.showHome] ? TabSelection.home : Defaults[.visibleSections].min()?.tabSelection #if os(macOS) if section == .playlists { diff --git a/tvOS/TVNavigationView.swift b/tvOS/TVNavigationView.swift index 7693a969..f24fc2b5 100644 --- a/tvOS/TVNavigationView.swift +++ b/tvOS/TVNavigationView.swift @@ -13,11 +13,9 @@ struct TVNavigationView: View { var body: some View { NavigationView { TabView(selection: navigation.tabSelectionBinding) { - if visibleSections.contains(.home) { - LazyView(HomeView()) - .tabItem { Text("Home") } - .tag(TabSelection.home) - } + LazyView(HomeView()) + .tabItem { Text("Home") } + .tag(TabSelection.home) if visibleSections.contains(.subscriptions), accounts.app.supportsSubscriptions, accounts.api.signedIn { LazyView(SubscriptionsView())