import { compact } from "es-toolkit/compat"; import { observer } from "mobx-react"; import * as React from "react"; import type Comment from "~/models/Comment"; import useHover from "~/hooks/useHover"; import useStores from "~/hooks/useStores"; import Logger from "~/utils/Logger"; import Flex from "../Flex"; import { ResizingHeightContainer } from "../ResizingHeightContainer"; import Reaction from "./Reaction"; type Props = { /** Model for which to show the reactions. */ model: Comment; /** Callback when the user intends to add a reaction. */ onAddReaction: (emoji: string) => Promise; /** Callback when the user intends to remove a reaction. */ onRemoveReaction: (emoji: string) => Promise; /** classname generated by styled-components. */ className?: string; /** Picker to render as the last element */ picker?: React.ReactElement; }; const ReactionList: React.FC = ({ model, onAddReaction, onRemoveReaction, className, picker, }) => { const { users } = useStores(); const listRef = React.useRef(null); const hovered = useHover({ ref: listRef, duration: 250, }); React.useEffect(() => { const loadReactedUsersData = async () => { try { await model.loadReactedUsersData(); } catch (_err) { Logger.warn("Could not prefetch reaction data"); } }; if (hovered) { void loadReactedUsersData(); } }, [hovered, model]); const hasReactions = !!model.reactions.length; const style = React.useMemo(() => { if (hasReactions) { return { minHeight: 28 }; } return undefined; }, [hasReactions]); return ( {model.reactions.map((reaction) => { const reactedUsers = compact( reaction.userIds.map((id) => users.get(id)) ); return ( ); })} {picker} ); }; export default observer(ReactionList);