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

84 lines
2.4 KiB
Swift
Raw Normal View History

2022-12-21 17:28:21 +00:00
import Foundation
import Models
import Network
2023-01-17 10:36:01 +00:00
import SwiftUI
2022-12-21 17:28:21 +00:00
@MainActor
class StatusDetailViewModel: ObservableObject {
public var statusId: String?
public var remoteStatusURL: URL?
2023-01-17 10:36:01 +00:00
2022-12-21 17:28:21 +00:00
var client: Client?
2023-01-17 10:36:01 +00:00
2022-12-21 17:28:21 +00:00
enum State {
case loading, display(status: Status, context: StatusContext), error(error: Error)
}
2023-01-17 10:36:01 +00:00
2022-12-21 17:28:21 +00:00
@Published var state: State = .loading
@Published var title: String = ""
2023-01-17 10:36:01 +00:00
2022-12-21 17:28:21 +00:00
init(statusId: String) {
state = .loading
self.statusId = statusId
2023-01-17 10:36:01 +00:00
remoteStatusURL = nil
2022-12-21 17:28:21 +00:00
}
2023-01-17 10:36:01 +00:00
init(remoteStatusURL: URL) {
state = .loading
self.remoteStatusURL = remoteStatusURL
2023-01-17 10:36:01 +00:00
statusId = nil
}
2023-01-17 10:36:01 +00:00
func fetch() async -> Bool {
if statusId != nil {
await fetchStatusDetail()
return true
} else if remoteStatusURL != nil {
return await fetchRemoteStatus()
}
return false
}
2023-01-17 10:36:01 +00:00
private func fetchRemoteStatus() async -> Bool {
guard let client, let remoteStatusURL else { return false }
let results: SearchResults? = try? await client.get(endpoint: Search.search(query: remoteStatusURL.absoluteString,
2023-01-17 10:36:01 +00:00
type: "statuses",
offset: nil,
following: nil),
forceVersion: .v2)
if let statusId = results?.statuses.first?.id {
self.statusId = statusId
await fetchStatusDetail()
return true
} else {
return false
}
}
2023-01-17 10:36:01 +00:00
private func fetchStatusDetail() async {
guard let client, let statusId else { return }
2022-12-21 17:28:21 +00:00
do {
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.displayNameWithoutEmojis)"
2022-12-21 17:28:21 +00:00
} catch {
state = .error(error: error)
}
}
2023-01-17 10:36:01 +00:00
2022-12-25 16:39:23 +00:00
func handleEvent(event: any StreamEvent, currentAccount: Account?) {
if let event = event as? StreamEventUpdate,
2023-01-17 10:36:01 +00:00
event.status.account.id == currentAccount?.id
{
2022-12-25 16:39:23 +00:00
Task {
await fetchStatusDetail()
}
} else if event is StreamEventDelete {
Task {
await fetchStatusDetail()
}
}
}
2022-12-21 17:28:21 +00:00
}