fix: restore favorited nodes to the top of the admin/configuration node picker#1977
Merged
garthvh merged 1 commit intoJun 23, 2026
Merged
Conversation
…de picker The CoreData→SwiftData conversion (meshtastic#1668) replaced the admin node picker's multi-key @fetchrequest sort with @query(sort: \.lastHeard, .reverse), which dropped `favorite` as a sort key. Favorited nodes were no longer surfaced at the top of the Remote Admin / Configuration list. Favorite-on-top can't be expressed as a SwiftData SortDescriptor because `favorite` is a `Bool` and `Bool` isn't `Comparable`, so it's restored in memory via NodeInfoEntity.adminPickerOrder(_:) — a stable, O(n) favorites-first partition over the @query's already-lastHeard-descending results. Using a partition (rather than a full re-sort) keeps it cheap to call per render and deterministic across re-renders, avoiding the kind of per-render work the node lists were recently tuned to minimize. Adds SettingsNodeSortTests covering favorites hoisting, recency preservation within each group, never-heard favorites, and edge cases.
garthvh
approved these changes
Jun 23, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed?
Favorited nodes are once again listed at the top of the Remote Admin / Configuration node picker (
Settings.swift), above non-favorites. Within each group, the existing most-recently-heard order is preserved.The ordering is applied via a new helper,
NodeInfoEntity.adminPickerOrder(_:), a stable favorites-first partition over the picker's@Queryresults. The picker'sForEachnow iterates asortedNodescomputed property instead of the raw@Query.Why did it change?
The CoreData→SwiftData conversion (#1668) replaced the picker's multi-key
@FetchRequestsort with@Query(sort: \.lastHeard, .reverse), which silently droppedfavoriteas a sort key. As a result, favorited nodes were no longer surfaced at the top of the list — they landed wherever their last-heard time placed them.Favorite-on-top can't be expressed as a SwiftData
SortDescriptorbecausefavoriteis aBoolandBoolisn'tComparable(so it's not a validSortDescriptorkey on a non-NSObject@Model). It's restored in memory instead, as a stable O(n) partition over the@Query's already-lastHeard-descending results — rather than an O(n log n) re-sort — so it stays cheap to evaluate per render and deterministic across re-renders.How is this tested?
Adds
SettingsNodeSortTests(Swift Testing, 7 cases) exercisingNodeInfoEntity.adminPickerOrder(_:):lastHeard == nil) favorite still sorts above a recently-heard non-favorite,All 7 pass locally (iPhone 16, iOS 18 simulator).
Screenshots/Videos (when applicable)
N/A — ordering change in the existing admin node picker; no UI structure change.
Checklist
docs/user/ordocs/developer/, and updated accordingly. No doc update needed (no documented behavior changes) — please apply theskip-docs-checklabel.