mirror of
https://github.com/Dimillian/IceCubesApp.git
synced 2024-12-23 07:36:48 +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
|
||||
try await Task.sleep(for: .milliseconds(250))
|
||||
var results: SearchResults = try await client.get(endpoint: Search.search(query: searchQuery,
|
||||
type: "accounts",
|
||||
type: .accounts,
|
||||
offset: nil,
|
||||
following: true),
|
||||
forceVersion: .v2)
|
||||
|
|
|
@ -260,7 +260,7 @@ public enum SettingsStartingPoint {
|
|||
public func navigateToAccountFrom(acct: String, url: URL) async {
|
||||
guard let client else { return }
|
||||
let results: SearchResults? = try? await client.get(endpoint: Search.search(query: acct,
|
||||
type: "accounts",
|
||||
type: .accounts,
|
||||
offset: nil,
|
||||
following: nil),
|
||||
forceVersion: .v2)
|
||||
|
@ -274,7 +274,7 @@ public enum SettingsStartingPoint {
|
|||
public func navigateToAccountFrom(url: URL) async {
|
||||
guard let client else { return }
|
||||
let results: SearchResults? = try? await client.get(endpoint: Search.search(query: url.absoluteString,
|
||||
type: "accounts",
|
||||
type: .accounts,
|
||||
offset: nil,
|
||||
following: nil),
|
||||
forceVersion: .v2)
|
||||
|
|
|
@ -181,6 +181,9 @@ public struct ExploreView: View {
|
|||
#endif
|
||||
}
|
||||
}
|
||||
if viewModel.searchScope == .people {
|
||||
makeNextPageView(for: .accounts)
|
||||
}
|
||||
}
|
||||
}
|
||||
if !results.hashtags.isEmpty, viewModel.searchScope == .all || viewModel.searchScope == .hashtags {
|
||||
|
@ -196,6 +199,9 @@ public struct ExploreView: View {
|
|||
#endif
|
||||
.padding(.vertical, 4)
|
||||
}
|
||||
if viewModel.searchScope == .hashtags {
|
||||
makeNextPageView(for: .hashtags)
|
||||
}
|
||||
}
|
||||
}
|
||||
if !results.statuses.isEmpty, viewModel.searchScope == .all || viewModel.searchScope == .posts {
|
||||
|
@ -211,6 +217,9 @@ public struct ExploreView: View {
|
|||
#endif
|
||||
.padding(.vertical, 8)
|
||||
}
|
||||
if viewModel.searchScope == .posts {
|
||||
makeNextPageView(for: .statuses)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -345,4 +354,14 @@ public struct ExploreView: View {
|
|||
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
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
public let accounts: [Account]
|
||||
public var accounts: [Account]
|
||||
public var relationships: [Relationship] = []
|
||||
public let statuses: [Status]
|
||||
public let hashtags: [Tag]
|
||||
public var statuses: [Status]
|
||||
public var hashtags: [Tag]
|
||||
|
||||
public var isEmpty: Bool {
|
||||
accounts.isEmpty && statuses.isEmpty && hashtags.isEmpty
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
import Foundation
|
||||
|
||||
public enum Search: Endpoint {
|
||||
case search(query: String, type: String?, offset: Int?, following: Bool?)
|
||||
case accountsSearch(query: String, type: String?, offset: Int?, following: Bool?)
|
||||
public enum EntityType: String, Sendable {
|
||||
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 {
|
||||
switch self {
|
||||
|
@ -19,7 +23,7 @@ public enum Search: Endpoint {
|
|||
let .accountsSearch(query, type, offset, following):
|
||||
var params: [URLQueryItem] = [.init(name: "q", value: query)]
|
||||
if let type {
|
||||
params.append(.init(name: "type", value: type))
|
||||
params.append(.init(name: "type", value: type.rawValue))
|
||||
}
|
||||
if let offset {
|
||||
params.append(.init(name: "offset", value: String(offset)))
|
||||
|
|
|
@ -58,7 +58,7 @@ import SwiftUI
|
|||
private func fetchRemoteStatus() async -> Bool {
|
||||
guard let client, let remoteStatusURL else { return false }
|
||||
let results: SearchResults? = try? await client.get(endpoint: Search.search(query: remoteStatusURL.absoluteString,
|
||||
type: "statuses",
|
||||
type: .statuses,
|
||||
offset: nil,
|
||||
following: nil),
|
||||
forceVersion: .v2)
|
||||
|
|
|
@ -591,7 +591,7 @@ public extension StatusEditor {
|
|||
showRecentsTagsInline = false
|
||||
query.removeFirst()
|
||||
results = try await client.get(endpoint: Search.search(query: query,
|
||||
type: "hashtags",
|
||||
type: .hashtags,
|
||||
offset: 0,
|
||||
following: nil),
|
||||
forceVersion: .v2)
|
||||
|
|
|
@ -280,7 +280,7 @@ import SwiftUI
|
|||
embed = try await client.get(endpoint: Statuses.status(id: String(id)))
|
||||
} else {
|
||||
let results: SearchResults = try await client.get(endpoint: Search.search(query: url.absoluteString,
|
||||
type: "statuses",
|
||||
type: .statuses,
|
||||
offset: 0,
|
||||
following: nil),
|
||||
forceVersion: .v2)
|
||||
|
@ -449,7 +449,7 @@ import SwiftUI
|
|||
guard isRemote, let remoteStatusURL = URL(string: finalStatus.url ?? "") else { return false }
|
||||
isLoadingRemoteContent = true
|
||||
let results: SearchResults? = try? await client.get(endpoint: Search.search(query: remoteStatusURL.absoluteString,
|
||||
type: "statuses",
|
||||
type: .statuses,
|
||||
offset: nil,
|
||||
following: nil),
|
||||
forceVersion: .v2)
|
||||
|
|
Loading…
Reference in a new issue