mirror of
https://github.com/Dimillian/IceCubesApp.git
synced 2024-12-22 07:06:40 +00:00
Status detail + context
This commit is contained in:
parent
c2a2fe1f86
commit
07188a6818
5 changed files with 108 additions and 4 deletions
6
Packages/Models/Sources/Models/StatusContext.swift
Normal file
6
Packages/Models/Sources/Models/StatusContext.swift
Normal file
|
@ -0,0 +1,6 @@
|
|||
import Foundation
|
||||
|
||||
public struct StatusContext: Decodable {
|
||||
public let ancestors: [Status]
|
||||
public let descendants: [Status]
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
import Foundation
|
||||
|
||||
public enum Statuses: Endpoint {
|
||||
case status(id: String)
|
||||
case context(id: String)
|
||||
case favourite(id: String)
|
||||
case unfavourite(id: String)
|
||||
case reblog(id: String)
|
||||
|
@ -8,6 +10,10 @@ public enum Statuses: Endpoint {
|
|||
|
||||
public func path() -> String {
|
||||
switch self {
|
||||
case .status(let id):
|
||||
return "statuses/\(id)"
|
||||
case .context(let id):
|
||||
return "statuses/\(id)/context"
|
||||
case .favourite(let id):
|
||||
return "statuses/\(id)/favourite"
|
||||
case .unfavourite(let id):
|
||||
|
|
|
@ -24,6 +24,7 @@ public struct NotificationsListView: View {
|
|||
.padding(.top, DS.Constants.layoutPadding)
|
||||
}
|
||||
.task {
|
||||
viewModel.client = client
|
||||
await viewModel.fetchNotifications()
|
||||
}
|
||||
.refreshable {
|
||||
|
|
|
@ -1,13 +1,68 @@
|
|||
import SwiftUI
|
||||
import Models
|
||||
import Shimmer
|
||||
import Routeur
|
||||
import Network
|
||||
import DesignSystem
|
||||
|
||||
public struct StatusDetailView: View {
|
||||
private let statusId: String
|
||||
|
||||
@EnvironmentObject private var client: Client
|
||||
@EnvironmentObject private var routeurPath: RouterPath
|
||||
@StateObject private var viewModel: StatusDetailViewModel
|
||||
@State private var isLoaded: Bool = false
|
||||
|
||||
public init(statusId: String) {
|
||||
self.statusId = statusId
|
||||
_viewModel = StateObject(wrappedValue: .init(statusId: statusId))
|
||||
}
|
||||
|
||||
public var body: some View {
|
||||
Text("Status id \(statusId)")
|
||||
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)
|
||||
}
|
||||
}
|
||||
StatusRowView(viewModel: .init(status: status, isEmbed: false))
|
||||
.id(status.id)
|
||||
Divider()
|
||||
.padding(.vertical, DS.Constants.dividerPadding)
|
||||
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)
|
||||
}
|
||||
.task {
|
||||
guard !isLoaded else { return }
|
||||
isLoaded = true
|
||||
viewModel.client = client
|
||||
await viewModel.fetchStatusDetail()
|
||||
DispatchQueue.main.async {
|
||||
proxy.scrollTo(viewModel.statusId, anchor: .center)
|
||||
}
|
||||
}
|
||||
}
|
||||
.navigationTitle(viewModel.title)
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
import Foundation
|
||||
import SwiftUI
|
||||
import Models
|
||||
import Network
|
||||
|
||||
@MainActor
|
||||
class StatusDetailViewModel: ObservableObject {
|
||||
public let statusId: String
|
||||
|
||||
var client: Client?
|
||||
|
||||
enum State {
|
||||
case loading, display(status: Status, context: StatusContext), error(error: Error)
|
||||
}
|
||||
|
||||
@Published var state: State = .loading
|
||||
@Published var title: String = ""
|
||||
|
||||
init(statusId: String) {
|
||||
state = .loading
|
||||
self.statusId = statusId
|
||||
}
|
||||
|
||||
func fetchStatusDetail() async {
|
||||
guard let client else { return }
|
||||
do {
|
||||
state = .loading
|
||||
let status: Status = try await client.get(endpoint: Statuses.status(id: statusId))
|
||||
let context: StatusContext = try await client.get(endpoint: Statuses.context(id: statusId))
|
||||
state = .display(status: status, context: context)
|
||||
title = "Post from \(status.account.displayName)"
|
||||
} catch {
|
||||
state = .error(error: error)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue