diff options
| -rw-r--r-- | Sora/Data/Settings/SettingsManager.swift | 177 | ||||
| -rw-r--r-- | Sora/Data/Settings/SettingsSyncKey.swift | 6 | ||||
| -rw-r--r-- | Sora/Views/Settings/Section/SettingsSettingsView.swift | 2 |
3 files changed, 98 insertions, 87 deletions
diff --git a/Sora/Data/Settings/SettingsManager.swift b/Sora/Data/Settings/SettingsManager.swift index 5112dcb..8f441d6 100644 --- a/Sora/Data/Settings/SettingsManager.swift +++ b/Sora/Data/Settings/SettingsManager.swift @@ -85,6 +85,7 @@ class SettingsManager: ObservableObject { // swiftlint:disable:this type_body_l localData: $bookmarksData, newValue: newValue ) { $0.sorted { $0.date > $1.date } } + triggerSyncIfNeeded(for: .bookmarks) } } @@ -131,6 +132,7 @@ class SettingsManager: ObservableObject { // swiftlint:disable:this type_body_l localData: $searchHistoryData, newValue: newValue, ) { $0.sorted { $0.date > $1.date } } + triggerSyncIfNeeded(for: .searchHistory) } } @@ -158,6 +160,7 @@ class SettingsManager: ObservableObject { // swiftlint:disable:this type_body_l localData: $customProvidersData, newValue: newValue, ) { $0 } + triggerSyncIfNeeded(for: .customProviders) } } @@ -270,6 +273,7 @@ class SettingsManager: ObservableObject { // swiftlint:disable:this type_body_l ) { $0.sorted { $0.date > $1.date } } loadBookmarksCache() await backupBookmarks() + triggerSyncIfNeeded(for: .bookmarks) } func updateSearchHistory(_ newValue: [BooruSearchQuery]) { @@ -279,6 +283,7 @@ class SettingsManager: ObservableObject { // swiftlint:disable:this type_body_l newValue: newValue, ) { $0.sorted { $0.date > $1.date } } loadSearchHistoryCache() + triggerSyncIfNeeded(for: .searchHistory) } func updateDisplayRatings(_ newValue: [BooruRating]) { @@ -415,6 +420,86 @@ class SettingsManager: ObservableObject { // swiftlint:disable:this type_body_l }.value } + // swiftlint:disable:next cyclomatic_complexity + private func triggerSyncIfNeeded(for key: SettingsSyncKey) { + guard enableSync else { return } + + Task.detached { [weak self] in + guard let self else { return } + + switch key { + case .bookmarks: + var iCloudBookmarks: [SettingsBookmark] = [] + + if let iCloudData = NSUbiquitousKeyValueStore.default.data(forKey: "bookmarks") { + iCloudBookmarks = + await Self + .decode([SettingsBookmark].self, from: iCloudData) ?? [] + } + + let localBookmarks = + await Self.decode([SettingsBookmark].self, from: bookmarksData) ?? [] + let mergedBookmarks = Array(Set(localBookmarks + iCloudBookmarks)) + .sorted { $0.date > $1.date } + + if let encoded = await Self.encode(mergedBookmarks) { + NSUbiquitousKeyValueStore.default.set(encoded, forKey: "bookmarks") + + await MainActor.run { + self.bookmarksData = encoded + } + } + + case .searchHistory: + var iCloudHistory: [BooruSearchQuery] = [] + + if let iCloudData = NSUbiquitousKeyValueStore.default.data(forKey: "searchHistory") { + iCloudHistory = await Self.decode([BooruSearchQuery].self, from: iCloudData) ?? [] + } + + let localHistory = + await Self.decode([BooruSearchQuery].self, from: searchHistoryData) ?? [] + let mergedHistory = Array(Set(localHistory + iCloudHistory)) + .sorted { $0.date > $1.date } + + if let encoded = await Self.encode(mergedHistory) { + NSUbiquitousKeyValueStore.default.set(encoded, forKey: "searchHistory") + + await MainActor.run { + self.searchHistoryData = encoded + } + } + + case .customProviders: + var iCloudProviders: [BooruProviderCustom] = [] + + if let iCloudData = NSUbiquitousKeyValueStore.default.data(forKey: "customProviders") { + iCloudProviders = + await Self + .decode([BooruProviderCustom].self, from: iCloudData) ?? [] + } + + let localProviders = + await Self.decode([BooruProviderCustom].self, from: customProvidersData) ?? [] + let mergedProviders = Array(Set(localProviders + iCloudProviders)) + + if let encoded = await Self.encode(mergedProviders) { + NSUbiquitousKeyValueStore.default.set(encoded, forKey: "customProviders") + + await MainActor.run { + self.customProvidersData = encoded + } + } + } + + await MainActor.run { + self.loadBookmarksCache() + self.loadSearchHistoryCache() + self.objectWillChange.send() + } + } + } + // MARK: Cache Loaders private func loadCache<T: Decodable & Sendable>( from data: Data, @@ -519,80 +604,10 @@ class SettingsManager: ObservableObject { // swiftlint:disable:this type_body_l } } - func syncToCloud() { - if enableSync { - Task.detached { [weak self] in - guard let self else { return } - - // Merge bookmarks - var iCloudBookmarks: [SettingsBookmark] = [] - - if let iCloudData = NSUbiquitousKeyValueStore.default.data(forKey: "bookmarks") { - iCloudBookmarks = - await Self - .decode([SettingsBookmark].self, from: iCloudData) ?? [] - } - - let localBookmarks = - await Self.decode([SettingsBookmark].self, from: bookmarksData) ?? [] - let mergedBookmarks = Array(Set(localBookmarks + iCloudBookmarks)) - .sorted { $0.date > $1.date } - - if let encoded = await Self.encode(mergedBookmarks) { - NSUbiquitousKeyValueStore.default.set(encoded, forKey: "bookmarks") - - await MainActor.run { - self.bookmarksData = encoded - } - } - - // Merge search history - var iCloudHistory: [BooruSearchQuery] = [] - - if let iCloudData = NSUbiquitousKeyValueStore.default.data(forKey: "searchHistory") { - iCloudHistory = await Self.decode([BooruSearchQuery].self, from: iCloudData) ?? [] - } - - let localHistory = - await Self.decode([BooruSearchQuery].self, from: searchHistoryData) ?? [] - let mergedHistory = Array(Set(localHistory + iCloudHistory)) - .sorted { $0.date > $1.date } - - 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] = [] - - if let iCloudData = NSUbiquitousKeyValueStore.default.data(forKey: "customProviders") { - iCloudProviders = - await Self - .decode([BooruProviderCustom].self, from: iCloudData) ?? [] - } - - let localProviders = - await Self.decode([BooruProviderCustom].self, from: customProvidersData) ?? [] - let mergedProviders = Array(Set(localProviders + iCloudProviders)) - - if let encoded = await Self.encode(mergedProviders) { - NSUbiquitousKeyValueStore.default.set(encoded, forKey: "customProviders") - - await MainActor.run { - self.customProvidersData = encoded - } - } - - await MainActor.run { - self.loadBookmarksCache() - self.loadSearchHistoryCache() - } - } - } + func triggerSyncIfNeededForAll() { + self.triggerSyncIfNeeded(for: .bookmarks) + self.triggerSyncIfNeeded(for: .searchHistory) + self.triggerSyncIfNeeded(for: .customProviders) } // MARK: Bookmark Management @@ -666,9 +681,7 @@ class SettingsManager: ObservableObject { // swiftlint:disable:this type_body_l await updateBookmarks(updated) } - Task { @MainActor in - self.syncToCloud() - } + triggerSyncIfNeeded(for: .bookmarks) } func updateBookmarkLastVisit(withID id: UUID, date: Date = Date()) { @@ -682,9 +695,7 @@ class SettingsManager: ObservableObject { // swiftlint:disable:this type_body_l await updateBookmarks(updated) } - Task { @MainActor in - self.syncToCloud() - } + triggerSyncIfNeeded(for: .bookmarks) } func incrementBookmarkVisitCount(withID id: UUID) { @@ -698,9 +709,7 @@ class SettingsManager: ObservableObject { // swiftlint:disable:this type_body_l await updateBookmarks(updated) } - Task { @MainActor in - self.syncToCloud() - } + triggerSyncIfNeeded(for: .bookmarks) } func folderName(forID id: UUID) -> String? { @@ -728,12 +737,14 @@ class SettingsManager: ObservableObject { // swiftlint:disable:this type_body_l updated.remove(atOffsets: offsets) updateSearchHistory(updated) + triggerSyncIfNeeded(for: .searchHistory) } func removeSearchHistoryEntry(withID id: UUID) { let updated = searchHistory.filter { $0.id != id } updateSearchHistory(updated) + triggerSyncIfNeeded(for: .searchHistory) } #if DEBUG diff --git a/Sora/Data/Settings/SettingsSyncKey.swift b/Sora/Data/Settings/SettingsSyncKey.swift index 5f26250..75c6afe 100644 --- a/Sora/Data/Settings/SettingsSyncKey.swift +++ b/Sora/Data/Settings/SettingsSyncKey.swift @@ -1,3 +1,3 @@ - private enum SettingsSyncKey { - case bookmarks, searchHistory, customProviders - } +enum SettingsSyncKey { + case bookmarks, customProviders, searchHistory +} diff --git a/Sora/Views/Settings/Section/SettingsSettingsView.swift b/Sora/Views/Settings/Section/SettingsSettingsView.swift index ab6a31a..0b10d31 100644 --- a/Sora/Views/Settings/Section/SettingsSettingsView.swift +++ b/Sora/Views/Settings/Section/SettingsSettingsView.swift @@ -11,7 +11,7 @@ struct SettingsSettingsView: View { .font(.caption) } .onChange(of: settings.enableSync) { _, _ in - settings.syncToCloud() + settings.triggerSyncIfNeededForAll() } Button("Reset to Defaults") { |