Merge branch 'emoji-button' into 'develop'

Emoji reacts: show the emoji you reacted with on the button

See merge request soapbox-pub/soapbox-fe!1571
This commit is contained in:
Alex Gleason 2022-07-07 16:10:59 +00:00
commit 334857045a
3 changed files with 54 additions and 28 deletions

View File

@ -1,7 +1,7 @@
import classNames from 'classnames'; import classNames from 'classnames';
import React from 'react'; import React from 'react';
import { Text, Icon } from 'soapbox/components/ui'; import { Text, Icon, Emoji } from 'soapbox/components/ui';
import { shortNumberFormat } from 'soapbox/utils/numbers'; import { shortNumberFormat } from 'soapbox/utils/numbers';
const COLORS = { const COLORS = {
@ -15,7 +15,7 @@ interface IStatusActionCounter {
count: number, count: number,
} }
/** Action button numerical counter, eg "5" likes */ /** Action button numerical counter, eg "5" likes. */
const StatusActionCounter: React.FC<IStatusActionCounter> = ({ count = 0 }): JSX.Element => { const StatusActionCounter: React.FC<IStatusActionCounter> = ({ count = 0 }): JSX.Element => {
return ( return (
<Text size='xs' weight='semibold' theme='inherit'> <Text size='xs' weight='semibold' theme='inherit'>
@ -31,10 +31,11 @@ interface IStatusActionButton extends React.ButtonHTMLAttributes<HTMLButtonEleme
active?: boolean, active?: boolean,
color?: Color, color?: Color,
filled?: boolean, filled?: boolean,
emoji?: string,
} }
const StatusActionButton = React.forwardRef((props: IStatusActionButton, ref: React.ForwardedRef<HTMLButtonElement>): JSX.Element => { const StatusActionButton = React.forwardRef<HTMLButtonElement, IStatusActionButton>((props, ref): JSX.Element => {
const { icon, className, iconClassName, active, color, filled = false, count = 0, ...filteredProps } = props; const { icon, className, iconClassName, active, color, filled = false, count = 0, emoji, ...filteredProps } = props;
return ( return (
<button <button
@ -46,22 +47,29 @@ const StatusActionButton = React.forwardRef((props: IStatusActionButton, ref: Re
'bg-white dark:bg-transparent', 'bg-white dark:bg-transparent',
'focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500 dark:ring-offset-0', 'focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500 dark:ring-offset-0',
{ {
'text-accent-300 hover:text-accent-300 dark:hover:text-accent-300': active && color === COLORS.accent, 'text-black dark:text-white': active && emoji,
'text-success-600 hover:text-success-600 dark:hover:text-success-600': active && color === COLORS.success, 'text-accent-300 hover:text-accent-300 dark:hover:text-accent-300': active && !emoji && color === COLORS.accent,
'text-success-600 hover:text-success-600 dark:hover:text-success-600': active && !emoji && color === COLORS.success,
}, },
className, className,
)} )}
{...filteredProps} {...filteredProps}
> >
<Icon {emoji ? (
src={icon} <span className='block w-6 h-6 flex items-center justify-center'>
className={classNames( <Emoji className='w-full h-full p-0.5' emoji={emoji} />
{ </span>
'fill-accent-300 hover:fill-accent-300': active && filled && color === COLORS.accent, ) : (
}, <Icon
iconClassName, src={icon}
)} className={classNames(
/> {
'fill-accent-300 hover:fill-accent-300': active && filled && color === COLORS.accent,
},
iconClassName,
)}
/>
)}
{(count || null) && ( {(count || null) && (
<StatusActionCounter count={count} /> <StatusActionCounter count={count} />

View File

@ -670,6 +670,7 @@ class StatusActionBar extends ImmutablePureComponent<IStatusActionBar, IStatusAc
color='accent' color='accent'
active={Boolean(meEmojiReact)} active={Boolean(meEmojiReact)}
count={emojiReactCount} count={emojiReactCount}
emoji={meEmojiReact}
/> />
</EmojiButtonWrapper> </EmojiButtonWrapper>
) : ( ) : (

View File

@ -6,7 +6,7 @@ import { withRouter, RouteComponentProps } from 'react-router-dom';
import { openModal } from 'soapbox/actions/modals'; import { openModal } from 'soapbox/actions/modals';
import EmojiButtonWrapper from 'soapbox/components/emoji-button-wrapper'; import EmojiButtonWrapper from 'soapbox/components/emoji-button-wrapper';
import { HStack, IconButton } from 'soapbox/components/ui'; import { HStack, IconButton, Emoji, Text } from 'soapbox/components/ui';
import DropdownMenuContainer from 'soapbox/containers/dropdown_menu_container'; import DropdownMenuContainer from 'soapbox/containers/dropdown_menu_container';
import { isUserTouching } from 'soapbox/is_mobile'; import { isUserTouching } from 'soapbox/is_mobile';
import { getReactForStatus } from 'soapbox/utils/emoji_reacts'; import { getReactForStatus } from 'soapbox/utils/emoji_reacts';
@ -583,18 +583,35 @@ class ActionBar extends React.PureComponent<IActionBar, IActionBarState> {
{features.emojiReacts ? ( {features.emojiReacts ? (
<EmojiButtonWrapper statusId={status.id}> <EmojiButtonWrapper statusId={status.id}>
<IconButton {meEmojiReact ? (
className={classNames({ <button
'text-gray-400 hover:text-gray-600': !meEmojiReact, // className copied from IconButton
'text-accent-300 hover:text-accent-300': Boolean(meEmojiReact), // TODO: better abstraction
})} className='flex items-center space-x-2 p-1 rounded-full focus:outline-none focus:ring-2 focus:ring-offset-2 dark:ring-offset-0 focus:ring-primary-500 bg-white dark:bg-transparent'
title={meEmojiTitle} title={meEmojiTitle}
src={require('@tabler/icons/icons/heart.svg')} >
iconClassName={classNames({ <span className='block w-6 h-6 flex items-center justify-center'>
'fill-accent-300': Boolean(meEmojiReact), <Emoji className='w-full h-full p-0.5' emoji={meEmojiReact} />
})} </span>
text={meEmojiTitle}
/> <Text tag='span' theme='muted' size='sm'>
{meEmojiTitle}
</Text>
</button>
) : (
<IconButton
className={classNames({
'text-gray-400 hover:text-gray-600': !meEmojiReact,
'text-accent-300 hover:text-accent-300': Boolean(meEmojiReact),
})}
title={meEmojiTitle}
src={require('@tabler/icons/icons/heart.svg')}
iconClassName={classNames({
'fill-accent-300': Boolean(meEmojiReact),
})}
text={meEmojiTitle}
/>
)}
</EmojiButtonWrapper> </EmojiButtonWrapper>
) : ( ) : (
<IconButton <IconButton