diff options
Diffstat (limited to 'Sora/Views/SearchSuggestionsView.swift')
| -rw-r--r-- | Sora/Views/SearchSuggestionsView.swift | 90 |
1 files changed, 43 insertions, 47 deletions
diff --git a/Sora/Views/SearchSuggestionsView.swift b/Sora/Views/SearchSuggestionsView.swift index e9593ec..afa30bb 100644 --- a/Sora/Views/SearchSuggestionsView.swift +++ b/Sora/Views/SearchSuggestionsView.swift @@ -9,21 +9,13 @@ struct SearchSuggestionsView: View { var items: [Either<BooruTag, BooruSearchQuery>] @Binding var searchText: String @Binding var suppressNextSearchSubmit: Bool - @State private var cachedTags: [CachedTag] = [] private var lastSearchTag: String { String(searchText.split(separator: " ").last ?? "").lowercased() } - private var itemsCacheKey: Int { - items.reduce(into: Hasher()) { hasher, item in - hasher.combine(item) - } - .finalize() - } - - private func refreshCachedTags() { - cachedTags = items.map { item in + private var cachedTags: [CachedTag] { + items.map { item in switch item { case .left(let tag): return CachedTag(original: item, names: [tag.name.lowercased()]) @@ -48,11 +40,23 @@ struct SearchSuggestionsView: View { for tag in cachedTags { if matchingTags.count >= matchingTagsLimit { break } - for name in tag.names { - if name.contains(matchCandidateTag), seenTags.insert(name).inserted { - matchingTags.append(tag.original) + switch tag.original { + case .left: + guard let name = tag.names.first, + seenTags.insert(name).inserted + else { + continue + } + + matchingTags.append(tag.original) - break + case .right: + for name in tag.names { + if name.contains(matchCandidateTag), seenTags.insert(name).inserted { + matchingTags.append(tag.original) + + break + } } } } @@ -61,46 +65,38 @@ struct SearchSuggestionsView: View { } var body: some View { - Group { - ForEach(filteredItems, id: \.self) { item in - switch item { - case .left(let tag): - Button { + ForEach(filteredItems, id: \.self) { item in + switch item { + case .left(let tag): + Button { + let previousTags = searchText.split(separator: " ").dropLast() + + suppressNextSearchSubmit = true + searchText = (previousTags.map(String.init) + [tag.name]).joined(separator: " ") + } label: { + Text(tag.name) + } + + case .right(let query): + let matchingTag = query.tags.first { tag in + tag.lowercased().contains(lastSearchTag) + } + + Button { + if let matchingTag { let previousTags = searchText.split(separator: " ").dropLast() suppressNextSearchSubmit = true - searchText = (previousTags.map(String.init) + [tag.name]).joined(separator: " ") - } label: { - Text(tag.name) + searchText = (previousTags.map(String.init) + [matchingTag]).joined(separator: " ") } - - case .right(let query): - let matchingTag = query.tags.first { tag in - tag.lowercased().contains(lastSearchTag) - } - - Button { - if let matchingTag { - let previousTags = searchText.split(separator: " ").dropLast() - - suppressNextSearchSubmit = true - searchText = (previousTags.map(String.init) + [matchingTag]).joined(separator: " ") - } - } label: { - if let matchingTag { - Text(matchingTag) - } else { - Text(query.tags.first ?? "") - } + } label: { + if let matchingTag { + Text(matchingTag) + } else { + Text(query.tags.first ?? "") } } } } - .onAppear { - refreshCachedTags() - } - .onChange(of: itemsCacheKey) { - refreshCachedTags() - } } } |