101 lines
2.9 KiB
TypeScript
101 lines
2.9 KiB
TypeScript
import { ActionIcon, Box, Paper, Textarea, Tooltip } from "@mantine/core";
|
|
import { useDisclosure } from "@mantine/hooks";
|
|
import { IconEye, IconEyeOff, IconTrash } from "@tabler/icons-react";
|
|
import { useEffect, useMemo, useState } from "react";
|
|
|
|
import dayjs from "dayjs";
|
|
|
|
export interface IMessageProps {
|
|
data: IMessage;
|
|
onDelete: () => void;
|
|
}
|
|
|
|
export default function Message({ data, onDelete }: IMessageProps) {
|
|
const [show, { toggle }] = useDisclosure(true);
|
|
|
|
const [animation, setAnimation] = useState(false);
|
|
|
|
const messageContent = useMemo(() => {
|
|
return show ? data.message : data.message.replace(/./g, "•");
|
|
}, [data.message, show]);
|
|
|
|
// Tắt hiệu ứng nhấp nháy sau 1 giây
|
|
useEffect(() => {
|
|
if (!animation) return;
|
|
|
|
const timer = setTimeout(() => {
|
|
setAnimation(false);
|
|
}, 5000);
|
|
return () => clearTimeout(timer);
|
|
}, [animation]);
|
|
|
|
useEffect(() => {
|
|
const showAnimation =
|
|
new Date().getTime() - new Date(data.time).getTime() <= 110000;
|
|
|
|
setAnimation(showAnimation);
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, []);
|
|
|
|
return (
|
|
<Tooltip
|
|
position="top-start"
|
|
style={{
|
|
fontSize: "11px",
|
|
}}
|
|
label={`Sender: ${data.sender}`}
|
|
>
|
|
<Paper
|
|
key={data.message}
|
|
shadow="xs"
|
|
radius="md"
|
|
p="xs"
|
|
withBorder
|
|
className={`flex items-center relative gap-3 w-full transition-all duration-300 ${
|
|
animation ? "animate-pulse !bg-blue-100" : ""
|
|
}`}
|
|
>
|
|
<div className="flex items-center w-full flex-col">
|
|
<Box className="flex items-center justify-between w-full">
|
|
<div className="text-xs">
|
|
{data.recipient.length > 0 && <span>{data.recipient}</span>}
|
|
</div>
|
|
<div>
|
|
<span className="text-xs">
|
|
{dayjs(data.time).format("HH:mm D/M/YYYY")}
|
|
</span>
|
|
</div>
|
|
</Box>
|
|
|
|
<Box className="w-full flex items-center">
|
|
<Textarea
|
|
defaultValue={messageContent}
|
|
value={messageContent}
|
|
className="flex-1"
|
|
variant="unstyled"
|
|
readOnly
|
|
/>
|
|
<Box className="flex gap-2">
|
|
<Tooltip label="View">
|
|
<ActionIcon onClick={toggle} variant="light" size="sm">
|
|
{show ? <IconEyeOff size={16} /> : <IconEye size={16} />}
|
|
</ActionIcon>
|
|
</Tooltip>
|
|
<Tooltip label="Delete">
|
|
<ActionIcon
|
|
onClick={onDelete}
|
|
variant="light"
|
|
size="sm"
|
|
color="red"
|
|
>
|
|
<IconTrash size={16} />
|
|
</ActionIcon>
|
|
</Tooltip>
|
|
</Box>
|
|
</Box>
|
|
</div>
|
|
</Paper>
|
|
</Tooltip>
|
|
);
|
|
}
|