feat: local display names for nodes#1620
Conversation
- Add NodeDisplayNameStore (UserDefaults) keyed by node number - Add displayLongName/displayShortName on UserEntity - Show custom name in node list, detail, messages, relay text - Add EditNodeDisplayNameView sheet and 'Set display name' in list/detail - Notify UI on change via NodeDisplayNameStore.didChangeNotification Made-with: Cursor
Made-with: Cursor
|
Meshtastic Contributor seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account. You have signed the CLA already but the status is still pending? Let us recheck it. |
|
This feature was in the app before and just caused confusion, without this data persisting on the node it just seems like a way to frustrate users. |
|
Maybe a notes field could be added instead? A small icon n next in the node list could signal that there's added info in the notes |
garthvh
left a comment
There was a problem hiding this comment.
Thanks for the PR — local display names is a genuinely useful feature and the core idea is well thought out. NodeDisplayNameStore is clean, the notification-based refresh pattern is correct, and the displayLongName/displayShortName computed properties are a nice drop-in replacement. However there are several blocking issues that need to be addressed before this can merge.
Critical — Wrong extension files / Core Data assumptions
This PR was authored against an old version of the repo. Core Data has been fully removed from this project — all persistence is SwiftData. The affected files have moved:
| PR targets | Correct path on main |
|---|---|
Meshtastic/Extensions/CoreData/UserEntityExtension.swift |
Meshtastic/Extensions/SwiftData/UserEntityExtension.swift |
Meshtastic/Extensions/CoreData/NodeInfoEntityExtension.swift |
Meshtastic/Extensions/SwiftData/NodeInfoEntityExtension.swift |
Meshtastic/Extensions/CoreData/MessageEntityExtension.swift |
Meshtastic/Extensions/SwiftData/MessageEntityExtension.swift |
Please rebase onto current main and redirect all changes to the SwiftData extension files.
Critical — NSManagedObjectID / Core Data API in NodeInfoEntityExtension
The diff adds:
extension NodeInfoEntity: Identifiable {
public var id: NSManagedObjectID { objectID }
}NSManagedObjectID and objectID are Core Data APIs. NodeInfoEntity is a SwiftData @Model — it already conforms to Identifiable through SwiftData via persistentModelID. This block needs to be removed entirely.
Critical — import CoreData in EditNodeDisplayNameView.swift
EditNodeDisplayNameView imports CoreData but does not use it. Remove the import — the view only needs SwiftUI.
Critical — NodeList uses @query, not NSFetchRequest
The PR's FilteredNodeList initialiser sets up an NSFetchRequest<NodeInfoEntity> — but on main, NodeList uses @Environment(\.modelContext) and @Query (SwiftData). These APIs are incompatible. After rebasing, the node-for-display-name binding needs to be wired into the existing SwiftData query-driven list.
Warning — Force-unwrap in MessageEntityExtension.swift
let name = users.first!.displayLongName // crash if users is somehow emptyThe original code safely used optional binding. Please restore a guard or use optional chaining instead.
Warning — Indentation regressions
The diff introduces broken indentation in NodeDetail.swift, NodeListItem.swift, NodeRow.swift, and NodeList.swift — mixed tabs/spaces and misaligned braces. The .sheet call in NodeDetail is de-indented out of its ScrollViewReader scope. Please run SwiftLint before submitting (scripts/lint).
Warning — docs/PULL_REQUEST_DISPLAY_NAMES.md should be removed
This file is a copy of the PR description dropped into docs/. It is not a user guide or developer doc. Please delete it. If you would like to document the feature, add a section to docs/user/nodes.md instead (per the view-to-doc mapping in CONTRIBUTING.md).
Warning — No tests
NodeDisplayNameStore is the most independently testable piece here and has no coverage. Please add a Swift Testing suite (import Testing, @Suite, @Test, #expect) covering at minimum: set/get, clear, persistence across instances, and notification posting. See MeshtasticTests/RouterTests.swift for the project's testing conventions.
What to keep as-is
NodeDisplayNameStore.swift— solid implementation, keep itEditNodeDisplayNameView.swift— clean UI, keep it (just removeimport CoreData)displayLongName/displayShortNamecomputed properties onUserEntity— correct approach, just apply them to the right SwiftData extension file- The
NodeDisplayNameStore.didChangeNotification+.id(displayNameRefresh)refresh pattern inNodeDetail— correct, keep it
Local display names for nodes
Users can set a local display name for any node. That name is shown in the app instead of the device’s long/short name, and is stored only on the device (not sent over the mesh).
Summary
NodeDisplayNameStore(UserDefaults), keyed by node numberUI
displayLongName/displayShortName.Technical details
num), the unique node ID.nodeDisplayNames; JSON dictionary[String: String]with node num as string key.UserEntityextensionsdisplayLongNameanddisplayShortName; they return the stored name if set, otherwise the existinglongName/shortName.NodeDisplayNameStore.didChangeNotificationis posted when a name is set or cleared; detail view subscribes to refresh the title.Checklist