import { useUserInformation } from "@/app/providers/InformationProvider/useUserInformation"; import { useRosettaColors } from "@/app/hooks/useRosettaColors"; import { Avatar, Badge, Box, Divider, Flex, Loader, Skeleton, Text, useComputedColorScheme, useMantineTheme } from "@mantine/core"; import { IconAlertCircle, IconBellOff, IconBookmark, IconCheck, IconChecks, IconClock, IconPin } from "@tabler/icons-react"; import { usePublicKey } from "@/app/providers/AccountProvider/usePublicKey"; import { VerifiedBadge } from "../VerifiedBadge/VerifiedBadge"; import { OnlineState } from "@/app/providers/ProtocolProvider/protocol/packets/packet.onlinestate"; import { DeliveredMessageState } from "@/app/providers/DialogProvider/DialogProvider"; import { dotMessageIfNeeded, isMessageDeliveredByTime } from "@/app/utils/utils"; import { usePacket } from "@/app/providers/ProtocolProvider/usePacket"; import { useRef, useState } from "react"; import { PacketTyping } from "@/app/providers/ProtocolProvider/protocol/packets/packet.typeing"; import { useAvatars } from "@/app/providers/AvatarProvider/useAvatars"; import { TextParser } from "../TextParser/TextParser"; import { useMemory } from "@/app/providers/MemoryProvider/useMemory"; import { DialogRow } from "@/app/providers/DialogListProvider/DialogListProvider"; import { useDialogInfo } from "@/app/providers/DialogListProvider/useDialogInfo"; import { useDialogContextMenu } from "@/app/hooks/useDialogContextMenu"; import { useDialogPin } from "@/app/providers/DialogStateProvider.tsx/useDialogPin"; import { useDialogMute } from "@/app/providers/DialogStateProvider.tsx/useDialogMute"; export interface DialogProps extends DialogRow { onClickDialog: (dialog: string) => void; } export function Dialog(props : DialogProps) { const colors = useRosettaColors(); const theme = useMantineTheme(); const computedTheme = useComputedColorScheme(); const publicKey = usePublicKey(); /** * Принимает public_key оппонента, для групп * есть отдельный компонент GroupDialog */ const opponent = props.dialog_id; const {isMuted} = useDialogMute(opponent); const {isPinned} = useDialogPin(opponent); const [userInfo] = useUserInformation(opponent); const {lastMessage, unreaded, loading} = useDialogInfo(props); const lastMessageFromMe = lastMessage.from_me == 1; const fromMe = opponent == publicKey; const [userTypeing, setUserTypeing] = useState(false); const timeoutRef = useRef(undefined); const avatars = useAvatars(opponent); const [сurrentDialogPublicKeyView] = useMemory("current-dialog-public-key-view", "", true); const {openContextMenu} = useDialogContextMenu(); const isInCurrentDialog = props.dialog_id == сurrentDialogPublicKeyView; const currentDialogColor = computedTheme == 'dark' ? '#2a6292' :'#438fd1'; usePacket(0x0B, (packet : PacketTyping) => { if(packet.getFromPublicKey() == opponent && packet.getToPublicKey() == publicKey && !fromMe){ console.info("User typeing packet received in Dialog"); setUserTypeing(true); clearTimeout(timeoutRef.current); timeoutRef.current = setTimeout(() => { setUserTypeing(false); }, 3000); } }, [opponent]); return ( props.onClickDialog(props.dialog_id)} onContextMenu={() => { openContextMenu(props.dialog_id) }} > { fromMe ? : 0 ? avatars[0].avatar : undefined} variant={isInCurrentDialog ? 'filled' : 'light'} name={userInfo.title} size={50} color={'initials'} /> {userInfo.online == OnlineState.ONLINE && ( )} } {fromMe ? "Saved messages" : dotMessageIfNeeded(userInfo.title, 15)} {isMuted && } {isPinned && } {!userTypeing && <> {loading && } {!loading && } } {userTypeing && <> typing } {!loading && ( {new Date(lastMessage.timestamp).toLocaleTimeString('en-GB', { hour: '2-digit', minute: '2-digit' })} )} {loading && ( )} {lastMessage.delivered == DeliveredMessageState.DELIVERED && <> {lastMessageFromMe && unreaded > 0 && } {lastMessageFromMe && unreaded <= 0 && } } {(lastMessage.delivered == DeliveredMessageState.WAITING && (isMessageDeliveredByTime(lastMessage.timestamp, lastMessage.attachments.length))) && <> } {!loading && (lastMessage.delivered == DeliveredMessageState.ERROR || (!isMessageDeliveredByTime(lastMessage.timestamp, lastMessage.attachments.length) && lastMessage.delivered != DeliveredMessageState.DELIVERED)) && ( )} {unreaded > 0 && !lastMessageFromMe && {unreaded > 99 ? '99+' : unreaded}} ) }