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 {
|
2023-01-06 11:14:05 +00:00
|
|
|
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
|
|
|
|
2023-01-06 11:14:05 +00:00
|
|
|
init(remoteStatusURL: URL) {
|
|
|
|
state = .loading
|
|
|
|
self.remoteStatusURL = remoteStatusURL
|
2023-01-17 10:36:01 +00:00
|
|
|
statusId = nil
|
2023-01-06 11:14:05 +00:00
|
|
|
}
|
2023-01-17 10:36:01 +00:00
|
|
|
|
2023-01-06 11:14:05 +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
|
|
|
|
2023-01-06 11:14:05 +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",
|
2023-01-06 11:14:05 +00:00
|
|
|
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
|
|
|
|
2023-01-06 11:14:05 +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)
|
2023-01-12 05:58:04 +00:00
|
|
|
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
|
|
|
}
|