diff --git a/app/soapbox/components/account.tsx b/app/soapbox/components/account.tsx index e0fe7ff14..d6d076889 100644 --- a/app/soapbox/components/account.tsx +++ b/app/soapbox/components/account.tsx @@ -9,7 +9,7 @@ import { getAcct } from 'soapbox/utils/accounts'; import { displayFqn } from 'soapbox/utils/state'; import RelativeTimestamp from './relative_timestamp'; -import { Avatar, HStack, Icon, IconButton, Text } from './ui'; +import { Avatar, Emoji, HStack, Icon, IconButton, Text } from './ui'; import type { Account as AccountEntity } from 'soapbox/types/entities'; @@ -60,6 +60,7 @@ interface IAccount { withDate?: boolean, withRelationship?: boolean, showEdit?: boolean, + emoji?: string, } const Account = ({ @@ -80,6 +81,7 @@ const Account = ({ withDate = false, withRelationship = true, showEdit = false, + emoji, }: IAccount) => { const overflowRef = React.useRef(null); const actionRef = React.useRef(null); @@ -160,7 +162,7 @@ const Account = ({ {children}} + wrapper={(children) => {children}} > event.stopPropagation()} > + {emoji && ( + + )} diff --git a/app/soapbox/components/hover_ref_wrapper.tsx b/app/soapbox/components/hover_ref_wrapper.tsx index f1da2e65d..2ef2d8372 100644 --- a/app/soapbox/components/hover_ref_wrapper.tsx +++ b/app/soapbox/components/hover_ref_wrapper.tsx @@ -1,3 +1,4 @@ +import classNames from 'classnames'; import { debounce } from 'lodash'; import React, { useRef } from 'react'; import { useDispatch } from 'react-redux'; @@ -15,10 +16,11 @@ const showProfileHoverCard = debounce((dispatch, ref, accountId) => { interface IHoverRefWrapper { accountId: string, inline: boolean, + className?: string, } /** Makes a profile hover card appear when the wrapped element is hovered. */ -export const HoverRefWrapper: React.FC = ({ accountId, children, inline = false }) => { +export const HoverRefWrapper: React.FC = ({ accountId, children, inline = false, className }) => { const dispatch = useDispatch(); const ref = useRef(null); const Elem: keyof JSX.IntrinsicElements = inline ? 'span' : 'div'; @@ -42,7 +44,7 @@ export const HoverRefWrapper: React.FC = ({ accountId, childre return ( = ({ index, ...props }) => { }; /** Structure to represent a tab. */ -type Item = { +export type Item = { /** Tab text. */ text: React.ReactNode, /** Tab tooltip text. */ diff --git a/app/soapbox/features/ui/components/reactions_modal.tsx b/app/soapbox/features/ui/components/reactions_modal.tsx index 4832f943d..f343dc5c4 100644 --- a/app/soapbox/features/ui/components/reactions_modal.tsx +++ b/app/soapbox/features/ui/components/reactions_modal.tsx @@ -3,12 +3,13 @@ import React, { useEffect, useState } from 'react'; import { FormattedMessage, defineMessages, useIntl } from 'react-intl'; import { fetchFavourites, fetchReactions } from 'soapbox/actions/interactions'; -import FilterBar from 'soapbox/components/filter_bar'; import ScrollableList from 'soapbox/components/scrollable_list'; -import { Modal, Spinner } from 'soapbox/components/ui'; +import { Emoji, Modal, Spinner, Tabs } from 'soapbox/components/ui'; import AccountContainer from 'soapbox/containers/account_container'; import { useAppDispatch, useAppSelector } from 'soapbox/hooks'; +import type { Item } from 'soapbox/components/ui/tabs/tabs'; + const messages = defineMessages({ close: { id: 'lightbox.close', defaultMessage: 'Close' }, all: { id: 'reactions.all', defaultMessage: 'All' }, @@ -24,14 +25,14 @@ const ReactionsModal: React.FC = ({ onClose, statusId, reaction const dispatch = useAppDispatch(); const intl = useIntl(); const [reaction, setReaction] = useState(initialReaction); - const reactions = useAppSelector, count: number, name: string, }>>((state) => { const favourites = state.user_lists.getIn(['favourited_by', statusId]); const reactions = state.user_lists.getIn(['reactions', statusId]); - return favourites && reactions && ImmutableList(favourites ? [{ accounts: favourites, count: favourites.size, name: '👍' }] : []).concat(reactions || []); + return favourites && reactions && ImmutableList(favourites.size ? [{ accounts: favourites, count: favourites.size, name: '👍' }] : []).concat(reactions || []); }); const fetchData = () => { @@ -44,7 +45,7 @@ const ReactionsModal: React.FC = ({ onClose, statusId, reaction }; const renderFilterBar = () => { - const items = [ + const items: Array = [ { text: intl.formatMessage(messages.all), action: () => setReaction(''), @@ -54,13 +55,16 @@ const ReactionsModal: React.FC = ({ onClose, statusId, reaction reactions.forEach(reaction => items.push( { - text: `${reaction.name} ${reaction.count}`, + text:
+ + {reaction.count} +
, action: () => setReaction(reaction.name), name: reaction.name, }, )); - return ; + return ; }; useEffect(() => { @@ -69,7 +73,7 @@ const ReactionsModal: React.FC = ({ onClose, statusId, reaction const accounts = reactions && (reaction ? reactions.find(({ name }) => name === reaction)?.accounts.map(account => ({ id: account, reaction: reaction })) - : reactions.map(({ accounts, name }) => accounts.map(account => ({ id: account, reaction: name }))).flat()); + : reactions.map(({ accounts, name }) => accounts.map(account => ({ id: account, reaction: name }))).flatten()) as Array<{ id: string, reaction: string }>; let body; @@ -79,14 +83,15 @@ const ReactionsModal: React.FC = ({ onClose, statusId, reaction const emptyMessage = ; body = (<> - {reactions.length > 0 && renderFilterBar()} + {reactions.size > 0 && renderFilterBar()} {accounts.map((account) => - , + , )} );