import { useRosettaColors } from "@/app/hooks/useRosettaColors"; import { Avatar, Badge, Box, Divider, Flex, Loader, Skeleton, Text, useComputedColorScheme, useMantineTheme } from "@mantine/core"; import { IconAlertCircle, IconBellOff, IconCheck, IconChecks, IconClock, IconPin, IconUsers } from "@tabler/icons-react"; import { DeliveredMessageState } from "@/app/providers/DialogProvider/DialogProvider"; import { dotMessageIfNeeded, isMessageDeliveredByTime } from "@/app/utils/utils"; import { usePacket } from "@/app/providers/ProtocolProvider/usePacket"; import { useEffect, 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 { useGroupInformation } from "@/app/providers/InformationProvider/useGroupInformation"; import { useDialogInfo } from "@/app/providers/DialogListProvider/useDialogInfo"; import { useUserInformation } from "@/app/providers/InformationProvider/useUserInformation"; import { useDialogContextMenu } from "@/app/hooks/useDialogContextMenu"; import { useDialogMute } from "@/app/providers/DialogStateProvider.tsx/useDialogMute"; import { useDialogPin } from "@/app/providers/DialogStateProvider.tsx/useDialogPin"; import { useMentions } from "@/app/providers/DialogStateProvider.tsx/useMentions"; export interface DialogProps extends DialogRow { onClickDialog: (dialog: string) => void; } export function GroupDialog(props : DialogProps) { const colors = useRosettaColors(); const theme = useMantineTheme(); const computedTheme = useComputedColorScheme(); /** * Принимает #group:group_id, для * диалогов между пользователями есть просто public_key собеседника */ const groupId = props.dialog_id; const {isMuted} = useDialogMute(groupId); const {isPinned} = useDialogPin(groupId); const {groupInfo} = useGroupInformation(groupId); const {lastMessage, unreaded, loading} = useDialogInfo(props); const lastMessageFromMe = lastMessage.from_me == 1; const [usersTypeing, setUsersTypeing] = useState<{ timeout: NodeJS.Timeout | null, fromPublicKey: string }[]>([]); const avatars = useAvatars(groupId); const [сurrentDialogPublicKeyView] = useMemory("current-dialog-public-key-view", "", true); const [userInfo] = useUserInformation(lastMessage.from_public_key); const [typingUser] = useUserInformation(usersTypeing[0]?.fromPublicKey || ''); const isInCurrentDialog = props.dialog_id == сurrentDialogPublicKeyView; const currentDialogColor = computedTheme == 'dark' ? '#2a6292' :'#438fd1'; const {openContextMenu} = useDialogContextMenu(); const {isMentioned} = useMentions(); useEffect(() => { clearUsersTypeing(); }, [props.dialog_id]); const clearUsersTypeing = () => { usersTypeing.forEach(ut => { if(ut.timeout){ clearTimeout(ut.timeout); } }); setUsersTypeing([]); } usePacket(0x0B, (packet : PacketTyping) => { if(packet.getToPublicKey() == props.dialog_id){ setUsersTypeing((prev) => [...prev, { fromPublicKey: packet.getFromPublicKey(), timeout: setTimeout(() => { setUsersTypeing((prev) => { return prev.filter(ut => ut.fromPublicKey != packet.getFromPublicKey()); }); }, 3000) }]); } }, [props.dialog_id]); return ( props.onClickDialog(props.dialog_id)} onContextMenu={() => { openContextMenu(props.dialog_id) }}> 0 ? avatars[0].avatar : undefined} variant={isInCurrentDialog ? 'filled' : 'light'} name={groupInfo.title} size={50} color={'initials'} /> {dotMessageIfNeeded(groupInfo.title, 15)} {isMuted && } {isPinned && } {usersTypeing.length <= 0 && <> {loading && } {!loading && ( <> {userInfo.title}: )} } {usersTypeing.length > 0 && <> {typingUser.title} {usersTypeing.length > 1 && 'and ' + (usersTypeing.length - 1)} 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 && !isMentioned(props.dialog_id) && {unreaded > 99 ? '99+' : unreaded}} {isMentioned(props.dialog_id) && !lastMessageFromMe && @} ) }