-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTranslatorPage.swift
More file actions
155 lines (140 loc) · 6.08 KB
/
TranslatorPage.swift
File metadata and controls
155 lines (140 loc) · 6.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
import SwiftUI
import AVFoundation
struct TranslatorView: View {
@StateObject private var audioRecorder = AudioRecorder()
@State private var transcribedText = ""
@State private var chatResponse = ""
@State private var audioPlayer: AVAudioPlayer?
private let apiManager = APIManager()
@Binding var selectedLanguage: String
@Binding var showLanguageSelection: Bool
@State private var durationTime = 0.4
private let defaultLanguage = UserDefaults.standard.string(forKey: "defaultLanguage") ?? "English"
@State private var currentTargetLanguage: String?
var body: some View {
VStack(spacing: 20) {
HStack {
Button(action: {
withAnimation(.easeInOut(duration: durationTime)) {
showLanguageSelection = true
}
}) {
Image(systemName: "arrow.left.circle.fill")
.resizable()
.frame(width: 40, height: 40)
.foregroundColor(.blue)
}
.padding(.leading, 20)
.padding(.top, 20)
.padding(.top, UIApplication.shared.windows.first?.safeAreaInsets.top)
Spacer()
Text(currentTargetLanguage ?? selectedLanguage)
.font(.custom("AvenirNext-Bold", size: 16))
.foregroundColor(.white)
.padding(.vertical, 10)
.padding(.horizontal, 20)
.background(Color.gray.opacity(0.2))
.cornerRadius(10)
.padding(.trailing, 20)
.padding(.top, 20)
.padding(.top, UIApplication.shared.windows.first?.safeAreaInsets.top)
}
Spacer()
Text(audioRecorder.isRecording ? "Recording..." : "Press to Record")
.font(.custom("AvenirNext-Bold", size: 24))
.foregroundColor(audioRecorder.isRecording ? .red : .blue)
Button(action: {
if self.audioRecorder.isRecording {
self.audioRecorder.stopRecording()
self.transcribeAudio()
} else {
self.audioRecorder.startRecording()
}
}) {
Image(systemName: audioRecorder.isRecording ? "stop.circle.fill" : "mic.circle.fill")
.resizable()
.frame(width: 100, height: 100)
.foregroundColor(audioRecorder.isRecording ? .red : .blue)
}
.padding()
ScrollView {
GeometryReader { geometry in
VStack(alignment: .leading, spacing: 10) {
Text("Transcribed Text:")
.font(.custom("AvenirNext-Bold", size: 20))
.foregroundColor(.white)
Text(transcribedText)
.font(.custom("AvenirNext-Regular", size: 18))
.foregroundColor(.white)
.padding()
.frame(width: geometry.size.width * 0.9)
.background(Color.gray.opacity(0.2))
.cornerRadius(10)
.lineLimit(nil)
.fixedSize(horizontal: false, vertical: true)
Text("Chat Response:")
.font(.custom("AvenirNext-Bold", size: 20))
.foregroundColor(.white)
Text(chatResponse)
.font(.custom("AvenirNext-Regular", size: 18))
.foregroundColor(.white)
.padding()
.frame(width: geometry.size.width * 0.9)
.background(Color.gray.opacity(0.2))
.cornerRadius(10)
.lineLimit(nil)
.fixedSize(horizontal: false, vertical: true)
}
.padding(.horizontal, 20)
}
}
Spacer()
}
.background(Color.black.edgesIgnoringSafeArea(.all))
.onAppear {
self.currentTargetLanguage = selectedLanguage
}
}
func transcribeAudio() {
let audioURL = self.audioRecorder.getAudioFileURL()
apiManager.transcribeAudio(audioURL: audioURL) { transcribedText in
DispatchQueue.main.async {
self.transcribedText = transcribedText ?? "Transcription failed"
if let transcribedText = transcribedText {
self.sendToChatCompletion(text: transcribedText)
}
}
}
}
func sendToChatCompletion(text: String) {
guard let targetLanguage = currentTargetLanguage else { return }
apiManager.chatCompletion(with: text, language: targetLanguage) { response in
DispatchQueue.main.async {
self.chatResponse = response ?? "Failed to get response from chat completion"
if let response = response {
self.convertTextToSpeech(text: response)
self.toggleTargetLanguage()
}
}
}
}
func toggleTargetLanguage() {
currentTargetLanguage = (currentTargetLanguage == selectedLanguage) ? defaultLanguage : selectedLanguage
}
func convertTextToSpeech(text: String) {
apiManager.textToSpeech(text: text) { audioURL in
guard let audioURL = audioURL else { return }
DispatchQueue.main.async {
do {
self.audioPlayer = try AVAudioPlayer(contentsOf: audioURL)
self.audioPlayer?.play()
} catch {
print("Failed to play audio: \(error.localizedDescription)")
}
}
}
}
}
#Preview {
TranslatorView(selectedLanguage: .constant("Turkish"), showLanguageSelection: .constant(false))
}