summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFuwn <[email protected]>2025-07-24 22:46:37 +0200
committerFuwn <[email protected]>2025-07-24 22:46:37 +0200
commit427993bc3ebfc24ab5367c0883e57f24fa5b1b2c (patch)
tree1f4de362c6a62d0087f2820e509a871f2ed11b12
parentfeat: Development commit (diff)
downloadsora-testing-427993bc3ebfc24ab5367c0883e57f24fa5b1b2c.tar.xz
sora-testing-427993bc3ebfc24ab5367c0883e57f24fa5b1b2c.zip
feat: Development commit
-rw-r--r--Sora/Data/Settings/SettingsManager.swift244
1 files changed, 149 insertions, 95 deletions
diff --git a/Sora/Data/Settings/SettingsManager.swift b/Sora/Data/Settings/SettingsManager.swift
index 684cc91..5112dcb 100644
--- a/Sora/Data/Settings/SettingsManager.swift
+++ b/Sora/Data/Settings/SettingsManager.swift
@@ -262,14 +262,14 @@ class SettingsManager: ObservableObject { // swiftlint:disable:this type_body_l
thumbnailQualityCache = _thumbnailQuality
}
- func updateBookmarks(_ newValue: [SettingsBookmark]) {
+ func updateBookmarks(_ newValue: [SettingsBookmark]) async {
syncableData(
key: "bookmarks",
localData: $bookmarksData,
newValue: newValue
) { $0.sorted { $0.date > $1.date } }
loadBookmarksCache()
- backupBookmarks()
+ await backupBookmarks()
}
func updateSearchHistory(_ newValue: [BooruSearchQuery]) {
@@ -366,50 +366,53 @@ class SettingsManager: ObservableObject { // swiftlint:disable:this type_body_l
}
}
- private func backupBookmarks() {
- guard
- let cachesDirectory = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask)
- .first
- else { return }
- let backupDirectory = cachesDirectory.appendingPathComponent("bookmarks_backups")
- let fileManager = FileManager.default
+ private func backupBookmarks() async {
+ await Task.detached {
+ guard
+ let cachesDirectory = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask)
+ .first
+ else { return }
- try? fileManager.createDirectory(at: backupDirectory, withIntermediateDirectories: true)
+ let backupDirectory = cachesDirectory.appendingPathComponent("bookmarks_backups")
+ let fileManager = FileManager.default
- let timestamp = Int(Date().timeIntervalSince1970)
- let backupFile = backupDirectory.appendingPathComponent("bookmarks_backup_\(timestamp).json")
+ try? fileManager.createDirectory(at: backupDirectory, withIntermediateDirectories: true)
- if let data = Self.encode(self.bookmarksCache) {
- try? data.write(to: backupFile)
- }
+ let timestamp = Int(Date().timeIntervalSince1970)
+ let backupFile = backupDirectory.appendingPathComponent("bookmarks_backup_\(timestamp).json")
- if let files = try? fileManager.contentsOfDirectory(
- at: backupDirectory,
- includingPropertiesForKeys: [.contentModificationDateKey],
- options: .skipsHiddenFiles
- ) {
- let jsonBackups = files.filter { file in
- file.lastPathComponent.hasPrefix("bookmarks_backup_") && file.pathExtension == "json"
- }
- let sortedBackups = jsonBackups.sorted { firstFile, secondFile in
- let firstDate =
- (try? firstFile.resourceValues(forKeys: [.contentModificationDateKey])
- .contentModificationDate)
- ?? .distantPast
- let secondDate =
- (try? secondFile.resourceValues(forKeys: [.contentModificationDateKey])
- .contentModificationDate)
- ?? .distantPast
-
- return firstDate > secondDate
+ if let data = await Self.encode(self.bookmarksCache) {
+ try? data.write(to: backupFile)
}
- if sortedBackups.count > 10 {
- for url in sortedBackups[10...] {
- try? fileManager.removeItem(at: url)
+ if let files = try? fileManager.contentsOfDirectory(
+ at: backupDirectory,
+ includingPropertiesForKeys: [.contentModificationDateKey],
+ options: .skipsHiddenFiles
+ ) {
+ let jsonBackups = files.filter { file in
+ file.lastPathComponent.hasPrefix("bookmarks_backup_") && file.pathExtension == "json"
+ }
+ let sortedBackups = jsonBackups.sorted { firstFile, secondFile in
+ let firstDate =
+ (try? firstFile.resourceValues(forKeys: [.contentModificationDateKey])
+ .contentModificationDate)
+ ?? .distantPast
+ let secondDate =
+ (try? secondFile.resourceValues(forKeys: [.contentModificationDateKey])
+ .contentModificationDate)
+ ?? .distantPast
+
+ return firstDate > secondDate
+ }
+
+ if sortedBackups.count > 10 {
+ for url in sortedBackups[10...] {
+ try? fileManager.removeItem(at: url)
+ }
}
}
- }
+ }.value
}
// MARK: Cache Loaders
@@ -486,78 +489,109 @@ class SettingsManager: ObservableObject { // swiftlint:disable:this type_body_l
func syncFromCloud() {
if self.enableSync {
- if let data = NSUbiquitousKeyValueStore.default.data(forKey: "bookmarks") {
- self.bookmarksData = data
- }
+ Task.detached { [weak self] in
+ guard let self else { return }
- if let data = NSUbiquitousKeyValueStore.default.data(forKey: "searchHistory") {
- self.searchHistoryData = data
- }
+ if let data = NSUbiquitousKeyValueStore.default.data(forKey: "bookmarks") {
+ await MainActor.run {
+ self.bookmarksData = data
+ }
+ }
- if let data = NSUbiquitousKeyValueStore.default.data(forKey: "customProviders") {
- self.customProvidersData = data
- }
+ if let data = NSUbiquitousKeyValueStore.default.data(forKey: "searchHistory") {
+ await MainActor.run {
+ self.searchHistoryData = data
+ }
+ }
+
+ if let data = NSUbiquitousKeyValueStore.default.data(forKey: "customProviders") {
+ await MainActor.run {
+ self.customProvidersData = data
+ }
+ }
- loadBookmarksCache()
- loadSearchHistoryCache()
- self.objectWillChange.send()
+ await MainActor.run {
+ self.loadBookmarksCache()
+ self.loadSearchHistoryCache()
+ self.objectWillChange.send()
+ }
+ }
}
}
func syncToCloud() {
if enableSync {
- // Merge bookmarks
- var iCloudBookmarks: [SettingsBookmark] = []
+ Task.detached { [weak self] in
+ guard let self else { return }
- if let iCloudData = NSUbiquitousKeyValueStore.default.data(forKey: "bookmarks") {
- iCloudBookmarks = Self.decode([SettingsBookmark].self, from: iCloudData) ?? []
- }
+ // Merge bookmarks
+ var iCloudBookmarks: [SettingsBookmark] = []
- let localBookmarks = Self.decode([SettingsBookmark].self, from: bookmarksData) ?? []
- let mergedBookmarks = Array(Set(localBookmarks + iCloudBookmarks))
- .sorted { $0.date > $1.date }
+ if let iCloudData = NSUbiquitousKeyValueStore.default.data(forKey: "bookmarks") {
+ iCloudBookmarks =
+ await Self
+ .decode([SettingsBookmark].self, from: iCloudData) ?? []
+ }
- if let encoded = Self.encode(mergedBookmarks) {
- NSUbiquitousKeyValueStore.default.set(encoded, forKey: "bookmarks")
+ let localBookmarks =
+ await Self.decode([SettingsBookmark].self, from: bookmarksData) ?? []
+ let mergedBookmarks = Array(Set(localBookmarks + iCloudBookmarks))
+ .sorted { $0.date > $1.date }
- bookmarksData = encoded
- }
+ if let encoded = await Self.encode(mergedBookmarks) {
+ NSUbiquitousKeyValueStore.default.set(encoded, forKey: "bookmarks")
- // Merge search history
- var iCloudHistory: [BooruSearchQuery] = []
+ await MainActor.run {
+ self.bookmarksData = encoded
+ }
+ }
- if let iCloudData = NSUbiquitousKeyValueStore.default.data(forKey: "searchHistory") {
- iCloudHistory = Self.decode([BooruSearchQuery].self, from: iCloudData) ?? []
- }
+ // Merge search history
+ var iCloudHistory: [BooruSearchQuery] = []
- let localHistory = Self.decode([BooruSearchQuery].self, from: searchHistoryData) ?? []
- let mergedHistory = Array(Set(localHistory + iCloudHistory))
- .sorted { $0.date > $1.date }
+ if let iCloudData = NSUbiquitousKeyValueStore.default.data(forKey: "searchHistory") {
+ iCloudHistory = await Self.decode([BooruSearchQuery].self, from: iCloudData) ?? []
+ }
- if let encoded = Self.encode(mergedHistory) {
- NSUbiquitousKeyValueStore.default.set(encoded, forKey: "searchHistory")
+ let localHistory =
+ await Self.decode([BooruSearchQuery].self, from: searchHistoryData) ?? []
+ let mergedHistory = Array(Set(localHistory + iCloudHistory))
+ .sorted { $0.date > $1.date }
- searchHistoryData = encoded
- }
+ if let encoded = await Self.encode(mergedHistory) {
+ NSUbiquitousKeyValueStore.default.set(encoded, forKey: "searchHistory")
+
+ await MainActor.run {
+ self.searchHistoryData = encoded
+ }
+ }
- // Merge custom providers
- var iCloudProviders: [BooruProviderCustom] = []
+ // Merge custom providers
+ var iCloudProviders: [BooruProviderCustom] = []
- if let iCloudData = NSUbiquitousKeyValueStore.default.data(forKey: "customProviders") {
- iCloudProviders = Self.decode([BooruProviderCustom].self, from: iCloudData) ?? []
- }
+ if let iCloudData = NSUbiquitousKeyValueStore.default.data(forKey: "customProviders") {
+ iCloudProviders =
+ await Self
+ .decode([BooruProviderCustom].self, from: iCloudData) ?? []
+ }
- let localProviders = Self.decode([BooruProviderCustom].self, from: customProvidersData) ?? []
- let mergedProviders = Array(Set(localProviders + iCloudProviders))
+ let localProviders =
+ await Self.decode([BooruProviderCustom].self, from: customProvidersData) ?? []
+ let mergedProviders = Array(Set(localProviders + iCloudProviders))
- if let encoded = Self.encode(mergedProviders) {
- NSUbiquitousKeyValueStore.default.set(encoded, forKey: "customProviders")
+ if let encoded = await Self.encode(mergedProviders) {
+ NSUbiquitousKeyValueStore.default.set(encoded, forKey: "customProviders")
- customProvidersData = encoded
- }
+ await MainActor.run {
+ self.customProvidersData = encoded
+ }
+ }
- loadBookmarksCache()
- loadSearchHistoryCache()
+ await MainActor.run {
+ self.loadBookmarksCache()
+ self.loadSearchHistoryCache()
+ }
+ }
}
}
@@ -570,7 +604,9 @@ class SettingsManager: ObservableObject { // swiftlint:disable:this type_body_l
)
if let data = Self.encode(updatedBookmarks), data.count < 1_000_000 { // 1 MB
- updateBookmarks(updatedBookmarks)
+ Task {
+ await updateBookmarks(updatedBookmarks)
+ }
} else {
debugPrint("SettingsManager.addBookmark: iCloud data limit exceeded")
}
@@ -581,19 +617,25 @@ class SettingsManager: ObservableObject { // swiftlint:disable:this type_body_l
updated.remove(atOffsets: offsets)
- updateBookmarks(updated)
+ Task {
+ await updateBookmarks(updated)
+ }
}
func removeBookmark(withTags tags: [String]) {
let updated = bookmarks.filter { !$0.tags.contains(where: tags.contains) }
- updateBookmarks(updated)
+ Task {
+ await updateBookmarks(updated)
+ }
}
func removeBookmark(withID id: UUID) {
let updated = bookmarks.filter { $0.id != id }
- updateBookmarks(updated)
+ Task {
+ await updateBookmarks(updated)
+ }
}
func exportBookmarks() throws -> Data {
@@ -608,16 +650,21 @@ class SettingsManager: ObservableObject { // swiftlint:disable:this type_body_l
updated.append(contentsOf: newBookmarks)
- updateBookmarks(updated)
+ Task {
+ await updateBookmarks(updated)
+ }
}
func updateBookmarkFolder(withID id: UUID, folder: UUID?) {
guard let index = bookmarks.firstIndex(where: { $0.id == id }) else { return }
+
var updated = bookmarks
updated[index].folder = folder
- updateBookmarks(updated)
+ Task {
+ await updateBookmarks(updated)
+ }
Task { @MainActor in
self.syncToCloud()
@@ -626,11 +673,14 @@ class SettingsManager: ObservableObject { // swiftlint:disable:this type_body_l
func updateBookmarkLastVisit(withID id: UUID, date: Date = Date()) {
guard let index = bookmarks.firstIndex(where: { $0.id == id }) else { return }
+
var updated = bookmarks
updated[index].lastVisit = date
- updateBookmarks(updated)
+ Task {
+ await updateBookmarks(updated)
+ }
Task { @MainActor in
self.syncToCloud()
@@ -639,11 +689,14 @@ class SettingsManager: ObservableObject { // swiftlint:disable:this type_body_l
func incrementBookmarkVisitCount(withID id: UUID) {
guard let index = bookmarks.firstIndex(where: { $0.id == id }) else { return }
+
var updated = bookmarks
updated[index].visitedCount += 1
- updateBookmarks(updated)
+ Task {
+ await updateBookmarks(updated)
+ }
Task { @MainActor in
self.syncToCloud()
@@ -656,6 +709,7 @@ class SettingsManager: ObservableObject { // swiftlint:disable:this type_body_l
func renameFolder(_ folder: SettingsFolder, to newName: String) {
var updated = folders
+
guard let index = updated.firstIndex(where: { $0.id == folder.id }) else { return }
updated[index].name = newName