IceCubesApp/Packages/Conversations/Sources/Conversations/Detail/ConversationDetailViewModel.swift
Thomas Ricouard 4189a59cf6
iOS 17+ only support + migrating to Observation framework (#1571)
* Initial iOS 17 + Observable migration

* More Observation

* More observation

* Checkpoint

* Checkpoint

* Bump version to 1.8.0

* SwiftFormat

* Fix home timeline switch on login

* Fix sidebar routerPath

* Fixes on detail view

* Remove print changes

* Simply detail view

* More opt

* Migrate DisplaySettingsLocalValues

* Better post detail transition

* Status detail animation finally right

* Cleanup
2023-09-18 07:01:23 +02:00

79 lines
2.3 KiB
Swift

import Foundation
import Models
import Network
import SwiftUI
@MainActor
@Observable class ConversationDetailViewModel {
var client: Client?
var conversation: Conversation
var isLoadingMessages: Bool = true
var messages: [Status] = []
var isSendingMessage: Bool = false
var newMessageText: String = ""
init(conversation: Conversation) {
self.conversation = conversation
messages = conversation.lastStatus != nil ? [conversation.lastStatus!] : []
}
func fetchMessages() async {
guard let client, let lastMessageId = messages.last?.id else { return }
do {
let context: StatusContext = try await client.get(endpoint: Statuses.context(id: lastMessageId))
isLoadingMessages = false
messages.insert(contentsOf: context.ancestors, at: 0)
messages.append(contentsOf: context.descendants)
} catch {}
}
func postMessage() async {
guard let client else { return }
isSendingMessage = true
var finalText = conversation.accounts.map { "@\($0.acct)" }.joined(separator: " ")
finalText += " "
finalText += newMessageText
let data = StatusData(status: finalText,
visibility: .direct,
inReplyToId: messages.last?.id)
do {
let status: Status = try await client.post(endpoint: Statuses.postStatus(json: data))
appendNewStatus(status: status)
withAnimation {
newMessageText = ""
isSendingMessage = false
}
} catch {
isSendingMessage = false
}
}
func handleEvent(event: any StreamEvent) {
if let event = event as? StreamEventStatusUpdate,
let index = messages.firstIndex(where: { $0.id == event.status.id })
{
messages[index] = event.status
} else if let event = event as? StreamEventDelete,
let index = messages.firstIndex(where: { $0.id == event.status })
{
messages.remove(at: index)
} else if let event = event as? StreamEventConversation,
event.conversation.id == conversation.id
{
conversation = event.conversation
if conversation.lastStatus != nil {
appendNewStatus(status: conversation.lastStatus!)
}
}
}
private func appendNewStatus(status: Status) {
if !messages.contains(where: { $0.id == status.id }) {
messages.append(status)
}
}
}