mirror of
https://github.com/Dimillian/IceCubesApp.git
synced 2024-11-29 03:31:02 +00:00
Add following search fix #1846
This commit is contained in:
parent
3a173a8cae
commit
e7864f7089
2 changed files with 144 additions and 79 deletions
|
@ -18,85 +18,7 @@ public struct AccountsListView: View {
|
|||
}
|
||||
|
||||
public var body: some View {
|
||||
List {
|
||||
switch viewModel.state {
|
||||
case .loading:
|
||||
ForEach(Account.placeholders()) { _ in
|
||||
AccountsListRow(viewModel: .init(account: .placeholder(), relationShip: .placeholder()))
|
||||
.redacted(reason: .placeholder)
|
||||
.allowsHitTesting(false)
|
||||
.shimmering()
|
||||
#if !os(visionOS)
|
||||
.listRowBackground(theme.primaryBackgroundColor)
|
||||
#endif
|
||||
}
|
||||
case let .display(accounts, relationships, nextPageState):
|
||||
if case .followers = viewModel.mode,
|
||||
!currentAccount.followRequests.isEmpty
|
||||
{
|
||||
Section(
|
||||
header: Text("account.follow-requests.pending-requests"),
|
||||
footer: Text("account.follow-requests.instructions")
|
||||
.font(.scaledFootnote)
|
||||
.foregroundColor(.secondary)
|
||||
.offset(y: -8)
|
||||
) {
|
||||
ForEach(currentAccount.followRequests) { account in
|
||||
AccountsListRow(
|
||||
viewModel: .init(account: account),
|
||||
isFollowRequest: true,
|
||||
requestUpdated: {
|
||||
Task {
|
||||
await viewModel.fetch()
|
||||
}
|
||||
}
|
||||
)
|
||||
#if !os(visionOS)
|
||||
.listRowBackground(theme.primaryBackgroundColor)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
Section {
|
||||
ForEach(accounts) { account in
|
||||
if let relationship = relationships.first(where: { $0.id == account.id }) {
|
||||
AccountsListRow(viewModel: .init(account: account,
|
||||
relationShip: relationship))
|
||||
#if !os(visionOS)
|
||||
.listRowBackground(theme.primaryBackgroundColor)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch nextPageState {
|
||||
case .hasNextPage:
|
||||
loadingRow
|
||||
#if !os(visionOS)
|
||||
.listRowBackground(theme.primaryBackgroundColor)
|
||||
#endif
|
||||
.onAppear {
|
||||
Task {
|
||||
await viewModel.fetchNextPage()
|
||||
}
|
||||
}
|
||||
|
||||
case .loadingNextPage:
|
||||
loadingRow
|
||||
#if !os(visionOS)
|
||||
.listRowBackground(theme.primaryBackgroundColor)
|
||||
#endif
|
||||
case .none:
|
||||
EmptyView()
|
||||
}
|
||||
|
||||
case let .error(error):
|
||||
Text(error.localizedDescription)
|
||||
#if !os(visionOS)
|
||||
.listRowBackground(theme.primaryBackgroundColor)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
listView
|
||||
#if !os(visionOS)
|
||||
.scrollContentBackground(.hidden)
|
||||
.background(theme.primaryBackgroundColor)
|
||||
|
@ -124,6 +46,122 @@ public struct AccountsListView: View {
|
|||
await viewModel.fetch()
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private var listView: some View {
|
||||
if currentAccount.account?.id == viewModel.accountId {
|
||||
searchableList
|
||||
} else {
|
||||
standardList
|
||||
}
|
||||
}
|
||||
|
||||
private var searchableList: some View {
|
||||
List {
|
||||
listContent
|
||||
}
|
||||
.searchable(text: $viewModel.searchQuery,
|
||||
placement: .navigationBarDrawer(displayMode: .always))
|
||||
.task(id: viewModel.searchQuery) {
|
||||
if !viewModel.searchQuery.isEmpty {
|
||||
await viewModel.search()
|
||||
}
|
||||
}
|
||||
.onChange(of: viewModel.searchQuery) { _, newValue in
|
||||
if newValue.isEmpty {
|
||||
Task {
|
||||
await viewModel.fetch()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var standardList: some View {
|
||||
List {
|
||||
listContent
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private var listContent: some View {
|
||||
switch viewModel.state {
|
||||
case .loading:
|
||||
ForEach(Account.placeholders()) { _ in
|
||||
AccountsListRow(viewModel: .init(account: .placeholder(), relationShip: .placeholder()))
|
||||
.redacted(reason: .placeholder)
|
||||
.allowsHitTesting(false)
|
||||
.shimmering()
|
||||
#if !os(visionOS)
|
||||
.listRowBackground(theme.primaryBackgroundColor)
|
||||
#endif
|
||||
}
|
||||
case let .display(accounts, relationships, nextPageState):
|
||||
if case .followers = viewModel.mode,
|
||||
!currentAccount.followRequests.isEmpty
|
||||
{
|
||||
Section(
|
||||
header: Text("account.follow-requests.pending-requests"),
|
||||
footer: Text("account.follow-requests.instructions")
|
||||
.font(.scaledFootnote)
|
||||
.foregroundColor(.secondary)
|
||||
.offset(y: -8)
|
||||
) {
|
||||
ForEach(currentAccount.followRequests) { account in
|
||||
AccountsListRow(
|
||||
viewModel: .init(account: account),
|
||||
isFollowRequest: true,
|
||||
requestUpdated: {
|
||||
Task {
|
||||
await viewModel.fetch()
|
||||
}
|
||||
}
|
||||
)
|
||||
#if !os(visionOS)
|
||||
.listRowBackground(theme.primaryBackgroundColor)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
Section {
|
||||
ForEach(accounts) { account in
|
||||
if let relationship = relationships.first(where: { $0.id == account.id }) {
|
||||
AccountsListRow(viewModel: .init(account: account,
|
||||
relationShip: relationship))
|
||||
#if !os(visionOS)
|
||||
.listRowBackground(theme.primaryBackgroundColor)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch nextPageState {
|
||||
case .hasNextPage:
|
||||
loadingRow
|
||||
#if !os(visionOS)
|
||||
.listRowBackground(theme.primaryBackgroundColor)
|
||||
#endif
|
||||
.onAppear {
|
||||
Task {
|
||||
await viewModel.fetchNextPage()
|
||||
}
|
||||
}
|
||||
|
||||
case .loadingNextPage:
|
||||
loadingRow
|
||||
#if !os(visionOS)
|
||||
.listRowBackground(theme.primaryBackgroundColor)
|
||||
#endif
|
||||
case .none:
|
||||
EmptyView()
|
||||
}
|
||||
|
||||
case let .error(error):
|
||||
Text(error.localizedDescription)
|
||||
#if !os(visionOS)
|
||||
.listRowBackground(theme.primaryBackgroundColor)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
private var loadingRow: some View {
|
||||
HStack {
|
||||
|
|
|
@ -47,6 +47,9 @@ public enum AccountsListMode {
|
|||
|
||||
var state = State.loading
|
||||
var totalCount: Int?
|
||||
var accountId: String?
|
||||
|
||||
var searchQuery: String = ""
|
||||
|
||||
private var nextPageId: String?
|
||||
|
||||
|
@ -66,6 +69,7 @@ public enum AccountsListMode {
|
|||
(accounts, link) = try await client.getWithLink(endpoint: Accounts.followers(id: accountId,
|
||||
maxId: nil))
|
||||
case let .following(accountId):
|
||||
self.accountId = accountId
|
||||
let account: Account = try await client.get(endpoint: Accounts.accounts(id: accountId))
|
||||
totalCount = account.followingCount
|
||||
(accounts, link) = try await client.getWithLink(endpoint: Accounts.following(id: accountId,
|
||||
|
@ -125,4 +129,27 @@ public enum AccountsListMode {
|
|||
print(error)
|
||||
}
|
||||
}
|
||||
|
||||
func search() async {
|
||||
guard let client, !searchQuery.isEmpty else { return }
|
||||
do {
|
||||
state = .loading
|
||||
try await Task.sleep(for: .milliseconds(250))
|
||||
var results: SearchResults = try await client.get(endpoint: Search.search(query: searchQuery,
|
||||
type: "accounts",
|
||||
offset: nil,
|
||||
following: true),
|
||||
forceVersion: .v2)
|
||||
let relationships: [Relationship] =
|
||||
try await client.get(endpoint: Accounts.relationships(ids: results.accounts.map(\.id)))
|
||||
results.relationships = relationships
|
||||
withAnimation {
|
||||
state = .display(accounts: results.accounts,
|
||||
relationships: relationships,
|
||||
nextPageState: .none)
|
||||
}
|
||||
} catch {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue