summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFuwn <[email protected]>2025-03-15 23:09:47 -0700
committerFuwn <[email protected]>2025-03-15 23:09:47 -0700
commite801cdd4e8581af30c7f7af6b28dab6dd92c985b (patch)
tree3f523f3e76655052bd3c47ab0c85b3ca72c5c82f
parentfeat: Development commit (diff)
downloadsora-testing-e801cdd4e8581af30c7f7af6b28dab6dd92c985b.tar.xz
sora-testing-e801cdd4e8581af30c7f7af6b28dab6dd92c985b.zip
feat: Development commit
-rw-r--r--Sora/Data/Settings/SettingsManager.swift222
1 files changed, 158 insertions, 64 deletions
diff --git a/Sora/Data/Settings/SettingsManager.swift b/Sora/Data/Settings/SettingsManager.swift
index b2749e1..63a6223 100644
--- a/Sora/Data/Settings/SettingsManager.swift
+++ b/Sora/Data/Settings/SettingsManager.swift
@@ -1,6 +1,8 @@
+// swiftlint:disable file_length
+
import SwiftUI
-class SettingsManager: ObservableObject {
+class SettingsManager: ObservableObject { // swiftlint:disable:this type_body_length
// MARK: - Stored Properties
@AppStorage("detailViewType")
var detailViewQuality: BooruPostFileType = .original
@@ -55,31 +57,22 @@ class SettingsManager: ObservableObject {
// MARK: - Computed Properties
var bookmarks: [SettingsBookmark] {
get {
- if enableICloudSync {
- if let data = NSUbiquitousKeyValueStore.default.data(forKey: "bookmarks") {
- return (Self.decode([SettingsBookmark].self, from: data) ?? [])
- .sorted { $0.date > $1.date }
- }
-
- return (Self.decode([SettingsBookmark].self, from: bookmarksData) ?? [])
- .sorted { $0.date > $1.date }
- }
-
- return (Self.decode([SettingsBookmark].self, from: bookmarksData) ?? [])
- .sorted { $0.date > $1.date }
+ syncableData(
+ key: "bookmarks",
+ localData: bookmarksData,
+ sort: { $0.sorted { $0.date > $1.date } },
+ identifier: { $0.id }
+ )
}
set {
- let sortedBookmarks = newValue.sorted { $0.date > $1.date }
-
- bookmarksData = Self.encode(sortedBookmarks) ?? Data()
-
- if enableICloudSync {
- NSUbiquitousKeyValueStore.default.set(
- Self.encode(sortedBookmarks),
- forKey: "bookmarks"
- )
- }
+ syncableData(
+ key: "bookmarks",
+ localData: $bookmarksData,
+ newValue: newValue,
+ sort: { $0.sorted { $0.date > $1.date } },
+ identifier: { $0.id }
+ )
}
}
@@ -99,30 +92,22 @@ class SettingsManager: ObservableObject {
var searchHistory: [BooruSearchQuery] {
get {
- if enableICloudSync {
- if let data = NSUbiquitousKeyValueStore.default.data(forKey: "searchHistory") {
- return (Self.decode([BooruSearchQuery].self, from: data) ?? [])
- .sorted { $0.date > $1.date }
- }
-
- return (Self.decode([BooruSearchQuery].self, from: searchHistoryData) ?? [])
- .sorted { $0.date > $1.date }
- }
-
- return (Self.decode([BooruSearchQuery].self, from: searchHistoryData) ?? [])
- .sorted { $0.date > $1.date }
+ syncableData(
+ key: "searchHistory",
+ localData: searchHistoryData,
+ sort: { $0.sorted { $0.date > $1.date } },
+ identifier: { $0.id }
+ )
}
set {
- let sortedHistory = newValue.sorted { $0.date > $1.date }
-
- searchHistoryData = Self.encode(sortedHistory) ?? Data()
-
- if enableICloudSync {
- NSUbiquitousKeyValueStore.default.set(
- Self.encode(sortedHistory), forKey: "searchHistory"
- )
- }
+ syncableData(
+ key: "searchHistory",
+ localData: $searchHistoryData,
+ newValue: newValue,
+ sort: { $0.sorted { $0.date > $1.date } },
+ identifier: { $0.id }
+ )
}
}
@@ -136,26 +121,22 @@ class SettingsManager: ObservableObject {
var customProviders: [BooruProviderCustom] {
get {
- if enableICloudSync {
- if let data = NSUbiquitousKeyValueStore.default.data(forKey: "customProviders") {
- return Self.decode([BooruProviderCustom].self, from: data) ?? []
- }
-
- return Self.decode([BooruProviderCustom].self, from: customProvidersData) ?? []
- }
-
- return Self.decode([BooruProviderCustom].self, from: customProvidersData) ?? []
+ syncableData(
+ key: "customProviders",
+ localData: customProvidersData,
+ sort: { $0 },
+ identifier: { $0.id }
+ )
}
set {
- customProvidersData = Self.encode(newValue) ?? Data()
-
- if enableICloudSync {
- NSUbiquitousKeyValueStore.default.set(
- Self.encode(newValue),
- forKey: "customProviders"
- )
- }
+ syncableData(
+ key: "customProviders",
+ localData: $customProvidersData,
+ newValue: newValue,
+ sort: { $0 },
+ identifier: { $0.id }
+ )
}
}
@@ -193,6 +174,64 @@ class SettingsManager: ObservableObject {
try? JSONDecoder().decode(type, from: data)
}
+ private func syncableData<T: Codable>(
+ key: String,
+ localData: Data,
+ sort: ([T]) -> [T],
+ identifier: (T) -> UUID
+ ) -> [T] {
+ if enableICloudSync {
+ if let iCloudData = NSUbiquitousKeyValueStore.default.data(forKey: key) {
+ if let iCloudValues = Self.decode([T].self, from: iCloudData) {
+ let localValues = Self.decode([T].self, from: localData) ?? []
+ let mergedValues = (localValues + iCloudValues)
+ .reduce(into: [T]()) { result, value in
+ if !result.contains(where: { identifier($0) == identifier(value) }) {
+ result.append(value)
+ }
+ }
+
+ return sort(mergedValues)
+ }
+ }
+ }
+
+ let localValues = Self.decode([T].self, from: localData) ?? []
+
+ return sort(localValues)
+ }
+
+ private func syncableData<T: Codable>(
+ key: String,
+ localData: Binding<Data>,
+ newValue: [T],
+ sort: ([T]) -> [T],
+ identifier: (T) -> UUID
+ ) {
+ let sortedValues = sort(newValue)
+
+ localData.wrappedValue = Self.encode(sortedValues) ?? Data()
+
+ if enableICloudSync {
+ var iCloudValues: [T] = []
+
+ if let iCloudData = NSUbiquitousKeyValueStore.default.data(forKey: key) {
+ iCloudValues = Self.decode([T].self, from: iCloudData) ?? []
+ }
+
+ let filteredICloudValues = iCloudValues.filter { iCloudItem in
+ sortedValues.contains { identifier($0) == identifier(iCloudItem) }
+ }
+ let newLocalItems = sortedValues.filter { localItem in
+ !filteredICloudValues.contains { identifier($0) == identifier(localItem) }
+ }
+ let mergedValues = filteredICloudValues + newLocalItems
+ let sortedMergedValues = sort(mergedValues)
+
+ NSUbiquitousKeyValueStore.default.set(Self.encode(sortedMergedValues), forKey: key)
+ }
+ }
+
// MARK: - Public Methods
func appendToSearchHistory(_ query: BooruSearchQuery) {
self.searchHistory.append(query)
@@ -217,9 +256,64 @@ class SettingsManager: ObservableObject {
func syncToICloud() {
if enableICloudSync {
- NSUbiquitousKeyValueStore.default.set(bookmarksData, forKey: "bookmarks")
- NSUbiquitousKeyValueStore.default.set(searchHistoryData, forKey: "searchHistory")
- NSUbiquitousKeyValueStore.default.set(customProvidersData, forKey: "customProviders")
+ // Merge bookmarks
+ var iCloudBookmarks: [SettingsBookmark] = []
+
+ if let iCloudData = NSUbiquitousKeyValueStore.default.data(forKey: "bookmarks") {
+ iCloudBookmarks = Self.decode([SettingsBookmark].self, from: iCloudData) ?? []
+ }
+
+ let localBookmarks = Self.decode([SettingsBookmark].self, from: bookmarksData) ?? []
+ let mergedBookmarks = (localBookmarks + iCloudBookmarks)
+ .reduce(into: [SettingsBookmark]()) { result, value in
+ if !result.contains(where: { $0.id == value.id }) {
+ result.append(value)
+ }
+ }
+ .sorted { $0.date > $1.date }
+
+ NSUbiquitousKeyValueStore.default.set(Self.encode(mergedBookmarks), forKey: "bookmarks")
+
+ bookmarksData = Self.encode(mergedBookmarks) ?? Data()
+
+ // Merge search history
+ var iCloudHistory: [BooruSearchQuery] = []
+
+ if let iCloudData = NSUbiquitousKeyValueStore.default.data(forKey: "searchHistory") {
+ iCloudHistory = Self.decode([BooruSearchQuery].self, from: iCloudData) ?? []
+ }
+
+ let localHistory = Self.decode([BooruSearchQuery].self, from: searchHistoryData) ?? []
+ let mergedHistory = (localHistory + iCloudHistory)
+ .reduce(into: [BooruSearchQuery]()) { result, value in
+ if !result.contains(where: { $0.id == value.id }) {
+ result.append(value)
+ }
+ }
+ .sorted { $0.date > $1.date }
+
+ NSUbiquitousKeyValueStore.default.set(Self.encode(mergedHistory), forKey: "searchHistory")
+
+ searchHistoryData = Self.encode(mergedHistory) ?? Data()
+
+ // Merge custom providers
+ var iCloudProviders: [BooruProviderCustom] = []
+
+ if let iCloudData = NSUbiquitousKeyValueStore.default.data(forKey: "customProviders") {
+ iCloudProviders = Self.decode([BooruProviderCustom].self, from: iCloudData) ?? []
+ }
+
+ let localProviders = Self.decode([BooruProviderCustom].self, from: customProvidersData) ?? []
+ let mergedProviders = (localProviders + iCloudProviders)
+ .reduce(into: [BooruProviderCustom]()) { result, value in
+ if !result.contains(where: { $0.id == value.id }) {
+ result.append(value)
+ }
+ }
+
+ NSUbiquitousKeyValueStore.default.set(Self.encode(mergedProviders), forKey: "customProviders")
+
+ customProvidersData = Self.encode(mergedProviders) ?? Data()
}
}