diff options
| author | Fuwn <[email protected]> | 2025-07-08 04:19:46 -0700 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2025-07-08 04:19:46 -0700 |
| commit | b647d1a7a13e38a529efea3d5d849e5b1a769904 (patch) | |
| tree | d921595d450414348dd512802e4492f18e9b5738 | |
| parent | feat: Development commit (diff) | |
| download | sora-testing-b647d1a7a13e38a529efea3d5d849e5b1a769904.tar.xz sora-testing-b647d1a7a13e38a529efea3d5d849e5b1a769904.zip | |
feat: Development commit
| -rw-r--r-- | Sora/Data/CollectionPickerOption.swift | 7 | ||||
| -rw-r--r-- | Sora/Data/Settings/SettingsFolder.swift | 12 | ||||
| -rw-r--r-- | Sora/Views/Generic/GenericListView.swift | 112 |
3 files changed, 75 insertions, 56 deletions
diff --git a/Sora/Data/CollectionPickerOption.swift b/Sora/Data/CollectionPickerOption.swift index 442ebdc..008d559 100644 --- a/Sora/Data/CollectionPickerOption.swift +++ b/Sora/Data/CollectionPickerOption.swift @@ -3,7 +3,6 @@ import Foundation enum CollectionPickerOption: Identifiable, Hashable { case all case folder(UUID) - case topLevel(String) case uncategorized var id: String { @@ -14,9 +13,6 @@ enum CollectionPickerOption: Identifiable, Hashable { case .folder(let id): return id.uuidString - case .topLevel(let name): - return name - case .uncategorized: return "uncategorized" } @@ -30,9 +26,6 @@ enum CollectionPickerOption: Identifiable, Hashable { case .folder(let id): return { settings in settings.folderName(forID: id) ?? "Unknown Folder" } - case .topLevel(let name): - return { _ in name } - case .uncategorized: return { _ in "Uncategorised" } } diff --git a/Sora/Data/Settings/SettingsFolder.swift b/Sora/Data/Settings/SettingsFolder.swift index 2464770..2f6830d 100644 --- a/Sora/Data/Settings/SettingsFolder.swift +++ b/Sora/Data/Settings/SettingsFolder.swift @@ -13,6 +13,18 @@ struct SettingsFolder: Codable, Identifiable, Hashable { return nil } + var shortName: String { + if name.contains("|") { + let components = name.split(separator: "|") + + if components.count > 1 { + return String(components[1]).trimmingCharacters(in: .whitespacesAndNewlines) + } + } + + return name + } + init(name: String, id: UUID = UUID()) { createdAt = Date() self.id = id diff --git a/Sora/Views/Generic/GenericListView.swift b/Sora/Views/Generic/GenericListView.swift index 0c8da79..0945b82 100644 --- a/Sora/Views/Generic/GenericListView.swift +++ b/Sora/Views/Generic/GenericListView.swift @@ -41,15 +41,6 @@ struct GenericListView<T: Identifiable & Hashable & GenericItem>: View { case .uncategorized: return item.folder == nil - case .topLevel(let topLevelName): - if let folderId = item.folder, - let folder = settings.folders.first(where: { $0.id == folderId }), - let itemTopLevelName = folder.topLevelName - { - return itemTopLevelName == topLevelName - } - return false - case .folder(let folderId): return item.folder == folderId } @@ -138,28 +129,28 @@ struct GenericListView<T: Identifiable & Hashable & GenericItem>: View { ) } - ForEach( - settings.folders - .filter { $0.topLevelName != nil } - .map { $0.topLevelName! } - .removingDuplicates(), id: \.self - ) { topLevelName in - Text(CollectionPickerOption.topLevel(topLevelName).name(settings)).tag( - CollectionPickerOption.topLevel(topLevelName) - ) + ForEach(settings.folders.filter { $0.topLevelName == nil }, id: \.id) { folder in + Text(folder.name).tag(CollectionPickerOption.folder(folder.id)) } - ForEach( - settings.folders.filter { folder in - folder.topLevelName == nil - || (selectedCollectionOption == .topLevel(folder.topLevelName!) - && folder.topLevelName != nil) - }, id: \.id - ) { folder in - if isCollectionPopulated(folder.id) { - Text(CollectionPickerOption.folder(folder.id).name(settings)).tag( - CollectionPickerOption.folder(folder.id) - ) + let topLevelFolders = settings.folders + .reduce(into: [String: [SettingsFolder]]()) { result, folder in + guard let topLevelName = folder.topLevelName else { return } + + result[topLevelName, default: []].append(folder) + } + + ForEach(topLevelFolders.keys.sorted(), id: \.self) { topLevelName in + Menu { + ForEach(topLevelFolders[topLevelName] ?? [], id: \.id) { folder in + Button(action: { + selectedCollectionOption = .folder(folder.id) + }) { + Text(folder.shortName) + } + } + } label: { + Text(topLevelName) } } } @@ -242,27 +233,29 @@ struct GenericListView<T: Identifiable & Hashable & GenericItem>: View { ) } - ForEach( - settings.folders - .filter { $0.topLevelName != nil } - .map { $0.topLevelName! } - .removingDuplicates(), id: \.self - ) { topLevelName in - Text(CollectionPickerOption.topLevel(topLevelName).name(settings)).tag( - CollectionPickerOption.topLevel(topLevelName) - ) + ForEach(settings.folders.filter { $0.topLevelName == nil }, id: \.id) { folder in + Text(folder.name).tag(CollectionPickerOption.folder(folder.id)) } - ForEach( - settings.folders.filter { folder in - folder.topLevelName == nil - || (selectedCollectionOption == .topLevel(folder.topLevelName!) - && folder.topLevelName != nil) - }, id: \.id - ) { folder in - Text(CollectionPickerOption.folder(folder.id).name(settings)) - .tag(CollectionPickerOption.folder(folder.id)) - .selectionDisabled(!isCollectionPopulated(folder.id)) + let topLevelFolders = settings.folders + .reduce(into: [String: [SettingsFolder]]()) { result, folder in + guard let topLevelName = folder.topLevelName else { return } + + result[topLevelName, default: []].append(folder) + } + + ForEach(topLevelFolders.keys.sorted(), id: \.self) { topLevelName in + Menu { + ForEach(topLevelFolders[topLevelName] ?? [], id: \.id) { folder in + Button(action: { + selectedCollectionOption = .folder(folder.id) + }) { + Text(folder.shortName) + } + } + } label: { + Text(topLevelName) + } } } } label: { @@ -391,7 +384,7 @@ struct GenericListView<T: Identifiable & Hashable & GenericItem>: View { } Menu { - ForEach(settings.folders, id: \.id) { folder in + ForEach(settings.folders.filter { $0.topLevelName == nil }, id: \.id) { folder in if item.folder != folder.id { Button(action: { settings.updateBookmarkFolder(withID: item.id, folder: folder.id) @@ -401,6 +394,27 @@ struct GenericListView<T: Identifiable & Hashable & GenericItem>: View { } } + let topLevelFolders = settings.folders + .reduce(into: [String: [SettingsFolder]]()) { result, folder in + guard let topLevelName = folder.topLevelName else { return } + + result[topLevelName, default: []].append(folder) + } + + ForEach(topLevelFolders.keys.sorted(), id: \.self) { topLevelName in + Menu { + ForEach(topLevelFolders[topLevelName] ?? [], id: \.id) { folder in + Button(action: { + settings.updateBookmarkFolder(withID: item.id, folder: folder.id) + }) { + Text(folder.shortName) + } + } + } label: { + Text(topLevelName) + } + } + Button(action: { itemPendingCollectionAssignment = item.id isNewCollectionAlertPresented = true |