Skip to content

Commit d62b979

Browse files
committed
feat(ai-chat-log): story for user cancel scroll to end
1 parent 869544f commit d62b979

File tree

2 files changed

+25
-8
lines changed

2 files changed

+25
-8
lines changed

packages/paste-core/components/ai-chat-log/stories/scrollableSidePanel.stories.tsx

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,9 @@ export const SidePanelScroll: StoryFn = () => {
195195
);
196196
const [message, setMessage] = React.useState("");
197197
const [mounted, setMounted] = React.useState(false);
198-
const loggerRef = React.useRef(null);
199-
const scrollerRef = React.useRef(null);
198+
const [userInterctedScroll, setUserInteractedScroll] = React.useState(false);
199+
const loggerRef = React.useRef<HTMLDivElement>(null);
200+
const scrollerRef = React.useRef<HTMLDivElement>(null);
200201

201202
React.useEffect(() => {
202203
setMounted(true);
@@ -222,20 +223,27 @@ export const SidePanelScroll: StoryFn = () => {
222223

223224
const onAnimationEnd = (): void => {
224225
setIsAnimating(false);
225-
scrollToChatEnd();
226+
setUserInteractedScroll(false);
226227
};
227228

228229
const onAnimationStart = (): void => {
230+
setUserInteractedScroll(false);
229231
setIsAnimating(true);
230232
};
231233

234+
const userScrolled = (): void => setUserInteractedScroll(true);
235+
232236
React.useEffect(() => {
233-
const interval = setInterval(() => isAnimating && scrollToChatEnd(), 30);
237+
scrollerRef.current?.addEventListener("wheel", userScrolled);
238+
scrollerRef.current?.addEventListener("touchmove", userScrolled);
234239

240+
const interval = setInterval(() => isAnimating && !userInterctedScroll && scrollToChatEnd(), 5);
235241
return () => {
236242
if (interval) clearInterval(interval);
243+
scrollerRef.current?.removeEventListener("wheel", userScrolled);
244+
scrollerRef.current?.removeEventListener("touchmove", userScrolled);
237245
};
238-
}, [isAnimating]);
246+
}, [isAnimating, userInterctedScroll]);
239247

240248
// eslint-disable-next-line storybook/prefer-pascal-case
241249
const createNewMessage = (newMessage: any, forceBot?: boolean): Omit<AIChat, "id"> => {

packages/paste-website/src/component-examples/AIChatLogExamples.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -770,6 +770,7 @@ const exampleAIResponseText =
770770
771771
const AnimatedBotScrollable = () => {
772772
const [isAnimating, setIsAnimating] = React.useState(false);
773+
const [userInterctedScroll, setUserInteractedScroll] = React.useState(false);
773774
const loggerRef = React.useRef(null);
774775
const scrollerRef = React.useRef(null);
775776
@@ -789,22 +790,30 @@ const AnimatedBotScrollable = () => {
789790
scrollPosition?.scrollTo({ top: scrollHeight.scrollHeight, behavior: "smooth" });
790791
};
791792
793+
const userScrolled = () => setUserInteractedScroll(true);
794+
792795
const onAnimationEnd = () => {
793796
setIsAnimating(false);
794-
scrollToChatEnd();
797+
setUserInteractedScroll(false);
795798
};
796799
797800
const onAnimationStart = () => {
801+
setUserInteractedScroll(false);
798802
setIsAnimating(true);
799803
};
800804
801805
React.useEffect(() => {
802-
const interval = setInterval(() => isAnimating && scrollToChatEnd(), 30);
806+
scrollerRef.current?.addEventListener("wheel", userScrolled);
807+
scrollerRef.current?.addEventListener("touchmove", userScrolled);
808+
809+
const interval = setInterval(() => isAnimating && !userInterctedScroll && scrollToChatEnd(), 5);
803810
804811
return () => {
805812
if (interval) clearInterval(interval);
813+
scrollerRef.current?.removeEventListener("wheel", userScrolled);
814+
scrollerRef.current?.removeEventListener("touchmove", userScrolled);
806815
};
807-
}, [isAnimating]);
816+
}, [isAnimating, userInterctedScroll, scrollerRef]);
808817
809818
const pushLargeBotMessage = () => {
810819
push({

0 commit comments

Comments
 (0)