Files
MeshCore-Solo/docs/design/nearby_redesign.md
MarekZegare4 27d88bed52 docs: sync docs with shipped state (Nearby menu, design status, delivery)
- tools_screen (Nearby): drop the removed "Filter…" Options action; filtering
  is LEFT/RIGHT on the list only. Sort is adjusted in place via LEFT/RIGHT on
  its row, stored-source only; filter/sort persist across re-entry.
- nearby_redesign / trail_redesign: mark Status implemented (branches merged);
  record the Nearby deviations from the proposal.
- FEATURES: DM delivery status moved from idea to  shipped, with deltas.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 09:50:57 +02:00

9.5 KiB
Raw Permalink Blame History

Nearby Nodes — analiza i propozycja uporządkowania

Branch: refactor/nearby-nodes (zmergowany do main) Plik źródłowy: NearbyScreen.h Status: zaimplementowane — dokument zachowany jako zapis analizy/decyzji.

Odchylenia od propozycji (stan faktyczny):

  • Akcji Filter… w menu nie ma — duplikowała cykl LEFT/RIGHT po typie, więc filtr został wyłącznie na liście (sekcja 3.1 zakładała Filter… też w menu).
  • Sort nie jest togglem przez Enter, lecz zmienia się in-place przez LEFT/RIGHT na podświetlonym wierszu w popupie (wzorzec ustawień Trail), a wiersz pojawia się tylko dla źródła Zapisane (skan nie ma dystansu).
  • Filtr i sort utrzymują się między wejściami na ekran (nie są resetowane).

1. Jak narzędzie jest zbudowane dzisiaj

Ekran łączy w sobie trzy osobne tryby o własnych listach, widokach szczegółów i popupach:

NearbyScreen
├── LIST (kontakty zapisane w mesh)        ← tryb domyślny
│   ├── filtr cyklowany LEFT/RIGHT (7 stanów)
│   ├── DETAIL  (Enter)  → Lat/Lon/Dist/Type/Seen
│   │   └── _opts popup (Hold Enter): Navigate / Ping / Save waypoint
│   │       └── _ping_menu popup
│   ├── NAV view (pełnoekranowa nawigacja)
│   └── _ctx_menu popup (Hold Enter): Discover / Navigate / Save waypoint
│
└── DISCOVER (skan na żywo NODE_DISCOVER_REQ) ← osobny pod-ekran
    ├── lista wyników (karty 2-liniowe)
    │   Hold Enter = ponowny skan (brak menu!)
    └── DETAIL (Enter) → pubkey / RSSI / SNR / status
        └── _ping_menu popup (Hold Enter = od razu ping, bez Options)

Stan ekranu trzyma 15+ pól (_detail, _nav, _discover_mode, _ddetail, _pinging, _filter, dwa komplety _sel/_scroll, trzy bufory wyników ping…) i trzy instancje PopupMenu (_ctx_menu, _opts, _ping_menu).


2. Co konkretnie jest nieuporządkowane

2.1 Jeden cykl filtra miesza trzy różne osie

LEFT/RIGHT przewija 7 stanów:

Fav · ALL · Comp · Rpt · Room · Snsr · TIME

Ale to nie jest jedna oś — to trzy wciśnięte w jeden liniowy cykl:

Stan Czym naprawdę jest
Fav filtr ulubionych (flaga ci.flags & 1)
ALL/Comp/Rpt/Room/Snsr filtr po typie węzła
TIME sortowanie (po lastmod zamiast po dystansie)

Konsekwencje:

  • użytkownik „scrolluje po kategoriach” na ślepo — nie widzi wszystkich naraz, musi cyklować, by trafić w to, czego szuka;
  • kombinacje są niemożliwe: nie da się zobaczyć „ulubionych repeaterów posortowanych po dystansie" ani „repeaterów posortowanych po czasie” — model wymusza dokładnie jeden stan z siedmiu;
  • TIME jako „filtr" jest mylące — zmienia kolejność, nie zawartość;
  • etykieta w nagłówku (NEARBY[TIME]) nie mówi, że to sort.

2.2 Te same akcje, różne menu w zależności od miejsca

Akcja Lista (_ctx_menu) Detail kontaktu (_opts) Detail discover
Navigate
Save waypoint
Ping
Discover

Ten sam węzeł oferuje inny zestaw akcji w zależności od tego, gdzie na niego patrzysz. Ping jest osiągalny tylko ze szczegółów, Discover tylko z listy.

2.3 „Hold Enter” znaczy co innego na każdym ekranie

Ekran Hold Enter (KEY_CONTEXT_MENU)
Lista nearby otwiera menu kontekstowe
Detail kontaktu otwiera menu Options
Lista discover ponowny skan (żadnego menu)
Detail discover od razu Ping (pomija Options)

Brak spójnego modelu „przytrzymaj = menu akcji”.

2.4 _ping_menu to bespoke widget

W przeciwieństwie do reszty popupów, ping-menu:

  • ma wiersze tylko-do-odczytu (RTT / SNR), więc połyka UP/DOWN;
  • przebudowuje się w trakcie (rebuildPingMenu) gdy przychodzą wyniki;
  • zostaje otwarte po SELECTED (reszta popupów się zamyka);
  • ma własny handlePingMenuInput z trybem allow_enter_to_open.

