remove EbeddedContact components

pull/1459/head
Audric Ackermann 4 years ago
parent 02fb5783a4
commit 3d47d7d0e8
No known key found for this signature in database
GPG Key ID: 999F434D76324AD4

@ -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'),

@ -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,

@ -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,
};
}

@ -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: Weve 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,

@ -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<Props> {
public render() {
const {
contact,
i18n,
isIncoming,
onClick,
withContentAbove,
withContentBelow,
} = this.props;
const module = 'embedded-contact';
const direction = isIncoming ? 'incoming' : 'outgoing';
return (
<div
className={classNames(
'module-embedded-contact',
withContentAbove
? 'module-embedded-contact--with-content-above'
: null,
withContentBelow
? 'module-embedded-contact--with-content-below'
: null
)}
role="button"
onClick={onClick}
>
{renderAvatar({ contact, i18n, size: 36, direction })}
<div className="module-embedded-contact__text-container">
{renderName({ contact, isIncoming, module })}
{renderContactShorthand({ contact, isIncoming, module })}
</div>
</div>
);
}
}

@ -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<MessageRegularProps, State> {
);
}
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 (
<EmbeddedContact
contact={contact}
isIncoming={direction === 'incoming'}
i18n={window.i18n}
onClick={contact.onClick}
withContentAbove={withContentAbove}
withContentBelow={withContentBelow}
/>
);
}
public renderAvatar() {
const {
authorAvatarPath,
@ -906,7 +876,6 @@ class MessageInner extends React.PureComponent<MessageRegularProps, State> {
{this.renderQuote()}
{this.renderAttachment()}
{this.renderPreview()}
{this.renderEmbeddedContact()}
{this.renderText()}
<MessageMetadata
{...this.props}

@ -24,7 +24,6 @@ const TypingBubbleContainer = styled.div<TypingBubbleProps>`
`;
export const TypingBubble = (props: TypingBubbleProps) => {
if (props.conversationType === 'group') {
return <></>;
}

@ -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 (
<div className="module-embedded-contact__spinner-container">
<Spinner size={spinnerSize} direction={direction} />
</div>
);
}
const pubkey = contact.name?.givenName || '0';
return (
<Avatar avatarPath={avatarPath} name={name} size={size} pubkey={pubkey} />
);
}
export function renderName({
contact,
isIncoming,
module,
}: {
contact: Contact;
isIncoming: boolean;
module: string;
}) {
return (
<div
className={classNames(
`module-${module}__contact-name`,
isIncoming ? `module-${module}__contact-name--incoming` : null
)}
>
{getName(contact)}
</div>
);
}
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 (
<div
className={classNames(
`module-${module}__contact-method`,
isIncoming ? `module-${module}__contact-method--incoming` : null
)}
>
{firstNumber || firstEmail}
</div>
);
}

@ -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) {

Loading…
Cancel
Save