feat: add in-app Sparkle update logging

- Add published logMessages array to SparkleUpdater to track all update events
- Display logs in the Updates preferences tab with Show/Hide toggle
- Each log entry is timestamped and shows both info and error messages
- Logs persist during session with max 100 entries
- Users can clear logs manually
- Helps diagnose update failures directly in the app UI
This commit is contained in:
Micha
2025-12-30 13:12:27 +01:00
parent 10683ebc73
commit 25723b7f07
2 changed files with 102 additions and 19 deletions

View File

@@ -257,11 +257,64 @@ private struct UpdatesPreferencesView: View {
.foregroundColor(.secondary)
.padding(.top, 4)
Divider()
.padding(.vertical, 8)
Button(action: { sparkleUpdater.showLogs.toggle() }) {
Label(sparkleUpdater.showLogs ? "Hide Logs" : "Show Logs", systemImage: "terminal.fill")
}
if sparkleUpdater.showLogs {
logsView
}
Spacer()
}
.toggleStyle(.switch)
.frame(maxWidth: .infinity, alignment: .leading)
}
private var logsView: some View {
VStack(alignment: .leading, spacing: 8) {
Text("Update Logs")
.font(.caption)
.fontWeight(.semibold)
.foregroundColor(.secondary)
ScrollView {
VStack(alignment: .leading, spacing: 4) {
if sparkleUpdater.logMessages.isEmpty {
Text("No logs yet. Check for updates to see activity.")
.font(.caption)
.foregroundColor(.secondary)
.italic()
} else {
ForEach(sparkleUpdater.logMessages, id: \.self) { message in
Text(message)
.font(.caption)
.foregroundColor(.secondary)
.lineLimit(3)
.textSelection(.enabled)
}
}
}
.frame(maxWidth: .infinity, alignment: .leading)
.padding(8)
}
.frame(height: 200)
.background(Color(nsColor: .controlBackgroundColor))
.cornerRadius(6)
.border(.separator, width: 1)
Button(action: {
sparkleUpdater.logMessages.removeAll()
}) {
Label("Clear Logs", systemImage: "trash")
.font(.caption)
}
.disabled(sparkleUpdater.logMessages.isEmpty)
}
}
}
private struct NotificationsPreferencesView: View {