import React, { MouseEventHandler, useCallback, useState } from 'react'; import { Box, Modal, Overlay, OverlayBackdrop, OverlayCenter, Text, Tooltip, TooltipProvider, as, toRem, } from 'folds'; import classNames from 'classnames'; import { Room } from 'matrix-js-sdk'; import { type Relations } from 'matrix-js-sdk/lib/models/relations'; import FocusTrap from 'focus-trap-react'; import { useMatrixClient } from '../../../hooks/useMatrixClient'; import { factoryEventSentBy } from '../../../utils/matrix'; import { Reaction, ReactionTooltipMsg } from '../../../components/message'; import { useRelations } from '../../../hooks/useRelations'; import * as css from './styles.css'; import { ReactionViewer } from '../reaction-viewer'; export type ReactionsProps = { room: Room; mEventId: string; canSendReaction?: boolean; relations: Relations; onReactionToggle: (targetEventId: string, key: string, shortcode?: string) => void; }; export const Reactions = as<'div', ReactionsProps>( ({ className, room, relations, mEventId, canSendReaction, onReactionToggle, ...props }, ref) => { const mx = useMatrixClient(); const [viewer, setViewer] = useState(false); const myUserId = mx.getUserId(); const reactions = useRelations( relations, useCallback((rel) => [...(rel.getSortedAnnotationsByKey() ?? [])], []) ); const handleViewReaction: MouseEventHandler = (evt) => { evt.stopPropagation(); evt.preventDefault(); const key = evt.currentTarget.getAttribute('data-reaction-key'); if (!key) setViewer(true); else setViewer(key); }; return ( {reactions.map(([key, events]) => { const rEvents = Array.from(events); if (rEvents.length === 0 || typeof key !== 'string') return null; const myREvent = myUserId ? rEvents.find(factoryEventSentBy(myUserId)) : undefined; const isPressed = !!myREvent?.getRelation(); return ( } > {(targetRef) => ( onReactionToggle(mEventId, key) : undefined} onContextMenu={handleViewReaction} aria-disabled={!canSendReaction} /> )} ); })} {reactions.length > 0 && ( { evt.stopPropagation(); }} open={!!viewer} backdrop={} > setViewer(false), clickOutsideDeactivates: true, }} > setViewer(false)} /> )} ); } );