Currently, there is no visual indicator showing how close a user is to the Meshtastic message payload limit (around 220 bytes). This is especially problematic for users typing in non-ASCII languages (like Cyrillic), where a single character takes 2 bytes. Users can unknowingly exceed the payload limit before hitting Enter.
Proposed Solution:
Add a live byte counter (e.g., 0/220b) to the bottom right border of the message entry window (entry_win).
The counter should calculate the actual UTF-8 byte length (len(content.encode('utf-8'))), not just the string character count.
If the limit (> 220 bytes) is exceeded, the counter should change color (e.g., using settings_warning) to visually alert the user.
Here is a working implementation that modifies the draw_message_input function in contact/ui/contact_ui.py:
def draw_message_input(draft: str) -> None:
"""Redraw the whole input row and scroll it to keep the draft cursor visible."""
height, width = entry_win.getmaxyx()
prompt = slice_to_width("Message: ", max(0, width - 3))
available = max(1, width - 2 - text_width(prompt))
ui_state.input_cursor = max(0, min(ui_state.input_cursor, len(draft)))
content = ui_state.reply_context + draft
# Calculate bytes in UTF-8 to account for non-ASCII characters
byte_count = len(content.encode('utf-8'))
counter_str = f" {byte_count}/220b "
cursor = len(ui_state.reply_context) + ui_state.input_cursor
start = cursor
used = 0
while start > 0 and used + text_width(content[start - 1]) < available:
start -= 1
used += text_width(content[start])
visible = slice_to_width(content[start:], available)
draw_text_field(entry_win, prompt + visible, get_color("input"))
paint_frame(entry_win, selected=ui_state.input_focused, refresh=False)
try:
hint = " Ctrl+K Help "
if width >= len(hint) + 4:
entry_win.addstr(0, width - len(hint) - 2, hint, get_color("commands"))
# Highlight the counter if it exceeds the limit
if byte_count > 220:
try:
counter_color = get_color("settings_warning", bold=True)
except:
counter_color = get_color("commands", bold=True, reverse=True)
else:
counter_color = get_color("commands")
# Draw the counter on the bottom border
if width >= len(counter_str) + 4 and height > 2:
entry_win.addstr(height - 1, width - len(counter_str) - 2, counter_str, counter_color)
curses.curs_set(1 if ui_state.input_focused else 0)
entry_win.move(1, min(width - 2, 1 + text_width(prompt) + used))
except curses.error:
pass
entry_win.refresh()
Currently, there is no visual indicator showing how close a user is to the Meshtastic message payload limit (around 220 bytes). This is especially problematic for users typing in non-ASCII languages (like Cyrillic), where a single character takes 2 bytes. Users can unknowingly exceed the payload limit before hitting Enter.
Proposed Solution:
Add a live byte counter (e.g., 0/220b) to the bottom right border of the message entry window (entry_win).
The counter should calculate the actual UTF-8 byte length (len(content.encode('utf-8'))), not just the string character count.
If the limit (> 220 bytes) is exceeded, the counter should change color (e.g., using settings_warning) to visually alert the user.
Here is a working implementation that modifies the draw_message_input function in contact/ui/contact_ui.py:
```
def draw_message_input(draft: str) -> None:
"""Redraw the whole input row and scroll it to keep the draft cursor visible."""
height, width = entry_win.getmaxyx()
prompt = slice_to_width("Message: ", max(0, width - 3))
available = max(1, width - 2 - text_width(prompt))
ui_state.input_cursor = max(0, min(ui_state.input_cursor, len(draft)))
content = ui_state.reply_context + draft
# Calculate bytes in UTF-8 to account for non-ASCII characters
byte_count = len(content.encode('utf-8'))
counter_str = f" {byte_count}/220b "
cursor = len(ui_state.reply_context) + ui_state.input_cursor
start = cursor
used = 0
while start > 0 and used + text_width(content[start - 1]) < available:
start -= 1
used += text_width(content[start])
visible = slice_to_width(content[start:], available)
draw_text_field(entry_win, prompt + visible, get_color("input"))
paint_frame(entry_win, selected=ui_state.input_focused, refresh=False)
try:
hint = " Ctrl+K Help "
if width >= len(hint) + 4:
entry_win.addstr(0, width - len(hint) - 2, hint, get_color("commands"))
# Highlight the counter if it exceeds the limit
if byte_count > 220:
try:
counter_color = get_color("settings_warning", bold=True)
except:
counter_color = get_color("commands", bold=True, reverse=True)
else:
counter_color = get_color("commands")
# Draw the counter on the bottom border
if width >= len(counter_str) + 4 and height > 2:
entry_win.addstr(height - 1, width - len(counter_str) - 2, counter_str, counter_color)
curses.curs_set(1 if ui_state.input_focused else 0)
entry_win.move(1, min(width - 2, 1 + text_width(prompt) + used))
except curses.error:
pass
entry_win.refresh()
```
<!-- github-sync-id:5929563096 -->
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Currently, there is no visual indicator showing how close a user is to the Meshtastic message payload limit (around 220 bytes). This is especially problematic for users typing in non-ASCII languages (like Cyrillic), where a single character takes 2 bytes. Users can unknowingly exceed the payload limit before hitting Enter.
Proposed Solution:
Add a live byte counter (e.g., 0/220b) to the bottom right border of the message entry window (entry_win).
Here is a working implementation that modifies the draw_message_input function in contact/ui/contact_ui.py:
Great idea! Please submit a PR and I will test/review.
Done
#320