mirror of
https://github.com/yattee/yattee.git
synced 2024-11-09 15:58:20 +00:00
Home settings
This commit is contained in:
parent
ef1f95a3ad
commit
51bd46b3ae
@ -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 {
|
||||
|
@ -21,7 +21,11 @@ extension Defaults.Keys {
|
||||
|
||||
static let enableReturnYouTubeDislike = Key<Bool>("enableReturnYouTubeDislike", default: false)
|
||||
|
||||
static let homeHistoryItems = Key<Int>("homeHistoryItems", default: 30)
|
||||
static let showHome = Key<Bool>("showHome", default: true)
|
||||
static let showOpenActionsInHome = Key<Bool>("showOpenActionsInHome", default: true)
|
||||
static let showOpenActionsToolbarItem = Key<Bool>("showOpenActionsToolbarItem", default: false)
|
||||
static let showFavoritesInHome = Key<Bool>("showFavoritesInHome", default: true)
|
||||
static let homeHistoryItems = Key<Int>("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>("trendingCategory", default: .default)
|
||||
static let trendingCountry = Key<Country>("trendingCountry", default: .us)
|
||||
|
||||
static let visibleSections = Key<Set<VisibleSection>>("visibleSections", default: [.home])
|
||||
static let visibleSections = Key<Set<VisibleSection>>("visibleSections", default: [.subscriptions, .trending, .playlists])
|
||||
|
||||
#if os(iOS)
|
||||
static let enterFullscreenInLandscape = Key<Bool>("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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -5,6 +5,8 @@ import SwiftUI
|
||||
#endif
|
||||
|
||||
struct AppSidebarNavigation: View {
|
||||
@Default(.showOpenActionsToolbarItem) private var showOpenActionsToolbarItem
|
||||
|
||||
@EnvironmentObject<AccountsModel> private var accounts
|
||||
@EnvironmentObject<NavigationModel> 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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,36 +13,48 @@ struct AppTabNavigation: View {
|
||||
@EnvironmentObject<SubscriptionsModel> private var subscriptions
|
||||
@EnvironmentObject<ThumbnailsModel> 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()
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ struct Sidebar: View {
|
||||
@EnvironmentObject<AccountsModel> private var accounts
|
||||
@EnvironmentObject<NavigationModel> 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"))
|
||||
|
@ -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 {
|
||||
|
@ -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<AccountsModel> 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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())
|
||||
|
Loading…
Reference in New Issue
Block a user