mirror of
https://github.com/yattee/yattee.git
synced 2025-08-04 01:34:10 +00:00
Search and trending menus for iOS
This commit is contained in:
@@ -145,7 +145,6 @@ struct AppTabNavigation: View {
|
||||
private var searchNavigationView: some View {
|
||||
NavigationView {
|
||||
LazyView(SearchView())
|
||||
.toolbar { toolbarContent }
|
||||
}
|
||||
.tabItem {
|
||||
Label("Search", systemImage: "magnifyingglass")
|
||||
|
@@ -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<FavoriteItem?>? = 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)
|
||||
}
|
||||
}
|
@@ -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
|
||||
|
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user