Search and trending menus for iOS

This commit is contained in:
Arkadiusz Fal 2022-12-10 02:19:36 +01:00
parent 64146b26c2
commit 2e3454a18f
6 changed files with 119 additions and 84 deletions

View File

@ -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 { var name: String {
id == "default" ? "Trending".localized() : title id == "default" ? "Trending".localized() : title
} }

View File

@ -145,7 +145,6 @@ struct AppTabNavigation: View {
private var searchNavigationView: some View { private var searchNavigationView: some View {
NavigationView { NavigationView {
LazyView(SearchView()) LazyView(SearchView())
.toolbar { toolbarContent }
} }
.tabItem { .tabItem {
Label("Search", systemImage: "magnifyingglass") Label("Search", systemImage: "magnifyingglass")

View File

@ -2,17 +2,9 @@ import Repeat
import SwiftUI import SwiftUI
struct SearchTextField: View { struct SearchTextField: View {
@Environment(\.navigationStyle) private var navigationStyle
private var navigation = NavigationModel.shared private var navigation = NavigationModel.shared
@ObservedObject private var state = SearchModel.shared @ObservedObject private var state = SearchModel.shared
@Binding var favoriteItem: FavoriteItem?
init(favoriteItem: Binding<FavoriteItem?>? = nil) {
_favoriteItem = favoriteItem ?? .constant(nil)
}
var body: some View { var body: some View {
ZStack { ZStack {
#if os(macOS) #if os(macOS)
@ -41,19 +33,10 @@ struct SearchTextField: View {
.textFieldStyle(.plain) .textFieldStyle(.plain)
#else #else
.textFieldStyle(.roundedBorder) .textFieldStyle(.roundedBorder)
.padding(.leading) .padding(.leading, 5)
.padding(.trailing, 15) .padding(.trailing, 10)
#endif #endif
if let favoriteItem {
#if os(iOS)
FavoriteButton(item: favoriteItem)
.id(favoriteItem.id)
.labelStyle(.iconOnly)
.padding(.trailing)
#endif
}
if !state.queryText.isEmpty { if !state.queryText.isEmpty {
clearButton clearButton
} else { } else {
@ -64,7 +47,6 @@ struct SearchTextField: View {
} }
} }
} }
.padding(.top, navigationStyle == .tab ? 10 : 0)
} }
private var fieldBorder: some View { private var fieldBorder: some View {
@ -83,17 +65,16 @@ struct SearchTextField: View {
self.state.queryText = "" self.state.queryText = ""
}) { }) {
Image(systemName: "xmark.circle.fill") Image(systemName: "xmark.circle.fill")
.resizable()
.aspectRatio(contentMode: .fit)
#if os(macOS) #if os(macOS)
.frame(width: 14, height: 14) .imageScale(.small)
#else #else
.frame(width: 18, height: 18) .imageScale(.medium)
#endif #endif
.padding(.trailing, 3)
} }
.buttonStyle(PlainButtonStyle()) .buttonStyle(PlainButtonStyle())
.padding(.trailing, 10) #if os(macOS)
.opacity(0.7) .padding(.trailing, 10)
#endif
.opacity(0.7)
} }
} }

View File

@ -37,27 +37,9 @@ struct SearchView: View {
} }
var body: some View { var body: some View {
BrowserPlayerControls(toolbar: { BrowserPlayerControls {
#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
}) {
#if os(iOS) #if os(iOS)
VStack { VStack {
SearchTextField(favoriteItem: $favoriteItem)
if accounts.app.supportsSearchSuggestions, state.query.query != state.queryText { if accounts.app.supportsSearchSuggestions, state.query.query != state.queryText {
SearchSuggestions() SearchSuggestions()
.opacity(state.queryText.isEmpty ? 0 : 1) .opacity(state.queryText.isEmpty ? 0 : 1)
@ -182,11 +164,61 @@ struct SearchView: View {
.navigationTitle("Search") .navigationTitle("Search")
#endif #endif
#if os(iOS) #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) .navigationBarTitleDisplayMode(.inline)
#endif #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 { private var navigationBarHidden: Bool {
if navigationStyle == .sidebar { if navigationStyle == .sidebar {
return true return true

View File

@ -33,30 +33,7 @@ struct TrendingView: View {
} }
var body: some View { var body: some View {
BrowserPlayerControls(toolbar: { BrowserPlayerControls {
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)
}) {
Section { Section {
VStack(spacing: 0) { VStack(spacing: 0) {
#if os(tvOS) #if os(tvOS)
@ -137,7 +114,12 @@ struct TrendingView: View {
} }
} }
} }
.navigationBarTitleDisplayMode(RefreshControl.navigationBarTitleDisplayMode) .navigationBarTitleDisplayMode(.inline)
.toolbar {
ToolbarItem(placement: .principal) {
trendingMenu
}
}
#endif #endif
#if !os(macOS) #if !os(macOS)
.onReceive(NotificationCenter.default.publisher(for: UIApplication.willEnterForegroundNotification)) { _ in .onReceive(NotificationCenter.default.publisher(for: UIApplication.willEnterForegroundNotification)) { _ in
@ -174,6 +156,29 @@ struct TrendingView: View {
} }
#endif #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 { private var categoryButton: some View {
#if os(tvOS) #if os(tvOS)
Button(category.name) { Button(category.name) {
@ -190,10 +195,9 @@ struct TrendingView: View {
#else #else
Picker(category.controlLabel, selection: $category) { Picker(category.controlLabel, selection: $category) {
ForEach(TrendingCategory.allCases) { category in ForEach(TrendingCategory.allCases) { category in
Text(category.controlLabel).tag(category) Label(category.controlLabel, systemImage: category.systemImage).tag(category)
} }
} }
.pickerStyle(.menu)
#endif #endif
} }
@ -202,7 +206,12 @@ struct TrendingView: View {
presentingCountrySelection.toggle() presentingCountrySelection.toggle()
resource.removeObservers(ownedBy: store) 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 { struct TrendingView_Previews: PreviewProvider {
static var previews: some View { static var previews: some View {
TrendingView(Video.allFixtures) NavigationView {
.injectFixtureEnvironmentObjects() TrendingView(Video.allFixtures)
}
} }
} }

View File

@ -288,8 +288,8 @@
3744A96028B99ADD005DE0A7 /* PlayerControlsLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3744A95F28B99ADD005DE0A7 /* PlayerControlsLayout.swift */; }; 3744A96028B99ADD005DE0A7 /* PlayerControlsLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3744A95F28B99ADD005DE0A7 /* PlayerControlsLayout.swift */; };
3744A96128B99ADD005DE0A7 /* 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 */; }; 3744A96228B99ADD005DE0A7 /* PlayerControlsLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3744A95F28B99ADD005DE0A7 /* PlayerControlsLayout.swift */; };
374710052755291C00CE0F87 /* SearchField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 374710042755291C00CE0F87 /* SearchField.swift */; }; 374710052755291C00CE0F87 /* SearchTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 374710042755291C00CE0F87 /* SearchTextField.swift */; };
374710062755291C00CE0F87 /* SearchField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 374710042755291C00CE0F87 /* SearchField.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 */; }; 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 */; }; 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 */; }; 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 = "<group>"; }; 3743CA51270F284F00E4D32B /* View+Borders.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View+Borders.swift"; sourceTree = "<group>"; };
3744A95F28B99ADD005DE0A7 /* PlayerControlsLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerControlsLayout.swift; sourceTree = "<group>"; }; 3744A95F28B99ADD005DE0A7 /* PlayerControlsLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerControlsLayout.swift; sourceTree = "<group>"; };
3744F85C293CC9B800B09AB9 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = "<group>"; }; 3744F85C293CC9B800B09AB9 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = "<group>"; };
374710042755291C00CE0F87 /* SearchField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchField.swift; sourceTree = "<group>"; }; 374710042755291C00CE0F87 /* SearchTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchTextField.swift; sourceTree = "<group>"; };
3748186526A7627F0084E870 /* Video+Fixtures.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Video+Fixtures.swift"; sourceTree = "<group>"; }; 3748186526A7627F0084E870 /* Video+Fixtures.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Video+Fixtures.swift"; sourceTree = "<group>"; };
3748186926A764FB0084E870 /* Thumbnail+Fixtures.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Thumbnail+Fixtures.swift"; sourceTree = "<group>"; }; 3748186926A764FB0084E870 /* Thumbnail+Fixtures.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Thumbnail+Fixtures.swift"; sourceTree = "<group>"; };
3748186D26A769D60084E870 /* DetailBadge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailBadge.swift; sourceTree = "<group>"; }; 3748186D26A769D60084E870 /* DetailBadge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailBadge.swift; sourceTree = "<group>"; };
@ -2007,8 +2007,8 @@
3782B95527557A2400990149 /* Search */ = { 3782B95527557A2400990149 /* Search */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
374710042755291C00CE0F87 /* SearchField.swift */,
3782B94E27553A6700990149 /* SearchSuggestions.swift */, 3782B94E27553A6700990149 /* SearchSuggestions.swift */,
374710042755291C00CE0F87 /* SearchTextField.swift */,
37AAF27F26737550007FC770 /* SearchView.swift */, 37AAF27F26737550007FC770 /* SearchView.swift */,
); );
path = Search; path = Search;
@ -2872,7 +2872,7 @@
isa = PBXSourcesBuildPhase; isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
374710052755291C00CE0F87 /* SearchField.swift in Sources */, 374710052755291C00CE0F87 /* SearchTextField.swift in Sources */,
37494EA529200B14000DF176 /* DocumentsView.swift in Sources */, 37494EA529200B14000DF176 /* DocumentsView.swift in Sources */,
374DE88028BB896C0062BBF2 /* PlayerDragGesture.swift in Sources */, 374DE88028BB896C0062BBF2 /* PlayerDragGesture.swift in Sources */,
37ECED56289FE166002BC2C9 /* SafeArea.swift in Sources */, 37ECED56289FE166002BC2C9 /* SafeArea.swift in Sources */,
@ -3123,7 +3123,7 @@
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
3727B74B27872B880021C15E /* VisualEffectBlur-macOS.swift in Sources */, 3727B74B27872B880021C15E /* VisualEffectBlur-macOS.swift in Sources */,
374710062755291C00CE0F87 /* SearchField.swift in Sources */, 374710062755291C00CE0F87 /* SearchTextField.swift in Sources */,
37F0F4EB286F397E00C06C2E /* SettingsModel.swift in Sources */, 37F0F4EB286F397E00C06C2E /* SettingsModel.swift in Sources */,
378AE93F274EDFB5006A4EE1 /* Tint+Backport.swift in Sources */, 378AE93F274EDFB5006A4EE1 /* Tint+Backport.swift in Sources */,
37C194C826F6A9C8005D3B96 /* RecentsModel.swift in Sources */, 37C194C826F6A9C8005D3B96 /* RecentsModel.swift in Sources */,