Files
jundot--omlx/apps/omlx-mac/Sources/AppView/ViewModels/LogsScreenVM.swift
T
wehub-resource-sync e9a2f726c9
CI / test (3.11) (push) Has been cancelled
CI / test (3.12) (push) Has been cancelled
CI / test (3.13) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:29:51 +08:00

90 lines
2.5 KiB
Swift

import SwiftUI
@MainActor
@Observable
final class LogsScreenVM {
var lines: Int = 100
var selectedFile: String = ""
var logText: String = ""
var availableFiles: [String] = []
var lastError: String?
private(set) var isLoading: Bool = false
private(set) var totalLines: Int = 0
private(set) var refreshKey: Int = 0
@ObservationIgnored
private weak var client: OMLXClient?
@ObservationIgnored
private var pollTask: Task<Void, Never>?
var subtitle: String {
guard !logText.isEmpty else { return "" }
return String(localized: "logs.subtitle.line_count",
defaultValue: "Lines: \(totalLines)",
comment: "Section header subtitle on the Logs screen; placeholder is the total number of log lines")
}
var fileOptions: [(String, String)] {
availableFiles.map { name in
let label = name == "server.log"
? String(localized: "logs.file.current",
defaultValue: "server.log (current)",
comment: "Popup label for the active server log file in the Logs screen file selector")
: name
return (name, label)
}
}
func start(client: OMLXClient) async {
self.client = client
pollTask?.cancel()
pollTask = Task { [weak self] in
while !Task.isCancelled {
guard let self else { return }
await self.tick()
try? await Task.sleep(for: .seconds(5))
}
}
}
func stop() {
pollTask?.cancel()
pollTask = nil
}
func reload() async {
await tick()
}
func bumpRefreshKey() {
refreshKey &+= 1
}
func copyToPasteboard() {
let pb = NSPasteboard.general
pb.clearContents()
pb.setString(logText, forType: .string)
}
private func tick() async {
guard let client else { return }
isLoading = true
defer { isLoading = false }
let file = selectedFile.isEmpty ? nil : selectedFile
do {
let dto = try await client.getLogs(lines: lines, file: file)
self.logText = dto.logs
self.totalLines = dto.totalLines
self.availableFiles = dto.availableFiles
if selectedFile.isEmpty {
self.selectedFile = dto.logFile
}
self.lastError = nil
} catch {
self.lastError = error.omlxDescription
}
}
}