Projects tab: create via +, sort by activity/name/count
Declared-but-empty projects persist locally (UserDefaults) until a note carries the name, at which point the project syncs via notes as usual. Empty declared projects can be swipe-deleted. Claude-Session: https://claude.ai/code/session_014esDWi42URLEC6Cj17hGQ3
This commit is contained in:
@@ -17,6 +17,8 @@ struct AssignProjectSheet: View {
|
||||
@AppStorage(ProjectsNaming.storageKey) private var namingRaw = ProjectsNaming.projects.rawValue
|
||||
private var naming: ProjectsNaming { ProjectsNaming(rawValue: namingRaw) ?? .projects }
|
||||
|
||||
@AppStorage(ProjectsPrefs.declaredKey) private var declaredRaw = ""
|
||||
|
||||
var body: some View {
|
||||
NavigationStack {
|
||||
List {
|
||||
@@ -79,14 +81,19 @@ struct AssignProjectSheet: View {
|
||||
newName.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
}
|
||||
|
||||
/// Distinct project names across live notes, count-sorted like
|
||||
/// `ProjectsView` so the most-used projects surface first.
|
||||
/// Distinct project names across live notes, unioned with names declared
|
||||
/// but not yet used (count 0) so a freshly "+"-created project is
|
||||
/// immediately offered here, count-sorted like `ProjectsView` so the
|
||||
/// most-used projects surface first.
|
||||
private var existingProjects: [(project: String, count: Int)] {
|
||||
var counts: [String: Int] = [:]
|
||||
for note in notes where note.isLive {
|
||||
guard let project = note.project else { continue }
|
||||
counts[project, default: 0] += 1
|
||||
}
|
||||
for name in ProjectsPrefs.decodeDeclared(declaredRaw) where counts[name] == nil {
|
||||
counts[name] = 0
|
||||
}
|
||||
return counts
|
||||
.map { (project: $0.key, count: $0.value) }
|
||||
.sorted { $0.count == $1.count ? $0.project < $1.project : $0.count > $1.count }
|
||||
|
||||
Reference in New Issue
Block a user