diff options
| author | Fuwn <[email protected]> | 2025-07-24 22:46:37 +0200 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2025-07-24 22:46:37 +0200 |
| commit | 427993bc3ebfc24ab5367c0883e57f24fa5b1b2c (patch) | |
| tree | 1f4de362c6a62d0087f2820e509a871f2ed11b12 | |
| parent | feat: Development commit (diff) | |
| download | sora-testing-427993bc3ebfc24ab5367c0883e57f24fa5b1b2c.tar.xz sora-testing-427993bc3ebfc24ab5367c0883e57f24fa5b1b2c.zip | |
feat: Development commit
| -rw-r--r-- | Sora/Data/Settings/SettingsManager.swift | 244 |
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 |