summaryrefslogtreecommitdiff
path: root/Hutch/Views/Builds/BuildTaskLogView.swift
diff options
context:
space:
mode:
Diffstat (limited to 'Hutch/Views/Builds/BuildTaskLogView.swift')
-rw-r--r--Hutch/Views/Builds/BuildTaskLogView.swift55
1 files changed, 55 insertions, 0 deletions
diff --git a/Hutch/Views/Builds/BuildTaskLogView.swift b/Hutch/Views/Builds/BuildTaskLogView.swift
new file mode 100644
index 0000000..9ed0bdd
--- /dev/null
+++ b/Hutch/Views/Builds/BuildTaskLogView.swift
@@ -0,0 +1,55 @@
+import SwiftUI
+import UIKit
+
+struct BuildTaskLogView: View {
+ let task: BuildTask
+ let viewModel: BuildDetailViewModel
+
+ var body: some View {
+ Group {
+ if viewModel.loadingTaskLogs.contains(task.logCacheKey) {
+ SRHTLoadingStateView(message: "Loading log…")
+ } else if let logText = viewModel.taskLogs[task.logCacheKey] {
+ GeometryReader { geometry in
+ ScrollView([.vertical, .horizontal]) {
+ Text(logText)
+ .font(.caption2.monospaced())
+ .textSelection(.enabled)
+ .padding()
+ .frame(
+ minWidth: geometry.size.width,
+ minHeight: geometry.size.height,
+ alignment: .topLeading
+ )
+ }
+ }
+ .toolbar {
+ ToolbarItem(placement: .topBarTrailing) {
+ ShareLink(item: logText)
+ }
+ ToolbarItem(placement: .topBarTrailing) {
+ Button {
+ UIPasteboard.general.string = logText
+ } label: {
+ Image(systemName: "doc.on.doc")
+ }
+ .accessibilityLabel("Copy log to clipboard")
+ }
+ }
+ } else if task.log == nil {
+ ContentUnavailableView(
+ "No Log",
+ systemImage: "doc.text",
+ description: Text("This task has no log output.")
+ )
+ } else {
+ SRHTLoadingStateView(message: "Loading log…")
+ }
+ }
+ .navigationTitle(task.name)
+ .navigationBarTitleDisplayMode(.inline)
+ .task {
+ await viewModel.loadTaskLog(task: task)
+ }
+ }
+}