feat: refactor reaction popup to use i18n component

pull/3206/head
Ryan Miller 8 months ago
parent 3f272244d2
commit 530c4b9fc1

@ -1,11 +1,8 @@
import { useEffect, useState, useMemo } from 'react'; import { useMemo } from 'react';
import { useSelector } from 'react-redux';
import styled from 'styled-components'; import styled from 'styled-components';
import { Data } from '../../../../data/data';
import { findAndFormatContact } from '../../../../models/message'; import { findAndFormatContact } from '../../../../models/message';
import { PubKey } from '../../../../session/types/PubKey'; import { PubKey } from '../../../../session/types/PubKey';
import { useIsDarkTheme } from '../../../../state/selectors/theme'; import { I18n } from '../../../basic/I18n';
import { nativeEmojiData } from '../../../../util/emoji';
export type TipPosition = 'center' | 'left' | 'right'; export type TipPosition = 'center' | 'left' | 'right';
@ -54,22 +51,6 @@ export const StyledPopupContainer = styled.div<{ tooltipPosition: TipPosition }>
} }
`; `;
const StyledEmoji = styled.span`
font-size: 36px;
margin-left: 8px;
`;
const StyledContacts = styled.span`
word-break: break-all;
span {
word-break: keep-all;
}
`;
const StyledOthers = styled.span<{ isDarkTheme: boolean }>`
color: ${props => (props.isDarkTheme ? 'var(--primary-color)' : 'var(--text-primary-color)')};
`;
const generateContactsString = ( const generateContactsString = (
senders: Array<string> senders: Array<string>
): { contacts: Array<string>; numberOfReactors: number; hasMe: boolean } => { ): { contacts: Array<string>; numberOfReactors: number; hasMe: boolean } => {
@ -90,70 +71,59 @@ const generateContactsString = (
return { contacts, hasMe, numberOfReactors }; return { contacts, hasMe, numberOfReactors };
}; };
const generateReactionString = ( const getI18nComponent = (
isYou: boolean, isYou: boolean,
contacts: Array<string>, contacts: Array<string>,
numberOfReactors: number numberOfReactors: number,
emoji: string
) => { ) => {
const name = contacts[0]; const name = contacts[0];
const other_name = contacts[1]; const other_name = contacts[1];
switch (numberOfReactors) { switch (numberOfReactors) {
case 1: case 1:
return isYou return isYou ? (
? window.i18n('emojiReactsHoverYou') <I18n token="emojiReactsHoverYouDesktop" endTagProps={{ emoji }} />
: window.i18n('emojiReactsHoverName', { name }); ) : (
<I18n token="emojiReactsHoverNameDesktop" args={{ name }} endTagProps={{ emoji }} />
);
case 2: case 2:
return isYou return isYou ? (
? window.i18n('emojiReactsHoverYouName', { name }) <I18n token="emojiReactsHoverYouNameDesktop" args={{ name }} endTagProps={{ emoji }} />
: window.i18n('emojiReactsHoverTwoName', { name, other_name }); ) : (
<I18n
token="emojiReactsHoverTwoNameDesktop"
args={{ name, other_name }}
endTagProps={{ emoji }}
/>
);
case 3: case 3:
return isYou return isYou ? (
? window.i18n('emojiReactsHoverYouNameOne', { name }) <I18n token="emojiReactsHoverYouNameOneDesktop" args={{ name }} endTagProps={{ emoji }} />
: window.i18n('emojiReactsHoverTwoNameOne', { name, other_name }); ) : (
<I18n
token="emojiReactsHoverTwoNameOneDesktop"
args={{ name, other_name }}
endTagProps={{ emoji }}
/>
);
default: default:
return isYou return isYou ? (
? window.i18n('emojiReactsHoverYouNameMultiple', { <I18n
name, token="emojiReactsHoverYouNameMultipleDesktop"
count: numberOfReactors - 2, args={{ name, count: numberOfReactors - 2 }}
}) endTagProps={{ emoji }}
: window.i18n('emojiReactsHoverTwoNameMultiple', { />
name, ) : (
other_name, <I18n
count: numberOfReactors - 2, token="emojiReactsHoverTwoNameMultipleDesktop"
}); args={{ name, other_name, count: numberOfReactors - 2 }}
endTagProps={{ emoji }}
/>
);
} }
}; };
const Contacts = (contacts: Array<string>, count: number) => {
const isDarkTheme = useIsDarkTheme();
const isYou = contacts[0] === window.i18n('you');
const reactionPopupKey = useMemo(
() => reactionKey(isYou, contacts.length),
[isYou, contacts.length]
);
return (
<StyledContacts>
{window.i18n(reactionPopupKey, {
name: contacts[0],
other_name: contacts[1],
count: contacts.length,
emoji: '',
})}{' '}
{contacts.length > 3 ? (
<StyledOthers darkMode={darkMode}>
{window.i18n(contacts.length === 4 ? 'otherSingular' : 'otherPlural', {
number: `${count - 3}`,
})}
</StyledOthers>
) : null}
<span>{window.i18n('reactionPopup')}</span>
</StyledContacts>
);
};
type Props = { type Props = {
messageId: string; messageId: string;
emoji: string; emoji: string;
@ -163,26 +133,22 @@ type Props = {
onClick: (...args: Array<any>) => void; onClick: (...args: Array<any>) => void;
}; };
export const ReactionPopup = (props: Props): ReactElement => { export const ReactionPopup = (props: Props) => {
const { emoji, count, senders, tooltipPosition = 'center', onClick } = props; const { emoji, senders, tooltipPosition = 'center', onClick } = props;
const darkMode = useSelector(isDarkTheme);
const { contacts, hasMe, numberOfReactors } = useMemo( const { contacts, hasMe, numberOfReactors } = useMemo(
() => generateContactsString(senders), () => generateContactsString(senders),
[senders] [senders]
); );
const reactionString = useMemo( const content = useMemo(
() => generateReactionString(hasMe, contacts, numberOfReactors), () => getI18nComponent(hasMe, contacts, numberOfReactors, emoji),
[hasMe, contacts.length, numberOfReactors] [hasMe, contacts, numberOfReactors]
); );
return ( return (
<StyledPopupContainer tooltipPosition={tooltipPosition} onClick={onClick}> <StyledPopupContainer tooltipPosition={tooltipPosition} onClick={onClick}>
{contacts.length ? <StyledContacts>{Contacts(contacts, count)}</StyledContacts> : null} {content}
<StyledEmoji role={'img'} aria-label={nativeEmojiData?.ariaLabels?.[emoji]}>
{emoji}
</StyledEmoji>
</StyledPopupContainer> </StyledPopupContainer>
); );
}; };

Loading…
Cancel
Save