AW-496-connect-chats
edits
This commit is contained in:
parent
ccffd32511
commit
3244655e38
@ -10,3 +10,9 @@
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
padding-top: 16px;
|
padding-top: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.suggestions.suggestions {
|
||||||
|
position: sticky;
|
||||||
|
bottom: 0;
|
||||||
|
padding: 0 16px 36px;
|
||||||
|
}
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import { useChat } from "@/providers/chat-provider";
|
|||||||
import { useChatStore } from "@/providers/chat-store-provider";
|
import { useChatStore } from "@/providers/chat-store-provider";
|
||||||
import { formatTime } from "@/shared/utils/date";
|
import { formatTime } from "@/shared/utils/date";
|
||||||
|
|
||||||
import { ChatMessages } from "..";
|
import { ChatMessages, Suggestions } from "..";
|
||||||
|
|
||||||
import styles from "./ChatMessagesWrapper.module.scss";
|
import styles from "./ChatMessagesWrapper.module.scss";
|
||||||
|
|
||||||
@ -20,9 +20,10 @@ export default function ChatMessagesWrapper() {
|
|||||||
messagesWrapperRef,
|
messagesWrapperRef,
|
||||||
loadOlder,
|
loadOlder,
|
||||||
scrollToBottom,
|
scrollToBottom,
|
||||||
|
send,
|
||||||
} = useChat();
|
} = useChat();
|
||||||
|
|
||||||
const { suggestionsHeight, _hasHydrated } = useChatStore(state => state);
|
const { _hasHydrated } = useChatStore(state => state);
|
||||||
|
|
||||||
const isInitialScrollDone = useRef(false);
|
const isInitialScrollDone = useRef(false);
|
||||||
|
|
||||||
@ -48,47 +49,19 @@ export default function ChatMessagesWrapper() {
|
|||||||
}, [socketMessages]);
|
}, [socketMessages]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (
|
if (socketMessages.length > 0 && _hasHydrated) {
|
||||||
socketMessages.length > 0 &&
|
|
||||||
!isInitialScrollDone.current &&
|
|
||||||
_hasHydrated
|
|
||||||
) {
|
|
||||||
scrollToBottom();
|
|
||||||
const timeout = setTimeout(() => {
|
const timeout = setTimeout(() => {
|
||||||
isInitialScrollDone.current = true;
|
scrollToBottom();
|
||||||
}, 1000);
|
});
|
||||||
return () => clearTimeout(timeout);
|
return () => clearTimeout(timeout);
|
||||||
}
|
}
|
||||||
}, [socketMessages.length, scrollToBottom, _hasHydrated]);
|
}, [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 (
|
return (
|
||||||
<div
|
<div
|
||||||
className={styles.messagesWrapper}
|
className={styles.messagesWrapper}
|
||||||
ref={messagesWrapperRef}
|
ref={messagesWrapperRef}
|
||||||
onScroll={handleScroll}
|
onScroll={handleScroll}
|
||||||
style={{
|
|
||||||
paddingBottom: suggestionsHeight,
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{isLoadingOlder && hasMoreOlderMessages && (
|
{isLoadingOlder && hasMoreOlderMessages && (
|
||||||
<div className={styles.loaderTop}>
|
<div className={styles.loaderTop}>
|
||||||
@ -99,6 +72,12 @@ export default function ChatMessagesWrapper() {
|
|||||||
messages={mappedMessages}
|
messages={mappedMessages}
|
||||||
isLoadingAdvisorMessage={isLoadingAdvisorMessage}
|
isLoadingAdvisorMessage={isLoadingAdvisorMessage}
|
||||||
/>
|
/>
|
||||||
|
<Suggestions
|
||||||
|
className={styles.suggestions}
|
||||||
|
onSuggestionClick={suggestion => {
|
||||||
|
send(suggestion);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import { useChat } from "@/providers/chat-provider";
|
import { useChat } from "@/providers/chat-provider";
|
||||||
|
|
||||||
import { MessageInput, Suggestions } from "..";
|
import { MessageInput } from "..";
|
||||||
|
|
||||||
import styles from "./MessageInputWrapper.module.scss";
|
import styles from "./MessageInputWrapper.module.scss";
|
||||||
|
|
||||||
@ -11,11 +11,6 @@ export default function MessageInputWrapper() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.container}>
|
<div className={styles.container}>
|
||||||
<Suggestions
|
|
||||||
onSuggestionClick={suggestion => {
|
|
||||||
send(suggestion);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<div className={styles.inputWrapper}>
|
<div className={styles.inputWrapper}>
|
||||||
<MessageInput onSend={send} />
|
<MessageInput onSend={send} />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,6 +1,4 @@
|
|||||||
.container {
|
.container {
|
||||||
position: absolute;
|
|
||||||
bottom: 100%;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useEffect, useRef } from "react";
|
import { useRef } from "react";
|
||||||
|
import clsx from "clsx";
|
||||||
|
|
||||||
import { Typography } from "@/components/ui";
|
import { Typography } from "@/components/ui";
|
||||||
import { useChatStore } from "@/providers/chat-store-provider";
|
import { useChatStore } from "@/providers/chat-store-provider";
|
||||||
@ -8,21 +9,21 @@ import { useChatStore } from "@/providers/chat-store-provider";
|
|||||||
import styles from "./Suggestions.module.scss";
|
import styles from "./Suggestions.module.scss";
|
||||||
|
|
||||||
interface SuggestionsProps {
|
interface SuggestionsProps {
|
||||||
|
className?: string;
|
||||||
onSuggestionClick: (suggestion: string) => void;
|
onSuggestionClick: (suggestion: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Suggestions({ onSuggestionClick }: SuggestionsProps) {
|
export default function Suggestions({
|
||||||
const { suggestions, setSuggestionsHeight } = useChatStore(state => state);
|
className,
|
||||||
|
onSuggestionClick,
|
||||||
|
}: SuggestionsProps) {
|
||||||
|
const { suggestions } = useChatStore(state => state);
|
||||||
const suggestionsRef = useRef<HTMLDivElement>(null);
|
const suggestionsRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setSuggestionsHeight(suggestionsRef.current?.clientHeight ?? 0);
|
|
||||||
}, [setSuggestionsHeight, suggestions]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{!!suggestions?.length && (
|
{!!suggestions?.length && (
|
||||||
<div className={styles.container} ref={suggestionsRef}>
|
<div className={clsx(styles.container, className)} ref={suggestionsRef}>
|
||||||
{suggestions?.map((suggestion, index) => (
|
{suggestions?.map((suggestion, index) => (
|
||||||
<div
|
<div
|
||||||
key={`suggestion-${index}`}
|
key={`suggestion-${index}`}
|
||||||
@ -35,6 +36,7 @@ export default function Suggestions({ onSuggestionClick }: SuggestionsProps) {
|
|||||||
as="p"
|
as="p"
|
||||||
weight="medium"
|
weight="medium"
|
||||||
className={styles.suggestionText}
|
className={styles.suggestionText}
|
||||||
|
align="left"
|
||||||
>
|
>
|
||||||
{suggestion}
|
{suggestion}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|||||||
@ -63,8 +63,6 @@ export const useChatSocket = (
|
|||||||
const [isSessionExpired, setIsSessionExpired] = useState(false);
|
const [isSessionExpired, setIsSessionExpired] = useState(false);
|
||||||
const [refillModals, setRefillModals] = useState<IRefillModals | null>(null);
|
const [refillModals, setRefillModals] = useState<IRefillModals | null>(null);
|
||||||
const { suggestions, setSuggestions } = useChatStore(state => state);
|
const { suggestions, setSuggestions } = useChatStore(state => state);
|
||||||
const [isSuggestionsInitialized, setIsSuggestionsInitialized] =
|
|
||||||
useState(false);
|
|
||||||
|
|
||||||
const isLoadingAdvisorMessage = useMemo(() => {
|
const isLoadingAdvisorMessage = useMemo(() => {
|
||||||
return messages.length > 0 && messages[0].role !== "assistant";
|
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 === "user") setIsLoadingSelfMessage(false);
|
||||||
// if (data[0].role === "assistant") setIsLoadingAdvisorMessage(false);
|
// if (data[0].role === "assistant") setIsLoadingAdvisorMessage(false);
|
||||||
|
|
||||||
setSuggestions(data[0].suggestions);
|
|
||||||
|
|
||||||
setMessages(prev => {
|
setMessages(prev => {
|
||||||
const map = new Map<string, UIMessage>();
|
const map = new Map<string, UIMessage>();
|
||||||
|
|
||||||
@ -182,6 +178,7 @@ export const useChatSocket = (
|
|||||||
text: d.text,
|
text: d.text,
|
||||||
createdDate: d.createdDate,
|
createdDate: d.createdDate,
|
||||||
isRead: d.isRead,
|
isRead: d.isRead,
|
||||||
|
suggestions: d.suggestions,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
return Array.from(map.values()).sort(
|
return Array.from(map.values()).sort(
|
||||||
@ -230,14 +227,8 @@ export const useChatSocket = (
|
|||||||
}, [socket, status, joinChat, leaveChat, fetchBalance]);
|
}, [socket, status, joinChat, leaveChat, fetchBalance]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isSuggestionsInitialized) {
|
setSuggestions(messages[0]?.suggestions);
|
||||||
setSuggestions([]);
|
}, [messages, setSuggestions]);
|
||||||
}
|
|
||||||
if (messages[0]?.suggestions && !isSuggestionsInitialized) {
|
|
||||||
setSuggestions(messages[0].suggestions);
|
|
||||||
setIsSuggestionsInitialized(true);
|
|
||||||
}
|
|
||||||
}, [messages, setSuggestions, isSuggestionsInitialized]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (session && status === ESocketStatus.CONNECTED) {
|
if (session && status === ESocketStatus.CONNECTED) {
|
||||||
|
|||||||
@ -42,7 +42,6 @@ export function ChatProvider({
|
|||||||
const value = useChatSocket(chatId, {
|
const value = useChatSocket(chatId, {
|
||||||
initialMessages,
|
initialMessages,
|
||||||
initialTotal,
|
initialTotal,
|
||||||
onNewMessage: _message => scrollToBottom(),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const messagesWrapperRef = useRef<HTMLDivElement>(null);
|
const messagesWrapperRef = useRef<HTMLDivElement>(null);
|
||||||
|
|||||||
@ -9,7 +9,6 @@ interface ChatState {
|
|||||||
currentChat: IChat | null;
|
currentChat: IChat | null;
|
||||||
isAutoTopUp: boolean;
|
isAutoTopUp: boolean;
|
||||||
suggestions: IChatMessage["suggestions"];
|
suggestions: IChatMessage["suggestions"];
|
||||||
suggestionsHeight: number;
|
|
||||||
_hasHydrated: boolean;
|
_hasHydrated: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -17,7 +16,6 @@ export type ChatActions = {
|
|||||||
setCurrentChat: (chat: IChat) => void;
|
setCurrentChat: (chat: IChat) => void;
|
||||||
setIsAutoTopUp: (isAutoTopUp: boolean) => void;
|
setIsAutoTopUp: (isAutoTopUp: boolean) => void;
|
||||||
setSuggestions: (suggestions: IChatMessage["suggestions"]) => void;
|
setSuggestions: (suggestions: IChatMessage["suggestions"]) => void;
|
||||||
setSuggestionsHeight: (height: number) => void;
|
|
||||||
clearChatData: () => void;
|
clearChatData: () => void;
|
||||||
setHasHydrated: (hasHydrated: boolean) => void;
|
setHasHydrated: (hasHydrated: boolean) => void;
|
||||||
};
|
};
|
||||||
@ -28,7 +26,6 @@ const initialState: ChatState = {
|
|||||||
currentChat: null,
|
currentChat: null,
|
||||||
isAutoTopUp: false,
|
isAutoTopUp: false,
|
||||||
suggestions: [],
|
suggestions: [],
|
||||||
suggestionsHeight: 0,
|
|
||||||
_hasHydrated: false,
|
_hasHydrated: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -41,8 +38,6 @@ export const createChatStore = (initState: ChatState = initialState) => {
|
|||||||
setIsAutoTopUp: (isAutoTopUp: boolean) => set({ isAutoTopUp }),
|
setIsAutoTopUp: (isAutoTopUp: boolean) => set({ isAutoTopUp }),
|
||||||
setSuggestions: (suggestions: IChatMessage["suggestions"]) =>
|
setSuggestions: (suggestions: IChatMessage["suggestions"]) =>
|
||||||
set({ suggestions }),
|
set({ suggestions }),
|
||||||
setSuggestionsHeight: (height: number) =>
|
|
||||||
set({ suggestionsHeight: height }),
|
|
||||||
clearChatData: () => set(initialState),
|
clearChatData: () => set(initialState),
|
||||||
|
|
||||||
setHasHydrated: (hasHydrated: boolean) =>
|
setHasHydrated: (hasHydrated: boolean) =>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user