import { useRosettaColors } from "@/app/hooks/useRosettaColors"; import { useDialog } from "@/app/providers/DialogProvider/useDialog"; import { ProtocolState } from "@/app/providers/ProtocolProvider/ProtocolProvider"; import { useProtocolState } from "@/app/providers/ProtocolProvider/useProtocolState"; import { Avatar, Box, Divider, Flex, Loader, Skeleton, Text, Tooltip, useComputedColorScheme, useMantineTheme } from "@mantine/core"; import { modals } from "@mantine/modals"; import { IconTrashX } from "@tabler/icons-react"; import { useEffect, useState } from "react"; import { usePacket } from "@/app/providers/ProtocolProvider/usePacket"; import { PacketTyping } from "@/app/providers/ProtocolProvider/protocol/packets/packet.typeing"; import { useAvatars } from "@/app/providers/AvatarProvider/useAvatars"; import { useReplyMessages } from "@/app/providers/DialogProvider/useReplyMessages"; import { ReplyHeader } from "../ReplyHeader/ReplyHeader"; import { useRosettaBreakpoints } from "@/app/hooks/useRosettaBreakpoints"; import { BackToDialogs } from "../BackToDialogs/BackToDialogs"; import { useGroupInformation } from "@/app/providers/InformationProvider/useGroupInformation"; import { useNavigate } from "react-router-dom"; import { useGroupMembers } from "@/app/providers/InformationProvider/useGroupMembers"; import { useUserInformation } from "@/app/providers/InformationProvider/useUserInformation"; export function GroupHeader() { const colors = useRosettaColors(); const computedTheme = useComputedColorScheme(); const {deleteMessages, dialog} = useDialog(); const theme = useMantineTheme(); const {groupInfo} = useGroupInformation(dialog); const [protocolState] = useProtocolState(); const [usersTypeing, setUsersTypeing] = useState<{ timeout: NodeJS.Timeout | null, fromPublicKey: string }[]>([]); const avatars = useAvatars(dialog); const {replyMessages} = useReplyMessages(); const {lg} = useRosettaBreakpoints(); const [userInfo] = useUserInformation(usersTypeing[0]?.fromPublicKey || ''); const navigate = useNavigate(); /** * Указывем force для того, чтобы при открытии диалога * с группой подгружался сразу актуальный список участников * даже если он уже был загружен ранее. Потому что * событие добавления/удаления участников могло произойти * когда диалог был закрыт. */ const {members, loading} = useGroupMembers(groupInfo.groupId, true); useEffect(() => { clearUsersTypeing(); }, [dialog]); const clearUsersTypeing = () => { usersTypeing.forEach(ut => { if(ut.timeout){ clearTimeout(ut.timeout); } }); setUsersTypeing([]); } usePacket(0x0B, (packet : PacketTyping) => { if(packet.getToPublicKey() == dialog){ setUsersTypeing((prev) => [...prev, { fromPublicKey: packet.getFromPublicKey(), timeout: setTimeout(() => { setUsersTypeing((prev) => { return prev.filter(ut => ut.fromPublicKey != packet.getFromPublicKey()); }); }, 3000) }]); } }, [dialog]); const clearMessages = async () => { deleteMessages(); modals.closeAll(); } const onClickClearMessages = () => { modals.openConfirmModal({ title: 'Clear all messages?', centered: true, children: ( Are you sure you want to clear all messages? This action cannot be undone. ), withCloseButton: false, labels: { confirm: 'Continue', cancel: "Cancel" }, confirmProps: { color: 'red' }, onConfirm: clearMessages }); } const onClickProfile = () => { navigate(`/main/group/${groupInfo.groupId.replace('#group:', '')}`); } return (<> {(replyMessages.messages.length <= 0 || replyMessages.inDialogInput) && {!lg && } 0 ? avatars[0].avatar : undefined} name={groupInfo.title}> {groupInfo.title} {members.length > 0 && usersTypeing.length <= 0 && protocolState == ProtocolState.CONNECTED && ( {members.length} member{members.length > 1 ? 's' : ''} )} {loading && usersTypeing.length <= 0 && protocolState == ProtocolState.CONNECTED && members.length == 0 && ( )} {!loading && members.length == 0 && ( Deleted group )} {usersTypeing.length > 0 && protocolState == ProtocolState.CONNECTED && <> {userInfo.title} {usersTypeing.length > 1 && 'and ' + (usersTypeing.length - 1)} typing } {protocolState != ProtocolState.CONNECTED && connecting... } } {replyMessages.messages.length > 0 && !replyMessages.inDialogInput && } ) }