From 40ab38084afc1380aea6f3c9a1c93516121b8563 Mon Sep 17 00:00:00 2001 From: Beingpax Date: Sun, 4 May 2025 22:50:09 +0545 Subject: [PATCH] Added copy feature to audio transcribe view --- VoiceInk/Views/AudioTranscribeView.swift | 33 +++++++--- .../Views/Common/AnimatedCopyButton.swift | 54 ++++++++++++++++ VoiceInk/Views/TranscriptionCard.swift | 61 ++----------------- 3 files changed, 83 insertions(+), 65 deletions(-) create mode 100644 VoiceInk/Views/Common/AnimatedCopyButton.swift diff --git a/VoiceInk/Views/AudioTranscribeView.swift b/VoiceInk/Views/AudioTranscribeView.swift index b4335e7..d7ea26c 100644 --- a/VoiceInk/Views/AudioTranscribeView.swift +++ b/VoiceInk/Views/AudioTranscribeView.swift @@ -33,9 +33,13 @@ struct AudioTranscribeView: View { if let enhancedText = transcription.enhancedText { VStack(alignment: .leading, spacing: 8) { - Text("Enhanced") - .font(.subheadline) - .foregroundColor(.secondary) + HStack { + Text("Enhanced") + .font(.subheadline) + .foregroundColor(.secondary) + Spacer() + AnimatedCopyButton(textToCopy: enhancedText) + } Text(enhancedText) .textSelection(.enabled) } @@ -43,15 +47,28 @@ struct AudioTranscribeView: View { Divider() VStack(alignment: .leading, spacing: 8) { - Text("Original") - .font(.subheadline) - .foregroundColor(.secondary) + HStack { + Text("Original") + .font(.subheadline) + .foregroundColor(.secondary) + Spacer() + AnimatedCopyButton(textToCopy: transcription.text) + } Text(transcription.text) .textSelection(.enabled) } } else { - Text(transcription.text) - .textSelection(.enabled) + VStack(alignment: .leading, spacing: 8) { + HStack { + Text("Transcription") + .font(.subheadline) + .foregroundColor(.secondary) + Spacer() + AnimatedCopyButton(textToCopy: transcription.text) + } + Text(transcription.text) + .textSelection(.enabled) + } } HStack { diff --git a/VoiceInk/Views/Common/AnimatedCopyButton.swift b/VoiceInk/Views/Common/AnimatedCopyButton.swift new file mode 100644 index 0000000..82003ab --- /dev/null +++ b/VoiceInk/Views/Common/AnimatedCopyButton.swift @@ -0,0 +1,54 @@ +import SwiftUI + +struct AnimatedCopyButton: View { + let textToCopy: String + @State private var isCopied: Bool = false + + var body: some View { + Button { + copyToClipboard() + } label: { + HStack(spacing: 4) { + Image(systemName: isCopied ? "checkmark" : "doc.on.doc") + .font(.system(size: 12, weight: isCopied ? .bold : .regular)) + .foregroundColor(.white) + Text(isCopied ? "Copied" : "Copy") + .font(.system(size: 12, weight: isCopied ? .medium : .regular)) + .foregroundColor(.white) + } + .padding(.horizontal, 8) + .padding(.vertical, 4) + .background( + Capsule() + .fill(isCopied ? Color.green.opacity(0.8) : Color.blue) + ) + } + .buttonStyle(.plain) + .scaleEffect(isCopied ? 1.05 : 1.0) + .animation(.spring(response: 0.3, dampingFraction: 0.7), value: isCopied) + } + + private func copyToClipboard() { + let _ = ClipboardManager.copyToClipboard(textToCopy) + withAnimation { + isCopied = true + } + + DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) { + withAnimation { + isCopied = false + } + } + } +} + +struct AnimatedCopyButton_Previews: PreviewProvider { + static var previews: some View { + VStack(spacing: 20) { + AnimatedCopyButton(textToCopy: "Sample text") + Text("Before Copy") + .padding() + } + .padding() + } +} \ No newline at end of file diff --git a/VoiceInk/Views/TranscriptionCard.swift b/VoiceInk/Views/TranscriptionCard.swift index e2bee84..32f7abd 100644 --- a/VoiceInk/Views/TranscriptionCard.swift +++ b/VoiceInk/Views/TranscriptionCard.swift @@ -7,8 +7,6 @@ struct TranscriptionCard: View { let isSelected: Bool let onDelete: () -> Void let onToggleSelection: () -> Void - @State private var showOriginalCopiedAlert = false - @State private var showEnhancedCopiedAlert = false var body: some View { HStack(spacing: 12) { @@ -45,21 +43,7 @@ struct TranscriptionCard: View { .font(.system(size: 14, weight: .medium)) .foregroundColor(.secondary) Spacer() - Button { - copyToClipboard(transcription.text) - showOriginalCopiedAlert = true - } label: { - HStack(spacing: 4) { - Image(systemName: showOriginalCopiedAlert ? "checkmark" : "doc.on.doc") - Text(showOriginalCopiedAlert ? "Copied" : "Copy") - } - .foregroundColor(showOriginalCopiedAlert ? .green : .blue) - .padding(.horizontal, 8) - .padding(.vertical, 4) - .background(Color.blue.opacity(0.1)) - .cornerRadius(6) - } - .buttonStyle(.plain) + AnimatedCopyButton(textToCopy: transcription.text) } } @@ -84,21 +68,7 @@ struct TranscriptionCard: View { .foregroundColor(.blue) } Spacer() - Button { - copyToClipboard(enhancedText) - showEnhancedCopiedAlert = true - } label: { - HStack(spacing: 4) { - Image(systemName: showEnhancedCopiedAlert ? "checkmark" : "doc.on.doc") - Text(showEnhancedCopiedAlert ? "Copied" : "Copy") - } - .foregroundColor(showEnhancedCopiedAlert ? .green : .blue) - .padding(.horizontal, 8) - .padding(.vertical, 4) - .background(Color.blue.opacity(0.1)) - .cornerRadius(6) - } - .buttonStyle(.plain) + AnimatedCopyButton(textToCopy: enhancedText) } Text(enhancedText) @@ -138,16 +108,14 @@ struct TranscriptionCard: View { .contextMenu { if let enhancedText = transcription.enhancedText { Button { - copyToClipboard(enhancedText) - showEnhancedCopiedAlert = true + let _ = ClipboardManager.copyToClipboard(enhancedText) } label: { Label("Copy Enhanced", systemImage: "doc.on.doc") } } Button { - copyToClipboard(transcription.text) - showOriginalCopiedAlert = true + let _ = ClipboardManager.copyToClipboard(transcription.text) } label: { Label("Copy Original", systemImage: "doc.on.doc") } @@ -158,27 +126,6 @@ struct TranscriptionCard: View { Label("Delete", systemImage: "trash") } } - .onChange(of: showOriginalCopiedAlert) { _, isShowing in - if isShowing { - DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) { - showOriginalCopiedAlert = false - } - } - } - .onChange(of: showEnhancedCopiedAlert) { _, isShowing in - if isShowing { - DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) { - showEnhancedCopiedAlert = false - } - } - } - } - - private func copyToClipboard(_ text: String) { - let success = ClipboardManager.copyToClipboard(text) - if !success { - print("Failed to copy text to clipboard") - } } private func formatDuration(_ duration: TimeInterval) -> String {