feat: open a conversation on its first unread message, under a "New" line

Both UIs: a channel, DM or room with unread messages opens on the oldest of
them (MessageHistory::firstUnreadChannel / firstUnreadDm, own messages not
counted), a "New" line above it, so it reads down to the newest. Nothing
unread: the newest, as before.

L1: the first unread is selected and scrolled up top with the line in view;
the channel's unread count now counts down as you read towards the newest.
L2: the page holding it, scrolled to the line; an incoming message scrolls
down only when the list is already at its end. Sim hooks: sim_unread (L1),
sim_open("unread") (L2).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Jakub
2026-10-08 22:20:04 +02:00
co-authored by Claude Opus 5.5
parent 5e87686183
commit aaf35351d7
8 changed files with 271 additions and 63 deletions
@@ -2210,6 +2210,17 @@ void UITask::simMessage(const char* text) {
onMessageArrived(ev);
}
// Sim tests: read and new messages (UiCore::simUnreadDemo), then channel 0
// (which 0) or the first chat contact (1) opened as from the list.
void UITask::simUnread(int which) {
if (which < 0) { _core->simUnreadDemo(); return; }
if (which == 0) { openChannelHistory(0); return; }
for (int i = 0; i < the_mesh.getNumContacts(); i++) {
ContactInfo c;
if (the_mesh.getContactByIdx(MAX_ANON_CONTACTS + i, c) && c.type == ADV_TYPE_CHAT) { openContactDM(c); return; }
}
}
void UITask::simCompose(const char* text) {
gotoMessagesScreen();
((MessagesScreen*)messages_screen)->simCompose(text);
@@ -2716,6 +2727,11 @@ extern "C" EMSCRIPTEN_KEEPALIVE void sim_compose(const char* text) {
if (g_sim_ui_task_for_js) g_sim_ui_task_for_js->simCompose(text);
}
// Sim tests: -1 files read and new messages, 0 opens channel 0, 1 the first DM.
extern "C" EMSCRIPTEN_KEEPALIVE void sim_unread(int which) {
if (g_sim_ui_task_for_js) g_sim_ui_task_for_js->simUnread(which);
}
// Sim tests: a channel message arrives, alerted in Settings > Message alert's
// style (0 Normal, 1 Compact, 2 Off).
extern "C" EMSCRIPTEN_KEEPALIVE void sim_message(const char* text, int style) {