diff --git a/Model/TrendingCategory.swift b/Model/TrendingCategory.swift index a56fe2c6..4cf0bc15 100644 --- a/Model/TrendingCategory.swift +++ b/Model/TrendingCategory.swift @@ -21,6 +21,19 @@ enum TrendingCategory: String, CaseIterable, Identifiable, Defaults.Serializable } } + var systemImage: String { + switch self { + case .default: + return "chart.bar" + case .music: + return "music.note" + case .gaming: + return "gamecontroller" + case .movies: + return "film" + } + } + var name: String { id == "default" ? "Trending".localized() : title } diff --git a/Shared/Navigation/AppTabNavigation.swift b/Shared/Navigation/AppTabNavigation.swift index 3c1772cb..b265a106 100644 --- a/Shared/Navigation/AppTabNavigation.swift +++ b/Shared/Navigation/AppTabNavigation.swift @@ -145,7 +145,6 @@ struct AppTabNavigation: View { private var searchNavigationView: some View { NavigationView { LazyView(SearchView()) - .toolbar { toolbarContent } } .tabItem { Label("Search", systemImage: "magnifyingglass") diff --git a/Shared/Search/SearchField.swift b/Shared/Search/SearchTextField.swift similarity index 70% rename from Shared/Search/SearchField.swift rename to Shared/Search/SearchTextField.swift index 4ba64491..845e2189 100644 --- a/Shared/Search/SearchField.swift +++ b/Shared/Search/SearchTextField.swift @@ -2,17 +2,9 @@ import Repeat import SwiftUI struct SearchTextField: View { - @Environment(\.navigationStyle) private var navigationStyle - private var navigation = NavigationModel.shared @ObservedObject private var state = SearchModel.shared - @Binding var favoriteItem: FavoriteItem? - - init(favoriteItem: Binding? = nil) { - _favoriteItem = favoriteItem ?? .constant(nil) - } - var body: some View { ZStack { #if os(macOS) @@ -41,19 +33,10 @@ struct SearchTextField: View { .textFieldStyle(.plain) #else .textFieldStyle(.roundedBorder) - .padding(.leading) - .padding(.trailing, 15) + .padding(.leading, 5) + .padding(.trailing, 10) #endif - if let favoriteItem { - #if os(iOS) - FavoriteButton(item: favoriteItem) - .id(favoriteItem.id) - .labelStyle(.iconOnly) - .padding(.trailing) - #endif - } - if !state.queryText.isEmpty { clearButton } else { @@ -64,7 +47,6 @@ struct SearchTextField: View { } } } - .padding(.top, navigationStyle == .tab ? 10 : 0) } private var fieldBorder: some View { @@ -83,17 +65,16 @@ struct SearchTextField: View { self.state.queryText = "" }) { Image(systemName: "xmark.circle.fill") - .resizable() - .aspectRatio(contentMode: .fit) #if os(macOS) - .frame(width: 14, height: 14) + .imageScale(.small) #else - .frame(width: 18, height: 18) + .imageScale(.medium) #endif - .padding(.trailing, 3) } .buttonStyle(PlainButtonStyle()) - .padding(.trailing, 10) - .opacity(0.7) + #if os(macOS) + .padding(.trailing, 10) + #endif + .opacity(0.7) } } diff --git a/Shared/Search/SearchView.swift b/Shared/Search/SearchView.swift index 6e54bf56..58206646 100644 --- a/Shared/Search/SearchView.swift +++ b/Shared/Search/SearchView.swift @@ -37,27 +37,9 @@ struct SearchView: View { } var body: some View { - BrowserPlayerControls(toolbar: { - #if os(iOS) - if accounts.app.supportsSearchFilters { - HStack(spacing: 0) { - Menu("Sort: \(searchSortOrder.name)") { - searchSortOrderPicker - } - .transaction { t in t.animation = .none } - - Spacer() - - filtersMenu - } - .padding() - } - #endif - }) { + BrowserPlayerControls { #if os(iOS) VStack { - SearchTextField(favoriteItem: $favoriteItem) - if accounts.app.supportsSearchSuggestions, state.query.query != state.queryText { SearchSuggestions() .opacity(state.queryText.isEmpty ? 0 : 1) @@ -182,11 +164,61 @@ struct SearchView: View { .navigationTitle("Search") #endif #if os(iOS) - .navigationBarHidden(navigationBarHidden) + .toolbar { + ToolbarItemGroup(placement: .navigationBarLeading) { + if !navigationBarHidden { + Button(action: { NavigationModel.shared.presentingSettings = true }) { + Image(systemName: "gearshape.2") + } + } + } + ToolbarItem(placement: .principal) { + HStack(spacing: 0) { + if !state.query.isEmpty { + searchMenu + } + SearchTextField() + } + } + } .navigationBarTitleDisplayMode(.inline) #endif } + #if os(iOS) + var searchMenu: some View { + Menu { + if accounts.app.supportsSearchFilters { + searchSortOrderPicker + .pickerStyle(.menu) + + Picker(selection: $searchDuration, label: Text("Duration")) { + ForEach(SearchQuery.Duration.allCases) { duration in + Text(duration.name).tag(duration) + } + } + .pickerStyle(.menu) + + Picker("Upload date", selection: $searchDate) { + ForEach(SearchQuery.Date.allCases) { date in + Text(date.name).tag(date) + } + } + .pickerStyle(.menu) + } + + Section { + FavoriteButton(item: favoriteItem) + } + + } label: { + Image(systemName: "chevron.down.circle.fill") + .foregroundColor(.accentColor) + .imageScale(.medium) + } + } + #endif + private var navigationBarHidden: Bool { if navigationStyle == .sidebar { return true diff --git a/Shared/Trending/TrendingView.swift b/Shared/Trending/TrendingView.swift index db350ce1..c931e4ad 100644 --- a/Shared/Trending/TrendingView.swift +++ b/Shared/Trending/TrendingView.swift @@ -33,30 +33,7 @@ struct TrendingView: View { } var body: some View { - BrowserPlayerControls(toolbar: { - HStack { - if accounts.app.supportsTrendingCategories { - categoryButton - .layoutPriority(1) - // only way to disable Menu animation is to - // force redraw of the view when it changes - .id(UUID()) - - Spacer() - } - - if let favoriteItem { - FavoriteButton(item: favoriteItem, labelPadding: true) - .id(favoriteItem.id) - .labelStyle(.iconOnly) - - Spacer() - } - - countryButton - } - .padding(.horizontal) - }) { + BrowserPlayerControls { Section { VStack(spacing: 0) { #if os(tvOS) @@ -137,7 +114,12 @@ struct TrendingView: View { } } } - .navigationBarTitleDisplayMode(RefreshControl.navigationBarTitleDisplayMode) + .navigationBarTitleDisplayMode(.inline) + .toolbar { + ToolbarItem(placement: .principal) { + trendingMenu + } + } #endif #if !os(macOS) .onReceive(NotificationCenter.default.publisher(for: UIApplication.willEnterForegroundNotification)) { _ in @@ -174,6 +156,29 @@ struct TrendingView: View { } #endif + #if os(iOS) + var trendingMenu: some View { + Menu { + countryButton + if accounts.app.supportsTrendingCategories { + categoryButton + } + FavoriteButton(item: favoriteItem) + } label: { + HStack(spacing: 12) { + Text("\(country.flag) \(country.name)") + .font(.headline) + .foregroundColor(.primary) + + Image(systemName: "chevron.down.circle.fill") + .foregroundColor(.accentColor) + .imageScale(.small) + } + .frame(maxWidth: 320) + } + } + #endif + private var categoryButton: some View { #if os(tvOS) Button(category.name) { @@ -190,10 +195,9 @@ struct TrendingView: View { #else Picker(category.controlLabel, selection: $category) { ForEach(TrendingCategory.allCases) { category in - Text(category.controlLabel).tag(category) + Label(category.controlLabel, systemImage: category.systemImage).tag(category) } } - .pickerStyle(.menu) #endif } @@ -202,7 +206,12 @@ struct TrendingView: View { presentingCountrySelection.toggle() resource.removeObservers(ownedBy: store) }) { - Text("\(country.flag) \(country.id)") + #if os(iOS) + Label("Switch country...", systemImage: "flag") + #else + Text("\(country.flag) \(country.id)") + + #endif } } @@ -213,7 +222,8 @@ struct TrendingView: View { struct TrendingView_Previews: PreviewProvider { static var previews: some View { - TrendingView(Video.allFixtures) - .injectFixtureEnvironmentObjects() + NavigationView { + TrendingView(Video.allFixtures) + } } } diff --git a/Yattee.xcodeproj/project.pbxproj b/Yattee.xcodeproj/project.pbxproj index d1e1f4c5..4ab2b379 100644 --- a/Yattee.xcodeproj/project.pbxproj +++ b/Yattee.xcodeproj/project.pbxproj @@ -288,8 +288,8 @@ 3744A96028B99ADD005DE0A7 /* PlayerControlsLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3744A95F28B99ADD005DE0A7 /* PlayerControlsLayout.swift */; }; 3744A96128B99ADD005DE0A7 /* PlayerControlsLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3744A95F28B99ADD005DE0A7 /* PlayerControlsLayout.swift */; }; 3744A96228B99ADD005DE0A7 /* PlayerControlsLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3744A95F28B99ADD005DE0A7 /* PlayerControlsLayout.swift */; }; - 374710052755291C00CE0F87 /* SearchField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 374710042755291C00CE0F87 /* SearchField.swift */; }; - 374710062755291C00CE0F87 /* SearchField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 374710042755291C00CE0F87 /* SearchField.swift */; }; + 374710052755291C00CE0F87 /* SearchTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 374710042755291C00CE0F87 /* SearchTextField.swift */; }; + 374710062755291C00CE0F87 /* SearchTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 374710042755291C00CE0F87 /* SearchTextField.swift */; }; 3748186626A7627F0084E870 /* Video+Fixtures.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3748186526A7627F0084E870 /* Video+Fixtures.swift */; }; 3748186726A7627F0084E870 /* Video+Fixtures.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3748186526A7627F0084E870 /* Video+Fixtures.swift */; }; 3748186826A7627F0084E870 /* Video+Fixtures.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3748186526A7627F0084E870 /* Video+Fixtures.swift */; }; @@ -1127,7 +1127,7 @@ 3743CA51270F284F00E4D32B /* View+Borders.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View+Borders.swift"; sourceTree = ""; }; 3744A95F28B99ADD005DE0A7 /* PlayerControlsLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerControlsLayout.swift; sourceTree = ""; }; 3744F85C293CC9B800B09AB9 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = ""; }; - 374710042755291C00CE0F87 /* SearchField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchField.swift; sourceTree = ""; }; + 374710042755291C00CE0F87 /* SearchTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchTextField.swift; sourceTree = ""; }; 3748186526A7627F0084E870 /* Video+Fixtures.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Video+Fixtures.swift"; sourceTree = ""; }; 3748186926A764FB0084E870 /* Thumbnail+Fixtures.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Thumbnail+Fixtures.swift"; sourceTree = ""; }; 3748186D26A769D60084E870 /* DetailBadge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailBadge.swift; sourceTree = ""; }; @@ -2007,8 +2007,8 @@ 3782B95527557A2400990149 /* Search */ = { isa = PBXGroup; children = ( - 374710042755291C00CE0F87 /* SearchField.swift */, 3782B94E27553A6700990149 /* SearchSuggestions.swift */, + 374710042755291C00CE0F87 /* SearchTextField.swift */, 37AAF27F26737550007FC770 /* SearchView.swift */, ); path = Search; @@ -2872,7 +2872,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 374710052755291C00CE0F87 /* SearchField.swift in Sources */, + 374710052755291C00CE0F87 /* SearchTextField.swift in Sources */, 37494EA529200B14000DF176 /* DocumentsView.swift in Sources */, 374DE88028BB896C0062BBF2 /* PlayerDragGesture.swift in Sources */, 37ECED56289FE166002BC2C9 /* SafeArea.swift in Sources */, @@ -3123,7 +3123,7 @@ buildActionMask = 2147483647; files = ( 3727B74B27872B880021C15E /* VisualEffectBlur-macOS.swift in Sources */, - 374710062755291C00CE0F87 /* SearchField.swift in Sources */, + 374710062755291C00CE0F87 /* SearchTextField.swift in Sources */, 37F0F4EB286F397E00C06C2E /* SettingsModel.swift in Sources */, 378AE93F274EDFB5006A4EE1 /* Tint+Backport.swift in Sources */, 37C194C826F6A9C8005D3B96 /* RecentsModel.swift in Sources */,