feat: a message's bytes left, counted as it will be sent, on every screen

The limit is what the send leaves of MAX_TEXT_LEN: a channel post carries
"<node name>: ", a direct message resent more than three times keeps two
bytes spare, and placeholders count as they expand (msgtext::limit/sentLen).
Bytes, not characters. The path and packet header sit outside the payload;
static_asserts keep a full message within the radio frame on the longest path.

From 40 bytes left the count shows: on the L2 as a tag on the field's top
edge, on OLED/e-ink at the right of the preview's last line with the text
wrapped short of it. Input stops at the limit; a send still over (a
placeholder grew) is held. Sim hooks to open a compose with text.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Jakub
2026-10-07 22:58:01 +02:00
co-authored by Claude Opus 5.5
parent 60df2a3268
commit 6c9186dc54
7 changed files with 179 additions and 9 deletions
@@ -128,6 +128,7 @@ public:
void setTrails(bool on);
void setVectorMap(bool on);
void simMapAt(const char* spec); // Map tools > Live tiles
void simCompose(const char* text); // the open thread's field: this text, keyboard up
// Navigation map (NavMap.h)
void navTargetsPopup();
void navClosePopup();
@@ -169,6 +170,8 @@ public:
void bannerOpen(); // the message banner tapped: its conversation
void back();
void sendFromCompose();
int composeLimit() const; // bytes the open thread's message may take
int composeLen(const char* typed) const; // what `typed` takes once sent
void setKeyboardVisible(bool show);
void showToast(const char* text, uint32_t ms = 2500);
// Clock tools (ClockScreen.h)