Просмотр исходного кода

Fix dictionary search to handle whitespace while typing.

Normalize leading, trailing, and extra spaces on lookup, and keep existing results visible when the trimmed query still matches.

Co-authored-by: Cursor <cursoragent@cursor.com>
AhtashamShahzad1 3 месяцев назад
Родитель
Сommit
d43f59678e
2 измененных файлов с 32 добавлено и 8 удалено
  1. 31 2
      gramora/ViewModels/DictionaryViewModel.swift
  2. 1 6
      gramora/Views/DictionaryView.swift

+ 31 - 2
gramora/ViewModels/DictionaryViewModel.swift

@@ -29,17 +29,21 @@ final class DictionaryViewModel: ObservableObject {
     var hasResult: Bool { entry != nil }
     var hasResult: Bool { entry != nil }
 
 
     var canLookUp: Bool {
     var canLookUp: Bool {
-        !query.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty && !isLoading
+        !normalizedQuery(from: query).isEmpty && !isLoading
     }
     }
 
 
     func lookUp() {
     func lookUp() {
-        let trimmed = query.trimmingCharacters(in: .whitespacesAndNewlines)
+        let trimmed = normalizedQuery(from: query)
         guard !trimmed.isEmpty else {
         guard !trimmed.isEmpty else {
             clearResult()
             clearResult()
             errorMessage = DictionaryServiceError.emptyInput.errorDescription
             errorMessage = DictionaryServiceError.emptyInput.errorDescription
             return
             return
         }
         }
 
 
+        if query != trimmed {
+            query = trimmed
+        }
+
         startLookUp(for: trimmed)
         startLookUp(for: trimmed)
     }
     }
 
 
@@ -67,6 +71,31 @@ final class DictionaryViewModel: ObservableObject {
         clearResult()
         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) {
     func playPronunciation(for entry: DictionaryEntry) {
         if let audioURL = entry.audioURL {
         if let audioURL = entry.audioURL {
             Task {
             Task {

+ 1 - 6
gramora/Views/DictionaryView.swift

@@ -34,12 +34,7 @@ struct DictionaryView: View {
         }
         }
         .clearHostingBackground()
         .clearHostingBackground()
         .onChange(of: viewModel.query) { newValue in
         .onChange(of: viewModel.query) { newValue in
-            if newValue.count > DictionaryViewModel.maxQueryLength {
-                viewModel.query = String(newValue.prefix(DictionaryViewModel.maxQueryLength))
-            }
-            if viewModel.hasResult {
-                viewModel.resetResult()
-            }
+            viewModel.handleQueryChange(newValue)
         }
         }
     }
     }