Build iOS App / Build .ipa and publish source (push) Failing after 5m44s
- LogStore: bounded in-memory + persisted log of API calls and errors, viewable and shareable from Settings → View logs. - GiteaClient: log every request/response status (esp. 404s). - Inbox: a single failing repo no longer wipes the whole inbox — per-repo errors are caught, logged, and the rest still load. - Bump to 1.2 so SideStore offers the update.
78 lines
2.8 KiB
Swift
78 lines
2.8 KiB
Swift
import SwiftUI
|
|
import UIKit
|
|
|
|
/// Diagnostic log viewer. Shows the in-memory/persisted log entries with a
|
|
/// Share button (so the user can send logs to Hermes) and a Clear button.
|
|
struct LogsView: View {
|
|
@ObservedObject private var store = LogStore.shared
|
|
@State private var showShare = false
|
|
|
|
var body: some View {
|
|
Group {
|
|
if store.entries.isEmpty {
|
|
ContentUnavailableView(
|
|
"No logs yet",
|
|
systemImage: "doc.text",
|
|
description: Text("Run the app and reproduce the issue, then come back here."))
|
|
} else {
|
|
List {
|
|
ForEach(store.entries.reversed()) { entry in
|
|
VStack(alignment: .leading, spacing: 2) {
|
|
HStack {
|
|
Text(entry.level.rawValue)
|
|
.font(.caption2.weight(.bold))
|
|
.foregroundColor(color(for: entry.level))
|
|
Text(entry.timestamp, style: .time)
|
|
.font(.caption2)
|
|
.foregroundColor(.secondary)
|
|
}
|
|
Text(entry.message)
|
|
.font(.caption.monospaced())
|
|
.textSelection(.enabled)
|
|
}
|
|
.padding(.vertical, 2)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.navigationTitle("Logs")
|
|
.navigationBarTitleDisplayMode(.inline)
|
|
.toolbar {
|
|
ToolbarItem(placement: .primaryAction) {
|
|
Button {
|
|
showShare = true
|
|
} label: {
|
|
Image(systemName: "square.and.arrow.up")
|
|
}
|
|
.disabled(store.entries.isEmpty)
|
|
}
|
|
ToolbarItem(placement: .cancellationAction) {
|
|
Button("Clear") { store.clear() }
|
|
.disabled(store.entries.isEmpty)
|
|
}
|
|
}
|
|
.sheet(isPresented: $showShare) {
|
|
ShareSheet(text: store.text)
|
|
}
|
|
}
|
|
|
|
private func color(for level: LogStore.Entry.Level) -> Color {
|
|
switch level {
|
|
case .info: return .secondary
|
|
case .warn: return .orange
|
|
case .error: return .red
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Minimal share sheet wrapper (ShareLink is iOS 16+; this is explicit).
|
|
struct ShareSheet: UIViewControllerRepresentable {
|
|
let text: String
|
|
|
|
func makeUIViewController(context: Context) -> UIActivityViewController {
|
|
UIActivityViewController(activityItems: [text], applicationActivities: nil)
|
|
}
|
|
func updateUIViewController(_ uiViewController: UIActivityViewController,
|
|
context: Context) {}
|
|
}
|