summaryrefslogtreecommitdiff
path: root/Sora/Views/Shared/FolderHierarchy.swift
diff options
context:
space:
mode:
authorFuwn <[email protected]>2026-02-18 12:21:39 -0800
committerFuwn <[email protected]>2026-02-18 12:21:44 -0800
commit9071518ffa16ff4d0d0e8d93490e67475a56cb61 (patch)
treedaf73fc670b69abb628f208694634c8e39922b77 /Sora/Views/Shared/FolderHierarchy.swift
parentrefactor: coalesce settings sync and skip unchanged writes (diff)
downloadsora-testing-9071518ffa16ff4d0d0e8d93490e67475a56cb61.tar.xz
sora-testing-9071518ffa16ff4d0d0e8d93490e67475a56cb61.zip
perf: memoize generic list derived data and folder grouping
Diffstat (limited to 'Sora/Views/Shared/FolderHierarchy.swift')
-rw-r--r--Sora/Views/Shared/FolderHierarchy.swift44
1 files changed, 44 insertions, 0 deletions
diff --git a/Sora/Views/Shared/FolderHierarchy.swift b/Sora/Views/Shared/FolderHierarchy.swift
new file mode 100644
index 0000000..99c4f8e
--- /dev/null
+++ b/Sora/Views/Shared/FolderHierarchy.swift
@@ -0,0 +1,44 @@
+import Foundation
+
+struct FolderHierarchy {
+ private let foldersByIdentifier: [UUID: SettingsFolder]
+ private let folderNames: Set<String>
+ private let nestedFoldersByTopLevelName: [String: [SettingsFolder]]
+ let rootFolders: [SettingsFolder]
+
+ var sortedTopLevelNames: [String] {
+ nestedFoldersByTopLevelName.keys.sorted()
+ }
+
+ init(folders: [SettingsFolder]) {
+ foldersByIdentifier = Dictionary(uniqueKeysWithValues: folders.map { ($0.id, $0) })
+ folderNames = Set(folders.map(\.name))
+
+ var rootFolders: [SettingsFolder] = []
+ var nestedFoldersByTopLevelName: [String: [SettingsFolder]] = [:]
+
+ for folder in folders {
+ guard let topLevelName = folder.topLevelName else {
+ rootFolders.append(folder)
+ continue
+ }
+
+ nestedFoldersByTopLevelName[topLevelName, default: []].append(folder)
+ }
+
+ self.rootFolders = rootFolders
+ self.nestedFoldersByTopLevelName = nestedFoldersByTopLevelName
+ }
+
+ func folder(for identifier: UUID) -> SettingsFolder? {
+ foldersByIdentifier[identifier]
+ }
+
+ func folders(forTopLevelName topLevelName: String) -> [SettingsFolder] {
+ nestedFoldersByTopLevelName[topLevelName] ?? []
+ }
+
+ func hasTopLevelUncategorized(forTopLevelName topLevelName: String) -> Bool {
+ folderNames.contains(topLevelName)
+ }
+}