diff --git a/VoiceInk/Services/VoiceInkCSVExportService.swift b/VoiceInk/Services/VoiceInkCSVExportService.swift new file mode 100644 index 0000000..5396898 --- /dev/null +++ b/VoiceInk/Services/VoiceInkCSVExportService.swift @@ -0,0 +1,53 @@ + +import Foundation +import AppKit +import SwiftData + +class VoiceInkCSVExportService { + + func exportTranscriptionsToCSV(transcriptions: [Transcription]) { + let csvString = generateCSV(for: transcriptions) + + let savePanel = NSSavePanel() + savePanel.allowedContentTypes = [.commaSeparatedText] + savePanel.nameFieldStringValue = "VoiceInk-transcription.csv" + + savePanel.begin { result in + if result == .OK, let url = savePanel.url { + do { + try csvString.write(to: url, atomically: true, encoding: .utf8) + } catch { + print("Error writing CSV file: \(error)") + } + } + } + } + + private func generateCSV(for transcriptions: [Transcription]) -> String { + var csvString = "Original Transcript,Enhanced Transcript,Enhancement Model,Transcription Model,Enhancement Time,Transcription Time,Timestamp,Duration\n" + + for transcription in transcriptions { + let originalText = escapeCSVString(transcription.text) + let enhancedText = escapeCSVString(transcription.enhancedText ?? "") + let enhancementModel = escapeCSVString(transcription.aiEnhancementModelName ?? "") + let transcriptionModel = escapeCSVString(transcription.transcriptionModelName ?? "") + let enhancementTime = transcription.enhancementDuration ?? 0 + let transcriptionTime = transcription.transcriptionDuration ?? 0 + let timestamp = transcription.timestamp.ISO8601Format() + let duration = transcription.duration + + let row = "\(originalText),\(enhancedText),\(enhancementModel),\(transcriptionModel),\(enhancementTime),\(transcriptionTime),\(timestamp),\(duration)\n" + csvString.append(row) + } + + return csvString + } + + private func escapeCSVString(_ string: String) -> String { + let escapedString = string.replacingOccurrences(of: "\"", with: "\"\"") + if escapedString.contains(",") || escapedString.contains("\n") { + return "\"\(escapedString)\"" + } + return escapedString + } +} \ No newline at end of file diff --git a/VoiceInk/Views/TranscriptionHistoryView.swift b/VoiceInk/Views/TranscriptionHistoryView.swift index 2fadced..ebd49d0 100644 --- a/VoiceInk/Views/TranscriptionHistoryView.swift +++ b/VoiceInk/Views/TranscriptionHistoryView.swift @@ -10,6 +10,8 @@ struct TranscriptionHistoryView: View { @State private var isViewCurrentlyVisible = false @State private var showAnalysisView = false + private let exportService = VoiceInkCSVExportService() + // Pagination states @State private var displayedTranscriptions: [Transcription] = [] @State private var isLoading = false @@ -235,6 +237,16 @@ struct TranscriptionHistoryView: View { } .buttonStyle(.borderless) + Button(action: { + exportService.exportTranscriptionsToCSV(transcriptions: Array(selectedTranscriptions)) + }) { + HStack(spacing: 4) { + Image(systemName: "square.and.arrow.up") + Text("Export") + } + } + .buttonStyle(.borderless) + Button(action: { showDeleteConfirmation = true }) {