mirror of
https://github.com/Dimillian/IceCubesApp.git
synced 2024-05-17 03:52:42 +00:00
156 lines
4.1 KiB
Swift
156 lines
4.1 KiB
Swift
import DesignSystem
|
|
import Env
|
|
import Models
|
|
import Network
|
|
import SwiftUI
|
|
|
|
@MainActor
|
|
public struct AccountsListView: View {
|
|
@Environment(Theme.self) private var theme
|
|
@Environment(Client.self) private var client
|
|
@Environment(CurrentAccount.self) private var currentAccount
|
|
@State private var viewModel: AccountsListViewModel
|
|
@State private var didAppear: Bool = false
|
|
|
|
public init(mode: AccountsListMode) {
|
|
_viewModel = .init(initialValue: .init(mode: mode))
|
|
}
|
|
|
|
public var body: some View {
|
|
listView
|
|
#if !os(visionOS)
|
|
.scrollContentBackground(.hidden)
|
|
.background(theme.primaryBackgroundColor)
|
|
#endif
|
|
.listStyle(.plain)
|
|
.toolbar {
|
|
ToolbarItem(placement: .principal) {
|
|
VStack {
|
|
Text(viewModel.mode.title)
|
|
.font(.headline)
|
|
if let count = viewModel.totalCount {
|
|
Text(String(count))
|
|
.font(.footnote)
|
|
.foregroundStyle(.secondary)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.navigationTitle(viewModel.mode.title)
|
|
.navigationBarTitleDisplayMode(.inline)
|
|
.task {
|
|
viewModel.client = client
|
|
guard !didAppear else { return }
|
|
didAppear = true
|
|
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)
|
|
#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:
|
|
NextPageView {
|
|
try await viewModel.fetchNextPage()
|
|
}
|
|
#if !os(visionOS)
|
|
.listRowBackground(theme.primaryBackgroundColor)
|
|
#endif
|
|
|
|
case .none:
|
|
EmptyView()
|
|
}
|
|
|
|
case let .error(error):
|
|
Text(error.localizedDescription)
|
|
#if !os(visionOS)
|
|
.listRowBackground(theme.primaryBackgroundColor)
|
|
#endif
|
|
}
|
|
}
|
|
}
|