Skip to content

nightshift/bug: drag-reorder has no effect — filtered() always sorts by useCount#2

Open
perandre wants to merge 1 commit intomainfrom
nightshift/bug-2026-04-09-move-order
Open

nightshift/bug: drag-reorder has no effect — filtered() always sorts by useCount#2
perandre wants to merge 1 commit intomainfrom
nightshift/bug-2026-04-09-move-order

Conversation

@perandre
Copy link
Copy Markdown
Owner

@perandre perandre commented Apr 9, 2026

Bug

SnippetStore.filtered(by:) in Sources/SnippetStore.swift always sorts the snippet list by useCount descending before returning it, even when the query is empty. SnippetStore.move(from:to:) correctly reorders snippets in-place and calls save(), but the very next SwiftUI render calls filtered(by: "") again and re-sorts the array by useCount, silently undoing the user's drag.

Result: drag-to-reorder appears to do nothing — the list springs back to useCount order on every frame.

Repro

  1. Add at least two snippets and use them different numbers of times so they have different useCount values.
  2. Open the panel with an empty search field.
  3. Drag a snippet to a new position.
  4. Observe: the list immediately re-sorts itself back to useCount order; the manual position is lost.

Reading the code confirms this without running the app: filtered(by: "") always executes let sorted = snippets.sorted { $0.useCount > $1.useCount } and returns sorted, discarding move()'s reorder.

Fix

filtered(by:) now returns snippets (stored order) directly when the query is empty, and only sorts by useCount when a non-empty search query is active so the most-relevant results surface first.

// before
func filtered(by query: String) -> [Snippet] {
    let sorted = snippets.sorted { $0.useCount > $1.useCount }
    guard !query.isEmpty else { return sorted }
    
}

// after
func filtered(by query: String) -> [Snippet] {
    guard !query.isEmpty else { return snippets }
    return snippets
        .filter {  }
        .sorted { $0.useCount > $1.useCount }
}

filtered(by:) always sorted snippets by useCount, making manual
drag-reordering via move(from:to:) invisible — the backing array was
saved correctly but the view immediately re-rendered in useCount order.

Now filtered(by:) returns snippets in their stored order when the query
is empty, so drag-reordering is preserved. When a search query is active
results are still sorted by useCount so the most-used matches surface
first.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant