fix: show correct count value for open group reactions

pull/2445/head
William Grant 3 years ago
parent d77c9fa824
commit 05b7bdb956

@ -138,6 +138,7 @@ export const Reaction = (props: ReactionProps): ReactElement => {
<ReactionPopup <ReactionPopup
messageId={messageId} messageId={messageId}
emoji={popupReaction} emoji={popupReaction}
count={reactionsMap[popupReaction].count}
senders={reactionsMap[popupReaction].senders} senders={reactionsMap[popupReaction].senders}
tooltipPosition={tooltipPosition} tooltipPosition={tooltipPosition}
onClick={() => { onClick={() => {

@ -3,7 +3,7 @@ import styled from 'styled-components';
import { Data } from '../../../../data/data'; import { Data } from '../../../../data/data';
import { PubKey } from '../../../../session/types/PubKey'; import { PubKey } from '../../../../session/types/PubKey';
import { nativeEmojiData } from '../../../../util/emoji'; import { nativeEmojiData } from '../../../../util/emoji';
import { readableList } from '../../../../util/readableList'; import { defaultConjunction, defaultWordLimit, readableList } from '../../../../util/readableList';
export type TipPosition = 'center' | 'left' | 'right'; export type TipPosition = 'center' | 'left' | 'right';
@ -59,8 +59,12 @@ const StyledOthers = styled.span`
color: var(--color-accent); color: var(--color-accent);
`; `;
const generateContacts = async (messageId: string, senders: Array<string>) => { const generateContactsString = async (
let results = null; messageId: string,
senders: Array<string>,
count: number
): Promise<string | null> => {
let results = [];
const message = await Data.getMessageById(messageId); const message = await Data.getMessageById(messageId);
if (message) { if (message) {
let meIndex = -1; let meIndex = -1;
@ -75,8 +79,18 @@ const generateContacts = async (messageId: string, senders: Array<string>) => {
results.splice(meIndex, 1); results.splice(meIndex, 1);
results = [window.i18n('you'), ...results]; results = [window.i18n('you'), ...results];
} }
if (results && results.length > 0) {
let contacts = readableList(results);
// This can only happen in an opengroup
if (results.length !== count) {
const [names, others] = contacts.split(`${defaultConjunction} `);
const [_, suffix] = others.split(' '); // i.e. 3 others
contacts = `${names} ${defaultConjunction} ${count - defaultWordLimit} ${suffix}`;
}
return contacts;
} }
return results; }
return null;
}; };
const Contacts = (contacts: string) => { const Contacts = (contacts: string) => {
@ -84,8 +98,8 @@ const Contacts = (contacts: string) => {
return; return;
} }
if (contacts.includes('&') && contacts.includes('other')) { if (contacts.includes(defaultConjunction) && contacts.includes('other')) {
const [names, others] = contacts.split('&'); const [names, others] = contacts.split(defaultConjunction);
return ( return (
<span> <span>
{names} & <StyledOthers>{others}</StyledOthers> {window.i18n('reactionTooltip')} {names} & <StyledOthers>{others}</StyledOthers> {window.i18n('reactionTooltip')}
@ -95,7 +109,7 @@ const Contacts = (contacts: string) => {
return ( return (
<span> <span>
{contacts} {window.i18n('reactionTooltip')} {contacts.replace(defaultConjunction, '&')} {window.i18n('reactionTooltip')}
</span> </span>
); );
}; };
@ -103,25 +117,26 @@ const Contacts = (contacts: string) => {
type Props = { type Props = {
messageId: string; messageId: string;
emoji: string; emoji: string;
count: number;
senders: Array<string>; senders: Array<string>;
tooltipPosition?: TipPosition; tooltipPosition?: TipPosition;
onClick: (...args: Array<any>) => void; onClick: (...args: Array<any>) => void;
}; };
export const ReactionPopup = (props: Props): ReactElement => { export const ReactionPopup = (props: Props): ReactElement => {
const { messageId, emoji, senders, tooltipPosition = 'center', onClick } = props; const { messageId, emoji, count, senders, tooltipPosition = 'center', onClick } = props;
const [contacts, setContacts] = useState(''); const [contacts, setContacts] = useState('');
useEffect(() => { useEffect(() => {
let isCancelled = false; let isCancelled = false;
generateContacts(messageId, senders) generateContactsString(messageId, senders, count)
.then(async results => { .then(async results => {
if (isCancelled) { if (isCancelled) {
return; return;
} }
if (results && results.length > 0) { if (results) {
setContacts(readableList(results)); setContacts(results);
} }
}) })
.catch(() => { .catch(() => {
@ -133,7 +148,7 @@ export const ReactionPopup = (props: Props): ReactElement => {
return () => { return () => {
isCancelled = true; isCancelled = true;
}; };
}, [generateContacts]); }, [count, generateContactsString, messageId, senders]);
return ( return (
<StyledPopupContainer tooltipPosition={tooltipPosition} onClick={onClick}> <StyledPopupContainer tooltipPosition={tooltipPosition} onClick={onClick}>

@ -753,7 +753,6 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
if (this.id.startsWith('15')) { if (this.id.startsWith('15')) {
window.log.info('Sending a blinded message to this user: ', this.id); window.log.info('Sending a blinded message to this user: ', this.id);
// TODO confirm this works with Reacts
await this.sendBlindedMessageRequest(chatMessageParams); await this.sendBlindedMessageRequest(chatMessageParams);
return; return;
} }
@ -789,7 +788,6 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
const destinationPubkey = new PubKey(destination); const destinationPubkey = new PubKey(destination);
if (this.isPrivate()) { if (this.isPrivate()) {
// TODO is this still fine without isMe?
const chatMessageMe = new VisibleMessage({ const chatMessageMe = new VisibleMessage({
...chatMessageParams, ...chatMessageParams,
syncTarget: this.id, syncTarget: this.id,

@ -918,7 +918,7 @@ export const getMessageReactsProps = createSelector(getMessagePropsByMessageId,
]); ]);
if (msgProps.reacts) { if (msgProps.reacts) {
// TODO we don't want to render reactions that have 'senders' as an object this is a deprecated type used during development 25/08/2022 // NOTE we don't want to render reactions that have 'senders' as an object this is a deprecated type used during development 25/08/2022
const oldReactions = Object.values(msgProps.reacts).filter( const oldReactions = Object.values(msgProps.reacts).filter(
reaction => !Array.isArray(reaction.senders) reaction => !Array.isArray(reaction.senders)
); );

@ -1,7 +1,11 @@
// we need to use a character that cannot be used as a display name for string manipulation up until we render the UI
export const defaultConjunction = '\uFFD7';
export const defaultWordLimit = 3;
export const readableList = ( export const readableList = (
arr: Array<string>, arr: Array<string>,
conjunction: string = '&', conjunction: string = defaultConjunction,
limit: number = 3 wordLimit: number = defaultWordLimit
): string => { ): string => {
if (arr.length === 0) { if (arr.length === 0) {
return ''; return '';
@ -15,11 +19,11 @@ export const readableList = (
let result = ''; let result = '';
let others = 0; let others = 0;
for (let i = 0; i < count; i++) { for (let i = 0; i < count; i++) {
if (others === 0 && i === count - 1 && i < limit) { if (others === 0 && i === count - 1 && i < wordLimit) {
result += ` ${conjunction} `; result += ` ${conjunction} `;
} else if (i !== 0 && i < limit) { } else if (i !== 0 && i < wordLimit) {
result += ', '; result += ', ';
} else if (i >= limit) { } else if (i >= wordLimit) {
others++; others++;
} }

Loading…
Cancel
Save