crossmate

A collaborative crossword app for iOS
Log | Files | Refs | LICENSE

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:
MCrossmate/Views/DiagnosticsView.swift | 38+++++++++++++++++++++++++++++++++++++-
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()