diff --git a/Shared/Home/DropFavorite.swift b/Shared/Home/DropFavorite.swift deleted file mode 100644 index 87f03f36..00000000 --- a/Shared/Home/DropFavorite.swift +++ /dev/null @@ -1,43 +0,0 @@ -import Foundation -import SwiftUI - -struct DropFavorite: DropDelegate { - let item: FavoriteItem - @Binding var favorites: [FavoriteItem] - @Binding var current: FavoriteItem? - - func dropEntered(info _: DropInfo) { - guard item != current else { - return - } - - guard let current else { - return - } - - let from = favorites.firstIndex(of: current) - let to = favorites.firstIndex(of: item) - - guard let from, let to else { - return - } - - guard favorites[to].id != current.id else { - return - } - - favorites.move( - fromOffsets: IndexSet(integer: from), - toOffset: to > from ? to + 1 : to - ) - } - - func dropUpdated(info _: DropInfo) -> DropProposal? { - DropProposal(operation: .move) - } - - func performDrop(info _: DropInfo) -> Bool { - current = nil - return true - } -} diff --git a/Shared/Home/DropFavoriteOutside.swift b/Shared/Home/DropFavoriteOutside.swift deleted file mode 100644 index 9204d5e1..00000000 --- a/Shared/Home/DropFavoriteOutside.swift +++ /dev/null @@ -1,11 +0,0 @@ -import Foundation -import SwiftUI - -struct DropFavoriteOutside: DropDelegate { - @Binding var current: FavoriteItem? - - func performDrop(info _: DropInfo) -> Bool { - current = nil - return true - } -} diff --git a/Shared/Home/FavoriteItemView.swift b/Shared/Home/FavoriteItemView.swift index 5ed686a6..f8452255 100644 --- a/Shared/Home/FavoriteItemView.swift +++ b/Shared/Home/FavoriteItemView.swift @@ -56,16 +56,6 @@ struct FavoriteItemView: View { resource?.addObserver(store) resource?.loadIfNeeded() } - #if !os(tvOS) - .onDrag { - dragging = item - return NSItemProvider(object: item.id as NSString) - } - .onDrop( - of: [UTType.text], - delegate: DropFavorite(item: item, favorites: $favorites, current: $dragging) - ) - #endif } } .onChange(of: accounts.current) { _ in diff --git a/Shared/Settings/BrowsingSettings.swift b/Shared/Settings/BrowsingSettings.swift index cf46d1a8..98e519df 100644 --- a/Shared/Settings/BrowsingSettings.swift +++ b/Shared/Settings/BrowsingSettings.swift @@ -23,6 +23,9 @@ struct BrowsingSettings: View { @EnvironmentObject private var accounts @State private var homeHistoryItemsText = "" + #if os(macOS) + @State private var presentingEditFavoritesSheet = false + #endif var body: some View { Group { @@ -67,9 +70,6 @@ struct BrowsingSettings: View { } #endif Toggle("Show Open Videos quick actions", isOn: $showOpenActionsInHome) - if !accounts.isEmpty { - Toggle("Show Favorites", isOn: $showFavoritesInHome) - } HStack { Text("Recent history") TextField("Recent history", text: $homeHistoryItemsText) @@ -85,6 +85,36 @@ struct BrowsingSettings: View { } } .multilineTextAlignment(.trailing) + if !accounts.isEmpty { + Toggle("Show Favorites", isOn: $showFavoritesInHome) + + Group { + #if os(macOS) + Button { + presentingEditFavoritesSheet = true + } label: { + Text("Edit Favorites...") + } + .sheet(isPresented: $presentingEditFavoritesSheet) { + VStack(alignment: .leading) { + Button("Done") { + presentingEditFavoritesSheet = false + } + .padding() + .keyboardShortcut(.cancelAction) + + EditFavorites() + } + .frame(width: 500, height: 300) + } + #else + NavigationLink(destination: LazyView(EditFavorites())) { + Text("Edit Favorites...") + } + #endif + } + .disabled(!showFavoritesInHome) + } } } diff --git a/Shared/Settings/EditFavorites.swift b/Shared/Settings/EditFavorites.swift new file mode 100644 index 00000000..de709b77 --- /dev/null +++ b/Shared/Settings/EditFavorites.swift @@ -0,0 +1,105 @@ +import Defaults +import SwiftUI + +struct EditFavorites: View { + @EnvironmentObject private var playlistsModel + + private var model = FavoritesModel.shared + + @Default(.favorites) private var favorites + + var body: some View { + Group { + List { + Section(header: Text("Favorites")) { + if favorites.isEmpty { + Text("Favorites is empty") + .foregroundColor(.secondary) + } + ForEach(favorites) { item in + HStack { + Text(label(item)) + + Spacer() + HStack(spacing: 30) { + Button { + model.moveUp(item) + } label: { + Label("Move Up", systemImage: "arrow.up") + } + + Button { + model.moveDown(item) + } label: { + Label("Move Down", systemImage: "arrow.down") + } + + Button { + model.remove(item) + } label: { + Label("Remove", systemImage: "trash") + } + } + #if !os(tvOS) + .buttonStyle(.borderless) + #endif + } + } + } + #if os(tvOS) + .padding(.trailing, 40) + #endif + + #if os(tvOS) + Divider() + .padding(20) + #endif + + Section(header: Text("Available")) { + ForEach(model.addableItems()) { item in + HStack { + Text(label(item)) + + Spacer() + + Button { + model.add(item) + } label: { + Label("Add to Favorites", systemImage: "heart") + #if os(tvOS) + .font(.system(size: 30)) + #endif + } + } + } + } + #if os(tvOS) + .padding(.trailing, 40) + #endif + } + .labelStyle(.iconOnly) + .frame(alignment: .leading) + #if os(tvOS) + .frame(width: 1000) + #endif + } + .navigationTitle("Favorites") + } + + func label(_ item: FavoriteItem) -> String { + if case let .playlist(id) = item.section { + return playlistsModel.find(id: id)?.title ?? "Playlist" + } + + return item.section.label + } +} + +struct EditFavorites_Previews: PreviewProvider { + static var previews: some View { + NavigationView { + EditFavorites() + } + .injectFixtureEnvironmentObjects() + } +} diff --git a/Shared/Views/PopularView.swift b/Shared/Views/PopularView.swift index 940b7b38..bb0f0a34 100644 --- a/Shared/Views/PopularView.swift +++ b/Shared/Views/PopularView.swift @@ -26,11 +26,6 @@ struct PopularView: View { #endif } #if !os(tvOS) - .toolbar { - ToolbarItem(placement: .automatic) { - FavoriteButton(item: FavoriteItem(section: .popular)) - } - } .background( Button("Refresh") { resource?.load() diff --git a/Shared/Views/SubscriptionsView.swift b/Shared/Views/SubscriptionsView.swift index cefb46b2..91ea419c 100644 --- a/Shared/Views/SubscriptionsView.swift +++ b/Shared/Views/SubscriptionsView.swift @@ -39,11 +39,6 @@ struct SubscriptionsView: View { } #if !os(tvOS) - .toolbar { - ToolbarItem(placement: .automatic) { - FavoriteButton(item: FavoriteItem(section: .subscriptions)) - } - } .background( Button("Refresh") { loadResources(force: true) diff --git a/Yattee.xcodeproj/project.pbxproj b/Yattee.xcodeproj/project.pbxproj index c2f68710..bb896921 100644 --- a/Yattee.xcodeproj/project.pbxproj +++ b/Yattee.xcodeproj/project.pbxproj @@ -265,6 +265,8 @@ 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 */; }; + 373EBD68291F1EAF002ADB9C /* EditFavorites.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37FADFFF272ED58000330459 /* EditFavorites.swift */; }; + 373EBD69291F252D002ADB9C /* EditFavorites.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37FADFFF272ED58000330459 /* EditFavorites.swift */; }; 3741A32C27E7EFFD00D266D1 /* PlayerControls.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37030FFE27B04DCC00ECDDAA /* PlayerControls.swift */; }; 3743B86927216D3600261544 /* ChannelCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3743B86727216D3600261544 /* ChannelCell.swift */; }; 3743B86A27216D3600261544 /* ChannelCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3743B86727216D3600261544 /* ChannelCell.swift */; }; @@ -666,10 +668,6 @@ 37BE0BD426A1D47D0092E2DB /* AppleAVPlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37BE0BD226A1D4780092E2DB /* AppleAVPlayerView.swift */; }; 37BE0BD726A1D4A90092E2DB /* AppleAVPlayerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37BE0BD526A1D4A90092E2DB /* AppleAVPlayerViewController.swift */; }; 37BE0BDC26A2367F0092E2DB /* AppleAVPlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37BE0BDB26A2367F0092E2DB /* AppleAVPlayerView.swift */; }; - 37BF661C27308859008CCFB0 /* DropFavorite.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37BF661B27308859008CCFB0 /* DropFavorite.swift */; }; - 37BF661D27308859008CCFB0 /* DropFavorite.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37BF661B27308859008CCFB0 /* DropFavorite.swift */; }; - 37BF661F27308884008CCFB0 /* DropFavoriteOutside.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37BF661E27308884008CCFB0 /* DropFavoriteOutside.swift */; }; - 37BF662027308884008CCFB0 /* DropFavoriteOutside.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37BF661E27308884008CCFB0 /* DropFavoriteOutside.swift */; }; 37C069782725962F00F7F6CB /* ScreenSaverManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37C069772725962F00F7F6CB /* ScreenSaverManager.swift */; }; 37C0697A2725C09E00F7F6CB /* PlayerQueueItemBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37C069792725C09E00F7F6CB /* PlayerQueueItemBridge.swift */; }; 37C0697B2725C09E00F7F6CB /* PlayerQueueItemBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37C069792725C09E00F7F6CB /* PlayerQueueItemBridge.swift */; }; @@ -1233,8 +1231,6 @@ 37BE0BD226A1D4780092E2DB /* AppleAVPlayerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppleAVPlayerView.swift; sourceTree = ""; }; 37BE0BD526A1D4A90092E2DB /* AppleAVPlayerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppleAVPlayerViewController.swift; sourceTree = ""; }; 37BE0BDB26A2367F0092E2DB /* AppleAVPlayerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppleAVPlayerView.swift; sourceTree = ""; }; - 37BF661B27308859008CCFB0 /* DropFavorite.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DropFavorite.swift; sourceTree = ""; }; - 37BF661E27308884008CCFB0 /* DropFavoriteOutside.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DropFavoriteOutside.swift; sourceTree = ""; }; 37C069772725962F00F7F6CB /* ScreenSaverManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenSaverManager.swift; sourceTree = ""; }; 37C069792725C09E00F7F6CB /* PlayerQueueItemBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerQueueItemBridge.swift; sourceTree = ""; }; 37C0697D2725C8D400F7F6CB /* CMTime+DefaultTimescale.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CMTime+DefaultTimescale.swift"; sourceTree = ""; }; @@ -1809,6 +1805,7 @@ 37732FEF2703A26300F04329 /* AccountValidationStatus.swift */, 37F0F4ED286F734400C06C2E /* AdvancedSettings.swift */, 376BE50A27349108009AD608 /* BrowsingSettings.swift */, + 37FADFFF272ED58000330459 /* EditFavorites.swift */, 37579D5C27864F5F00FD0B98 /* Help.swift */, 37BC50A72778A84700510953 /* HistorySettings.swift */, 37484C2426FC83E000287258 /* InstanceForm.swift */, @@ -1927,8 +1924,6 @@ 3788AC2126F683AB00F6BAA9 /* Home */ = { isa = PBXGroup; children = ( - 37BF661B27308859008CCFB0 /* DropFavorite.swift */, - 37BF661E27308884008CCFB0 /* DropFavoriteOutside.swift */, 3788AC2626F6840700F6BAA9 /* FavoriteItemView.swift */, 37B263192735EAAB00FE0D40 /* FavoriteResourceObserver.swift */, 37A9965D26D6F9B9006E3224 /* HomeView.swift */, @@ -2093,7 +2088,6 @@ children = ( 37666BA927023AF000F869E5 /* AccountSelectionView.swift */, 37D6025C28C17719009E8D98 /* ControlsOverlayButton.swift */, - 37FADFFF272ED58000330459 /* EditFavorites.swift */, 3730D89F2712E2B70020ED53 /* NowPlayingView.swift */, 37BAB54B269B39FD00E75ED1 /* TVNavigationView.swift */, 37D4B15E267164AF00C925CA /* Assets.xcassets */, @@ -2877,12 +2871,12 @@ 3782B9522755667600990149 /* String+Format.swift in Sources */, 37F9619F27BD90BB00058149 /* PlayerBackendType.swift in Sources */, 373CFAEF2697A78B003CB2C6 /* AddToPlaylistView.swift in Sources */, - 37BF661F27308884008CCFB0 /* DropFavoriteOutside.swift in Sources */, 37EF9A76275BEB8E0043B585 /* CommentView.swift in Sources */, 373C8FE4275B955100CB5936 /* CommentsPage.swift in Sources */, 3700155B271B0D4D0049C794 /* PipedAPI.swift in Sources */, 373031F32838388A000CFD59 /* PlayerLayerView.swift in Sources */, 376E331228AD3B320070E30C /* ScrollDismissesKeyboard+Backport.swift in Sources */, + 373EBD68291F1EAF002ADB9C /* EditFavorites.swift in Sources */, 37B044B726F7AB9000E1419D /* SettingsView.swift in Sources */, 377FC7E3267A084A00A6BBAF /* VideoCell.swift in Sources */, 37C3A251272366440087A57A /* ChannelPlaylistView.swift in Sources */, @@ -2891,7 +2885,6 @@ 37E8B0EC27B326C00024006F /* TimelineView.swift in Sources */, 37136CAC286273060095C0CF /* PersistentSystemOverlays+Backport.swift in Sources */, 374C053527242D9F009BDDBE /* SponsorBlockSettings.swift in Sources */, - 37BF661C27308859008CCFB0 /* DropFavorite.swift in Sources */, 376A33E42720CB35000C1D6B /* Account.swift in Sources */, 3756C2A62861131100E4B059 /* NetworkState.swift in Sources */, 37BA794326DBA973002A0235 /* PlaylistsModel.swift in Sources */, @@ -3067,6 +3060,7 @@ 37CC3F4D270CFE1700608308 /* PlayerQueueView.swift in Sources */, 37B81B0026D2CA3700675966 /* VideoDetails.swift in Sources */, 3752069A285E8DD300CA655F /* Chapter.swift in Sources */, + 373EBD69291F252D002ADB9C /* EditFavorites.swift in Sources */, 37484C1A26FC837400287258 /* PlayerSettings.swift in Sources */, 37BD07C32698AD4F003EBB87 /* ContentView.swift in Sources */, 37484C3226FCB8F900287258 /* AccountValidator.swift in Sources */, @@ -3112,7 +3106,6 @@ 3782B9532755667600990149 /* String+Format.swift in Sources */, 37635FE5291EA6CF00C11E79 /* OpenVideosButton.swift in Sources */, 37E2EEAC270656EC00170416 /* BrowserPlayerControls.swift in Sources */, - 37BF662027308884008CCFB0 /* DropFavoriteOutside.swift in Sources */, 3776ADD7287381240078EBC4 /* Captions.swift in Sources */, 37E70924271CD43000D34DDE /* WelcomeScreen.swift in Sources */, 37F5E8B7291BE9D0006C15F5 /* URLBookmarkModel.swift in Sources */, @@ -3124,7 +3117,6 @@ 37BD07BC2698AB60003EBB87 /* AppSidebarNavigation.swift in Sources */, 37579D5E27864F5F00FD0B98 /* Help.swift in Sources */, 37EF9A77275BEB8E0043B585 /* CommentView.swift in Sources */, - 37BF661D27308859008CCFB0 /* DropFavorite.swift in Sources */, 3748186F26A769D60084E870 /* DetailBadge.swift in Sources */, 3744A96128B99ADD005DE0A7 /* PlayerControlsLayout.swift in Sources */, 372915E72687E3B900F5A35B /* Defaults.swift in Sources */, diff --git a/tvOS/EditFavorites.swift b/tvOS/EditFavorites.swift deleted file mode 100644 index 56745607..00000000 --- a/tvOS/EditFavorites.swift +++ /dev/null @@ -1,91 +0,0 @@ -import Defaults -import SwiftUI - -struct EditFavorites: View { - @EnvironmentObject private var playlistsModel - - private var model = FavoritesModel.shared - - @Default(.favorites) private var favorites - - var body: some View { - VStack { - ScrollView { - ForEach(favorites) { item in - HStack { - Text(label(item)) - - Spacer() - HStack(spacing: 30) { - Button { - model.moveUp(item) - } label: { - Image(systemName: "arrow.up") - } - - Button { - model.moveDown(item) - } label: { - Image(systemName: "arrow.down") - } - - Button { - model.remove(item) - } label: { - Image(systemName: "trash") - } - } - } - } - .padding(.trailing, 40) - - Divider() - .padding(20) - - ForEach(model.addableItems()) { item in - HStack { - Text(label(item)) - - Spacer() - - Button { - model.add(item) - } label: { - Label("Add to Favorites", systemImage: "heart") - .font(.system(size: 30)) - } - } - } - .padding(.trailing, 40) - - HStack { - Text("Add Channels, Playlists and Searches to Favorites using") - Button {} label: { - Label("Add to Favorites", systemImage: "heart") - .labelStyle(.iconOnly) - } - .disabled(true) - } - .foregroundColor(.secondary) - .padding(.top, 80) - } - .frame(width: 1000, alignment: .leading) - } - .navigationTitle("Favorites") - } - - func label(_ item: FavoriteItem) -> String { - if case let .playlist(id) = item.section { - return playlistsModel.find(id: id)?.title ?? "Playlist" - } - - return item.section.label - } -} - -struct EditFavorites_Previews: PreviewProvider { - static var previews: some View { - EditFavorites() - .injectFixtureEnvironmentObjects() - } -}