summaryrefslogtreecommitdiff
path: root/Sora/Views/SearchSuggestionsView.swift
diff options
context:
space:
mode:
Diffstat (limited to 'Sora/Views/SearchSuggestionsView.swift')
-rw-r--r--Sora/Views/SearchSuggestionsView.swift90
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()
- }
}
}