@hef2024/llmasaservice-ui 0.22.3 → 0.22.4
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.
- package/dist/index.js +17 -7
- package/dist/index.mjs +17 -7
- package/package.json +1 -1
- package/src/AIChatPanel.tsx +25 -12
package/dist/index.js
CHANGED
|
@@ -3895,6 +3895,8 @@ var AIChatPanel = ({
|
|
|
3895
3895
|
const scrollRAFRef = (0, import_react12.useRef)(null);
|
|
3896
3896
|
const lastScrollTimeRef = (0, import_react12.useRef)(0);
|
|
3897
3897
|
const prevResponseLengthRef = (0, import_react12.useRef)(0);
|
|
3898
|
+
const scrollToEndRef = (0, import_react12.useRef)(scrollToEnd || false);
|
|
3899
|
+
const userHasScrolledRef = (0, import_react12.useRef)(userHasScrolled);
|
|
3898
3900
|
const prevIdleRef = (0, import_react12.useRef)(true);
|
|
3899
3901
|
const hasNotifiedCompletionRef = (0, import_react12.useRef)(true);
|
|
3900
3902
|
const latestHistoryRef = (0, import_react12.useRef)(initialHistory);
|
|
@@ -4574,6 +4576,16 @@ var AIChatPanel = ({
|
|
|
4574
4576
|
}
|
|
4575
4577
|
}, [idle]);
|
|
4576
4578
|
(0, import_react12.useEffect)(() => {
|
|
4579
|
+
scrollToEndRef.current = scrollToEnd || false;
|
|
4580
|
+
}, [scrollToEnd]);
|
|
4581
|
+
(0, import_react12.useEffect)(() => {
|
|
4582
|
+
userHasScrolledRef.current = userHasScrolled;
|
|
4583
|
+
}, [userHasScrolled]);
|
|
4584
|
+
(0, import_react12.useEffect)(() => {
|
|
4585
|
+
if (idle) {
|
|
4586
|
+
console.log("AIChatPanel - Auto-scroll effect: SKIPPED (idle)");
|
|
4587
|
+
return;
|
|
4588
|
+
}
|
|
4577
4589
|
const currentResponseLength = response.length;
|
|
4578
4590
|
const responseGotLonger = currentResponseLength > prevResponseLengthRef.current;
|
|
4579
4591
|
console.log("AIChatPanel - Auto-scroll effect:", {
|
|
@@ -4581,20 +4593,18 @@ var AIChatPanel = ({
|
|
|
4581
4593
|
currentResponseLength,
|
|
4582
4594
|
prevLength: prevResponseLengthRef.current,
|
|
4583
4595
|
responseGotLonger,
|
|
4584
|
-
userHasScrolled,
|
|
4585
|
-
scrollToEnd
|
|
4596
|
+
userHasScrolled: userHasScrolledRef.current,
|
|
4597
|
+
scrollToEnd: scrollToEndRef.current
|
|
4586
4598
|
});
|
|
4587
4599
|
prevResponseLengthRef.current = currentResponseLength;
|
|
4588
|
-
const shouldAutoScroll =
|
|
4589
|
-
if (
|
|
4600
|
+
const shouldAutoScroll = scrollToEndRef.current || !userHasScrolledRef.current;
|
|
4601
|
+
if (shouldAutoScroll && response && responseGotLonger) {
|
|
4590
4602
|
console.log("AIChatPanel - Calling scrollToBottom");
|
|
4591
4603
|
scrollToBottom(false);
|
|
4592
4604
|
}
|
|
4593
|
-
}, [response,
|
|
4605
|
+
}, [response, idle]);
|
|
4594
4606
|
const idleRef = (0, import_react12.useRef)(idle);
|
|
4595
4607
|
idleRef.current = idle;
|
|
4596
|
-
const userHasScrolledRef = (0, import_react12.useRef)(userHasScrolled);
|
|
4597
|
-
userHasScrolledRef.current = userHasScrolled;
|
|
4598
4608
|
(0, import_react12.useEffect)(() => {
|
|
4599
4609
|
const scrollArea = responseAreaRef.current;
|
|
4600
4610
|
if (!scrollArea) return;
|
package/dist/index.mjs
CHANGED
|
@@ -3862,6 +3862,8 @@ var AIChatPanel = ({
|
|
|
3862
3862
|
const scrollRAFRef = useRef5(null);
|
|
3863
3863
|
const lastScrollTimeRef = useRef5(0);
|
|
3864
3864
|
const prevResponseLengthRef = useRef5(0);
|
|
3865
|
+
const scrollToEndRef = useRef5(scrollToEnd || false);
|
|
3866
|
+
const userHasScrolledRef = useRef5(userHasScrolled);
|
|
3865
3867
|
const prevIdleRef = useRef5(true);
|
|
3866
3868
|
const hasNotifiedCompletionRef = useRef5(true);
|
|
3867
3869
|
const latestHistoryRef = useRef5(initialHistory);
|
|
@@ -4541,6 +4543,16 @@ var AIChatPanel = ({
|
|
|
4541
4543
|
}
|
|
4542
4544
|
}, [idle]);
|
|
4543
4545
|
useEffect7(() => {
|
|
4546
|
+
scrollToEndRef.current = scrollToEnd || false;
|
|
4547
|
+
}, [scrollToEnd]);
|
|
4548
|
+
useEffect7(() => {
|
|
4549
|
+
userHasScrolledRef.current = userHasScrolled;
|
|
4550
|
+
}, [userHasScrolled]);
|
|
4551
|
+
useEffect7(() => {
|
|
4552
|
+
if (idle) {
|
|
4553
|
+
console.log("AIChatPanel - Auto-scroll effect: SKIPPED (idle)");
|
|
4554
|
+
return;
|
|
4555
|
+
}
|
|
4544
4556
|
const currentResponseLength = response.length;
|
|
4545
4557
|
const responseGotLonger = currentResponseLength > prevResponseLengthRef.current;
|
|
4546
4558
|
console.log("AIChatPanel - Auto-scroll effect:", {
|
|
@@ -4548,20 +4560,18 @@ var AIChatPanel = ({
|
|
|
4548
4560
|
currentResponseLength,
|
|
4549
4561
|
prevLength: prevResponseLengthRef.current,
|
|
4550
4562
|
responseGotLonger,
|
|
4551
|
-
userHasScrolled,
|
|
4552
|
-
scrollToEnd
|
|
4563
|
+
userHasScrolled: userHasScrolledRef.current,
|
|
4564
|
+
scrollToEnd: scrollToEndRef.current
|
|
4553
4565
|
});
|
|
4554
4566
|
prevResponseLengthRef.current = currentResponseLength;
|
|
4555
|
-
const shouldAutoScroll =
|
|
4556
|
-
if (
|
|
4567
|
+
const shouldAutoScroll = scrollToEndRef.current || !userHasScrolledRef.current;
|
|
4568
|
+
if (shouldAutoScroll && response && responseGotLonger) {
|
|
4557
4569
|
console.log("AIChatPanel - Calling scrollToBottom");
|
|
4558
4570
|
scrollToBottom(false);
|
|
4559
4571
|
}
|
|
4560
|
-
}, [response,
|
|
4572
|
+
}, [response, idle]);
|
|
4561
4573
|
const idleRef = useRef5(idle);
|
|
4562
4574
|
idleRef.current = idle;
|
|
4563
|
-
const userHasScrolledRef = useRef5(userHasScrolled);
|
|
4564
|
-
userHasScrolledRef.current = userHasScrolled;
|
|
4565
4575
|
useEffect7(() => {
|
|
4566
4576
|
const scrollArea = responseAreaRef.current;
|
|
4567
4577
|
if (!scrollArea) return;
|
package/package.json
CHANGED
package/src/AIChatPanel.tsx
CHANGED
|
@@ -847,6 +847,8 @@ const AIChatPanel: React.FC<AIChatPanelProps> = ({
|
|
|
847
847
|
const scrollRAFRef = useRef<number | null>(null);
|
|
848
848
|
const lastScrollTimeRef = useRef<number>(0);
|
|
849
849
|
const prevResponseLengthRef = useRef<number>(0);
|
|
850
|
+
const scrollToEndRef = useRef<boolean>(scrollToEnd || false);
|
|
851
|
+
const userHasScrolledRef = useRef<boolean>(userHasScrolled);
|
|
850
852
|
|
|
851
853
|
// === NEW: Clean history management refs ===
|
|
852
854
|
// Track previous idle state to detect transitions (false→true = completion)
|
|
@@ -1821,10 +1823,26 @@ const AIChatPanel: React.FC<AIChatPanelProps> = ({
|
|
|
1821
1823
|
}
|
|
1822
1824
|
}, [idle]); // ONLY depends on idle - no history, no callbacks in deps
|
|
1823
1825
|
|
|
1826
|
+
// Keep refs in sync
|
|
1827
|
+
useEffect(() => {
|
|
1828
|
+
scrollToEndRef.current = scrollToEnd || false;
|
|
1829
|
+
}, [scrollToEnd]);
|
|
1830
|
+
|
|
1831
|
+
useEffect(() => {
|
|
1832
|
+
userHasScrolledRef.current = userHasScrolled;
|
|
1833
|
+
}, [userHasScrolled]);
|
|
1834
|
+
|
|
1824
1835
|
// Auto-scroll to bottom - only while streaming and user hasn't manually scrolled
|
|
1836
|
+
// CRITICAL: Only depends on response and idle to avoid re-running on layout changes
|
|
1825
1837
|
useEffect(() => {
|
|
1838
|
+
// CRITICAL: Skip entirely if idle - no scrolling when not streaming
|
|
1839
|
+
if (idle) {
|
|
1840
|
+
console.log('AIChatPanel - Auto-scroll effect: SKIPPED (idle)');
|
|
1841
|
+
return;
|
|
1842
|
+
}
|
|
1843
|
+
|
|
1826
1844
|
// Only auto-scroll if:
|
|
1827
|
-
// 1. We're actively streaming (!idle)
|
|
1845
|
+
// 1. We're actively streaming (!idle) - checked above
|
|
1828
1846
|
// 2. User hasn't manually scrolled up during this response (or scrollToEnd prop is true)
|
|
1829
1847
|
// 3. We have content to show (response exists)
|
|
1830
1848
|
// 4. The response actually got longer (not just a re-render from layout change)
|
|
@@ -1836,30 +1854,25 @@ const AIChatPanel: React.FC<AIChatPanelProps> = ({
|
|
|
1836
1854
|
currentResponseLength,
|
|
1837
1855
|
prevLength: prevResponseLengthRef.current,
|
|
1838
1856
|
responseGotLonger,
|
|
1839
|
-
userHasScrolled,
|
|
1840
|
-
scrollToEnd,
|
|
1857
|
+
userHasScrolled: userHasScrolledRef.current,
|
|
1858
|
+
scrollToEnd: scrollToEndRef.current,
|
|
1841
1859
|
});
|
|
1842
1860
|
|
|
1843
1861
|
prevResponseLengthRef.current = currentResponseLength;
|
|
1844
1862
|
|
|
1845
|
-
//
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
if (!idle && shouldAutoScroll && response && responseGotLonger) {
|
|
1863
|
+
// Only scroll if response actually grew - use refs to avoid unnecessary effect runs
|
|
1864
|
+
const shouldAutoScroll = scrollToEndRef.current || !userHasScrolledRef.current;
|
|
1865
|
+
if (shouldAutoScroll && response && responseGotLonger) {
|
|
1849
1866
|
console.log('AIChatPanel - Calling scrollToBottom');
|
|
1850
1867
|
// Use non-forced scroll - will only scroll if near bottom
|
|
1851
1868
|
scrollToBottom(false);
|
|
1852
1869
|
}
|
|
1853
|
-
}, [response,
|
|
1870
|
+
}, [response, idle]); // ONLY response and idle - no other dependencies!
|
|
1854
1871
|
|
|
1855
1872
|
// Ref to track idle state for scroll handler (avoids stale closure)
|
|
1856
1873
|
const idleRef = useRef(idle);
|
|
1857
1874
|
idleRef.current = idle;
|
|
1858
1875
|
|
|
1859
|
-
// Ref to track userHasScrolled to avoid redundant state updates
|
|
1860
|
-
const userHasScrolledRef = useRef(userHasScrolled);
|
|
1861
|
-
userHasScrolledRef.current = userHasScrolled;
|
|
1862
|
-
|
|
1863
1876
|
// Detect user scroll to disable auto-scroll
|
|
1864
1877
|
useEffect(() => {
|
|
1865
1878
|
const scrollArea = responseAreaRef.current;
|