mirror of
https://github.com/Dimillian/IceCubesApp.git
synced 2024-11-26 02:01:02 +00:00
Paginate search results fix #2143
This commit is contained in:
parent
719c023369
commit
123f05538a
9 changed files with 74 additions and 13 deletions
|
@ -150,7 +150,7 @@ public enum AccountsListMode {
|
||||||
state = .loading
|
state = .loading
|
||||||
try await Task.sleep(for: .milliseconds(250))
|
try await Task.sleep(for: .milliseconds(250))
|
||||||
var results: SearchResults = try await client.get(endpoint: Search.search(query: searchQuery,
|
var results: SearchResults = try await client.get(endpoint: Search.search(query: searchQuery,
|
||||||
type: "accounts",
|
type: .accounts,
|
||||||
offset: nil,
|
offset: nil,
|
||||||
following: true),
|
following: true),
|
||||||
forceVersion: .v2)
|
forceVersion: .v2)
|
||||||
|
|
|
@ -260,7 +260,7 @@ public enum SettingsStartingPoint {
|
||||||
public func navigateToAccountFrom(acct: String, url: URL) async {
|
public func navigateToAccountFrom(acct: String, url: URL) async {
|
||||||
guard let client else { return }
|
guard let client else { return }
|
||||||
let results: SearchResults? = try? await client.get(endpoint: Search.search(query: acct,
|
let results: SearchResults? = try? await client.get(endpoint: Search.search(query: acct,
|
||||||
type: "accounts",
|
type: .accounts,
|
||||||
offset: nil,
|
offset: nil,
|
||||||
following: nil),
|
following: nil),
|
||||||
forceVersion: .v2)
|
forceVersion: .v2)
|
||||||
|
@ -274,7 +274,7 @@ public enum SettingsStartingPoint {
|
||||||
public func navigateToAccountFrom(url: URL) async {
|
public func navigateToAccountFrom(url: URL) async {
|
||||||
guard let client else { return }
|
guard let client else { return }
|
||||||
let results: SearchResults? = try? await client.get(endpoint: Search.search(query: url.absoluteString,
|
let results: SearchResults? = try? await client.get(endpoint: Search.search(query: url.absoluteString,
|
||||||
type: "accounts",
|
type: .accounts,
|
||||||
offset: nil,
|
offset: nil,
|
||||||
following: nil),
|
following: nil),
|
||||||
forceVersion: .v2)
|
forceVersion: .v2)
|
||||||
|
|
|
@ -181,6 +181,9 @@ public struct ExploreView: View {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if viewModel.searchScope == .people {
|
||||||
|
makeNextPageView(for: .accounts)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !results.hashtags.isEmpty, viewModel.searchScope == .all || viewModel.searchScope == .hashtags {
|
if !results.hashtags.isEmpty, viewModel.searchScope == .all || viewModel.searchScope == .hashtags {
|
||||||
|
@ -196,6 +199,9 @@ public struct ExploreView: View {
|
||||||
#endif
|
#endif
|
||||||
.padding(.vertical, 4)
|
.padding(.vertical, 4)
|
||||||
}
|
}
|
||||||
|
if viewModel.searchScope == .hashtags {
|
||||||
|
makeNextPageView(for: .hashtags)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !results.statuses.isEmpty, viewModel.searchScope == .all || viewModel.searchScope == .posts {
|
if !results.statuses.isEmpty, viewModel.searchScope == .all || viewModel.searchScope == .posts {
|
||||||
|
@ -211,6 +217,9 @@ public struct ExploreView: View {
|
||||||
#endif
|
#endif
|
||||||
.padding(.vertical, 8)
|
.padding(.vertical, 8)
|
||||||
}
|
}
|
||||||
|
if viewModel.searchScope == .posts {
|
||||||
|
makeNextPageView(for: .statuses)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -345,4 +354,14 @@ public struct ExploreView: View {
|
||||||
viewModel.scrollToTopVisible = false
|
viewModel.scrollToTopVisible = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func makeNextPageView(for type: Search.EntityType) -> some View {
|
||||||
|
NextPageView {
|
||||||
|
await viewModel.fetchNextPage(of: type)
|
||||||
|
}
|
||||||
|
.padding(.horizontal, .layoutPadding)
|
||||||
|
#if !os(visionOS)
|
||||||
|
.listRowBackground(theme.primaryBackgroundColor)
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,4 +115,42 @@ import SwiftUI
|
||||||
isSearching = false
|
isSearching = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func fetchNextPage(of type: Search.EntityType) async {
|
||||||
|
guard let client, !searchQuery.isEmpty,
|
||||||
|
let results = results[searchQuery] else { return }
|
||||||
|
do {
|
||||||
|
let offset = switch type {
|
||||||
|
case .accounts:
|
||||||
|
results.accounts.count
|
||||||
|
case .hashtags:
|
||||||
|
results.hashtags.count
|
||||||
|
case .statuses:
|
||||||
|
results.statuses.count
|
||||||
|
}
|
||||||
|
|
||||||
|
var newPageResults: SearchResults = try await client.get(endpoint: Search.search(query: searchQuery,
|
||||||
|
type: type,
|
||||||
|
offset: offset,
|
||||||
|
following: nil),
|
||||||
|
forceVersion: .v2)
|
||||||
|
if type == .accounts {
|
||||||
|
let relationships: [Relationship] =
|
||||||
|
try await client.get(endpoint: Accounts.relationships(ids: newPageResults.accounts.map(\.id)))
|
||||||
|
newPageResults.relationships = relationships
|
||||||
|
}
|
||||||
|
|
||||||
|
switch type {
|
||||||
|
case .accounts:
|
||||||
|
self.results[searchQuery]?.accounts.append(contentsOf: newPageResults.accounts)
|
||||||
|
self.results[searchQuery]?.relationships.append(contentsOf: newPageResults.relationships)
|
||||||
|
case .hashtags:
|
||||||
|
self.results[searchQuery]?.hashtags.append(contentsOf: newPageResults.hashtags)
|
||||||
|
case .statuses:
|
||||||
|
self.results[searchQuery]?.statuses.append(contentsOf: newPageResults.statuses)
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,10 +5,10 @@ public struct SearchResults: Decodable {
|
||||||
case accounts, statuses, hashtags
|
case accounts, statuses, hashtags
|
||||||
}
|
}
|
||||||
|
|
||||||
public let accounts: [Account]
|
public var accounts: [Account]
|
||||||
public var relationships: [Relationship] = []
|
public var relationships: [Relationship] = []
|
||||||
public let statuses: [Status]
|
public var statuses: [Status]
|
||||||
public let hashtags: [Tag]
|
public var hashtags: [Tag]
|
||||||
|
|
||||||
public var isEmpty: Bool {
|
public var isEmpty: Bool {
|
||||||
accounts.isEmpty && statuses.isEmpty && hashtags.isEmpty
|
accounts.isEmpty && statuses.isEmpty && hashtags.isEmpty
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
public enum Search: Endpoint {
|
public enum Search: Endpoint {
|
||||||
case search(query: String, type: String?, offset: Int?, following: Bool?)
|
public enum EntityType: String, Sendable {
|
||||||
case accountsSearch(query: String, type: String?, offset: Int?, following: Bool?)
|
case accounts, hashtags, statuses
|
||||||
|
}
|
||||||
|
|
||||||
|
case search(query: String, type: EntityType?, offset: Int?, following: Bool?)
|
||||||
|
case accountsSearch(query: String, type: EntityType?, offset: Int?, following: Bool?)
|
||||||
|
|
||||||
public func path() -> String {
|
public func path() -> String {
|
||||||
switch self {
|
switch self {
|
||||||
|
@ -19,7 +23,7 @@ public enum Search: Endpoint {
|
||||||
let .accountsSearch(query, type, offset, following):
|
let .accountsSearch(query, type, offset, following):
|
||||||
var params: [URLQueryItem] = [.init(name: "q", value: query)]
|
var params: [URLQueryItem] = [.init(name: "q", value: query)]
|
||||||
if let type {
|
if let type {
|
||||||
params.append(.init(name: "type", value: type))
|
params.append(.init(name: "type", value: type.rawValue))
|
||||||
}
|
}
|
||||||
if let offset {
|
if let offset {
|
||||||
params.append(.init(name: "offset", value: String(offset)))
|
params.append(.init(name: "offset", value: String(offset)))
|
||||||
|
|
|
@ -58,7 +58,7 @@ import SwiftUI
|
||||||
private func fetchRemoteStatus() async -> Bool {
|
private func fetchRemoteStatus() async -> Bool {
|
||||||
guard let client, let remoteStatusURL else { return false }
|
guard let client, let remoteStatusURL else { return false }
|
||||||
let results: SearchResults? = try? await client.get(endpoint: Search.search(query: remoteStatusURL.absoluteString,
|
let results: SearchResults? = try? await client.get(endpoint: Search.search(query: remoteStatusURL.absoluteString,
|
||||||
type: "statuses",
|
type: .statuses,
|
||||||
offset: nil,
|
offset: nil,
|
||||||
following: nil),
|
following: nil),
|
||||||
forceVersion: .v2)
|
forceVersion: .v2)
|
||||||
|
|
|
@ -591,7 +591,7 @@ public extension StatusEditor {
|
||||||
showRecentsTagsInline = false
|
showRecentsTagsInline = false
|
||||||
query.removeFirst()
|
query.removeFirst()
|
||||||
results = try await client.get(endpoint: Search.search(query: query,
|
results = try await client.get(endpoint: Search.search(query: query,
|
||||||
type: "hashtags",
|
type: .hashtags,
|
||||||
offset: 0,
|
offset: 0,
|
||||||
following: nil),
|
following: nil),
|
||||||
forceVersion: .v2)
|
forceVersion: .v2)
|
||||||
|
|
|
@ -280,7 +280,7 @@ import SwiftUI
|
||||||
embed = try await client.get(endpoint: Statuses.status(id: String(id)))
|
embed = try await client.get(endpoint: Statuses.status(id: String(id)))
|
||||||
} else {
|
} else {
|
||||||
let results: SearchResults = try await client.get(endpoint: Search.search(query: url.absoluteString,
|
let results: SearchResults = try await client.get(endpoint: Search.search(query: url.absoluteString,
|
||||||
type: "statuses",
|
type: .statuses,
|
||||||
offset: 0,
|
offset: 0,
|
||||||
following: nil),
|
following: nil),
|
||||||
forceVersion: .v2)
|
forceVersion: .v2)
|
||||||
|
@ -449,7 +449,7 @@ import SwiftUI
|
||||||
guard isRemote, let remoteStatusURL = URL(string: finalStatus.url ?? "") else { return false }
|
guard isRemote, let remoteStatusURL = URL(string: finalStatus.url ?? "") else { return false }
|
||||||
isLoadingRemoteContent = true
|
isLoadingRemoteContent = true
|
||||||
let results: SearchResults? = try? await client.get(endpoint: Search.search(query: remoteStatusURL.absoluteString,
|
let results: SearchResults? = try? await client.get(endpoint: Search.search(query: remoteStatusURL.absoluteString,
|
||||||
type: "statuses",
|
type: .statuses,
|
||||||
offset: nil,
|
offset: nil,
|
||||||
following: nil),
|
following: nil),
|
||||||
forceVersion: .v2)
|
forceVersion: .v2)
|
||||||
|
|
Loading…
Reference in a new issue