diff --git a/src/components/domains/chat/ChatMessagesWrapper/ChatMessagesWrapper.module.scss b/src/components/domains/chat/ChatMessagesWrapper/ChatMessagesWrapper.module.scss index 17d0054..186ee76 100644 --- a/src/components/domains/chat/ChatMessagesWrapper/ChatMessagesWrapper.module.scss +++ b/src/components/domains/chat/ChatMessagesWrapper/ChatMessagesWrapper.module.scss @@ -10,3 +10,9 @@ justify-content: center; padding-top: 16px; } + +.suggestions.suggestions { + position: sticky; + bottom: 0; + padding: 0 16px 36px; +} diff --git a/src/components/domains/chat/ChatMessagesWrapper/ChatMessagesWrapper.tsx b/src/components/domains/chat/ChatMessagesWrapper/ChatMessagesWrapper.tsx index 46cfbcb..819db9b 100644 --- a/src/components/domains/chat/ChatMessagesWrapper/ChatMessagesWrapper.tsx +++ b/src/components/domains/chat/ChatMessagesWrapper/ChatMessagesWrapper.tsx @@ -7,7 +7,7 @@ import { useChat } from "@/providers/chat-provider"; import { useChatStore } from "@/providers/chat-store-provider"; import { formatTime } from "@/shared/utils/date"; -import { ChatMessages } from ".."; +import { ChatMessages, Suggestions } from ".."; import styles from "./ChatMessagesWrapper.module.scss"; @@ -20,9 +20,10 @@ export default function ChatMessagesWrapper() { messagesWrapperRef, loadOlder, scrollToBottom, + send, } = useChat(); - const { suggestionsHeight, _hasHydrated } = useChatStore(state => state); + const { _hasHydrated } = useChatStore(state => state); const isInitialScrollDone = useRef(false); @@ -48,47 +49,19 @@ export default function ChatMessagesWrapper() { }, [socketMessages]); useEffect(() => { - if ( - socketMessages.length > 0 && - !isInitialScrollDone.current && - _hasHydrated - ) { - scrollToBottom(); + if (socketMessages.length > 0 && _hasHydrated) { const timeout = setTimeout(() => { - isInitialScrollDone.current = true; - }, 1000); + scrollToBottom(); + }); return () => clearTimeout(timeout); } }, [socketMessages.length, scrollToBottom, _hasHydrated]); - // useEffect(() => { - // if (suggestionsHeight) { - // const timeout = setTimeout(() => { - // scrollToBottom(); - // console.log("scrollToBottom 2"); - // }, 0); - // return () => clearTimeout(timeout); - // } - // }, [suggestionsHeight, scrollToBottom]); - - useEffect(() => { - if (messagesWrapperRef.current?.style.paddingBottom) { - scrollToBottom(); - } - }, [ - scrollToBottom, - messagesWrapperRef.current?.style.paddingBottom, - messagesWrapperRef, - ]); - return (
{isLoadingOlder && hasMoreOlderMessages && (
@@ -99,6 +72,12 @@ export default function ChatMessagesWrapper() { messages={mappedMessages} isLoadingAdvisorMessage={isLoadingAdvisorMessage} /> + { + send(suggestion); + }} + />
); } diff --git a/src/components/domains/chat/MessageInputWrapper/MessageInputWrapper.tsx b/src/components/domains/chat/MessageInputWrapper/MessageInputWrapper.tsx index ac87bee..20e32a1 100644 --- a/src/components/domains/chat/MessageInputWrapper/MessageInputWrapper.tsx +++ b/src/components/domains/chat/MessageInputWrapper/MessageInputWrapper.tsx @@ -2,7 +2,7 @@ import { useChat } from "@/providers/chat-provider"; -import { MessageInput, Suggestions } from ".."; +import { MessageInput } from ".."; import styles from "./MessageInputWrapper.module.scss"; @@ -11,11 +11,6 @@ export default function MessageInputWrapper() { return (
- { - send(suggestion); - }} - />
diff --git a/src/components/domains/chat/Suggestions/Suggestions.module.scss b/src/components/domains/chat/Suggestions/Suggestions.module.scss index 1e862b1..66391ec 100644 --- a/src/components/domains/chat/Suggestions/Suggestions.module.scss +++ b/src/components/domains/chat/Suggestions/Suggestions.module.scss @@ -1,6 +1,4 @@ .container { - position: absolute; - bottom: 100%; display: flex; flex-wrap: wrap; gap: 12px; diff --git a/src/components/domains/chat/Suggestions/Suggestions.tsx b/src/components/domains/chat/Suggestions/Suggestions.tsx index 1ca884e..b9cfc84 100644 --- a/src/components/domains/chat/Suggestions/Suggestions.tsx +++ b/src/components/domains/chat/Suggestions/Suggestions.tsx @@ -1,6 +1,7 @@ "use client"; -import { useEffect, useRef } from "react"; +import { useRef } from "react"; +import clsx from "clsx"; import { Typography } from "@/components/ui"; import { useChatStore } from "@/providers/chat-store-provider"; @@ -8,21 +9,21 @@ import { useChatStore } from "@/providers/chat-store-provider"; import styles from "./Suggestions.module.scss"; interface SuggestionsProps { + className?: string; onSuggestionClick: (suggestion: string) => void; } -export default function Suggestions({ onSuggestionClick }: SuggestionsProps) { - const { suggestions, setSuggestionsHeight } = useChatStore(state => state); +export default function Suggestions({ + className, + onSuggestionClick, +}: SuggestionsProps) { + const { suggestions } = useChatStore(state => state); const suggestionsRef = useRef(null); - useEffect(() => { - setSuggestionsHeight(suggestionsRef.current?.clientHeight ?? 0); - }, [setSuggestionsHeight, suggestions]); - return ( <> {!!suggestions?.length && ( -
+
{suggestions?.map((suggestion, index) => (
{suggestion} diff --git a/src/hooks/chats/useChatSocket.ts b/src/hooks/chats/useChatSocket.ts index 6d35e2f..cde91b5 100644 --- a/src/hooks/chats/useChatSocket.ts +++ b/src/hooks/chats/useChatSocket.ts @@ -63,8 +63,6 @@ export const useChatSocket = ( const [isSessionExpired, setIsSessionExpired] = useState(false); const [refillModals, setRefillModals] = useState(null); const { suggestions, setSuggestions } = useChatStore(state => state); - const [isSuggestionsInitialized, setIsSuggestionsInitialized] = - useState(false); const isLoadingAdvisorMessage = useMemo(() => { return messages.length > 0 && messages[0].role !== "assistant"; @@ -166,8 +164,6 @@ export const useChatSocket = ( if (data[0].role === "user") setIsLoadingSelfMessage(false); // if (data[0].role === "assistant") setIsLoadingAdvisorMessage(false); - setSuggestions(data[0].suggestions); - setMessages(prev => { const map = new Map(); @@ -182,6 +178,7 @@ export const useChatSocket = ( text: d.text, createdDate: d.createdDate, isRead: d.isRead, + suggestions: d.suggestions, }) ); return Array.from(map.values()).sort( @@ -230,14 +227,8 @@ export const useChatSocket = ( }, [socket, status, joinChat, leaveChat, fetchBalance]); useEffect(() => { - if (!isSuggestionsInitialized) { - setSuggestions([]); - } - if (messages[0]?.suggestions && !isSuggestionsInitialized) { - setSuggestions(messages[0].suggestions); - setIsSuggestionsInitialized(true); - } - }, [messages, setSuggestions, isSuggestionsInitialized]); + setSuggestions(messages[0]?.suggestions); + }, [messages, setSuggestions]); useEffect(() => { if (session && status === ESocketStatus.CONNECTED) { diff --git a/src/providers/chat-provider.tsx b/src/providers/chat-provider.tsx index fca329d..7310fd8 100644 --- a/src/providers/chat-provider.tsx +++ b/src/providers/chat-provider.tsx @@ -42,7 +42,6 @@ export function ChatProvider({ const value = useChatSocket(chatId, { initialMessages, initialTotal, - onNewMessage: _message => scrollToBottom(), }); const messagesWrapperRef = useRef(null); diff --git a/src/stores/chat-store.ts b/src/stores/chat-store.ts index 2d4b9cb..2dd6bac 100644 --- a/src/stores/chat-store.ts +++ b/src/stores/chat-store.ts @@ -9,7 +9,6 @@ interface ChatState { currentChat: IChat | null; isAutoTopUp: boolean; suggestions: IChatMessage["suggestions"]; - suggestionsHeight: number; _hasHydrated: boolean; } @@ -17,7 +16,6 @@ export type ChatActions = { setCurrentChat: (chat: IChat) => void; setIsAutoTopUp: (isAutoTopUp: boolean) => void; setSuggestions: (suggestions: IChatMessage["suggestions"]) => void; - setSuggestionsHeight: (height: number) => void; clearChatData: () => void; setHasHydrated: (hasHydrated: boolean) => void; }; @@ -28,7 +26,6 @@ const initialState: ChatState = { currentChat: null, isAutoTopUp: false, suggestions: [], - suggestionsHeight: 0, _hasHydrated: false, }; @@ -41,8 +38,6 @@ export const createChatStore = (initState: ChatState = initialState) => { setIsAutoTopUp: (isAutoTopUp: boolean) => set({ isAutoTopUp }), setSuggestions: (suggestions: IChatMessage["suggestions"]) => set({ suggestions }), - setSuggestionsHeight: (height: number) => - set({ suggestionsHeight: height }), clearChatData: () => set(initialState), setHasHydrated: (hasHydrated: boolean) =>