Show badges on message avatars where applicable

This commit is contained in:
Evan Hahn 2021-11-15 16:53:42 -06:00 committed by GitHub
parent fbd7292663
commit 7d17158add
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 90 additions and 9 deletions

View file

@ -31,6 +31,8 @@ import { getDefaultConversation } from '../../test-both/helpers/getDefaultConver
import { WidthBreakpoint } from '../_util'; import { WidthBreakpoint } from '../_util';
import { fakeAttachment } from '../../test-both/helpers/fakeAttachment'; import { fakeAttachment } from '../../test-both/helpers/fakeAttachment';
import { getFakeBadge } from '../../test-both/helpers/getFakeBadge';
import { ThemeType } from '../../types/Util';
const i18n = setupI18n('en', enMessages); const i18n = setupI18n('en', enMessages);
@ -95,6 +97,7 @@ const renderAudioAttachment: Props['renderAudioAttachment'] = props => (
const createProps = (overrideProps: Partial<Props> = {}): Props => ({ const createProps = (overrideProps: Partial<Props> = {}): Props => ({
attachments: overrideProps.attachments, attachments: overrideProps.attachments,
author: overrideProps.author || getDefaultConversation(), author: overrideProps.author || getDefaultConversation(),
authorBadge: overrideProps.authorBadge,
reducedMotion: boolean('reducedMotion', false), reducedMotion: boolean('reducedMotion', false),
bodyRanges: overrideProps.bodyRanges, bodyRanges: overrideProps.bodyRanges,
canReply: true, canReply: true,
@ -176,6 +179,7 @@ const createProps = (overrideProps: Partial<Props> = {}): Props => ({
status: overrideProps.status || 'sent', status: overrideProps.status || 'sent',
text: overrideProps.text || text('text', ''), text: overrideProps.text || text('text', ''),
textPending: boolean('textPending', overrideProps.textPending || false), textPending: boolean('textPending', overrideProps.textPending || false),
theme: ThemeType.light,
timestamp: number('timestamp', overrideProps.timestamp || Date.now()), timestamp: number('timestamp', overrideProps.timestamp || Date.now()),
}); });
@ -538,6 +542,17 @@ story.add('Avatar in Group', () => {
return <Message {...props} />; return <Message {...props} />;
}); });
story.add('Badge in Group', () => {
const props = createProps({
authorBadge: getFakeBadge(),
conversationType: 'group',
status: 'sent',
text: 'Hello it is me, the saxophone.',
});
return <Message {...props} />;
});
story.add('Sticker', () => { story.add('Sticker', () => {
const props = createProps({ const props = createProps({
attachments: [ attachments: [

View file

@ -62,6 +62,7 @@ import type {
LocalizerType, LocalizerType,
ThemeType, ThemeType,
} from '../../types/Util'; } from '../../types/Util';
import type { BadgeType } from '../../badges/types';
import type { import type {
ContactNameColorType, ContactNameColorType,
ConversationColorType, ConversationColorType,
@ -145,6 +146,7 @@ export type PropsData = {
ConversationType, ConversationType,
| 'acceptedMessageRequest' | 'acceptedMessageRequest'
| 'avatarPath' | 'avatarPath'
| 'badges'
| 'color' | 'color'
| 'id' | 'id'
| 'isMe' | 'isMe'
@ -155,6 +157,7 @@ export type PropsData = {
| 'title' | 'title'
| 'unblurredAvatarPath' | 'unblurredAvatarPath'
>; >;
authorBadge: undefined | BadgeType;
reducedMotion?: boolean; reducedMotion?: boolean;
conversationType: ConversationTypeType; conversationType: ConversationTypeType;
attachments?: Array<AttachmentType>; attachments?: Array<AttachmentType>;
@ -203,7 +206,7 @@ export type PropsHousekeeping = {
containerWidthBreakpoint: WidthBreakpoint; containerWidthBreakpoint: WidthBreakpoint;
i18n: LocalizerType; i18n: LocalizerType;
interactionMode: InteractionModeType; interactionMode: InteractionModeType;
theme?: ThemeType; theme: ThemeType;
disableMenu?: boolean; disableMenu?: boolean;
disableScroll?: boolean; disableScroll?: boolean;
collapseMetadata?: boolean; collapseMetadata?: boolean;
@ -1188,7 +1191,7 @@ export class Message extends React.PureComponent<Props, State> {
} }
public renderAvatar(): JSX.Element | undefined { public renderAvatar(): JSX.Element | undefined {
const { author, i18n, showContactModal } = this.props; const { author, authorBadge, i18n, showContactModal, theme } = this.props;
if (!this.hasAvatar()) { if (!this.hasAvatar()) {
return undefined; return undefined;
@ -1204,6 +1207,7 @@ export class Message extends React.PureComponent<Props, State> {
<Avatar <Avatar
acceptedMessageRequest={author.acceptedMessageRequest} acceptedMessageRequest={author.acceptedMessageRequest}
avatarPath={author.avatarPath} avatarPath={author.avatarPath}
badge={authorBadge}
color={author.color} color={author.color}
conversationType="direct" conversationType="direct"
i18n={i18n} i18n={i18n}
@ -1219,6 +1223,7 @@ export class Message extends React.PureComponent<Props, State> {
profileName={author.profileName} profileName={author.profileName}
sharedGroupNames={author.sharedGroupNames} sharedGroupNames={author.sharedGroupNames}
size={28} size={28}
theme={theme}
title={author.title} title={author.title}
unblurredAvatarPath={author.unblurredAvatarPath} unblurredAvatarPath={author.unblurredAvatarPath}
/> />

View file

@ -15,6 +15,8 @@ import { ReadStatus } from '../../messages/MessageReadStatus';
import { getDefaultConversation } from '../../test-both/helpers/getDefaultConversation'; import { getDefaultConversation } from '../../test-both/helpers/getDefaultConversation';
import { setupI18n } from '../../util/setupI18n'; import { setupI18n } from '../../util/setupI18n';
import enMessages from '../../../_locales/en/messages.json'; import enMessages from '../../../_locales/en/messages.json';
import { getFakeBadge } from '../../test-both/helpers/getFakeBadge';
import { ThemeType } from '../../types/Util';
const i18n = setupI18n('en', enMessages); const i18n = setupI18n('en', enMessages);
@ -25,6 +27,7 @@ const defaultMessage: MessageDataPropsType = {
id: 'some-id', id: 'some-id',
title: 'Max', title: 'Max',
}), }),
authorBadge: getFakeBadge(),
canReply: true, canReply: true,
canDeleteForEveryone: true, canDeleteForEveryone: true,
canDownload: true, canDownload: true,
@ -61,6 +64,7 @@ const createProps = (overrideProps: Partial<Props> = {}): Props => ({
i18n, i18n,
interactionMode: 'keyboard', interactionMode: 'keyboard',
theme: ThemeType.light,
showSafetyNumber: action('showSafetyNumber'), showSafetyNumber: action('showSafetyNumber'),

View file

@ -14,7 +14,7 @@ import type {
PropsData as MessagePropsDataType, PropsData as MessagePropsDataType,
} from './Message'; } from './Message';
import { Message } from './Message'; import { Message } from './Message';
import type { LocalizerType } from '../../types/Util'; import type { LocalizerType, ThemeType } from '../../types/Util';
import type { ConversationType } from '../../state/ducks/conversations'; import type { ConversationType } from '../../state/ducks/conversations';
import { groupBy } from '../../util/mapUtil'; import { groupBy } from '../../util/mapUtil';
import type { ContactNameColorType } from '../../types/Colors'; import type { ContactNameColorType } from '../../types/Colors';
@ -60,6 +60,7 @@ export type PropsData = {
showSafetyNumber: (contactId: string) => void; showSafetyNumber: (contactId: string) => void;
i18n: LocalizerType; i18n: LocalizerType;
theme: ThemeType;
} & Pick<MessagePropsType, 'interactionMode'>; } & Pick<MessagePropsType, 'interactionMode'>;
export type PropsBackboneActions = Pick< export type PropsBackboneActions = Pick<
@ -288,6 +289,7 @@ export class MessageDetail extends React.Component<Props> {
showExpiredOutgoingTapToViewToast, showExpiredOutgoingTapToViewToast,
showForwardMessageModal, showForwardMessageModal,
showVisualAttachment, showVisualAttachment,
theme,
} = this.props; } = this.props;
return ( return (
@ -350,6 +352,7 @@ export class MessageDetail extends React.Component<Props> {
log.warn('MessageDetail: deleteMessageForEveryone called!'); log.warn('MessageDetail: deleteMessageForEveryone called!');
}} }}
showVisualAttachment={showVisualAttachment} showVisualAttachment={showVisualAttachment}
theme={theme}
/> />
</div> </div>
<table className="module-message-detail__info"> <table className="module-message-detail__info">

View file

@ -26,6 +26,7 @@ import { setupI18n } from '../../util/setupI18n';
import enMessages from '../../../_locales/en/messages.json'; import enMessages from '../../../_locales/en/messages.json';
import { getDefaultConversation } from '../../test-both/helpers/getDefaultConversation'; import { getDefaultConversation } from '../../test-both/helpers/getDefaultConversation';
import { WidthBreakpoint } from '../_util'; import { WidthBreakpoint } from '../_util';
import { ThemeType } from '../../types/Util';
const i18n = setupI18n('en', enMessages); const i18n = setupI18n('en', enMessages);
@ -36,6 +37,7 @@ const defaultMessageProps: MessagesProps = {
id: 'some-id', id: 'some-id',
title: 'Person X', title: 'Person X',
}), }),
authorBadge: undefined,
canReply: true, canReply: true,
canDeleteForEveryone: true, canDeleteForEveryone: true,
canDownload: true, canDownload: true,
@ -90,6 +92,7 @@ const defaultMessageProps: MessagesProps = {
showVisualAttachment: action('default--showVisualAttachment'), showVisualAttachment: action('default--showVisualAttachment'),
status: 'sent', status: 'sent',
text: 'This is really interesting.', text: 'This is really interesting.',
theme: ThemeType.light,
timestamp: Date.now(), timestamp: Date.now(),
}; };

View file

@ -47,6 +47,7 @@ const items: Record<string, TimelineItemType> = {
author: getDefaultConversation({ author: getDefaultConversation({
phoneNumber: '(202) 555-2001', phoneNumber: '(202) 555-2001',
}), }),
authorBadge: undefined,
canDeleteForEveryone: false, canDeleteForEveryone: false,
canDownload: true, canDownload: true,
canReply: true, canReply: true,
@ -67,6 +68,7 @@ const items: Record<string, TimelineItemType> = {
type: 'message', type: 'message',
data: { data: {
author: getDefaultConversation({}), author: getDefaultConversation({}),
authorBadge: undefined,
canDeleteForEveryone: false, canDeleteForEveryone: false,
canDownload: true, canDownload: true,
canReply: true, canReply: true,
@ -100,6 +102,7 @@ const items: Record<string, TimelineItemType> = {
type: 'message', type: 'message',
data: { data: {
author: getDefaultConversation({}), author: getDefaultConversation({}),
authorBadge: undefined,
canDeleteForEveryone: false, canDeleteForEveryone: false,
canDownload: true, canDownload: true,
canReply: true, canReply: true,
@ -189,6 +192,7 @@ const items: Record<string, TimelineItemType> = {
type: 'message', type: 'message',
data: { data: {
author: getDefaultConversation({}), author: getDefaultConversation({}),
authorBadge: undefined,
canDeleteForEveryone: false, canDeleteForEveryone: false,
canDownload: true, canDownload: true,
canReply: true, canReply: true,
@ -210,6 +214,7 @@ const items: Record<string, TimelineItemType> = {
type: 'message', type: 'message',
data: { data: {
author: getDefaultConversation({}), author: getDefaultConversation({}),
authorBadge: undefined,
canDeleteForEveryone: false, canDeleteForEveryone: false,
canDownload: true, canDownload: true,
canReply: true, canReply: true,
@ -231,6 +236,7 @@ const items: Record<string, TimelineItemType> = {
type: 'message', type: 'message',
data: { data: {
author: getDefaultConversation({}), author: getDefaultConversation({}),
authorBadge: undefined,
canDeleteForEveryone: false, canDeleteForEveryone: false,
canDownload: true, canDownload: true,
canReply: true, canReply: true,
@ -252,6 +258,7 @@ const items: Record<string, TimelineItemType> = {
type: 'message', type: 'message',
data: { data: {
author: getDefaultConversation({}), author: getDefaultConversation({}),
authorBadge: undefined,
canDeleteForEveryone: false, canDeleteForEveryone: false,
canDownload: true, canDownload: true,
canReply: true, canReply: true,
@ -273,6 +280,7 @@ const items: Record<string, TimelineItemType> = {
type: 'message', type: 'message',
data: { data: {
author: getDefaultConversation({}), author: getDefaultConversation({}),
authorBadge: undefined,
canDeleteForEveryone: false, canDeleteForEveryone: false,
canDownload: true, canDownload: true,
canReply: true, canReply: true,
@ -390,6 +398,7 @@ const renderItem = ({
nextItem={undefined} nextItem={undefined}
i18n={i18n} i18n={i18n}
interactionMode="keyboard" interactionMode="keyboard"
theme={ThemeType.light}
containerElementRef={containerElementRef} containerElementRef={containerElementRef}
containerWidthBreakpoint={containerWidthBreakpoint} containerWidthBreakpoint={containerWidthBreakpoint}
conversationId="" conversationId=""

View file

@ -16,6 +16,7 @@ import { CallMode } from '../../types/Calling';
import { AvatarColors } from '../../types/Colors'; import { AvatarColors } from '../../types/Colors';
import { getDefaultConversation } from '../../test-both/helpers/getDefaultConversation'; import { getDefaultConversation } from '../../test-both/helpers/getDefaultConversation';
import { WidthBreakpoint } from '../_util'; import { WidthBreakpoint } from '../_util';
import { ThemeType } from '../../types/Util';
const i18n = setupI18n('en', enMessages); const i18n = setupI18n('en', enMessages);
@ -53,6 +54,7 @@ const getDefaultProps = () => ({
id: 'asdf', id: 'asdf',
isSelected: false, isSelected: false,
interactionMode: 'keyboard' as const, interactionMode: 'keyboard' as const,
theme: ThemeType.light,
selectMessage: action('selectMessage'), selectMessage: action('selectMessage'),
reactToMessage: action('reactToMessage'), reactToMessage: action('reactToMessage'),
checkForAccount: action('checkForAccount'), checkForAccount: action('checkForAccount'),

View file

@ -148,7 +148,7 @@ type PropsLocalType = {
renderUniversalTimerNotification: () => JSX.Element; renderUniversalTimerNotification: () => JSX.Element;
i18n: LocalizerType; i18n: LocalizerType;
interactionMode: InteractionModeType; interactionMode: InteractionModeType;
theme?: ThemeType; theme: ThemeType;
previousItem: undefined | TimelineItemType; previousItem: undefined | TimelineItemType;
nextItem: undefined | TimelineItemType; nextItem: undefined | TimelineItemType;
}; };

View file

@ -134,6 +134,8 @@ import type { LinkPreviewType } from '../types/message/LinkPreviews';
import * as log from '../logging/log'; import * as log from '../logging/log';
import * as Bytes from '../Bytes'; import * as Bytes from '../Bytes';
import { computeHash } from '../Crypto'; import { computeHash } from '../Crypto';
import type { PreferredBadgeSelectorType } from '../state/selectors/badges';
import { getPreferredBadgeSelector } from '../state/selectors/badges';
/* eslint-disable camelcase */ /* eslint-disable camelcase */
/* eslint-disable more/no-then */ /* eslint-disable more/no-then */
@ -392,6 +394,13 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
ourConversationId, ourConversationId,
ourNumber: window.textsecure.storage.user.getNumber(), ourNumber: window.textsecure.storage.user.getNumber(),
ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(), ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(),
preferredBadgeSelector: (
...args: Parameters<PreferredBadgeSelectorType>
) => {
const state = window.reduxStore.getState();
const preferredBadgeSelector = getPreferredBadgeSelector(state);
return preferredBadgeSelector(...args);
},
regionCode: window.storage.get('regionCode', 'ZZ'), regionCode: window.storage.get('regionCode', 'ZZ'),
accountSelector: (identifier?: string) => { accountSelector: (identifier?: string) => {
const state = window.reduxStore.getState(); const state = window.reduxStore.getState();

View file

@ -51,12 +51,14 @@ export const getBadgesSelector = createSelector(
} }
); );
export type PreferredBadgeSelectorType = (
conversationBadges: ReadonlyArray<Pick<BadgeType, 'id'>>
) => undefined | BadgeType;
export const getPreferredBadgeSelector = createSelector( export const getPreferredBadgeSelector = createSelector(
getBadgesById, getBadgesById,
badgesById => (badgesById): PreferredBadgeSelectorType =>
( conversationBadges => {
conversationBadges: ReadonlyArray<Pick<BadgeType, 'id'>>
): undefined | BadgeType => {
const firstId: undefined | string = conversationBadges[0]?.id; const firstId: undefined | string = conversationBadges[0]?.id;
if (!firstId) { if (!firstId) {
return undefined; return undefined;

View file

@ -49,6 +49,8 @@ import { getPinnedConversationIds } from './items';
import { getPropsForBubble } from './message'; import { getPropsForBubble } from './message';
import type { CallSelectorType, CallStateType } from './calling'; import type { CallSelectorType, CallStateType } from './calling';
import { getActiveCall, getCallSelector } from './calling'; import { getActiveCall, getCallSelector } from './calling';
import type { PreferredBadgeSelectorType } from './badges';
import { getPreferredBadgeSelector } from './badges';
import type { AccountSelectorType } from './accounts'; import type { AccountSelectorType } from './accounts';
import { getAccountSelector } from './accounts'; import { getAccountSelector } from './accounts';
import * as log from '../../logging/log'; import * as log from '../../logging/log';
@ -793,6 +795,7 @@ export const getMessageSelector = createSelector(
getMessages, getMessages,
getSelectedMessage, getSelectedMessage,
getConversationSelector, getConversationSelector,
getPreferredBadgeSelector,
getRegionCode, getRegionCode,
getUserNumber, getUserNumber,
getUserUuid, getUserUuid,
@ -806,6 +809,7 @@ export const getMessageSelector = createSelector(
messageLookup: MessageLookupType, messageLookup: MessageLookupType,
selectedMessage: SelectedMessageType | undefined, selectedMessage: SelectedMessageType | undefined,
conversationSelector: GetConversationByIdType, conversationSelector: GetConversationByIdType,
preferredBadgeSelector: PreferredBadgeSelectorType,
regionCode: string, regionCode: string,
ourNumber: string, ourNumber: string,
ourUuid: UUIDStringType, ourUuid: UUIDStringType,
@ -826,6 +830,7 @@ export const getMessageSelector = createSelector(
ourConversationId, ourConversationId,
ourNumber, ourNumber,
ourUuid, ourUuid,
preferredBadgeSelector,
regionCode, regionCode,
selectedMessageId: selectedMessage?.id, selectedMessageId: selectedMessage?.id,
selectedMessageCounter: selectedMessage?.counter, selectedMessageCounter: selectedMessage?.counter,

View file

@ -63,6 +63,7 @@ import type {
} from '../ducks/conversations'; } from '../ducks/conversations';
import type { AccountSelectorType } from './accounts'; import type { AccountSelectorType } from './accounts';
import type { PreferredBadgeSelectorType } from './badges';
import type { CallSelectorType, CallStateType } from './calling'; import type { CallSelectorType, CallStateType } from './calling';
import type { import type {
GetConversationByIdType, GetConversationByIdType,
@ -81,6 +82,7 @@ import {
someSendStatus, someSendStatus,
} from '../../messages/MessageSendState'; } from '../../messages/MessageSendState';
import * as log from '../../logging/log'; import * as log from '../../logging/log';
import type { BadgeType } from '../../badges/types';
const THREE_HOURS = 3 * 60 * 60 * 1000; const THREE_HOURS = 3 * 60 * 60 * 1000;
@ -106,6 +108,7 @@ export type GetPropsForBubbleOptions = Readonly<{
ourConversationId: string; ourConversationId: string;
ourNumber?: string; ourNumber?: string;
ourUuid: UUIDStringType; ourUuid: UUIDStringType;
preferredBadgeSelector: PreferredBadgeSelectorType;
selectedMessageId?: string; selectedMessageId?: string;
selectedMessageCounter?: number; selectedMessageCounter?: number;
regionCode: string; regionCode: string;
@ -307,6 +310,7 @@ const getAuthorForMessage = createSelectorCreator(memoizeByRoot)(
const { const {
acceptedMessageRequest, acceptedMessageRequest,
avatarPath, avatarPath,
badges,
color, color,
id, id,
isMe, isMe,
@ -321,6 +325,7 @@ const getAuthorForMessage = createSelectorCreator(memoizeByRoot)(
const unsafe = { const unsafe = {
acceptedMessageRequest, acceptedMessageRequest,
avatarPath, avatarPath,
badges,
color, color,
id, id,
isMe, isMe,
@ -345,6 +350,19 @@ const getCachedAuthorForMessage = createSelectorCreator(memoizeByRoot, isEqual)(
(_, author): PropsData['author'] => author (_, author): PropsData['author'] => author
); );
const getAuthorBadgeForMessage: (
message: MessageWithUIFieldsType,
options: {
preferredBadgeSelector: PreferredBadgeSelectorType;
}
) => undefined | BadgeType = createSelectorCreator(memoizeByRoot, isEqual)(
// `memoizeByRoot` requirement
identity,
(_, { preferredBadgeSelector }) => preferredBadgeSelector,
getAuthorForMessage,
(_, preferredBadgeSelector, author) => preferredBadgeSelector(author.badges)
);
export const getPreviewsForMessage = createSelectorCreator(memoizeByRoot)( export const getPreviewsForMessage = createSelectorCreator(memoizeByRoot)(
// `memoizeByRoot` requirement // `memoizeByRoot` requirement
identity, identity,
@ -496,6 +514,7 @@ export type GetPropsForMessageOptions = Pick<
| 'ourConversationId' | 'ourConversationId'
| 'ourUuid' | 'ourUuid'
| 'ourNumber' | 'ourNumber'
| 'preferredBadgeSelector'
| 'selectedMessageId' | 'selectedMessageId'
| 'selectedMessageCounter' | 'selectedMessageCounter'
| 'regionCode' | 'regionCode'
@ -637,6 +656,7 @@ export const getPropsForMessage: (
getAttachmentsForMessage, getAttachmentsForMessage,
processBodyRanges, processBodyRanges,
getCachedAuthorForMessage, getCachedAuthorForMessage,
getAuthorBadgeForMessage,
getPreviewsForMessage, getPreviewsForMessage,
getReactionsForMessage, getReactionsForMessage,
getPropsForQuote, getPropsForQuote,
@ -646,6 +666,7 @@ export const getPropsForMessage: (
attachments: Array<AttachmentType>, attachments: Array<AttachmentType>,
bodyRanges: BodyRangesType | undefined, bodyRanges: BodyRangesType | undefined,
author: PropsData['author'], author: PropsData['author'],
authorBadge: undefined | BadgeType,
previews: Array<LinkPreviewType>, previews: Array<LinkPreviewType>,
reactions: PropsData['reactions'], reactions: PropsData['reactions'],
quote: PropsData['quote'], quote: PropsData['quote'],
@ -654,6 +675,7 @@ export const getPropsForMessage: (
return { return {
attachments, attachments,
author, author,
authorBadge,
bodyRanges, bodyRanges,
previews, previews,
quote, quote,

View file

@ -8,7 +8,7 @@ import { MessageDetail } from '../../components/conversation/MessageDetail';
import { mapDispatchToProps } from '../actions'; import { mapDispatchToProps } from '../actions';
import type { StateType } from '../reducer'; import type { StateType } from '../reducer';
import { getIntl, getInteractionMode } from '../selectors/user'; import { getIntl, getInteractionMode, getTheme } from '../selectors/user';
import { renderAudioAttachment } from './renderAudioAttachment'; import { renderAudioAttachment } from './renderAudioAttachment';
import { renderEmojiPicker } from './renderEmojiPicker'; import { renderEmojiPicker } from './renderEmojiPicker';
import { renderReactionPicker } from './renderReactionPicker'; import { renderReactionPicker } from './renderReactionPicker';
@ -22,6 +22,7 @@ export type OwnProps = Omit<
| 'renderAudioAttachment' | 'renderAudioAttachment'
| 'renderEmojiPicker' | 'renderEmojiPicker'
| 'renderReactionPicker' | 'renderReactionPicker'
| 'theme'
>; >;
const mapStateToProps = ( const mapStateToProps = (
@ -72,6 +73,7 @@ const mapStateToProps = (
i18n: getIntl(state), i18n: getIntl(state),
interactionMode: getInteractionMode(state), interactionMode: getInteractionMode(state),
theme: getTheme(state),
showSafetyNumber, showSafetyNumber,