Add following search fix #1846

This commit is contained in:
Thomas Ricouard 2024-01-09 13:28:51 +01:00
parent 3a173a8cae
commit e7864f7089
2 changed files with 144 additions and 79 deletions

View file

@ -18,85 +18,7 @@ public struct AccountsListView: View {
} }
public var body: some View { public var body: some View {
List { listView
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
}
}
#if !os(visionOS) #if !os(visionOS)
.scrollContentBackground(.hidden) .scrollContentBackground(.hidden)
.background(theme.primaryBackgroundColor) .background(theme.primaryBackgroundColor)
@ -124,6 +46,122 @@ public struct AccountsListView: View {
await viewModel.fetch() 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 { private var loadingRow: some View {
HStack { HStack {

View file

@ -47,6 +47,9 @@ public enum AccountsListMode {
var state = State.loading var state = State.loading
var totalCount: Int? var totalCount: Int?
var accountId: String?
var searchQuery: String = ""
private var nextPageId: String? private var nextPageId: String?
@ -66,6 +69,7 @@ public enum AccountsListMode {
(accounts, link) = try await client.getWithLink(endpoint: Accounts.followers(id: accountId, (accounts, link) = try await client.getWithLink(endpoint: Accounts.followers(id: accountId,
maxId: nil)) maxId: nil))
case let .following(accountId): case let .following(accountId):
self.accountId = accountId
let account: Account = try await client.get(endpoint: Accounts.accounts(id: accountId)) let account: Account = try await client.get(endpoint: Accounts.accounts(id: accountId))
totalCount = account.followingCount totalCount = account.followingCount
(accounts, link) = try await client.getWithLink(endpoint: Accounts.following(id: accountId, (accounts, link) = try await client.getWithLink(endpoint: Accounts.following(id: accountId,
@ -125,4 +129,27 @@ public enum AccountsListMode {
print(error) 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 {
}
}
} }