|
|
@@ -29,17 +29,21 @@ final class DictionaryViewModel: ObservableObject {
|
|
|
var hasResult: Bool { entry != nil }
|
|
|
|
|
|
var canLookUp: Bool {
|
|
|
- !query.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty && !isLoading
|
|
|
+ !normalizedQuery(from: query).isEmpty && !isLoading
|
|
|
}
|
|
|
|
|
|
func lookUp() {
|
|
|
- let trimmed = query.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
|
+ let trimmed = normalizedQuery(from: query)
|
|
|
guard !trimmed.isEmpty else {
|
|
|
clearResult()
|
|
|
errorMessage = DictionaryServiceError.emptyInput.errorDescription
|
|
|
return
|
|
|
}
|
|
|
|
|
|
+ if query != trimmed {
|
|
|
+ query = trimmed
|
|
|
+ }
|
|
|
+
|
|
|
startLookUp(for: trimmed)
|
|
|
}
|
|
|
|
|
|
@@ -67,6 +71,31 @@ final class DictionaryViewModel: ObservableObject {
|
|
|
clearResult()
|
|
|
}
|
|
|
|
|
|
+ func handleQueryChange(_ newValue: String) {
|
|
|
+ if newValue.count > Self.maxQueryLength {
|
|
|
+ query = String(newValue.prefix(Self.maxQueryLength))
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ let trimmed = normalizedQuery(from: newValue)
|
|
|
+
|
|
|
+ if let entry, !trimmed.isEmpty, trimmed.caseInsensitiveCompare(entry.word) == .orderedSame {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ if hasResult {
|
|
|
+ clearResult()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private func normalizedQuery(from value: String) -> String {
|
|
|
+ value
|
|
|
+ .trimmingCharacters(in: .whitespacesAndNewlines)
|
|
|
+ .components(separatedBy: .whitespacesAndNewlines)
|
|
|
+ .filter { !$0.isEmpty }
|
|
|
+ .joined(separator: " ")
|
|
|
+ }
|
|
|
+
|
|
|
func playPronunciation(for entry: DictionaryEntry) {
|
|
|
if let audioURL = entry.audioURL {
|
|
|
Task {
|