From 1fd487be3fe8db7b010857f2298b16348fdea7a5 Mon Sep 17 00:00:00 2001 From: Scott Nonnenberg Date: Mon, 7 May 2018 17:51:29 -0700 Subject: [PATCH] Refactor to remove duplicated code, lint/prettier fixes --- .prettierignore | 2 + ts/components/conversation/ContactDetail.tsx | 91 ++--------- .../conversation/EmbeddedContact.tsx | 148 +++++++++--------- ts/styleguide/StyleGuideUtil.ts | 4 +- ts/util/formatPhoneNumber.ts | 11 +- 5 files changed, 99 insertions(+), 157 deletions(-) diff --git a/.prettierignore b/.prettierignore index c7b5de7190ab..91afe1a0a170 100644 --- a/.prettierignore +++ b/.prettierignore @@ -15,6 +15,7 @@ test/test.js ts/**/*.js ts/protobuf/*.d.ts ts/protobuf/*.js +stylesheets/manifest.css # Third-party files components/** @@ -37,3 +38,4 @@ _locales/** # Symlink into third-party `components`: stylesheets/_intlTelInput.scss + diff --git a/ts/components/conversation/ContactDetail.tsx b/ts/components/conversation/ContactDetail.tsx index be6bf9654771..1d1a8741f7bd 100644 --- a/ts/components/conversation/ContactDetail.tsx +++ b/ts/components/conversation/ContactDetail.tsx @@ -1,15 +1,22 @@ import React from 'react'; import { + AddressType, Contact, ContactType, - AddressType, - Phone, Email, + Phone, PostalAddress, } from '../../types/Contact'; import { missingCaseError } from '../../util/missingCaseError'; +import { + renderAvatar, + renderContactShorthand, + renderName, + renderSendMessage, +} from './EmbeddedContact'; + type Localizer = (key: string, values?: Array) => string; interface Props { @@ -47,77 +54,7 @@ function getLabelForAddress(address: PostalAddress, i18n: Localizer) { } } -function getInitials(name: string): string { - return name.trim()[0] || '#'; -} - -function getName(contact: Contact): string { - const { name, organization } = contact; - return (name && name.displayName) || organization || ''; -} - export class ContactDetail extends React.Component { - public renderAvatar() { - const { contact } = this.props; - const { avatar } = contact; - - const path = avatar && avatar.avatar && avatar.avatar.path; - if (!path) { - const name = getName(contact); - const initials = getInitials(name); - return ( -
-
{initials}
-
- ); - } - - return ( -
- -
- ); - } - - public renderName() { - const { contact } = this.props; - - return
{getName(contact)}
; - } - - public renderContactShorthand() { - const { contact } = this.props; - const { number, email } = contact; - const firstNumber = number && number[0] && number[0].value; - const firstEmail = email && email[0] && email[0].value; - - return
{firstNumber || firstEmail}
; - } - - public renderSendMessage() { - const { hasSignalAccount, i18n, onSendMessage } = this.props; - - if (!hasSignalAccount) { - return null; - } - - // We don't want the overall click handler for this element to fire, so we stop - // propagation before handing control to the caller's callback. - const onClick = (e: React.MouseEvent<{}>): void => { - e.stopPropagation(); - onSendMessage(); - }; - - return ( -
- -
- ); - } - public renderAdditionalContact( items: Array | undefined, i18n: Localizer @@ -191,14 +128,14 @@ export class ContactDetail extends React.Component { } public render() { - const { contact, i18n } = this.props; + const { contact, hasSignalAccount, i18n, onSendMessage } = this.props; return (
- {this.renderAvatar()} - {this.renderName()} - {this.renderContactShorthand()} - {this.renderSendMessage()} + {renderAvatar(contact)} + {renderName(contact)} + {renderContactShorthand(contact)} + {renderSendMessage({ hasSignalAccount, i18n, onSendMessage })} {this.renderAdditionalContact(contact.number, i18n)} {this.renderAdditionalContact(contact.email, i18n)} {this.renderAddresses(contact.address, i18n)} diff --git a/ts/components/conversation/EmbeddedContact.tsx b/ts/components/conversation/EmbeddedContact.tsx index 370423d6b358..2c2246e99ec4 100644 --- a/ts/components/conversation/EmbeddedContact.tsx +++ b/ts/components/conversation/EmbeddedContact.tsx @@ -9,86 +9,94 @@ interface Props { onOpenContact: () => void; } -function getInitials(name: string): string { - return name.trim()[0] || '#'; -} - export class EmbeddedContact extends React.Component { - public renderAvatar() { - const { contact } = this.props; - const { avatar } = contact; - - const path = avatar && avatar.avatar && avatar.avatar.path; - if (!path) { - const name = getName(contact); - const initials = getInitials(name || ''); - return ( -
-
{initials}
-
- ); - } - - return ( -
- -
- ); - } - - public renderName() { - const { contact } = this.props; - - return
{getName(contact)}
; - } - - public renderContactShorthand() { - const { contact } = this.props; - const { number, email } = contact; - const firstNumber = number && number[0] && number[0].value; - const firstEmail = email && email[0] && email[0].value; - - return
{firstNumber || firstEmail}
; - } - - public renderSendMessage() { - const { hasSignalAccount, i18n, onSendMessage } = this.props; - - if (!hasSignalAccount) { - return null; - } - - // We don't want the overall click handler for this element to fire, so we stop - // propagation before handing control to the caller's callback. - const onClick = (e: React.MouseEvent<{}>): void => { - e.stopPropagation(); - onSendMessage(); - }; - - return ( -
- -
- ); - } - public render() { - const { onOpenContact } = this.props; + const { + contact, + hasSignalAccount, + i18n, + onOpenContact, + onSendMessage, + } = this.props; return (
- {this.renderAvatar()} + {renderAvatar(contact)}
- {this.renderName()} - {this.renderContactShorthand()} + {renderName(contact)} + {renderContactShorthand(contact)}
- {this.renderSendMessage()} + {renderSendMessage({ hasSignalAccount, i18n, onSendMessage })}
); } } + +// Note: putting these below the main component so style guide picks up EmbeddedContact + +function getInitials(name: string): string { + return name.trim()[0] || '#'; +} + +export function renderAvatar(contact: Contact) { + const { avatar } = contact; + + const path = avatar && avatar.avatar && avatar.avatar.path; + if (!path) { + const name = getName(contact); + const initials = getInitials(name || ''); + return ( +
+
{initials}
+
+ ); + } + + return ( +
+ +
+ ); +} + +export function renderName(contact: Contact) { + return
{getName(contact)}
; +} + +export function renderContactShorthand(contact: Contact) { + const { number: phoneNumber, email } = contact; + const firstNumber = phoneNumber && phoneNumber[0] && phoneNumber[0].value; + const firstEmail = email && email[0] && email[0].value; + + return
{firstNumber || firstEmail}
; +} + +export function renderSendMessage(props: { + hasSignalAccount: boolean; + i18n: (key: string, values?: Array) => string; + onSendMessage: () => void; +}) { + const { hasSignalAccount, i18n, onSendMessage } = props; + + if (!hasSignalAccount) { + return null; + } + + // We don't want the overall click handler for this element to fire, so we stop + // propagation before handing control to the caller's callback. + const onClick = (e: React.MouseEvent<{}>): void => { + e.stopPropagation(); + onSendMessage(); + }; + + return ( +
+ +
+ ); +} diff --git a/ts/styleguide/StyleGuideUtil.ts b/ts/styleguide/StyleGuideUtil.ts index 5fdd2cdeff0a..432de2cbe8e5 100644 --- a/ts/styleguide/StyleGuideUtil.ts +++ b/ts/styleguide/StyleGuideUtil.ts @@ -200,8 +200,8 @@ export { COLORS, CONTACTS, me, group }; parent.textsecure.storage.user.getNumber = () => ourNumber; parent.textsecure.messaging = { - getProfile: async (number: string): Promise => { - if (parent.ConversationController.get(number)) { + getProfile: async (phoneNumber: string): Promise => { + if (parent.ConversationController.get(phoneNumber)) { return true; } diff --git a/ts/util/formatPhoneNumber.ts b/ts/util/formatPhoneNumber.ts index 8fe50c96b8f8..21c8e153f3f8 100644 --- a/ts/util/formatPhoneNumber.ts +++ b/ts/util/formatPhoneNumber.ts @@ -1,15 +1,14 @@ -import { toLogFormat } from '../../js/modules/types/errors'; import { instance, PhoneNumberFormat } from './libphonenumberInstance'; export function formatPhoneNumber( - number: string, + phoneNumber: string, options: { ourRegionCode: string; } ) { try { const { ourRegionCode } = options; - const parsedNumber = instance.parse(number); + const parsedNumber = instance.parse(phoneNumber); const regionCode = instance.getRegionCodeForNumber(parsedNumber); if (ourRegionCode && regionCode === ourRegionCode) { @@ -18,10 +17,6 @@ export function formatPhoneNumber( return instance.format(parsedNumber, PhoneNumberFormat.INTERNATIONAL); } catch (error) { - console.log( - 'formatPhoneNumber - had problems formatting number:', - toLogFormat(error) - ); - return number; + return phoneNumber; } }