d8a6299600
Recognise own messages by id (prefix and case insensitive) or by node number, so chat bubbles align right with the accent colour even when the message only carries fromNodeNum. Fetch /api/v1/status and /api/status in parallel and merge them, since MeshMonitor 4 dropped localNode from the legacy endpoint. Add a "How to create a token" link, plus Source code and Report a bug links to the Settings screen. Default the server port to 8080 (MeshMonitor's Docker default). Add PRIVACY.md, refresh the README and ignore CLAUDE.md.
54 lines
1.3 KiB
Swift
54 lines
1.3 KiB
Swift
import Foundation
|
|
import Observation
|
|
|
|
@Observable
|
|
final class MeshDataStore {
|
|
var channels: [Channel] = []
|
|
var nodes: [Node] = []
|
|
var status: ServerStatus?
|
|
var loading = false
|
|
var error: String?
|
|
|
|
private(set) var nodeNames: [String: String] = [:]
|
|
|
|
var localNodeId: String? { status?.localNodeId }
|
|
var localNodeNum: Int? { status?.localNodeNum }
|
|
|
|
func refresh(api: APIClient) async {
|
|
await MainActor.run { loading = true; error = nil }
|
|
do {
|
|
async let chTask = api.fetchChannels()
|
|
async let ndTask = api.fetchNodes()
|
|
async let stTask = api.fetchStatus()
|
|
let (chs, nds, st) = try await (chTask, ndTask, stTask)
|
|
await MainActor.run {
|
|
channels = chs.filter { $0.isUsable }.sorted { $0.id < $1.id }
|
|
nodes = nds.sorted {
|
|
(($0.hopsAway ?? 99) < ($1.hopsAway ?? 99))
|
|
}
|
|
status = st
|
|
rebuildNodeNames()
|
|
loading = false
|
|
}
|
|
} catch {
|
|
await MainActor.run {
|
|
self.error = error.localizedDescription
|
|
loading = false
|
|
}
|
|
}
|
|
}
|
|
|
|
private func rebuildNodeNames() {
|
|
var dict: [String: String] = [:]
|
|
for n in nodes {
|
|
if let id = n.nodeId { dict[id] = n.displayName }
|
|
if let num = n.nodeNum { dict[String(num)] = n.displayName }
|
|
}
|
|
nodeNames = dict
|
|
}
|
|
|
|
func displayName(for nodeId: String) -> String {
|
|
nodeNames[nodeId] ?? nodeId
|
|
}
|
|
}
|