Adding search queries to favorites

This commit is contained in:
Arkadiusz Fal
2021-11-09 18:43:15 +01:00
parent afcefc2e54
commit ef5ac0ec65
6 changed files with 96 additions and 21 deletions

View File

@@ -36,7 +36,10 @@ extension Defaults.Keys {
static let sponsorBlockCategories = Key<Set<String>>("sponsorBlockCategories", default: Set(SponsorBlockAPI.categories))
static let favorites = Key<[FavoriteItem]>("favorites", default: [
.init(section: .trending("US", nil))
.init(section: .trending("US", nil)),
.init(section: .searchQuery("World Discoveries", "", "", "")),
.init(section: .searchQuery("Full Body Workout", "", "", "")),
.init(section: .searchQuery("Apple Pie Recipes", "", "", ""))
])
static let channelOnThumbnail = Key<Bool>("channelOnThumbnail", default: true)

View File

@@ -105,6 +105,14 @@ struct FavoriteItemView: View {
case let .playlist(id):
return accounts.api.playlist(id)
case let .searchQuery(text, date, duration, order):
return accounts.api.search(.init(
query: text,
sortBy: SearchQuery.SortOrder(rawValue: order) ?? .uploadDate,
date: SearchQuery.Date(rawValue: date),
duration: SearchQuery.Duration(rawValue: duration)
))
}
return nil

View File

@@ -2,21 +2,19 @@ import Foundation
import Siesta
final class FavoriteResourceObserver: ObservableObject, ResourceObserver {
@Published var videos = [Video]()
@Published var contentItems = [ContentItem]()
func resourceChanged(_ resource: Resource, event _: ResourceEvent) {
if let videos: [Video] = resource.typedContent() {
self.videos = videos
contentItems = videos.map { ContentItem(video: $0) }
} else if let channel: Channel = resource.typedContent() {
videos = channel.videos
contentItems = channel.videos.map { ContentItem(video: $0) }
} else if let playlist: ChannelPlaylist = resource.typedContent() {
videos = playlist.videos
contentItems = playlist.videos.map { ContentItem(video: $0) }
} else if let playlist: Playlist = resource.typedContent() {
videos = playlist.videos
contentItems = playlist.videos.map { ContentItem(video: $0) }
} else if let items: [ContentItem] = resource.typedContent() {
contentItems = items
}
}
var contentItems: [ContentItem] {
videos.map { ContentItem(video: $0) }
}
}

View File

@@ -17,6 +17,8 @@ struct SearchView: View {
@State private var recentsDebounce = Debounce()
#endif
@State private var favoriteItem: FavoriteItem?
@Environment(\.navigationStyle) private var navigationStyle
@EnvironmentObject<AccountsModel> private var accounts
@@ -42,8 +44,17 @@ struct SearchView: View {
} else {
#if os(tvOS)
ScrollView(.vertical, showsIndicators: false) {
if accounts.app.supportsSearchFilters {
filtersHorizontalStack
HStack(spacing: 0) {
if accounts.app.supportsSearchFilters {
filtersHorizontalStack
}
if let favoriteItem = favoriteItem {
FavoriteButton(item: favoriteItem)
.id(favoriteItem.id)
.labelStyle(.iconOnly)
.font(.system(size: 25))
}
}
HorizontalCells(items: items)
@@ -68,6 +79,13 @@ struct SearchView: View {
.toolbar {
#if !os(tvOS)
ToolbarItemGroup(placement: toolbarPlacement) {
#if os(macOS)
if let favoriteItem = favoriteItem {
FavoriteButton(item: favoriteItem)
.id(favoriteItem.id)
}
#endif
if accounts.app.supportsSearchFilters {
Section {
#if os(macOS)
@@ -84,9 +102,20 @@ struct SearchView: View {
#endif
}
.transaction { t in t.animation = .none }
}
#if os(iOS)
Spacer()
if let favoriteItem = favoriteItem {
FavoriteButton(item: favoriteItem)
.id(favoriteItem.id)
}
Spacer()
#endif
if accounts.app.supportsSearchFilters {
filtersMenu
}
}
@@ -96,6 +125,7 @@ struct SearchView: View {
if query != nil {
state.queryText = query!.query
state.resetQuery(query!)
updateFavoriteItem()
}
if !videos.isEmpty {
@@ -120,7 +150,10 @@ struct SearchView: View {
recentsDebounce.invalidate()
searchDebounce.debouncing(2) {
state.changeQuery { query in query.query = newQuery }
state.changeQuery { query in
query.query = newQuery
updateFavoriteItem()
}
}
recentsDebounce.debouncing(10) {
@@ -131,15 +164,25 @@ struct SearchView: View {
.onSubmit(of: .search) {
state.changeQuery { query in query.query = state.queryText }
recents.addQuery(state.queryText)
updateFavoriteItem()
}
.onChange(of: searchSortOrder) { order in
state.changeQuery { query in query.sortBy = order }
state.changeQuery { query in
query.sortBy = order
updateFavoriteItem()
}
}
.onChange(of: searchDate) { date in
state.changeQuery { query in query.date = date }
state.changeQuery { query in
query.date = date
updateFavoriteItem()
}
}
.onChange(of: searchDuration) { duration in
state.changeQuery { query in query.duration = duration }
state.changeQuery { query in
query.duration = duration
updateFavoriteItem()
}
}
#if !os(tvOS)
.navigationTitle("Search")
@@ -192,6 +235,7 @@ struct SearchView: View {
Button(item.title) {
state.queryText = item.title
state.changeQuery { query in query.query = item.title }
updateFavoriteItem()
}
#if os(iOS)
.swipeActions(edge: .trailing) {
@@ -312,21 +356,21 @@ struct SearchView: View {
.foregroundColor(.secondary)
searchSortOrderButton
}
.frame(maxWidth: .infinity, alignment: .trailing)
.frame(maxWidth: 300, alignment: .trailing)
HStack(spacing: 30) {
Text("Duration")
.foregroundColor(.secondary)
searchDurationButton
}
.frame(maxWidth: .infinity)
.frame(maxWidth: 300)
HStack(spacing: 30) {
Text("Date")
.foregroundColor(.secondary)
searchDateButton
}
.frame(maxWidth: .infinity, alignment: .leading)
.frame(maxWidth: 300, alignment: .leading)
}
.font(.system(size: 30))
}
@@ -348,8 +392,16 @@ struct SearchView: View {
.foregroundColor(filtersActive ? .accentColor : .secondary)
.transaction { t in t.animation = .none }
}
#endif
private func updateFavoriteItem() {
favoriteItem = FavoriteItem(section: .searchQuery(
state.query.query,
state.query.date?.rawValue ?? "",
state.query.duration?.rawValue ?? "",
state.query.sortBy.rawValue
))
}
}
struct SearchView_Previews: PreviewProvider {