mirror of
https://github.com/torlando-tech/pyxis.git
synced 2026-10-15 02:30:10 +00:00
fix(chat): stream older messages on scroll-up too (no synchronous batch)
on_scroll() loaded a full MESSAGES_PER_PAGE batch synchronously under the LVGL lock, which froze scrolling. Make it trigger the same incremental tick_background_fill() streaming as the open path instead. _bg_fill_active is now std::atomic since on_scroll() (LVGL task) sets it while tick_background_fill() (main loop) reads it; the target is written before the flag for visibility. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UWZuYkHBRqNb6BZHV8sTG5
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
f8bbfba3e3
commit
13b3d7d73a
@@ -260,11 +260,12 @@ void ChatScreen::refresh() {
|
||||
create_message_bubble(item);
|
||||
}
|
||||
|
||||
// Queue the rest of the first page to stream in on the main loop.
|
||||
// Queue the rest of the first page to stream in on the main loop. Set the
|
||||
// target before activating so tick sees a consistent target.
|
||||
_bg_fill_target = (_all_message_hashes.size() > MESSAGES_PER_PAGE)
|
||||
? _all_message_hashes.size() - MESSAGES_PER_PAGE
|
||||
: 0;
|
||||
_bg_fill_active = (_display_start_idx > _bg_fill_target);
|
||||
_bg_fill_active.store(_display_start_idx > _bg_fill_target);
|
||||
|
||||
// Scroll to bottom
|
||||
lv_obj_scroll_to_y(_message_list, LV_COORD_MAX, LV_ANIM_OFF);
|
||||
@@ -274,17 +275,17 @@ void ChatScreen::refresh() {
|
||||
// the main loop. Each tick prepends a small batch under a brief LVGL lock, so a
|
||||
// large conversation fills in without freezing the UI or holding the lock long.
|
||||
void ChatScreen::tick_background_fill() {
|
||||
if (!_bg_fill_active) {
|
||||
if (!_bg_fill_active.load()) {
|
||||
return;
|
||||
}
|
||||
if (_display_start_idx <= _bg_fill_target) {
|
||||
_bg_fill_active = false;
|
||||
_bg_fill_active.store(false);
|
||||
return;
|
||||
}
|
||||
size_t remaining = _display_start_idx - _bg_fill_target;
|
||||
load_more_messages(remaining < BG_FILL_BATCH ? remaining : BG_FILL_BATCH);
|
||||
if (_display_start_idx <= _bg_fill_target) {
|
||||
_bg_fill_active = false;
|
||||
_bg_fill_active.store(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -356,8 +357,14 @@ void ChatScreen::on_scroll(lv_event_t* event) {
|
||||
// Check if scrolled to top
|
||||
lv_coord_t scroll_y = lv_obj_get_scroll_y(screen->_message_list);
|
||||
|
||||
if (scroll_y <= 5) { // Near top (with small threshold)
|
||||
screen->load_more_messages();
|
||||
if (scroll_y <= 5 && screen->_display_start_idx > 0 && !screen->_bg_fill_active.load()) {
|
||||
// Near the top: stream the next page in incrementally on the main loop
|
||||
// (tick_background_fill) rather than loading a full batch synchronously
|
||||
// under the LVGL lock here, which froze scrolling. Target before active.
|
||||
screen->_bg_fill_target = (screen->_display_start_idx > MESSAGES_PER_PAGE)
|
||||
? screen->_display_start_idx - MESSAGES_PER_PAGE
|
||||
: 0;
|
||||
screen->_bg_fill_active.store(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <deque>
|
||||
#include <map>
|
||||
#include <functional>
|
||||
#include <atomic>
|
||||
#include <microReticulum/Bytes.h>
|
||||
#include "LXMF/LXMessage.h"
|
||||
#include "LXMF/MessageStore.h"
|
||||
@@ -192,7 +193,11 @@ private:
|
||||
static constexpr size_t BG_FILL_BATCH = 2; // older messages streamed per tick
|
||||
static constexpr size_t MAX_DISPLAYED_MESSAGES = 50; // Cap to prevent memory exhaustion
|
||||
bool _loading_more; // Prevent concurrent loads
|
||||
bool _bg_fill_active = false; // streaming the rest of the page in
|
||||
// Streaming state. _bg_fill_active is atomic because on_scroll() (LVGL task)
|
||||
// and refresh() may set it while tick_background_fill() (main loop) reads it;
|
||||
// writers always set _bg_fill_target BEFORE _bg_fill_active so the target is
|
||||
// visible once active is observed true.
|
||||
std::atomic<bool> _bg_fill_active{false}; // streaming the rest of the page in
|
||||
size_t _bg_fill_target = 0; // _display_start_idx to fill down to
|
||||
|
||||
// Load more messages (infinite scroll + background fill)
|
||||
|
||||
Reference in New Issue
Block a user