vOOice/VoiceInk/Views/TranscriptionCard.swift
2025-05-04 22:50:09 +05:45

137 lines
5.2 KiB
Swift

import SwiftUI
import SwiftData
struct TranscriptionCard: View {
let transcription: Transcription
let isExpanded: Bool
let isSelected: Bool
let onDelete: () -> Void
let onToggleSelection: () -> Void
var body: some View {
HStack(spacing: 12) {
// Selection checkbox in macOS style
Toggle("", isOn: Binding(
get: { isSelected },
set: { _ in onToggleSelection() }
))
.toggleStyle(CircularCheckboxStyle())
.labelsHidden()
VStack(alignment: .leading, spacing: 8) {
// Header with date and duration
HStack {
Text(transcription.timestamp, style: .date)
.font(.system(size: 14, weight: .medium, design: .default))
.foregroundColor(.secondary)
Spacer()
Text(formatDuration(transcription.duration))
.font(.system(size: 14, weight: .medium, design: .default))
.padding(.horizontal, 8)
.padding(.vertical, 4)
.background(Color.blue.opacity(0.1))
.foregroundColor(.blue)
.cornerRadius(6)
}
// Original text section
VStack(alignment: .leading, spacing: 8) {
if isExpanded {
HStack {
Text("Original")
.font(.system(size: 14, weight: .medium))
.foregroundColor(.secondary)
Spacer()
AnimatedCopyButton(textToCopy: transcription.text)
}
}
Text(transcription.text)
.font(.system(size: 15, weight: .regular, design: .default))
.lineLimit(isExpanded ? nil : 2)
.lineSpacing(2)
}
// Enhanced text section (only when expanded)
if isExpanded, let enhancedText = transcription.enhancedText {
Divider()
.padding(.vertical, 8)
VStack(alignment: .leading, spacing: 8) {
HStack {
HStack(spacing: 4) {
Image(systemName: "sparkles")
.foregroundColor(.blue)
Text("Enhanced")
.font(.system(size: 14, weight: .medium))
.foregroundColor(.blue)
}
Spacer()
AnimatedCopyButton(textToCopy: enhancedText)
}
Text(enhancedText)
.font(.system(size: 15, weight: .regular, design: .default))
.lineSpacing(2)
}
}
// Audio player (if available)
if isExpanded, let urlString = transcription.audioFileURL,
let url = URL(string: urlString),
FileManager.default.fileExists(atPath: url.path) {
Divider()
.padding(.vertical, 8)
AudioPlayerView(url: url)
}
// Timestamp (only when expanded)
if isExpanded {
HStack {
Text(transcription.timestamp, style: .time)
.font(.system(size: 14, weight: .regular, design: .default))
.foregroundColor(.secondary)
Spacer()
}
.padding(.top, 4)
}
}
}
.padding(16)
.background(
RoundedRectangle(cornerRadius: 12)
.fill(Color(.windowBackgroundColor).opacity(0.4))
)
.cornerRadius(12)
.shadow(color: Color.black.opacity(0.05), radius: 3, x: 0, y: 2)
.contextMenu {
if let enhancedText = transcription.enhancedText {
Button {
let _ = ClipboardManager.copyToClipboard(enhancedText)
} label: {
Label("Copy Enhanced", systemImage: "doc.on.doc")
}
}
Button {
let _ = ClipboardManager.copyToClipboard(transcription.text)
} label: {
Label("Copy Original", systemImage: "doc.on.doc")
}
Button(role: .destructive) {
onDelete()
} label: {
Label("Delete", systemImage: "trash")
}
}
}
private func formatDuration(_ duration: TimeInterval) -> String {
let minutes = Int(duration) / 60
let seconds = Int(duration) % 60
return String(format: "%d:%02d", minutes, seconds)
}
}