From 0917354dc0b79d1ac414392ae036f784eb397113 Mon Sep 17 00:00:00 2001 From: Fuwn Date: Wed, 18 Feb 2026 12:29:25 -0800 Subject: refactor: share folder menu hierarchy across views --- Sora/Views/Shared/FolderMenuView.swift | 72 ++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 Sora/Views/Shared/FolderMenuView.swift (limited to 'Sora/Views/Shared') 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) + } + } + } +} -- cgit v1.2.3