Skip to content

Feature: Add "None" option to View → Sort By menu #1921

@gjouret

Description

@gjouret

Summary

The right-click folder settings already offer a "None" sort option that preserves note order when editing. However, this option is missing from the View → Sort By menu, making it inaccessible for virtual folders (All Notes, Untagged, Todo) and as a global default.

Current Behavior

  • Right-click a folder → Sort By → includes "None" option ✓
  • View → Sort By → only offers Modification Date, Creation Date, Title ✗
  • No way to set "don't re-sort" for virtual folders like All Notes

Proposed Behavior

Add a "None (Global Default)" option to the View → Sort By submenu that:

  1. Preserves note list order — editing a note does not cause it to jump position
  2. Shows a checkmark in the menu when active (like other sort options)
  3. Works for all folder types including virtual folders (All Notes, Untagged, Todo)
  4. Does not toggle sort direction (unlike date/title sort options)

Implementation Notes

This requires addressing three underlying issues:

1. Swift Optional.none vs SortBy.none conflation

The SortBy enum has a case none. When used with failable initializers like SortBy(rawValue: "none"), the result Optional.some(SortBy.none) is conflated with Optional.none (nil) in guard let / if let pattern matching. This causes:

  • The sortBy: action handler to silently return without setting the sort mode
  • UserDefaultsManagement.sort getter to return .modificationDate instead of .none
  • ProjectSettings decoder to skip the .none value when loading saved settings

Every SortBy(rawValue:) call site needs explicit handling: check for "none" string before using the failable initializer.

2. UserDefaultsManagement.sort uses NSUbiquitousKeyValueStore which silently fails

The sort property reads/writes to global (NSUbiquitousKeyValueStore.default), which requires iCloud KV Store entitlements. In debug builds (and potentially some production configurations), writes silently fail and reads return nil, falling back to .modificationDate. The property should also write to/read from UserDefaults.standard (shared) as the primary store.

3. Menu validation uses global defaults instead of effective sort state

validateMenuItem for viewSortBy was reading directly from UserDefaultsManagement.sort and UserDefaultsManagement.sortDirection, ignoring per-folder and virtual-folder sort overrides. It should use Storage.getSortByState() and getSortDirectionState() which resolve the three-tier precedence (per-folder → virtual folder → global).

Files Changed

  • Main.storyboard — Add "None (Global Default)" menu item (tag 0, identifier SB.none) to Sort By submenu
  • ViewController.swiftsortBy: handler: explicit "none" string check before SortBy(rawValue:); update virtual folder project settings; skip direction toggle for None
  • EditorViewController.swiftvalidateMenuItem: use Storage.getSortByState(); add case 0: for None checkmark
  • UserDefaultsManagement.swiftsort property: read from UserDefaults.standard first; explicit "none" handling in getter; write to both stores
  • ProjectSettings.swiftinit(coder:): explicit "none" handling when decoding sort setting
  • Storage.swiftbuildSortBy(): handle .none for real projects; sortQuery(): separate .none case from .modificationDate

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions