Indicate when reaction is from the current user
This commit is contained in:
parent
c2d1979c1e
commit
7461250caf
6 changed files with 105 additions and 28 deletions
|
@ -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"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue