IceCubesApp/Packages/Status/Sources/Status/Detail/StatusDetailVIew.swift

94 lines
3.2 KiB
Swift
Raw Normal View History

2022-11-29 10:46:02 +00:00
import SwiftUI
2022-12-21 17:28:21 +00:00
import Models
import Shimmer
2022-12-22 09:53:36 +00:00
import Env
2022-12-21 17:28:21 +00:00
import Network
import DesignSystem
2022-11-29 10:46:02 +00:00
public struct StatusDetailView: View {
2022-12-29 09:39:34 +00:00
@EnvironmentObject private var theme: Theme
2022-12-25 16:39:23 +00:00
@EnvironmentObject private var currentAccount: CurrentAccount
@EnvironmentObject private var watcher: StreamWatcher
2022-12-21 17:28:21 +00:00
@EnvironmentObject private var client: Client
@EnvironmentObject private var routeurPath: RouterPath
@StateObject private var viewModel: StatusDetailViewModel
@State private var isLoaded: Bool = false
2022-11-29 10:46:02 +00:00
public init(statusId: String) {
2022-12-21 17:28:21 +00:00
_viewModel = StateObject(wrappedValue: .init(statusId: statusId))
2022-11-29 10:46:02 +00:00
}
public init(remoteStatusURL: URL) {
_viewModel = StateObject(wrappedValue: .init(remoteStatusURL: remoteStatusURL))
}
2022-11-29 10:46:02 +00:00
public var body: some View {
2022-12-21 17:28:21 +00:00
ScrollViewReader { proxy in
ScrollView {
LazyVStack {
switch viewModel.state {
case .loading:
ForEach(Status.placeholders()) { status in
2022-12-29 16:22:07 +00:00
StatusRowView(viewModel: .init(status: status, isCompact: false))
2023-01-03 17:46:35 +00:00
.padding(.horizontal, .layoutPadding)
2022-12-21 17:28:21 +00:00
.redacted(reason: .placeholder)
.shimmering()
2023-01-03 17:46:35 +00:00
Divider()
.padding(.vertical, .dividerPadding)
2022-12-21 17:28:21 +00:00
}
case let.display(status, context):
if !context.ancestors.isEmpty {
ForEach(context.ancestors) { ancestor in
2022-12-29 16:22:07 +00:00
StatusRowView(viewModel: .init(status: ancestor, isCompact: false))
2023-01-03 17:46:35 +00:00
.padding(.horizontal, .layoutPadding)
2022-12-21 17:28:21 +00:00
Divider()
.padding(.vertical, .dividerPadding)
2022-12-21 17:28:21 +00:00
}
}
2022-12-24 12:41:25 +00:00
StatusRowView(viewModel: .init(status: status,
2022-12-29 16:22:07 +00:00
isCompact: false,
2022-12-24 12:41:25 +00:00
isFocused: true))
2023-01-03 17:46:35 +00:00
.padding(.horizontal, .layoutPadding)
2022-12-21 17:28:21 +00:00
.id(status.id)
Divider()
.padding(.bottom, .dividerPadding * 2)
2022-12-21 17:28:21 +00:00
if !context.descendants.isEmpty {
ForEach(context.descendants) { descendant in
2022-12-29 16:22:07 +00:00
StatusRowView(viewModel: .init(status: descendant, isCompact: false))
2023-01-03 17:46:35 +00:00
.padding(.horizontal, .layoutPadding)
2022-12-21 17:28:21 +00:00
Divider()
.padding(.vertical, .dividerPadding)
2022-12-21 17:28:21 +00:00
}
}
case let .error(error):
Text(error.localizedDescription)
2023-01-03 17:46:35 +00:00
.padding(.horizontal, .layoutPadding)
2022-12-21 17:28:21 +00:00
}
}
.padding(.top, .layoutPadding)
2022-12-21 17:28:21 +00:00
}
.scrollContentBackground(.hidden)
2022-12-29 09:39:34 +00:00
.background(theme.primaryBackgroundColor)
2022-12-21 17:28:21 +00:00
.task {
guard !isLoaded else { return }
isLoaded = true
viewModel.client = client
let result = await viewModel.fetch()
if !result {
_ = routeurPath.path.popLast()
}
2022-12-21 17:28:21 +00:00
DispatchQueue.main.async {
proxy.scrollTo(viewModel.statusId, anchor: .center)
}
}
2022-12-25 16:39:23 +00:00
.onChange(of: watcher.latestEvent?.id) { _ in
guard let lastEvent = watcher.latestEvent else { return }
viewModel.handleEvent(event: lastEvent, currentAccount: currentAccount.account)
}
2022-12-21 17:28:21 +00:00
}
.navigationTitle(viewModel.title)
.navigationBarTitleDisplayMode(.inline)
2022-11-29 10:46:02 +00:00
}
}