To działa, ale jest to czwarty, niestandardowy wzorzec interakcji w jednym narzędziu.

2.5 Duplikacja list/detail/ping

renderDiscover/handleInputDiscover/renderDiscoverDetail to niemal równoległa kopia logiki listy i szczegółów nearby (osobne _dsel, _dscroll, _d_visible, własne rysowanie kart). Discover i Nearby robią to samo — pokazują listę węzłów z możliwością wejścia w szczegóły i pingowania — ale dwoma osobnymi ścieżkami kodu.


3. Propozycja uporządkowania

Trzy zasady przewodnie: (a) jedno menu akcji wszędzie, (b) filtr i sortowanie jako osobne, jawne osie, (c) jeden wzorzec listy.

3.1 Rozdziel filtr od sortowania

Zamiast jednego cyklu 7-stanowego — dwie niezależne osie wybierane z menu (nie przez ślepe cyklowanie):

Filtr (oś „co pokazujemy") i sort (oś „w jakiej kolejności") są od siebie niezależne i łączą się dowolnie:

FILTR (jedna oś — typ węzła, z Ulubionymi)      SORT (przełącznik)
  • Wszystkie                                      • Dystans (domyślnie)
  • Ulubione                                       • Ostatnio słyszane
  • Companion
  • Repeater
  • Room
  • Sensor

Sterowanie (zatwierdzone):

  • LEFT/RIGHT = szybki cykl tylko po filtrze-typie (jedna spójna oś, znany gest; bez „TIME" zanieczyszczającego cykl);
  • Sort = przełącznik w menu akcji (Dystans ↔ Ostatnio słyszane), trzymany niezależnie od filtra;
  • Filter… dostępny też w menu akcji (odkrywalność — cała lista widoczna naraz, nie tylko cyklowanie).

Dzięki temu „ulubione repeatery po dystansie" staje się możliwe, a w nagłówku widać oba wymiary, np. NEARBY · Rpt · ↓dist.

3.2 Jedno spójne menu akcji (Hold Enter wszędzie)

Jeden PopupMenu (zamiast _ctx_menu + _opts), pozycje zależne od kontekstu, ale kolejność i nazwy stałe:

Hold Enter →  Options
  • Navigate        (gdy węzeł ma GPS)
  • Ping            (gdy znamy pubkey)
  • Save waypoint   (gdy węzeł ma GPS)
  ──────────────
  • Filter…         (podmenu z 3.1)
  • Sort…           (toggle z 3.1)
  • Discover scan   (uruchamia skan na żywo = przełącza źródło)

To samo menu na liście i w szczegółach, w obu źródłach (Zapisane / Skan). Pozycje niedostępne są pomijane (jak już teraz robi has_node), ale nigdy nie zmieniają kolejności ani nazw. „Hold Enter = menu akcji" — bez wyjątków. Ping zawsze przez Options (znika „od razu Ping" z detalu Discover); rescan to pozycja menu, nie ukryty Hold Enter.

3.3 Jedna lista, dwa źródła (Zapisane / Skan na żywo)

Zatwierdzone: zamiast osobnego pod-ekranu Discover — jeden komponent listy/szczegółów/menu/ping napędzany przełącznikiem źródła:

  • ta sama nawigacja, to samo menu akcji, ten sam wzorzec szczegółów i pingu (znika duplikacja renderDiscover*, niespójne Hold Enter i połowa pól stanu);
  • różni się tylko prawa kolumna wiersza i pola w detalu:
    • źródło Zapisane → dystans / azymut / lastmod (jak dziś),
    • źródło Skan na żywo → RSSI / SNR (dane z DiscoverResult).

To nie jest dosłowne zlanie dwóch list w jedną tablicę (dane mają różny kształt — kontakt ma GPS, wynik skanu ma sygnał), tylko jedna ścieżka interakcji nad dwoma źródłami. Wybór źródła = „Discover scan" w menu (uruchamia NODE_DISCOVER_REQ i przełącza widok na wyniki) oraz powrót do Zapisanych przez Cancel.


4. Proponowany zakres (etapami)

Etap Zmiana Ryzyko
1 Rozdziel sort od filtra: TIME znika z cyklu; LEFT/RIGHT cyklują tylko typ+Fav; sort jako stan + toggle niskie
2 Scal _ctx_menu i _opts w jedno menu akcji o stałej kolejności; dodaj Filter…/Sort… niskie
3 Ujednolić Hold Enter w Discover (menu zamiast bezpośredniego rescan/ping; Ping zawsze przez Options) średnie
4 Scal listę Discover z listą Nearby w jeden komponent z przełącznikiem źródła wyższe

Kolejność implementacji: 1 → 2 → 3 → 4. Etapy 12 dają największą poprawę „uporządkowania" przy najmniejszym ryzyku; 34 domykają spójność (jedna lista, jedno menu wszędzie).


5. Decyzje (zatwierdzone 2026-06-14)

  1. Filtr i sort — pełne rozdzielenie osi. LEFT/RIGHT = szybki cykl filtra-typu; Sort jako toggle w menu; Filter… też w menu dla odkrywalności. (Nie chowamy wszystkiego do menu — zachowujemy szybki gest.)
  2. Discover — jedna lista, dwa źródła. Wspólny komponent interakcji; różni się tylko prawa kolumna/pola detalu (dystans vs sygnał).