@linxin666/dsh-remote-web-ui 0.1.6 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -126,7 +126,6 @@ export function ChatView({ session, mux, onBack }: ChatViewProps) {
126
126
  // plugin (augmentation), so the base SDK map is indexed loosely.
127
127
  const projections = page.projections?.values as Record<string, unknown> | undefined
128
128
  setPermissions(parsePermissionSelect(projections?.['permissions']))
129
- scrollToBottom()
130
129
  },
131
130
  (reason: unknown) => {
132
131
  if (cancelled) return
@@ -163,17 +162,32 @@ export function ChatView({ session, mux, onBack }: ChatViewProps) {
163
162
  })
164
163
  }, [mux, session.sessionId])
165
164
 
166
- // Keep the newest content visible while streaming.
167
- useEffect(() => {
168
- if (messages.some(message => message.pending === true)) scrollToBottom()
169
- }, [messages])
170
-
171
165
  const scrollToBottom = useCallback(() => {
172
166
  const el = scrollRef.current
173
167
  if (el === undefined) return
174
168
  el.scrollTop = el.scrollHeight
175
169
  }, [])
176
170
 
171
+ // Track the last message's fold key so scrolling only fires when the
172
+ // newest message actually changes (seq bump and/or pending flip). Runs
173
+ // after React has committed the render, so scrollHeight reflects the
174
+ // freshly appended content.
175
+ const lastMessageKeyRef = useRef<string | undefined>(undefined)
176
+
177
+ // Keep the newest content visible. This covers the initial tail page (the
178
+ // effect runs after commit, fixing the stale scrollHeight from the old
179
+ // open-time scrollToBottom), live streaming chunks on the pending message,
180
+ // and finalized/appended messages. Prepending older pages via loadOlder
181
+ // leaves the last message untouched, so it never disturbs the scroll position.
182
+ useEffect(() => {
183
+ const last = messages[messages.length - 1]
184
+ if (last === undefined) return
185
+ const key = last.seq + ':' + (last.pending === true ? 'p' : 'f')
186
+ if (key === lastMessageKeyRef.current) return
187
+ lastMessageKeyRef.current = key
188
+ scrollToBottom()
189
+ }, [messages, scrollToBottom])
190
+
177
191
  /** Load one older page and prepend it. The fold is directional (incremental
178
192
  * tails only), so the older page folds standalone and concatenates ahead —
179
193
  * host page boundaries never cut a message, so the seam is exact. */