import React, { useCallback, useRef, useState } from 'react'; import { Avatar, Box, Button, Icon, Icons, Overlay, OverlayBackdrop, OverlayCenter, Scroll, Spinner, Text, color, config, } from 'folds'; import { useAtomValue } from 'jotai'; import FocusTrap from 'focus-trap-react'; import { MatrixError, Room } from 'matrix-js-sdk'; import { Page, PageContent, PageContentCenter, PageHeader } from '../../../components/page'; import { useDirectInvites, useRoomInvites, useSpaceInvites } from '../../../state/hooks/inviteList'; import { useMatrixClient } from '../../../hooks/useMatrixClient'; import { allInvitesAtom } from '../../../state/room-list/inviteList'; import { mDirectAtom } from '../../../state/mDirectList'; import { SequenceCard } from '../../../components/sequence-card'; import { getDirectRoomAvatarUrl, getMemberDisplayName, getRoomAvatarUrl, isDirectInvite, } from '../../../utils/room'; import { nameInitials } from '../../../utils/common'; import { RoomAvatar } from '../../../components/room-avatar'; import { addRoomIdToMDirect, getMxIdLocalPart, guessDmRoomUserId } from '../../../utils/matrix'; import { Time } from '../../../components/message'; import { useElementSizeObserver } from '../../../hooks/useElementSizeObserver'; import { onEnterOrSpace } from '../../../utils/keyboard'; import { RoomTopicViewer } from '../../../components/room-topic-viewer'; import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback'; import { useRoomNavigate } from '../../../hooks/useRoomNavigate'; import { useRoomTopic } from '../../../hooks/useRoomMeta'; const COMPACT_CARD_WIDTH = 548; type InviteCardProps = { room: Room; userId: string; direct?: boolean; compact?: boolean; onNavigate: (roomId: string) => void; }; function InviteCard({ room, userId, direct, compact, onNavigate }: InviteCardProps) { const mx = useMatrixClient(); const roomName = room.name || room.getCanonicalAlias() || room.roomId; const member = room.getMember(userId); const memberEvent = member?.events.member; const memberTs = memberEvent?.getTs() ?? 0; const senderId = memberEvent?.getSender(); const senderName = senderId ? getMemberDisplayName(room, senderId) ?? getMxIdLocalPart(senderId) ?? senderId : undefined; const topic = useRoomTopic(room); const [viewTopic, setViewTopic] = useState(false); const closeTopic = () => setViewTopic(false); const openTopic = () => setViewTopic(true); const [joinState, join] = useAsyncCallback( useCallback(async () => { const dmUserId = isDirectInvite(room, userId) ? guessDmRoomUserId(room, userId) : undefined; await mx.joinRoom(room.roomId); if (dmUserId) { await addRoomIdToMDirect(mx, room.roomId, dmUserId); } onNavigate(room.roomId); }, [mx, room, userId, onNavigate]) ); const [leaveState, leave] = useAsyncCallback, MatrixError, []>( useCallback(() => mx.leave(room.roomId), [mx, room]) ); const joining = joinState.status === AsyncStatus.Loading || joinState.status === AsyncStatus.Success; const leaving = leaveState.status === AsyncStatus.Loading || leaveState.status === AsyncStatus.Success; return ( Invited by {senderName} ( {nameInitials(roomName)} )} /> {roomName} {topic && ( {topic} )} }> {joinState.status === AsyncStatus.Error && ( {joinState.error.message} )} {leaveState.status === AsyncStatus.Error && ( {leaveState.error.message} )} ); } export function Invites() { const mx = useMatrixClient(); const userId = mx.getUserId()!; const mDirects = useAtomValue(mDirectAtom); const directInvites = useDirectInvites(mx, allInvitesAtom, mDirects); const spaceInvites = useSpaceInvites(mx, allInvitesAtom); const roomInvites = useRoomInvites(mx, allInvitesAtom, mDirects); const containerRef = useRef(null); const [compact, setCompact] = useState(document.body.clientWidth <= COMPACT_CARD_WIDTH); useElementSizeObserver( useCallback(() => containerRef.current, []), useCallback((width) => setCompact(width <= COMPACT_CARD_WIDTH), []) ); const { navigateRoom, navigateSpace } = useRoomNavigate(); const renderInvite = (roomId: string, direct: boolean, handleNavigate: (rId: string) => void) => { const room = mx.getRoom(roomId); if (!room) return null; return ( ); }; return ( Invitations {directInvites.length > 0 && ( Direct Messages {directInvites.map((roomId) => renderInvite(roomId, true, navigateRoom))} )} {spaceInvites.length > 0 && ( Spaces {spaceInvites.map((roomId) => renderInvite(roomId, false, navigateSpace))} )} {roomInvites.length > 0 && ( Rooms {roomInvites.map((roomId) => renderInvite(roomId, false, navigateRoom))} )} {directInvites.length === 0 && spaceInvites.length === 0 && roomInvites.length === 0 && (
No Pending Invitations You don't have any new pending invitations to display yet.
)}
); }