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 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
|
|
|
|
StatusRowView(viewModel: .init(status: status, isEmbed: false))
|
|
|
|
.redacted(reason: .placeholder)
|
|
|
|
.shimmering()
|
|
|
|
}
|
|
|
|
case let.display(status, context):
|
|
|
|
if !context.ancestors.isEmpty {
|
|
|
|
ForEach(context.ancestors) { ancestor in
|
|
|
|
StatusRowView(viewModel: .init(status: ancestor, isEmbed: false))
|
|
|
|
Divider()
|
|
|
|
.padding(.vertical, DS.Constants.dividerPadding)
|
|
|
|
}
|
|
|
|
}
|
2022-12-24 12:41:25 +00:00
|
|
|
StatusRowView(viewModel: .init(status: status,
|
|
|
|
isEmbed: false,
|
|
|
|
isFocused: true))
|
2022-12-21 17:28:21 +00:00
|
|
|
.id(status.id)
|
|
|
|
Divider()
|
2022-12-24 12:41:25 +00:00
|
|
|
.padding(.bottom, DS.Constants.dividerPadding * 2)
|
2022-12-21 17:28:21 +00:00
|
|
|
if !context.descendants.isEmpty {
|
|
|
|
ForEach(context.descendants) { descendant in
|
|
|
|
StatusRowView(viewModel: .init(status: descendant, isEmbed: false))
|
|
|
|
Divider()
|
|
|
|
.padding(.vertical, DS.Constants.dividerPadding)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
case let .error(error):
|
|
|
|
Text(error.localizedDescription)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.padding(.horizontal, DS.Constants.layoutPadding)
|
2022-12-26 07:47:41 +00:00
|
|
|
.padding(.top, DS.Constants.layoutPadding)
|
2022-12-21 17:28:21 +00:00
|
|
|
}
|
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
|
|
|
|
await viewModel.fetchStatusDetail()
|
|
|
|
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
|
|
|
}
|
|
|
|
}
|