Skip to content

Commit 4cbec02

Browse files
authored
Merge pull request #88 from aws-samples/feature/report
feat: scroll bug
2 parents f32fa93 + e1788ee commit 4cbec02

File tree

4 files changed

+56
-30
lines changed

4 files changed

+56
-30
lines changed

report-front-end/src/components/chatbot-panel/chat-input-panel.tsx

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Button, Container, Icon, SpaceBetween, } from "@cloudscape-design/components";
2-
import { Dispatch, SetStateAction, useState, } from "react";
2+
import { Dispatch, SetStateAction, useEffect, useLayoutEffect, useState, } from "react";
33
import TextareaAutosize from "react-textarea-autosize";
44
import { ChatBotHistoryItem, ChatInputState, } from "./types";
55
import CustomQuestions from "./custom-questions";
@@ -15,6 +15,12 @@ export interface ChatInputPanelProps {
1515
setMessageHistory: Dispatch<SetStateAction<ChatBotHistoryItem[]>>;
1616
}
1717

18+
export abstract class ChatScrollState {
19+
static userHasScrolled = false;
20+
static skipNextScrollEvent = false;
21+
static skipNextHistoryUpdate = false;
22+
}
23+
1824
export default function ChatInputPanel(props: ChatInputPanelProps) {
1925
const [state, setTextValue] = useState<ChatInputState>({
2026
value: ""
@@ -39,6 +45,45 @@ export default function ChatInputPanel(props: ChatInputPanelProps) {
3945
props.setMessageHistory([]);
4046
};
4147

48+
useEffect(() => {
49+
const onWindowScroll = () => {
50+
if (ChatScrollState.skipNextScrollEvent) {
51+
ChatScrollState.skipNextScrollEvent = false;
52+
return;
53+
}
54+
55+
const isScrollToTheEnd =
56+
Math.abs(
57+
window.innerHeight +
58+
window.scrollY -
59+
document.documentElement.scrollHeight
60+
) <= 10;
61+
62+
ChatScrollState.userHasScrolled = !isScrollToTheEnd;
63+
};
64+
65+
window.addEventListener("scroll", onWindowScroll);
66+
67+
return () => {
68+
window.removeEventListener("scroll", onWindowScroll);
69+
};
70+
}, []);
71+
72+
useLayoutEffect(() => {
73+
if (ChatScrollState.skipNextHistoryUpdate) {
74+
ChatScrollState.skipNextHistoryUpdate = false;
75+
return;
76+
}
77+
78+
if (!ChatScrollState.userHasScrolled && props.messageHistory.length > 0) {
79+
ChatScrollState.skipNextScrollEvent = true;
80+
window.scrollTo({
81+
top: document.documentElement.scrollHeight + 1000,
82+
behavior: "smooth",
83+
});
84+
}
85+
}, [props.messageHistory]);
86+
4287
return (
4388
<Container>
4489
<SpaceBetween size={'s'}>

report-front-end/src/components/chatbot-panel/chat-message.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ import {
1212
import {
1313
ChatBotAnswerItem,
1414
ChatBotHistoryItem,
15-
ChatBotMessageType, FeedBackItem, FeedBackType,
15+
ChatBotMessageType,
16+
FeedBackItem,
17+
FeedBackType,
1618
SQLSearchResult
1719
} from "./types";
1820
import Button from "@cloudscape-design/components/button";
@@ -187,7 +189,7 @@ function SQLResultPanel(props: SQLResultProps) {
187189
variant="footer"
188190
headerText="SQL">
189191
<SpaceBetween size={'s'}>
190-
<div className={styles.sql}>
192+
<div className={styles.sql_container}>
191193
<SyntaxHighlighter language="javascript">
192194
{props.result.sql}
193195
</SyntaxHighlighter>

report-front-end/src/components/chatbot-panel/chat.module.scss

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
}
2727
}
2828

29-
.sql {
29+
.sql_container {
3030
display: grid;
3131
grid-template-columns: 1fr 1fr;
3232
align-items: stretch;
@@ -65,8 +65,8 @@
6565
transparent 0%,
6666
awsui.$color-background-container-content 20%
6767
);
68-
margin-left: -8px;
69-
margin-right: -8px;
68+
//margin-left: -8px;
69+
//margin-right: -8px;
7070
container-type: inline-size;
7171
container-name: input_container;
7272
}

report-front-end/src/components/chatbot-panel/chat.tsx

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -13,34 +13,12 @@ export default function Chat(
1313
const [messageHistory, setMessageHistory] = useState<ChatBotHistoryItem[]>([]);
1414
const [loading, setLoading] = useState<boolean>(false);
1515

16-
const scrollTo = (element : any) => {
17-
if (element && !isInViewPort(element)) {
18-
element.scrollIntoView({behavior: "smooth"});
19-
}
20-
};
21-
22-
function isInViewPort(element: any) {
23-
const viewWidth = window.innerWidth || document.documentElement.clientWidth;
24-
const viewHeight = window.innerHeight || document.documentElement.clientHeight;
25-
const {
26-
top,
27-
right,
28-
bottom,
29-
left,
30-
} = element.getBoundingClientRect();
31-
32-
return (
33-
top >= 0 && left >= 0 && right <= viewWidth && bottom <= (viewHeight - 500)
34-
);
35-
}
36-
3716
return (
3817
<div className={styles.chat_container}>
3918
<SpaceBetween size={'xxl'}>
4019
{messageHistory.map((message, idx) => {
41-
const isLast = idx === messageHistory.length - 2;
4220
return (
43-
<div key={idx} ref={!loading && isLast ? scrollTo : undefined}>
21+
<div key={idx}>
4422
<ChatMessage
4523
key={idx}
4624
message={message}
@@ -52,7 +30,8 @@ export default function Chat(
5230
}
5331
)}
5432
{loading && (
55-
<div ref={loading ? scrollTo : undefined}>
33+
/*<div ref={loading ? scrollTo : undefined}>*/
34+
<div>
5635
<Box float="left">
5736
<Spinner/>
5837
</Box>

0 commit comments

Comments
 (0)