Add suggestions in search screen

This commit is contained in:
PangMo5 2021-07-15 23:59:10 +09:00
parent 356b9176f7
commit 9bdb9a2c62
3 changed files with 77 additions and 27 deletions

View File

@ -12,43 +12,70 @@ import SwiftUI
struct LibrarySearchView: View {
@StateObject var viewModel: LibrarySearchViewModel
@State var searchQuery = ""
@State private var tracks: [GridItem] = Array(repeating: .init(.flexible()), count: Int(UIScreen.main.bounds.size.width) / 125)
func recalcTracks() {
tracks = Array(repeating: .init(.flexible()), count: Int(UIScreen.main.bounds.size.width) / 125)
}
var body: some View {
VStack {
Spacer().frame(height: 6)
SearchBar(text: $searchQuery)
ZStack {
if !viewModel.isLoading {
ScrollView(.vertical) {
if !viewModel.items.isEmpty {
Spacer().frame(height: 16)
LazyVGrid(columns: tracks) {
ForEach(viewModel.items, id: \.id) { item in
PortraitItemView(item: item)
}
Spacer().frame(height: 16)
}
.onRotate { _ in
recalcTracks()
}
} else {
Text("Query returned 0 results.")
}
}
ZStack {
VStack {
SearchBar(text: $searchQuery)
.padding(.vertical, 8)
if searchQuery.isEmpty {
suggestionsListView
} else {
ProgressView()
itemsGridView
}
}
if viewModel.isLoading {
ProgressView()
}
}
.onChange(of: searchQuery) { query in
viewModel.searchQuerySubject.send(query)
}
.navigationBarTitle("Search", displayMode: .inline)
}
var suggestionsListView: some View {
ScrollView {
LazyVStack(alignment: .leading, spacing: 8) {
Text("Suggestions")
.font(.title)
.foregroundColor(.primary)
.padding(.bottom, 8)
ForEach(viewModel.suggestions, id: \.id) { item in
Button {
searchQuery = item.name ?? ""
} label: {
Text(item.name ?? "")
.font(.body)
.foregroundColor(.secondary)
}
}
}
.padding(.horizontal, 16)
}
}
var itemsGridView: some View {
ScrollView {
if !viewModel.items.isEmpty {
LazyVGrid(columns: tracks) {
ForEach(viewModel.items, id: \.id) { item in
PortraitItemView(item: item)
}
}
.padding(.bottom, 16)
.onRotate { _ in
recalcTracks()
}
} else {
Text("Query returned 0 results.")
}
}
}
}

View File

@ -12,8 +12,9 @@ import Foundation
import JellyfinAPI
final class LibrarySearchViewModel: ViewModel {
@Published
var items = [BaseItemDto]()
@Published var items = [BaseItemDto]()
@Published var suggestions = [BaseItemDto]()
var searchQuerySubject = CurrentValueSubject<String, Never>("")
var parentID: String?
@ -23,9 +24,29 @@ final class LibrarySearchViewModel: ViewModel {
super.init()
searchQuerySubject
.filter { !$0.isEmpty }
.debounce(for: 0.25, scheduler: DispatchQueue.main)
.sink(receiveValue: search(with:))
.store(in: &cancellables)
requestSuggestions()
}
func requestSuggestions() {
ItemsAPI.getItemsByUserId(userId: SessionManager.current.user.user_id!,
limit: 20,
recursive: true,
parentId: parentID,
includeItemTypes: ["Movie", "Series", "MusicArtist"],
sortBy: ["IsFavoriteOrLiked", "Random"],
imageTypeLimit: 0,
enableTotalRecordCount: false,
enableImages: false)
.trackActivity(loading)
.sink(receiveCompletion: handleAPIRequestCompletion(completion:)) { [weak self] response in
self?.suggestions = response.items ?? []
}
.store(in: &cancellables)
}
func search(with query: String) {

View File

@ -10,6 +10,7 @@
import Foundation
import Combine
import Nuke
import UIKit
#if !os(tvOS)
import WidgetKit
@ -28,6 +29,7 @@ final class SplashViewModel: ViewModel {
#if !os(tvOS)
WidgetCenter.shared.reloadAllTimelines()
UIScrollView.appearance().keyboardDismissMode = .onDrag
#endif
let nc = NotificationCenter.default