zulip-notes-app/src/components/message.tsx

68 lines
2.4 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 (
<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 gap-2 w-full">
<Textarea defaultValue={messageContent} value={messageContent} className="flex-1" variant="unstyled" readOnly />
<Box className="flex gap-1">
<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>
</div>
<span className='absolute top-1 right-2 text-xs'>{dayjs(data.time).format('HH:ss:mm DD/MM/YYYY')}</span>
</Paper>
);
}