summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFuwn <[email protected]>2025-03-01 19:53:45 -0800
committerFuwn <[email protected]>2025-03-01 19:53:45 -0800
commit774087d67eb231cb603abc73069cd74f4aafefe3 (patch)
tree8f36b1b783d0ac9845ac2485a624ff775220952d
parentfeat: Development commit (diff)
downloadsora-testing-774087d67eb231cb603abc73069cd74f4aafefe3.tar.xz
sora-testing-774087d67eb231cb603abc73069cd74f4aafefe3.zip
feat: Development commit
-rw-r--r--Sora/Data/Either.swift4
-rw-r--r--Sora/Views/Post/Grid/PostGridView.swift23
-rw-r--r--Sora/Views/SearchSuggestionsView.swift57
3 files changed, 69 insertions, 15 deletions
diff --git a/Sora/Data/Either.swift b/Sora/Data/Either.swift
new file mode 100644
index 0000000..2c2dd22
--- /dev/null
+++ b/Sora/Data/Either.swift
@@ -0,0 +1,4 @@
+enum Either<Left: Hashable, Right: Hashable>: Hashable {
+ case left(Left)
+ case right(Right)
+}
diff --git a/Sora/Views/Post/Grid/PostGridView.swift b/Sora/Views/Post/Grid/PostGridView.swift
index d5d583b..dc6546d 100644
--- a/Sora/Views/Post/Grid/PostGridView.swift
+++ b/Sora/Views/Post/Grid/PostGridView.swift
@@ -31,9 +31,9 @@ struct PostGridView: View {
}
.searchable(text: $manager.searchText, prompt: "Tags")
.searchSuggestions {
- if settings.searchSuggestionsMode == .tags {
+ if settings.searchSuggestionsMode != .disabled {
SearchSuggestionsView(
- tags: manager.allTags,
+ items: searchSuggestionsItems(),
searchText: $manager.searchText
)
}
@@ -127,4 +127,23 @@ struct PostGridView: View {
}
}
}
+
+ private func searchSuggestionsItems() -> [Either<BooruTag, BooruSearchQuery>] {
+ let items: [Either<BooruTag, BooruSearchQuery>]
+
+ switch settings.searchSuggestionsMode {
+ case .tags:
+ items = manager.allTags
+ .map { Either<BooruTag, BooruSearchQuery>.left($0) }
+
+ case .history:
+ items = settings.searchHistory
+ .map { Either<BooruTag, BooruSearchQuery>.right($0) }
+
+ case .disabled:
+ items = []
+ }
+
+ return items
+ }
}
diff --git a/Sora/Views/SearchSuggestionsView.swift b/Sora/Views/SearchSuggestionsView.swift
index 2a1a8d6..244de49 100644
--- a/Sora/Views/SearchSuggestionsView.swift
+++ b/Sora/Views/SearchSuggestionsView.swift
@@ -1,29 +1,60 @@
import SwiftUI
struct SearchSuggestionsView: View {
- var tags: [BooruTag]
+ var items: [Either<BooruTag, BooruSearchQuery>]
@Binding var searchText: String
private var lastSearchTag: String {
String(searchText.split(separator: " ").last ?? "").lowercased()
}
- private var filteredTags: [BooruTag] {
+ private var filteredItems: [Either<BooruTag, BooruSearchQuery>] {
guard !lastSearchTag.isEmpty else { return [] }
- return tags.filter { $0.name.lowercased().contains(lastSearchTag) }
+ var seen = Set<String>()
+
+ return items.filter { item in
+ switch item {
+ case .left(let tag):
+ return tag.name.lowercased().contains(lastSearchTag)
+ && seen.insert(tag.name.lowercased()).inserted
+
+ case .right(let query):
+ let newTags = query.tags.filter { tag in
+ tag.lowercased().contains(lastSearchTag)
+ && seen.insert(tag.lowercased()).inserted
+ }
+
+ return !newTags.isEmpty
+ }
+ }
}
var body: some View {
- ForEach(
- tags.filter { tag in
- tag.name.lowercased().contains(lastSearchTag)
- }
- ) { suggestion in
- Button {
- if let range = searchText.range(of: lastSearchTag, options: .backwards) {
- searchText.replaceSubrange(range, with: suggestion.name)
+ ForEach(filteredItems, id: \.self) { item in
+ switch item {
+ case .left(let tag):
+ Button {
+ if let range = searchText.range(of: lastSearchTag, options: .backwards) {
+ searchText.replaceSubrange(range, with: tag.name)
+ }
+ } label: {
+ Text(tag.name)
+ }
+
+ case .right(let query):
+ Button {
+ if let range = searchText.range(of: lastSearchTag, options: .backwards),
+ let matchingTag = query.tags.first(where: { $0.lowercased().contains(lastSearchTag) })
+ {
+ searchText.replaceSubrange(range, with: matchingTag)
+ }
+ } label: {
+ if let matchingTag = query.tags.first(where: { $0.lowercased().contains(lastSearchTag) })
+ {
+ Text(matchingTag)
+ } else {
+ Text(query.tags.first ?? "")
+ }
}
- } label: {
- Text(suggestion.name)
}
}
}