mirror of
https://github.com/vicliu624/trail-mate.git
synced 2026-06-26 23:21:43 +00:00
bf7068b02b
* refactor: render chat rows from presentation state * Fix Meshtastic channel sync and add MeshCore CN preset * Add granular chat notification settings * Add SD settings backup and restore * Prepare 0.1.26-alpha release --------- Co-authored-by: vicliu624 <vicliu@outlook.com>
3.0 KiB
3.0 KiB
UI Presentation Architecture Specification
Trail Mate supports embedded LVGL, ASCII/TUI, GTK, CLI, and headless product targets. UI code must therefore be split by responsibility rather than by the first toolkit that implemented a page.
Three UI Layers
App Service
Business state and business actions.
Presentation Model
UI-independent page/workspace state and actions.
Shell / Renderer
LVGL / ASCII / GTK / CLI / Headless concrete rendering and input.
App Service
App services own business-facing state and actions.
Examples:
ChatService
ContactService
LocationService
MeshService
ConfigService
DeviceStatusService
App services must not know:
LVGL
GTK
terminal handles
screen size
font objects
button widgets
layout widgets
framebuffers
Presentation Model
Presentation models convert app-service state into displayable workspace state.
Examples:
ChatWorkspaceModel
MapWorkspaceModel
SettingsWorkspaceModel
DeviceStatusModel
GpsStatusModel
MeshStatusModel
Presentation models may know:
selected conversation
abstract list cursor
current workspace action set
field formatting policy
row/column/panel concepts
compact/desktop/terminal presentation profile
Presentation models must not know:
lv_obj_t
GtkWidget
ncurses WINDOW
stdout
framebuffer
RadioLib
sx1262
GPS UART
board pin maps
Renderer and Shell
Renderers know concrete UI technology:
LVGL renderer: Presentation snapshot -> lv_obj_t tree
ASCII renderer: Presentation snapshot -> text grid / ANSI output
GTK renderer: Presentation snapshot -> GtkWidget tree
CLI renderer: command result -> stdout/stderr
Headless shell: snapshot/log/API export only
Renderer rules:
Renderer consumes PresentationModel snapshots.
Renderer sends UI actions.
Renderer does not own business state.
Renderer does not call platform radio/GPS/storage adapters directly.
Renderer does not mutate app-service internals.
UI Shell Roles
LVGL:
embedded compact shell
single UI owner task/thread
small-screen layout profile
button/touch/encoder/keyboard inputs depending on target
ASCII/TUI:
terminal shell
single terminal output owner
keyboard input
stable text canvas or panel model
GTK:
desktop-class workbench shell
GTK main loop owner
keyboard/pointer input
wide layout profile
CLI:
command shell
stateless or short-lived command execution
stdout/stderr output
Headless:
no renderer
only API/log/snapshot exposure
Forbidden Couplings
lvgl_chat_page.cpp implements message deduplication
gtk_map_page.cpp parses GPS NMEA
ascii_mesh_view.cpp reads peer key store directly
AppService includes lv_obj_t or GtkWidget
PresentationModel stores terminal handles
Renderer writes direct to radio or GPS driver
Allowed Couplings
Renderer -> PresentationModel snapshot
Renderer -> PresentationModel action
PresentationModel -> AppService snapshot/action API
AppService -> UseCase/Domain/Protocol/Ports
CompositionRoot -> concrete renderer and service graph