summaryrefslogtreecommitdiff
path: root/Sora/Views/Shared/FolderMenuView.swift
diff options
context:
space:
mode:
authorFuwn <[email protected]>2026-02-18 12:29:25 -0800
committerFuwn <[email protected]>2026-02-18 12:29:29 -0800
commit0917354dc0b79d1ac414392ae036f784eb397113 (patch)
treeede2a5b3935eed05607f6a493d8a34ce74d9834d /Sora/Views/Shared/FolderMenuView.swift
parentperf: eliminate repeated favorites sort map and grid recompute (diff)
downloadsora-testing-0917354dc0b79d1ac414392ae036f784eb397113.tar.xz
sora-testing-0917354dc0b79d1ac414392ae036f784eb397113.zip
refactor: share folder menu hierarchy across views
Diffstat (limited to 'Sora/Views/Shared/FolderMenuView.swift')
-rw-r--r--Sora/Views/Shared/FolderMenuView.swift72
1 files changed, 72 insertions, 0 deletions
diff --git a/Sora/Views/Shared/FolderMenuView.swift b/Sora/Views/Shared/FolderMenuView.swift
new file mode 100644
index 0000000..b068985
--- /dev/null
+++ b/Sora/Views/Shared/FolderMenuView.swift
@@ -0,0 +1,72 @@
+import SwiftUI
+
+struct FolderMenuView: View {
+ let folderHierarchy: FolderHierarchy
+ let showsTopLevelUncategorized: Bool
+ let onSelectFolder: (UUID) -> Void
+ let onCreateTopLevelUncategorized: (String) -> Void
+ let isFolderDisabled: (UUID) -> Bool
+
+ init(
+ folderHierarchy: FolderHierarchy,
+ showsTopLevelUncategorized: Bool = true,
+ onSelectFolder: @escaping (UUID) -> Void,
+ onCreateTopLevelUncategorized: @escaping (String) -> Void = { topLevelName in
+ _ = topLevelName
+ },
+ isFolderDisabled: @escaping (UUID) -> Bool = { _ in false }
+ ) {
+ self.folderHierarchy = folderHierarchy
+ self.showsTopLevelUncategorized = showsTopLevelUncategorized
+ self.onSelectFolder = onSelectFolder
+ self.onCreateTopLevelUncategorized = onCreateTopLevelUncategorized
+ self.isFolderDisabled = isFolderDisabled
+ }
+
+ var body: some View {
+ ForEach(folderHierarchy.rootFolders, id: \.id) { folder in
+ Button(action: {
+ onSelectFolder(folder.id)
+ }) {
+ Text(folder.name)
+ }
+ .disabled(isFolderDisabled(folder.id))
+ }
+
+ ForEach(folderHierarchy.sortedTopLevelNames, id: \.self) { topLevelName in
+ Menu {
+ if showsTopLevelUncategorized {
+ let topLevelFolder = folderHierarchy.rootFolders.first { $0.name == topLevelName }
+
+ if let topLevelFolder {
+ Button(action: {
+ onSelectFolder(topLevelFolder.id)
+ }) {
+ Text("Uncategorized")
+ }
+ .disabled(isFolderDisabled(topLevelFolder.id))
+ } else {
+ Button(action: {
+ onCreateTopLevelUncategorized(topLevelName)
+ }) {
+ Text("Uncategorized")
+ }
+ }
+
+ Divider()
+ }
+
+ ForEach(folderHierarchy.folders(forTopLevelName: topLevelName), id: \.id) { folder in
+ Button(action: {
+ onSelectFolder(folder.id)
+ }) {
+ Text(folder.shortName)
+ }
+ .disabled(isFolderDisabled(folder.id))
+ }
+ } label: {
+ Text(topLevelName)
+ }
+ }
+ }
+}