commit 75ad17c32d19a5f1d18e79d49c0b0c0424ef0767
parent 31ec4b0183b1f1b704922c09897421e315feda34
Author: Michael Camilleri <[email protected]>
Date: Sat, 6 Jun 2026 10:55:16 +0900
Support sharing of diagnostics via a text file
Diffstat:
1 file changed, 37 insertions(+), 1 deletion(-)
diff --git a/Crossmate/Views/DiagnosticsView.swift b/Crossmate/Views/DiagnosticsView.swift
@@ -39,6 +39,7 @@ struct DiagnosticsView: View {
@Environment(EventLog.self) private var eventLog
@State private var isSyncing = false
+ @State private var diagnosticShareFile: URL?
var body: some View {
List {
@@ -110,21 +111,56 @@ struct DiagnosticsView: View {
.navigationTitle("Diagnostics Log")
.navigationBarTitleDisplayMode(.inline)
.toolbar {
- ToolbarItem(placement: .topBarTrailing) {
+ ToolbarItemGroup(placement: .topBarTrailing) {
+ if let diagnosticShareFile {
+ ShareLink(
+ item: diagnosticShareFile,
+ preview: SharePreview(
+ "Crossmate Diagnostics",
+ image: Image(systemName: "doc.text")
+ )
+ ) {
+ Label("Share Full Log", systemImage: "square.and.arrow.up")
+ }
+ }
+
Button("Copy") {
UIPasteboard.general.string = diagnosticDump
}
}
}
+ .onAppear {
+ refreshDiagnosticShareFile()
+ }
+ .onChange(of: diagnosticDump) { _, _ in
+ refreshDiagnosticShareFile()
+ }
.task {
guard let syncEngine else { return }
let snapshot = await syncEngine.diagnosticSnapshot()
syncMonitor.updateSnapshot(snapshot)
+ refreshDiagnosticShareFile()
}
}
// MARK: - Actions
+ private func refreshDiagnosticShareFile() {
+ do {
+ diagnosticShareFile = try writeDiagnosticShareFile()
+ } catch {
+ diagnosticShareFile = nil
+ eventLog.note("diagnostics share file failed: \(error.localizedDescription)", level: "error")
+ }
+ }
+
+ private func writeDiagnosticShareFile() throws -> URL {
+ let url = FileManager.default.temporaryDirectory
+ .appendingPathComponent("crossmate-diagnostics.txt")
+ try diagnosticDump.write(to: url, atomically: true, encoding: .utf8)
+ return url
+ }
+
private func resetSyncState() async {
guard let syncEngine else { return }
await syncEngine.resetSyncState()