import clsx from 'clsx'; import React from 'react'; import { TransitionMotion, spring } from 'react-motion'; import EmojiPickerDropdown from 'soapbox/features/emoji/containers/emoji-picker-dropdown-container'; import { useSettings } from 'soapbox/hooks'; import Reaction from './reaction'; import type { List as ImmutableList, Map as ImmutableMap } from 'immutable'; import type { Emoji, NativeEmoji } from 'soapbox/features/emoji'; import type { AnnouncementReaction } from 'soapbox/types/entities'; interface IReactionsBar { announcementId: string reactions: ImmutableList<AnnouncementReaction> emojiMap: ImmutableMap<string, ImmutableMap<string, string>> addReaction: (id: string, name: string) => void removeReaction: (id: string, name: string) => void } const ReactionsBar: React.FC<IReactionsBar> = ({ announcementId, reactions, addReaction, removeReaction, emojiMap }) => { const reduceMotion = useSettings().get('reduceMotion'); const handleEmojiPick = (data: Emoji) => { addReaction(announcementId, (data as NativeEmoji).native.replace(/:/g, '')); }; const willEnter = () => ({ scale: reduceMotion ? 1 : 0 }); const willLeave = () => ({ scale: reduceMotion ? 0 : spring(0, { stiffness: 170, damping: 26 }) }); const visibleReactions = reactions.filter(x => x.count > 0); const styles = visibleReactions.map(reaction => ({ key: reaction.name, data: reaction, style: { scale: reduceMotion ? 1 : spring(1, { stiffness: 150, damping: 13 }) }, })).toArray(); return ( <TransitionMotion styles={styles} willEnter={willEnter} willLeave={willLeave}> {items => ( <div className={clsx('flex flex-wrap items-center gap-1', { 'reactions-bar--empty': visibleReactions.isEmpty() })}> {items.map(({ key, data, style }) => ( <Reaction key={key} reaction={data} style={{ transform: `scale(${style.scale})`, position: style.scale < 0.5 ? 'absolute' : 'static' }} announcementId={announcementId} addReaction={addReaction} removeReaction={removeReaction} emojiMap={emojiMap} /> ))} {visibleReactions.size < 8 && <EmojiPickerDropdown onPickEmoji={handleEmojiPick} />} </div> )} </TransitionMotion> ); }; export default ReactionsBar;