summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFuwn <[email protected]>2025-02-24 06:04:35 -0800
committerFuwn <[email protected]>2025-02-24 06:04:35 -0800
commitbb3adb028da4bf0f11790c5f081d199cae659201 (patch)
tree02a4376e860277b59280894430eccaacac0064cd
parentfeat: Development commit (diff)
downloadsora-testing-bb3adb028da4bf0f11790c5f081d199cae659201.tar.xz
sora-testing-bb3adb028da4bf0f11790c5f081d199cae659201.zip
feat: Development commit
-rw-r--r--Sora/Data/Booru/BooruManager.swift43
-rw-r--r--Sora/Data/Booru/Tag/BooruTag.swift4
-rw-r--r--Sora/Views/SearchSuggestionsView.swift13
3 files changed, 53 insertions, 7 deletions
diff --git a/Sora/Data/Booru/BooruManager.swift b/Sora/Data/Booru/BooruManager.swift
index 45a2240..00fb3d1 100644
--- a/Sora/Data/Booru/BooruManager.swift
+++ b/Sora/Data/Booru/BooruManager.swift
@@ -21,6 +21,14 @@ class BooruManager: ObservableObject {
.map { $0.trimmingCharacters(in: .whitespacesAndNewlines) }
.filter { !$0.isEmpty }
}
+ private var tagsCacheFileURL: URL? {
+ guard let directory = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first
+ else {
+ return nil
+ }
+
+ return directory.appendingPathComponent("\(provider)_tags.json")
+ }
#if os(macOS)
@Published var selectedPost: BooruPost?
@@ -29,6 +37,7 @@ class BooruManager: ObservableObject {
init(_ provider: BooruProvider) {
self.provider = provider
+ loadCachedTags()
fetchAllTags()
}
@@ -103,7 +112,7 @@ class BooruManager: ObservableObject {
}
}
- func fetchAllTags(limit: Int = 100_000) {
+ func fetchAllTags(limit: Int = 0) {
Task {
guard let url = urlForTags(limit: limit) else { return }
@@ -114,6 +123,7 @@ class BooruManager: ObservableObject {
DispatchQueue.main.async {
self.allTags = BooruTagXMLParser(data: data).parse().sorted { $0.count > $1.count }
+ self.saveTagsToCache()
}
} catch {
if (error as? URLError)?.code != .cancelled {
@@ -170,6 +180,37 @@ class BooruManager: ObservableObject {
}
}
+ private func saveTagsToCache() {
+ guard let url = tagsCacheFileURL else { return }
+
+ do {
+ let data = try JSONEncoder().encode(allTags)
+
+ try data.write(to: url)
+ } catch {
+ #if DEBUG
+ print("saveTagsToCache: \(error)")
+ #endif
+ }
+ }
+
+ private func loadCachedTags() {
+ guard let url = tagsCacheFileURL else { return }
+
+ do {
+ let data = try Data(contentsOf: url)
+ let cachedTags = try JSONDecoder().decode([BooruTag].self, from: data)
+
+ DispatchQueue.main.async {
+ self.allTags = cachedTags
+ }
+ } catch {
+ #if DEBUG
+ print("loadCachedTags: \(error)")
+ #endif
+ }
+ }
+
deinit {
currentTask?.cancel()
}
diff --git a/Sora/Data/Booru/Tag/BooruTag.swift b/Sora/Data/Booru/Tag/BooruTag.swift
index d603e9f..06de48a 100644
--- a/Sora/Data/Booru/Tag/BooruTag.swift
+++ b/Sora/Data/Booru/Tag/BooruTag.swift
@@ -1,6 +1,4 @@
-import Foundation
-
-struct BooruTag: Identifiable, Hashable {
+struct BooruTag: Identifiable, Hashable, Encodable, Decodable {
let id: String
let name: String
let count: Int
diff --git a/Sora/Views/SearchSuggestionsView.swift b/Sora/Views/SearchSuggestionsView.swift
index 34ccfbc..2a1a8d6 100644
--- a/Sora/Views/SearchSuggestionsView.swift
+++ b/Sora/Views/SearchSuggestionsView.swift
@@ -3,8 +3,13 @@ import SwiftUI
struct SearchSuggestionsView: View {
var tags: [BooruTag]
@Binding var searchText: String
- var lastSearchTag: String {
- String(searchText.split(separator: " ").last ?? "")
+ private var lastSearchTag: String {
+ String(searchText.split(separator: " ").last ?? "").lowercased()
+ }
+ private var filteredTags: [BooruTag] {
+ guard !lastSearchTag.isEmpty else { return [] }
+
+ return tags.filter { $0.name.lowercased().contains(lastSearchTag) }
}
var body: some View {
@@ -14,7 +19,9 @@ struct SearchSuggestionsView: View {
}
) { suggestion in
Button {
- searchText.replaceSubrange(searchText.range(of: lastSearchTag)!, with: suggestion.name)
+ if let range = searchText.range(of: lastSearchTag, options: .backwards) {
+ searchText.replaceSubrange(range, with: suggestion.name)
+ }
} label: {
Text(suggestion.name)
}