IceCubesApp/Packages/Explore/Sources/Explore/ExploreView.swift

232 lines
7.5 KiB
Swift
Raw Normal View History

2023-01-17 10:36:01 +00:00
import Account
import DesignSystem
2023-01-17 10:36:01 +00:00
import Env
import Models
2023-01-17 10:36:01 +00:00
import Network
import Shimmer
2023-01-17 10:36:01 +00:00
import Status
import SwiftUI
public struct ExploreView: View {
2022-12-24 14:09:17 +00:00
@EnvironmentObject private var theme: Theme
@EnvironmentObject private var client: Client
@EnvironmentObject private var routeurPath: RouterPath
2023-01-17 10:36:01 +00:00
@StateObject private var viewModel = ExploreViewModel()
2023-01-17 10:36:01 +00:00
public init() {}
public var body: some View {
List {
2022-12-27 09:04:39 +00:00
if !viewModel.searchQuery.isEmpty {
if let results = viewModel.results[viewModel.searchQuery] {
makeSearchResultsView(results: results)
} else {
loadingView
}
2022-12-27 09:04:39 +00:00
} else if !viewModel.isLoaded {
loadingView
} else if viewModel.allSectionsEmpty {
2023-01-12 05:30:43 +00:00
EmptyView(iconName: "magnifyingglass",
title: "Search your instance",
message: "From this screen you can search anything on \(client.server)")
2023-01-17 10:36:01 +00:00
.listRowBackground(theme.secondaryBackgroundColor)
} else {
2023-01-12 05:30:43 +00:00
if !viewModel.trendingTags.isEmpty {
trendingTagsSection
}
if !viewModel.suggestedAccounts.isEmpty {
suggestedAccountsSection
}
if !viewModel.trendingStatuses.isEmpty {
trendingPostsSection
}
if !viewModel.trendingLinks.isEmpty {
trendingLinksSection
}
}
}
.task {
viewModel.client = client
await viewModel.fetchTrending()
}
.refreshable {
Task {
await viewModel.fetchTrending()
}
}
.listStyle(.grouped)
2022-12-29 09:39:34 +00:00
.scrollContentBackground(.hidden)
.background(theme.secondaryBackgroundColor)
.navigationTitle("Explore")
2022-12-27 06:51:44 +00:00
.searchable(text: $viewModel.searchQuery,
tokens: $viewModel.tokens,
suggestedTokens: $viewModel.suggestedToken,
prompt: Text("Search users, posts and tags"),
token: { token in
2023-01-17 10:36:01 +00:00
Text(token.rawValue)
})
}
2023-01-17 10:36:01 +00:00
2022-12-27 09:04:39 +00:00
private var loadingView: some View {
ForEach(Status.placeholders()) { status in
2022-12-29 16:22:07 +00:00
StatusRowView(viewModel: .init(status: status, isCompact: false))
2022-12-27 09:04:39 +00:00
.padding(.vertical, 8)
.redacted(reason: .placeholder)
.shimmering()
2022-12-29 09:39:34 +00:00
.listRowBackground(theme.primaryBackgroundColor)
2022-12-27 09:04:39 +00:00
}
}
2023-01-17 10:36:01 +00:00
2022-12-27 09:04:39 +00:00
@ViewBuilder
private func makeSearchResultsView(results: SearchResults) -> some View {
if !results.accounts.isEmpty {
Section("Users") {
ForEach(results.accounts) { account in
if let relationship = results.relationships.first(where: { $0.id == account.id }) {
AccountsListRow(viewModel: .init(account: account, relationShip: relationship))
2022-12-29 09:39:34 +00:00
.listRowBackground(theme.primaryBackgroundColor)
2022-12-27 09:04:39 +00:00
}
}
}
}
if !results.hashtags.isEmpty {
Section("Tags") {
ForEach(results.hashtags) { tag in
TagRowView(tag: tag)
2022-12-29 09:39:34 +00:00
.listRowBackground(theme.primaryBackgroundColor)
2022-12-27 09:04:39 +00:00
.padding(.vertical, 4)
}
}
}
if !results.statuses.isEmpty {
Section("Posts") {
ForEach(results.statuses) { status in
StatusRowView(viewModel: .init(status: status))
2022-12-29 09:39:34 +00:00
.listRowBackground(theme.primaryBackgroundColor)
2022-12-27 09:04:39 +00:00
.padding(.vertical, 8)
}
}
}
}
2023-01-17 10:36:01 +00:00
private var suggestedAccountsSection: some View {
Section("Suggested Users") {
ForEach(viewModel.suggestedAccounts
.prefix(upTo: viewModel.suggestedAccounts.count > 3 ? 3 : viewModel.suggestedAccounts.count)) { account in
2023-01-17 10:36:01 +00:00
if let relationship = viewModel.suggestedAccountsRelationShips.first(where: { $0.id == account.id }) {
AccountsListRow(viewModel: .init(account: account, relationShip: relationship))
.listRowBackground(theme.primaryBackgroundColor)
}
}
NavigationLink {
List {
ForEach(viewModel.suggestedAccounts) { account in
if let relationship = viewModel.suggestedAccountsRelationShips.first(where: { $0.id == account.id }) {
2022-12-23 17:47:19 +00:00
AccountsListRow(viewModel: .init(account: account, relationShip: relationship))
2022-12-29 09:39:34 +00:00
.listRowBackground(theme.primaryBackgroundColor)
}
}
}
.scrollContentBackground(.hidden)
.background(theme.primaryBackgroundColor)
.listStyle(.plain)
.navigationTitle("Suggested Users")
.navigationBarTitleDisplayMode(.inline)
} label: {
Text("See more")
2022-12-24 14:09:17 +00:00
.foregroundColor(theme.tintColor)
}
2022-12-29 09:39:34 +00:00
.listRowBackground(theme.primaryBackgroundColor)
}
}
2023-01-17 10:36:01 +00:00
private var trendingTagsSection: some View {
Section("Trending Tags") {
ForEach(viewModel.trendingTags
.prefix(upTo: viewModel.trendingTags.count > 5 ? 5 : viewModel.trendingTags.count)) { tag in
2023-01-17 10:36:01 +00:00
TagRowView(tag: tag)
2022-12-29 09:39:34 +00:00
.listRowBackground(theme.primaryBackgroundColor)
2023-01-17 10:36:01 +00:00
.padding(.vertical, 4)
}
NavigationLink {
List {
ForEach(viewModel.trendingTags) { tag in
TagRowView(tag: tag)
2022-12-29 09:39:34 +00:00
.listRowBackground(theme.primaryBackgroundColor)
.padding(.vertical, 4)
}
}
.scrollContentBackground(.hidden)
.background(theme.primaryBackgroundColor)
.listStyle(.plain)
.navigationTitle("Trending Tags")
.navigationBarTitleDisplayMode(.inline)
} label: {
Text("See more")
2022-12-24 14:09:17 +00:00
.foregroundColor(theme.tintColor)
}
2022-12-29 09:39:34 +00:00
.listRowBackground(theme.primaryBackgroundColor)
}
}
2023-01-17 10:36:01 +00:00
private var trendingPostsSection: some View {
Section("Trending Posts") {
ForEach(viewModel.trendingStatuses
.prefix(upTo: viewModel.trendingStatuses.count > 3 ? 3 : viewModel.trendingStatuses.count)) { status in
2023-01-17 10:36:01 +00:00
StatusRowView(viewModel: .init(status: status, isCompact: false))
2022-12-29 09:39:34 +00:00
.listRowBackground(theme.primaryBackgroundColor)
2023-01-17 10:36:01 +00:00
.padding(.vertical, 8)
}
NavigationLink {
List {
ForEach(viewModel.trendingStatuses) { status in
2022-12-29 16:22:07 +00:00
StatusRowView(viewModel: .init(status: status, isCompact: false))
2022-12-29 09:39:34 +00:00
.listRowBackground(theme.primaryBackgroundColor)
.padding(.vertical, 8)
}
}
.scrollContentBackground(.hidden)
.background(theme.primaryBackgroundColor)
.listStyle(.plain)
.navigationTitle("Trending Posts")
.navigationBarTitleDisplayMode(.inline)
} label: {
Text("See more")
2022-12-24 14:09:17 +00:00
.foregroundColor(theme.tintColor)
}
2022-12-29 09:39:34 +00:00
.listRowBackground(theme.primaryBackgroundColor)
}
}
2023-01-17 10:36:01 +00:00
private var trendingLinksSection: some View {
Section("Trending Links") {
ForEach(viewModel.trendingLinks
.prefix(upTo: viewModel.trendingLinks.count > 3 ? 3 : viewModel.trendingLinks.count)) { card in
2023-01-17 10:36:01 +00:00
StatusCardView(card: card)
2022-12-29 09:39:34 +00:00
.listRowBackground(theme.primaryBackgroundColor)
2023-01-17 10:36:01 +00:00
.padding(.vertical, 8)
}
NavigationLink {
List {
ForEach(viewModel.trendingLinks) { card in
StatusCardView(card: card)
2022-12-29 09:39:34 +00:00
.listRowBackground(theme.primaryBackgroundColor)
.padding(.vertical, 8)
}
}
.scrollContentBackground(.hidden)
.background(theme.primaryBackgroundColor)
.listStyle(.plain)
.navigationTitle("Trending Links")
.navigationBarTitleDisplayMode(.inline)
} label: {
Text("See more")
2022-12-24 14:09:17 +00:00
.foregroundColor(theme.tintColor)
}
2022-12-29 09:39:34 +00:00
.listRowBackground(theme.primaryBackgroundColor)
}
}
}