perf(chat): lay out and draw only the visible chat thread rows
Every frame the open chat thread handled all N messages: grouping flags from two day keys each, a measuring layout of every body, then the draw, which laid every body out a second time and ran the bubble, hover and popup code, however few rows were on screen. The thread now keeps a layout cache: grouping flags, each body's wrapped size (keyed by message, so only new or re-wrapped bodies are measured) and each row's height, with prefix offsets. A frame binary- searches the visible range and submits those rows plus any failed send (Retry stays reachable with Tab), the row being drag-selected and the row whose context menu is open; one spacer stands in for each skipped run, and scrolling to the newest message works as before. - Rows are rebuilt when the chat store changes or when the wrap width, fonts, font size, DPI scale, rasterizer density or compact mode change. Fonts are keyed by FontId, so a font reload at the same size (the colour-emoji toggle) re-measures. A rebuild is O(N), about 0.5-1 ms at 3000 messages. - Grouping flags are recomputed on a data change and once a minute, together with util::refreshTimezone(), so a system timezone change reaches chat timestamps within a minute. Rows above the visible range are now one spacer of their summed heights, so the visible rows no longer move by a pixel each time a row above them crosses the top of the app window. Debug builds log once if a cached wrap width or row height ever disagrees with the live layout. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -664,6 +664,7 @@ set(APP_HEADERS
|
||||
src/ui/windows/balance_address_list.h
|
||||
src/ui/windows/balance_recent_tx.h
|
||||
src/ui/windows/balance_lerp.h
|
||||
src/ui/windows/chat_thread_layout.h
|
||||
src/ui/windows/balance_tab_helpers.h
|
||||
src/ui/windows/send_tab.h
|
||||
src/ui/windows/receive_tab.h
|
||||
|
||||
Reference in New Issue
Block a user