MCPcopy
hub / github.com/GitbookIO/gitbook / AIChatBody

Function AIChatBody

packages/gitbook/src/components/AIChat/AIChat.tsx:157–284  ·  view source on GitHub ↗
(props: {
    chatController: AIChatController;
    chat: AIChatState;
    trademark: boolean;
    welcomeMessage?: string;
    suggestions?: string[];
})

Source from the content-addressed store, hash-verified

155 * Body of the AI chat window.
156 */
157export function AIChatBody(props: {
158 chatController: AIChatController;
159 chat: AIChatState;
160 trademark: boolean;
161 welcomeMessage?: string;
162 suggestions?: string[];
163}) {
164 const { chatController, chat, trademark, suggestions } = props;
165
166 const [input, setInput] = React.useState('');
167
168 const scrollContainerRef = React.useRef<HTMLDivElement>(null);
169 // Ref for the last user message element
170 const lastUserMessageRef = React.useRef<HTMLDivElement>(null);
171 const inputRef = React.useRef<HTMLDivElement>(null);
172
173 const [inputHeight, setInputHeight] = React.useState(0);
174 const language = useLanguage();
175 const now = useNow(60 * 60 * 1000); // Refresh every hour for greeting
176
177 const isEmpty = !chat.messages.length;
178
179 const timeGreeting = React.useMemo(() => {
180 const hour = new Date(now).getHours();
181 if (hour < 6) return tString(language, 'ai_chat_assistant_greeting_night');
182 if (hour < 12) return tString(language, 'ai_chat_assistant_greeting_morning');
183 if (hour < 18) return tString(language, 'ai_chat_assistant_greeting_afternoon');
184 return tString(language, 'ai_chat_assistant_greeting_evening');
185 }, [now, language]);
186
187 // Auto-scroll to the latest user message when messages change
188 React.useEffect(() => {
189 if (chat.messages.length > 0 && lastUserMessageRef.current) {
190 lastUserMessageRef.current.scrollIntoView({
191 behavior: 'smooth',
192 block: 'start',
193 });
194 }
195 }, [chat.messages.length]);
196
197 React.useEffect(() => {
198 const timeout = setTimeout(() => {
199 if (lastUserMessageRef.current) {
200 lastUserMessageRef.current.scrollIntoView({
201 behavior: 'smooth',
202 block: 'start',
203 });
204 }
205 }, 100);
206
207 // We want the chat messages to scroll underneath the input, but they should scroll past the input when scrolling all the way down.
208 // The best way to do this is to observe the input height and adjust the padding bottom of the scroll container accordingly.
209 const observer = new ResizeObserver((entries) => {
210 entries.forEach((entry) => {
211 setInputHeight(entry.contentRect.height + 32);
212 });
213 });
214 if (inputRef.current) {

Callers

nothing calls this directly

Calls 4

useLanguageFunction · 0.90
useNowFunction · 0.90
tStringFunction · 0.50
tFunction · 0.50

Tested by

no test coverage detected