hiento09 86f0ffc7d1
Chore/disable submodule (#56)
* Chore disable git submodule for web-client and app-backend

* Chore add newest source code of app-backend and web-client

---------

Co-authored-by: Hien To <tominhhien97@gmail.com>
2023-09-05 16:29:07 +07:00

108 lines
3.0 KiB
TypeScript

import React, { useEffect } from "react";
import { displayDate } from "@/_utils/datetime";
import { TextCode } from "../TextCode";
import { getMessageCode } from "@/_utils/message";
import { useSubscription } from "@apollo/client";
import {
SubscribeMessageDocument,
SubscribeMessageSubscription,
} from "@/graphql";
import { useStore } from "@/_models/RootStore";
type Props = {
id?: string;
avatarUrl?: string;
senderName: string;
createdAt: number;
text?: string;
};
const StreamTextMessage: React.FC<Props> = ({
id,
senderName,
createdAt,
avatarUrl = "",
text = "",
}) => {
const [textMessage, setTextMessage] = React.useState(text);
const [completedTyping, setCompletedTyping] = React.useState(false);
const tokenIndex = React.useRef(0);
const { historyStore } = useStore();
const { data } = useSubscription<SubscribeMessageSubscription>(
SubscribeMessageDocument,
{
variables: {
id,
},
}
);
useEffect(() => {
if (
data?.messages_by_pk?.content &&
data.messages_by_pk.content.length > text.length
) {
historyStore.finishActiveConversationWaiting();
}
}, [data, text]); // eslint-disable-line react-hooks/exhaustive-deps
useEffect(() => {
setCompletedTyping(false);
const stringResponse = data?.messages_by_pk?.content ?? text;
const intervalId = setInterval(() => {
setTextMessage(stringResponse.slice(0, tokenIndex.current));
tokenIndex.current++;
if (tokenIndex.current > stringResponse.length) {
clearInterval(intervalId);
setCompletedTyping(true);
}
}, 20);
return () => clearInterval(intervalId);
}, [data?.messages_by_pk?.content, text]);
return textMessage.length > 0 ? (
<div className="flex items-start gap-2">
<img
className="rounded-full"
src={avatarUrl}
width={32}
height={32}
alt=""
/>
<div className="flex flex-col gap-1 w-full">
<div className="flex gap-1 justify-start items-baseline">
<div className="text-[#1B1B1B] text-[13px] font-extrabold leading-[15.2px] dark:text-[#d1d5db]">
{senderName}
</div>
<div className="text-[11px] leading-[13.2px] font-medium text-gray-400">
{displayDate(createdAt)}
</div>
</div>
{textMessage.includes("```") ? (
getMessageCode(textMessage).map((item, i) => (
<div className="flex gap-1 flex-col" key={i}>
<p className="leading-[20px] whitespace-break-spaces text-[14px] font-normal dark:text-[#d1d5db]">
{item.text}
</p>
{item.code.trim().length > 0 && <TextCode text={item.code} />}
</div>
))
) : (
<p className="leading-[20px] whitespace-break-spaces text-[14px] font-normal dark:text-[#d1d5db]">
{textMessage}
</p>
)}
</div>
</div>
) : (
<></>
);
};
export default React.memo(StreamTextMessage);