Indicate when reaction is from the current user

This commit is contained in:
Ken Powers 2020-01-29 13:58:50 -08:00 committed by GitHub
parent c2d1979c1e
commit 7461250caf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 105 additions and 28 deletions

View file

@ -2155,6 +2155,16 @@
}, },
"Reactions--error": { "Reactions--error": {
"message": "Failed to send reaction. Please try again.", "message": "Failed to send reaction. Please try again.",
"description": "Shown when a reaction fails to send." "description": "Shown when a reaction fails to send"
},
"ContactName--you": {
"message": "$name$ (you)",
"descriptions": "Indicates that a name represents the current user",
"placeholders": {
"name": {
"content": "$1",
"example": "Captain Jack Sparrow"
}
}
} }
} }

View file

@ -4933,7 +4933,8 @@ button.module-image__border-overlay:focus {
min-width: 32px; min-width: 32px;
} }
&__name { &__name,
&__name_profile-name {
@include font-body-1-bold(); @include font-body-1-bold();
margin-left: 8px; margin-left: 8px;
white-space: nowrap; white-space: nowrap;

View file

@ -14,10 +14,12 @@ interface Props {
export class Intl extends React.Component<Props> { export class Intl extends React.Component<Props> {
public static defaultProps: Partial<Props> = { public static defaultProps: Partial<Props> = {
renderText: ({ text }) => text, renderText: ({ text, key }) => (
<React.Fragment key={key}>{text}</React.Fragment>
),
}; };
public getComponent(index: number): FullJSX | undefined { public getComponent(index: number, key: number): FullJSX | undefined {
const { id, components } = this.props; const { id, components } = this.props;
if (!components || !components.length || components.length <= index) { if (!components || !components.length || components.length <= index) {
@ -29,7 +31,7 @@ export class Intl extends React.Component<Props> {
return; return;
} }
return components[index]; return <React.Fragment key={key}>{components[index]}</React.Fragment>;
} }
public render() { public render() {
@ -61,8 +63,9 @@ export class Intl extends React.Component<Props> {
key += 1; key += 1;
} }
results.push(this.getComponent(componentIndex)); results.push(this.getComponent(componentIndex, key));
componentIndex += 1; componentIndex += 1;
key += 1;
// @ts-ignore // @ts-ignore
lastTextIndex = FIND_REPLACEMENTS.lastIndex; lastTextIndex = FIND_REPLACEMENTS.lastIndex;

View file

@ -1,17 +1,21 @@
import React from 'react'; import React from 'react';
import { Emojify } from './Emojify'; import { Emojify } from './Emojify';
import { Intl } from '../Intl';
import { LocalizerType } from '../../types/util';
interface Props { interface Props {
phoneNumber: string; phoneNumber?: string;
name?: string; name?: string;
profileName?: string; profileName?: string;
module?: string; module?: string;
isMe?: boolean;
i18n?: LocalizerType;
} }
export class ContactName extends React.Component<Props> { export class ContactName extends React.Component<Props> {
public render() { public render() {
const { phoneNumber, name, profileName, module } = this.props; const { phoneNumber, name, profileName, module, isMe, i18n } = this.props;
const prefix = module ? module : 'module-contact-name'; const prefix = module ? module : 'module-contact-name';
const title = name ? name : phoneNumber; const title = name ? name : phoneNumber;
@ -22,11 +26,21 @@ export class ContactName extends React.Component<Props> {
</span> </span>
) : null; ) : null;
return ( const fragment = (
<span className={prefix} dir="auto"> <>
<Emojify text={title} /> <Emojify text={title} />
{shouldShowProfile ? ' ' : null} {shouldShowProfile ? ' ' : null}
{profileElement} {profileElement}
</>
);
return (
<span className={prefix} dir="auto">
{isMe ? (
<Intl i18n={i18n} id="ContactName--you" components={[fragment]} />
) : (
fragment
)}
</span> </span>
); );
} }

View file

@ -7,8 +7,18 @@
<ReactionViewer <ReactionViewer
i18n={util.i18n} i18n={util.i18n}
reactions={[ reactions={[
{ emoji: '❤️', from: { id: '+14155552671', name: 'Amelia Briggs' } }, {
{ emoji: '👍', from: { id: '+14155552671', name: 'Joel Ferrari' } }, emoji: '❤️',
from: { id: '+14155552671', name: 'Amelia Briggs', isMe: true },
},
{
emoji: '👍',
from: {
id: '+14155552671',
phoneNumber: '+14155552671',
profileName: 'Joel Ferrari',
},
},
]} ]}
/> />
</util.ConversationContext> </util.ConversationContext>
@ -24,7 +34,11 @@
{ {
emoji: '❤️', emoji: '❤️',
timestamp: 1, timestamp: 1,
from: { id: '+14155552671', name: 'Ameila Briggs' }, from: {
id: '+14155552671',
phoneNumber: '+14155552671',
profileName: 'Ameila Briggs',
},
}, },
{ {
emoji: '❤️', emoji: '❤️',
@ -59,12 +73,16 @@
{ {
emoji: '❤️', emoji: '❤️',
timestamp: 7, timestamp: 7,
from: { id: '+14155552678', name: 'Adam Burrel' }, from: {
id: '+14155552678',
phoneNumber: '+14155552678',
profileName: 'Adam Burrel',
},
}, },
{ {
emoji: '❤️', emoji: '❤️',
timestamp: 8, timestamp: 8,
from: { id: '+14155552679', name: 'Rick Owens' }, from: { id: '+14155552679', name: 'Rick Owens', isMe: true },
}, },
{ {
emoji: '👍', emoji: '👍',
@ -112,6 +130,23 @@
emoji: '❤️', emoji: '❤️',
from: { id: '+14155552671', name: 'Foo McBarringtonMcBazzingtonMcKay' }, from: { id: '+14155552671', name: 'Foo McBarringtonMcBazzingtonMcKay' },
}, },
{
emoji: '❤️',
from: {
id: '+14155552671',
name: 'Foo McBarringtonMcBazzingtonMcKay',
isMe: true,
},
},
{
emoji: '❤️',
from: {
id: '+14155552671',
phoneNumber: '+14155552671',
profileName: 'Foo McBarringtonMcBazzingtonMcKay',
isMe: true,
},
},
]} ]}
/> />
</util.ConversationContext> </util.ConversationContext>

View file

@ -1,6 +1,7 @@
import * as React from 'react'; import * as React from 'react';
import { groupBy, mapValues, orderBy, sortBy } from 'lodash'; import { groupBy, mapValues, orderBy, sortBy } from 'lodash';
import classNames from 'classnames'; import classNames from 'classnames';
import { ContactName } from './ContactName';
import { Avatar, Props as AvatarProps } from '../Avatar'; import { Avatar, Props as AvatarProps } from '../Avatar';
import { Emoji } from '../emoji/Emoji'; import { Emoji } from '../emoji/Emoji';
import { useRestoreFocus } from '../hooks'; import { useRestoreFocus } from '../hooks';
@ -11,10 +12,11 @@ export type Reaction = {
from: { from: {
id: string; id: string;
color?: string; color?: string;
profileName?: string;
name?: string;
isMe?: boolean;
avatarPath?: string; avatarPath?: string;
name?: string;
profileName?: string;
isMe?: boolean;
phoneNumber?: string;
}; };
}; };
@ -63,10 +65,14 @@ export const ReactionViewer = React.forwardRef<HTMLDivElement, Props>(
const emojiSet = new Set<string>(); const emojiSet = new Set<string>();
reactions.forEach(re => emojiSet.add(re.emoji)); reactions.forEach(re => emojiSet.add(re.emoji));
return sortBy( return sortBy(Array.from(emojiSet), emoji => {
Array.from(emojiSet), const idx = emojisOrder.indexOf(emoji);
emoji => emojisOrder.indexOf(emoji) || Infinity if (idx > -1) {
); return idx;
}
return Infinity;
});
}, [reactions]); }, [reactions]);
// If we have previously selected a reaction type that is no longer present // If we have previously selected a reaction type that is no longer present
@ -119,22 +125,30 @@ export const ReactionViewer = React.forwardRef<HTMLDivElement, Props>(
})} })}
</header> </header>
<main className="module-reaction-viewer__body"> <main className="module-reaction-viewer__body">
{selectedReactions.map(re => ( {selectedReactions.map(({ from, emoji }) => (
<div <div
key={`${re.from.id}-${re.emoji}`} key={`${from.id}-${emoji}`}
className="module-reaction-viewer__body__row" className="module-reaction-viewer__body__row"
> >
<div className="module-reaction-viewer__body__row__avatar"> <div className="module-reaction-viewer__body__row__avatar">
<Avatar <Avatar
avatarPath={re.from.avatarPath} avatarPath={from.avatarPath}
conversationType="direct" conversationType="direct"
size={32} size={32}
name={from.name}
profileName={from.profileName}
phoneNumber={from.phoneNumber}
i18n={i18n} i18n={i18n}
/> />
</div> </div>
<span className="module-reaction-viewer__body__row__name"> <ContactName
{re.from.name || re.from.profileName} module="module-reaction-viewer__body__row__name"
</span> i18n={i18n}
name={from.name}
profileName={from.profileName}
phoneNumber={from.phoneNumber}
isMe={from.isMe}
/>
</div> </div>
))} ))}
</main> </main>