- Replace @MainActor with Combine framework for TTS functionality - Create VoiceManager class for voice selection and caching - Add UserDefaults persistence for selected voice - Optimize performance with voice caching and immediate UI updates - Remove @MainActor from TTS-related Use Cases - Add proper pause/resume delegate methods - Improve reactive UI updates with @StateObject - Clean up code and remove unnecessary comments
77 lines
2.1 KiB
Swift
77 lines
2.1 KiB
Swift
import Foundation
|
|
import Combine
|
|
|
|
class SpeechQueue: ObservableObject {
|
|
private var queue: [String] = []
|
|
private var isProcessing = false
|
|
private let ttsManager: TTSManager
|
|
private let language: String
|
|
|
|
static let shared = SpeechQueue()
|
|
|
|
@Published var queueItems: [String] = []
|
|
@Published var currentText: String = ""
|
|
@Published var hasItems: Bool = false
|
|
|
|
var queueCount: Int {
|
|
return queueItems.count
|
|
}
|
|
|
|
var currentItem: String? {
|
|
return queueItems.first
|
|
}
|
|
|
|
private init(ttsManager: TTSManager = .shared, language: String = "de-DE") {
|
|
self.ttsManager = ttsManager
|
|
self.language = language
|
|
}
|
|
|
|
func enqueue(_ text: String) {
|
|
queue.append(text)
|
|
updatePublishedProperties()
|
|
processQueue()
|
|
}
|
|
|
|
func enqueue(contentsOf texts: [String]) {
|
|
queue.append(contentsOf: texts)
|
|
updatePublishedProperties()
|
|
processQueue()
|
|
}
|
|
|
|
func clear() {
|
|
queue.removeAll()
|
|
ttsManager.stop()
|
|
isProcessing = false
|
|
updatePublishedProperties()
|
|
}
|
|
|
|
private func updatePublishedProperties() {
|
|
queueItems = queue
|
|
currentText = queue.first ?? ""
|
|
hasItems = !queue.isEmpty || ttsManager.isCurrentlySpeaking()
|
|
}
|
|
|
|
private func processQueue() {
|
|
guard !isProcessing, !queue.isEmpty else { return }
|
|
isProcessing = true
|
|
let next = queue.removeFirst()
|
|
ttsManager.speak(text: next, language: language)
|
|
// Delegate/Notification für didFinish kann hier angebunden werden
|
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) { [weak self] in
|
|
self?.waitForSpeechToFinish()
|
|
}
|
|
}
|
|
|
|
private func waitForSpeechToFinish() {
|
|
if ttsManager.isCurrentlySpeaking() {
|
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { [weak self] in
|
|
self?.waitForSpeechToFinish()
|
|
}
|
|
} else {
|
|
self.isProcessing = false
|
|
self.updatePublishedProperties()
|
|
self.processQueue()
|
|
}
|
|
}
|
|
}
|