feat(ui): Favourites phase 2 — pin from Contact options

Adds a fourth item to the QuickMsg Contact options popup that toggles
between "Pin to dial" (when the contact isn't pinned) and
"Unpin (slot N)" (when it is). Pinning opens a six-slot picker submenu
labeled "Slot N: <name>" or "Slot N: empty"; the chosen slot stores the
6-byte pub_key prefix in NodePrefs::favourite_contacts and savePrefs
commits to flash with a brief confirmation alert.

New UITask helpers backing the flow:
- findFavouriteSlot(pub_key) — returns 0..5 if pinned, -1 otherwise
- isFavouriteSlotEmpty(slot)
- setFavouriteSlot(slot, pub_key) / clearFavouriteSlot(slot)

PopupMenu reuse: a single _ctx_menu instance hosts both the Contact
options menu and the slot picker, gated by _pin_picker_active so input
routes correctly. Reset on screen reset() and on any non-NONE menu
result.

Slot labels live in a member buffer (6×22 B) because PopupMenu stores
the string pointers verbatim.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Jakub
2026-05-24 23:30:16 +02:00
parent aedb7f6f5d
commit bee8e7c3dd
3 changed files with 93 additions and 4 deletions

View File

@@ -22,8 +22,8 @@ Implementation:
### 🚧 Favourites dial
Phase 1 ✅ (storage + read-only render + grid nav)
Phase 2 📋 (pin from Contact options menu in QuickMsg)
Phase 3 📋 (pin from empty slot via mini-picker: favourites first, then recent)
Phase 2 (pin from Contact options menu in QuickMsg + slot picker submenu)
Phase 3 📋 (pin from empty slot on the grid via mini-picker: favourites first, then recent)
A 2×3 grid (six slots) of pinned contacts on its own home page, between Clock and Messages. Joystick picks a tile, Enter opens the existing DM conversation or sends a pre-set quick reply.