From 3d47d7d0e8e3f26ad6515fc93f60f7e76d82f2a7 Mon Sep 17 00:00:00 2001 From: Audric Ackermann Date: Thu, 28 Jan 2021 10:52:16 +1100 Subject: [PATCH] remove EbeddedContact components --- js/models/conversations.js | 1 + js/modules/signal.js | 4 - js/modules/types/contact.js | 107 ++++++++++++++++++ js/modules/types/message.js | 8 ++ .../conversation/EmbeddedContact.tsx | 57 ---------- ts/components/conversation/Message.tsx | 31 ----- ts/components/conversation/TypingBubble.tsx | 1 - ts/components/conversation/_contactUtil.tsx | 88 -------------- ts/session/types/PubKey.ts | 9 +- 9 files changed, 123 insertions(+), 183 deletions(-) create mode 100644 js/modules/types/contact.js delete mode 100644 ts/components/conversation/EmbeddedContact.tsx delete mode 100644 ts/components/conversation/_contactUtil.tsx diff --git a/js/models/conversations.js b/js/models/conversations.js index 4f2f6b1c9..88011f182 100644 --- a/js/models/conversations.js +++ b/js/models/conversations.js @@ -375,6 +375,7 @@ unreadCount: this.get('unreadCount') || 0, mentionedUs: this.get('mentionedUs') || false, isBlocked: this.isBlocked(), + phoneNumber: this.id, lastMessage: { status: this.get('lastMessageStatus'), text: this.get('lastMessage'), diff --git a/js/modules/signal.js b/js/modules/signal.js index ee8ac7ccd..c73a5e8f6 100644 --- a/js/modules/signal.js +++ b/js/modules/signal.js @@ -16,9 +16,6 @@ const AttachmentDownloads = require('./attachment_downloads'); // Components const { ContactListItem } = require('../../ts/components/ContactListItem'); const { ContactName } = require('../../ts/components/conversation/ContactName'); -const { - EmbeddedContact, -} = require('../../ts/components/conversation/EmbeddedContact'); const { Emojify } = require('../../ts/components/conversation/Emojify'); const { Lightbox } = require('../../ts/components/Lightbox'); const { LightboxGallery } = require('../../ts/components/LightboxGallery'); @@ -212,7 +209,6 @@ exports.setup = (options = {}) => { const Components = { ContactListItem, ContactName, - EmbeddedContact, Emojify, Lightbox, LightboxGallery, diff --git a/js/modules/types/contact.js b/js/modules/types/contact.js new file mode 100644 index 000000000..1becc80aa --- /dev/null +++ b/js/modules/types/contact.js @@ -0,0 +1,107 @@ +const { omit, compact, map } = require('lodash'); + +const { toLogFormat } = require('./errors'); +const { SignalService } = require('../../../ts/protobuf'); +const { parse: parsePhoneNumber } = require('../../../ts/types/PhoneNumber'); + +const DEFAULT_PHONE_TYPE = SignalService.DataMessage.Contact.Phone.Type.HOME; + +exports.parseAndWriteAvatar = upgradeAttachment => async ( + contact, + context = {} +) => { + const { message, logger } = context; + const { avatar } = contact; + + // This is to ensure that an omit() call doesn't pull in prototype props/methods + const contactShallowCopy = Object.assign({}, contact); + + const contactWithUpdatedAvatar = + avatar && avatar.avatar + ? Object.assign({}, contactShallowCopy, { + avatar: Object.assign({}, avatar, { + avatar: await upgradeAttachment(avatar.avatar, context), + }), + }) + : omit(contactShallowCopy, ['avatar']); + + // eliminates empty numbers, emails, and addresses; adds type if not provided + const parsedContact = parseContact(contactWithUpdatedAvatar); + + const error = exports._validate(parsedContact, { + messageId: idForLogging(message), + }); + if (error) { + logger.error( + 'Contact.parseAndWriteAvatar: contact was malformed.', + toLogFormat(error) + ); + } + + return parsedContact; +}; + +function parseContact(contact) { + const boundParsePhone = phoneNumber => parsePhoneItem(phoneNumber); + + return Object.assign( + {}, + omit(contact, ['avatar', 'number', 'email', 'address']), + parseAvatar(contact.avatar), + createArrayKey('number', compact(map(contact.number, boundParsePhone))) + ); +} + +function idForLogging(message) { + return `${message.source}.${message.sourceDevice} ${message.sent_at}`; +} + +exports._validate = (contact, options = {}) => { + const { messageId } = options; + const { name, number, organization } = contact; + + if ((!name || !name.displayName) && !organization) { + return new Error( + `Message ${messageId}: Contact had neither 'displayName' nor 'organization'` + ); + } + + if (!number || !number.length) { + return new Error(`Message ${messageId}: Contact had no included numbers`); + } + + return null; +}; + +function parsePhoneItem(item) { + if (!item.value) { + return null; + } + + return Object.assign({}, item, { + type: item.type || DEFAULT_PHONE_TYPE, + value: parsePhoneNumber(item.value), + }); +} + +function parseAvatar(avatar) { + if (!avatar) { + return null; + } + + return { + avatar: Object.assign({}, avatar, { + isProfile: avatar.isProfile || false, + }), + }; +} + +function createArrayKey(key, array) { + if (!array || !array.length) { + return null; + } + + return { + [key]: array, + }; +} diff --git a/js/modules/types/message.js b/js/modules/types/message.js index 6f220405b..8080099d4 100644 --- a/js/modules/types/message.js +++ b/js/modules/types/message.js @@ -7,6 +7,7 @@ const { initializeAttachmentMetadata, } = require('../../../ts/types/message/initializeAttachmentMetadata'); const MessageTS = require('../../../ts/types/Message'); +const Contact = require('./contact'); const GROUP = 'group'; const PRIVATE = 'private'; @@ -282,6 +283,12 @@ const toVersion5 = exports._withSchemaVersion({ schemaVersion: 5, upgrade: initializeAttachmentMetadata, }); +const toVersion6 = exports._withSchemaVersion({ + schemaVersion: 6, + upgrade: exports._mapContact( + Contact.parseAndWriteAvatar(Attachment.migrateDataToFileSystem) + ), +}); // IMPORTANT: We’ve updated our definition of `initializeAttachmentMetadata`, so // we need to run it again on existing items that have previously been incorrectly // classified: @@ -311,6 +318,7 @@ const VERSIONS = [ toVersion3, toVersion4, toVersion5, + toVersion6, toVersion7, toVersion8, toVersion9, diff --git a/ts/components/conversation/EmbeddedContact.tsx b/ts/components/conversation/EmbeddedContact.tsx deleted file mode 100644 index 4537930b4..000000000 --- a/ts/components/conversation/EmbeddedContact.tsx +++ /dev/null @@ -1,57 +0,0 @@ -import React from 'react'; -import classNames from 'classnames'; - -import { Contact } from '../../types/Contact'; - -import { LocalizerType } from '../../types/Util'; -import { - renderAvatar, - renderContactShorthand, - renderName, -} from './_contactUtil'; - -interface Props { - contact: Contact; - i18n: LocalizerType; - isIncoming: boolean; - withContentAbove: boolean; - withContentBelow: boolean; - onClick?: () => void; -} - -export class EmbeddedContact extends React.Component { - public render() { - const { - contact, - i18n, - isIncoming, - onClick, - withContentAbove, - withContentBelow, - } = this.props; - const module = 'embedded-contact'; - const direction = isIncoming ? 'incoming' : 'outgoing'; - - return ( -
- {renderAvatar({ contact, i18n, size: 36, direction })} -
- {renderName({ contact, isIncoming, module })} - {renderContactShorthand({ contact, isIncoming, module })} -
-
- ); - } -} diff --git a/ts/components/conversation/Message.tsx b/ts/components/conversation/Message.tsx index 7e578c6be..f96a194e7 100644 --- a/ts/components/conversation/Message.tsx +++ b/ts/components/conversation/Message.tsx @@ -8,7 +8,6 @@ import { ImageGrid } from './ImageGrid'; import { Image } from './Image'; import { ContactName } from './ContactName'; import { Quote } from './Quote'; -import { EmbeddedContact } from './EmbeddedContact'; // Audio Player import H5AudioPlayer from 'react-h5-audio-player'; @@ -467,35 +466,6 @@ class MessageInner extends React.PureComponent { ); } - public renderEmbeddedContact() { - const { - collapseMetadata, - contact, - conversationType, - direction, - text, - } = this.props; - if (!contact) { - return null; - } - - const withCaption = Boolean(text); - const withContentAbove = - conversationType === 'group' && direction === 'incoming'; - const withContentBelow = withCaption || !collapseMetadata; - - return ( - - ); - } - public renderAvatar() { const { authorAvatarPath, @@ -906,7 +876,6 @@ class MessageInner extends React.PureComponent { {this.renderQuote()} {this.renderAttachment()} {this.renderPreview()} - {this.renderEmbeddedContact()} {this.renderText()} ` `; export const TypingBubble = (props: TypingBubbleProps) => { - if (props.conversationType === 'group') { return <>; } diff --git a/ts/components/conversation/_contactUtil.tsx b/ts/components/conversation/_contactUtil.tsx deleted file mode 100644 index 0fb6810b1..000000000 --- a/ts/components/conversation/_contactUtil.tsx +++ /dev/null @@ -1,88 +0,0 @@ -import React from 'react'; -import classNames from 'classnames'; - -import { Avatar } from '../Avatar'; -import { Spinner } from '../Spinner'; - -import { LocalizerType } from '../../types/Util'; -import { Contact, getName } from '../../types/Contact'; - -// This file starts with _ to keep it from showing up in the StyleGuide. - -export function renderAvatar({ - contact, - i18n, - size, - direction, -}: { - contact: Contact; - i18n: LocalizerType; - size: number; - direction?: string; -}) { - const { avatar } = contact; - - const avatarPath = avatar && avatar.avatar && avatar.avatar.path; - const pending = avatar && avatar.avatar && avatar.avatar.pending; - const name = getName(contact) || ''; - const spinnerSize = size < 50 ? 'small' : 'normal'; - - if (pending) { - return ( -
- -
- ); - } - - const pubkey = contact.name?.givenName || '0'; - return ( - - ); -} - -export function renderName({ - contact, - isIncoming, - module, -}: { - contact: Contact; - isIncoming: boolean; - module: string; -}) { - return ( -
- {getName(contact)} -
- ); -} - -export function renderContactShorthand({ - contact, - isIncoming, - module, -}: { - contact: Contact; - isIncoming: boolean; - module: string; -}) { - const { number: phoneNumber, email } = contact; - const firstNumber = phoneNumber && phoneNumber[0] && phoneNumber[0].value; - const firstEmail = email && email[0] && email[0].value; - - return ( -
- {firstNumber || firstEmail} -
- ); -} diff --git a/ts/session/types/PubKey.ts b/ts/session/types/PubKey.ts index 7e1e04a28..7d62c6c42 100644 --- a/ts/session/types/PubKey.ts +++ b/ts/session/types/PubKey.ts @@ -60,7 +60,9 @@ export class PubKey { const pk = value instanceof PubKey ? valAny.key : value; if (!pk) { - throw new Error('PubkKey.shorten was given an invalid PubKey to shorten.') + throw new Error( + 'PubkKey.shorten was given an invalid PubKey to shorten.' + ); } return `(...${pk.substring(pk.length - 6)})`; @@ -100,7 +102,10 @@ export class PubKey { /** * Returns a localized string of the error, or undefined in the given pubkey is valid. */ - public static validateWithError(pubkey: string, i18n: LocalizerType = window.i18n): string | undefined { + public static validateWithError( + pubkey: string, + i18n: LocalizerType = window.i18n + ): string | undefined { // Check if it's hex const isHex = pubkey.replace(/[\s]*/g, '').match(/^[0-9a-fA-F]+$/); if (!isHex) {