feat(settings): add streaming auto-follow toggle

New Streaming section on the Chat settings page with a checkbox that
controls whether the viewport follows new content while a response
streams. Default stays on. With it off, the anchored user message still
parks at the top on send, but no glide or end-follow correction runs and
the list's maintain-scroll-at-end stays disabled; the scroll-to-bottom
pill and session open keep scrolling explicitly.

Persisted through desktop settings like the other chat toggles (auto-save
diff, authoritative apply, sanitize), registered in settings search, and
localized in every locale.
This commit is contained in:
Bohdan Triapitsyn
2026-08-25 14:53:43 +03:00
parent 87c1ae809d
commit dac31ee026
19 changed files with 109 additions and 1 deletions
@@ -1021,6 +1021,10 @@ const TimelineList = React.memo(({
rowContext,
}: TimelineListProps) => {
const listRef = React.useRef<LegendListRef | null>(null);
// With streaming auto-follow off, content growth must never move the
// viewport; explicit commands (the scroll-to-bottom pill, session open)
// still scroll through the imperative handle.
const streamingAutoFollowEnabled = useUIStore((state) => state.streamingAutoFollowEnabled);
const isAtEndRef = React.useRef(true);
const setListRef = React.useCallback((list: LegendListRef | null) => {
@@ -1067,7 +1071,7 @@ const TimelineList = React.memo(({
contentInsetEndAdjustment={composerOverlayHeight}
// While a turn is anchored, the reserved end space — not the
// live edge — defines where the viewport rests.
maintainScrollAtEnd={anchoredEndSpace
maintainScrollAtEnd={anchoredEndSpace || !streamingAutoFollowEnabled
? false
: { animated: false, on: { dataChange: true, itemLayout: true, layout: true } }}
// Prepending older history must not move what the user is