Wire up all contact behaviors, refactor Contact type/selector
This commit is contained in:
parent
41be7f126b
commit
37821e5a1b
13 changed files with 198 additions and 192 deletions
|
@ -1,5 +1,13 @@
|
|||
import React from 'react';
|
||||
|
||||
import {
|
||||
Contact,
|
||||
ContactType,
|
||||
AddressType,
|
||||
Phone,
|
||||
Email,
|
||||
PostalAddress,
|
||||
} from '../../types/Contact';
|
||||
import { missingCaseError } from '../../util/missingCaseError';
|
||||
|
||||
type Localizer = (key: string, values?: Array<string>) => string;
|
||||
|
@ -11,70 +19,6 @@ interface Props {
|
|||
onSendMessage: () => void;
|
||||
}
|
||||
|
||||
interface Contact {
|
||||
name: Name;
|
||||
number?: Array<Phone>;
|
||||
email?: Array<Email>;
|
||||
address?: Array<PostalAddress>;
|
||||
avatar?: Avatar;
|
||||
organization?: string;
|
||||
}
|
||||
|
||||
interface Name {
|
||||
givenName?: string;
|
||||
familyName?: string;
|
||||
prefix?: string;
|
||||
suffix?: string;
|
||||
middleName?: string;
|
||||
displayName: string;
|
||||
}
|
||||
|
||||
enum ContactType {
|
||||
HOME = 1,
|
||||
MOBILE = 2,
|
||||
WORK = 3,
|
||||
CUSTOM = 4,
|
||||
}
|
||||
|
||||
enum AddressType {
|
||||
HOME = 1,
|
||||
WORK = 2,
|
||||
CUSTOM = 3,
|
||||
}
|
||||
|
||||
interface Phone {
|
||||
value: string;
|
||||
type: ContactType;
|
||||
label?: string;
|
||||
}
|
||||
|
||||
interface Email {
|
||||
value: string;
|
||||
type: ContactType;
|
||||
label?: string;
|
||||
}
|
||||
|
||||
interface PostalAddress {
|
||||
type: AddressType;
|
||||
label?: string;
|
||||
street?: string;
|
||||
pobox?: string;
|
||||
neighborhood?: string;
|
||||
city?: string;
|
||||
region?: string;
|
||||
postcode?: string;
|
||||
country?: string;
|
||||
}
|
||||
|
||||
interface Avatar {
|
||||
avatar: Attachment;
|
||||
isProfile: boolean;
|
||||
}
|
||||
|
||||
interface Attachment {
|
||||
path: string;
|
||||
}
|
||||
|
||||
function getLabelForContactMethod(method: Phone | Email, i18n: Localizer) {
|
||||
switch (method.type) {
|
||||
case ContactType.CUSTOM:
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import React from 'react';
|
||||
import { Contact } from '../../types/Contact';
|
||||
|
||||
interface Props {
|
||||
contact: Contact;
|
||||
|
@ -8,70 +9,6 @@ interface Props {
|
|||
onOpenContact: () => void;
|
||||
}
|
||||
|
||||
interface Contact {
|
||||
name: Name;
|
||||
number?: Array<Phone>;
|
||||
email?: Array<Email>;
|
||||
address?: Array<PostalAddress>;
|
||||
avatar?: Avatar;
|
||||
organization?: string;
|
||||
}
|
||||
|
||||
interface Name {
|
||||
givenName?: string;
|
||||
familyName?: string;
|
||||
prefix?: string;
|
||||
suffix?: string;
|
||||
middleName?: string;
|
||||
displayName: string;
|
||||
}
|
||||
|
||||
enum ContactType {
|
||||
HOME = 1,
|
||||
MOBILE = 2,
|
||||
WORK = 3,
|
||||
CUSTOM = 4,
|
||||
}
|
||||
|
||||
enum AddressType {
|
||||
HOME = 1,
|
||||
WORK = 2,
|
||||
CUSTOM = 3,
|
||||
}
|
||||
|
||||
interface Phone {
|
||||
value: string;
|
||||
type: ContactType;
|
||||
label?: string;
|
||||
}
|
||||
|
||||
interface Email {
|
||||
value: string;
|
||||
type: ContactType;
|
||||
label?: string;
|
||||
}
|
||||
|
||||
interface PostalAddress {
|
||||
type: AddressType;
|
||||
label?: string;
|
||||
street?: string;
|
||||
pobox?: string;
|
||||
neighborhood?: string;
|
||||
city?: string;
|
||||
region?: string;
|
||||
postcode?: string;
|
||||
country?: string;
|
||||
}
|
||||
|
||||
interface Avatar {
|
||||
avatar: Attachment;
|
||||
isProfile: boolean;
|
||||
}
|
||||
|
||||
interface Attachment {
|
||||
path: string;
|
||||
}
|
||||
|
||||
function getInitials(name: string): string {
|
||||
return name.trim()[0] || '#';
|
||||
}
|
||||
|
|
|
@ -19,6 +19,8 @@ export { BackboneWrapper } from '../components/utility/BackboneWrapper';
|
|||
|
||||
import { Quote } from '../components/conversation/Quote';
|
||||
import { EmbeddedContact } from '../components/conversation/EmbeddedContact';
|
||||
import * as Contact from '../types/Contact';
|
||||
|
||||
import * as HTML from '../html';
|
||||
|
||||
import * as Attachment from '../../ts/types/Attachment';
|
||||
|
@ -130,6 +132,7 @@ parent.ReactDOM = ReactDOM;
|
|||
parent.Signal.HTML = HTML;
|
||||
parent.Signal.Types.MIME = MIME;
|
||||
parent.Signal.Types.Attachment = Attachment;
|
||||
parent.Signal.Types.Contact = Contact;
|
||||
parent.Signal.Components = {
|
||||
Quote,
|
||||
EmbeddedContact,
|
||||
|
|
99
ts/types/Contact.ts
Normal file
99
ts/types/Contact.ts
Normal file
|
@ -0,0 +1,99 @@
|
|||
// @ts-ignore
|
||||
import Attachments from '../../app/attachments';
|
||||
import { formatPhoneNumber } from '../util/formatPhoneNumber';
|
||||
|
||||
export interface Contact {
|
||||
name: Name;
|
||||
number?: Array<Phone>;
|
||||
email?: Array<Email>;
|
||||
address?: Array<PostalAddress>;
|
||||
avatar?: Avatar;
|
||||
organization?: string;
|
||||
}
|
||||
|
||||
interface Name {
|
||||
givenName?: string;
|
||||
familyName?: string;
|
||||
prefix?: string;
|
||||
suffix?: string;
|
||||
middleName?: string;
|
||||
displayName: string;
|
||||
}
|
||||
|
||||
export enum ContactType {
|
||||
HOME = 1,
|
||||
MOBILE = 2,
|
||||
WORK = 3,
|
||||
CUSTOM = 4,
|
||||
}
|
||||
|
||||
export enum AddressType {
|
||||
HOME = 1,
|
||||
WORK = 2,
|
||||
CUSTOM = 3,
|
||||
}
|
||||
|
||||
export interface Phone {
|
||||
value: string;
|
||||
type: ContactType;
|
||||
label?: string;
|
||||
}
|
||||
|
||||
export interface Email {
|
||||
value: string;
|
||||
type: ContactType;
|
||||
label?: string;
|
||||
}
|
||||
|
||||
export interface PostalAddress {
|
||||
type: AddressType;
|
||||
label?: string;
|
||||
street?: string;
|
||||
pobox?: string;
|
||||
neighborhood?: string;
|
||||
city?: string;
|
||||
region?: string;
|
||||
postcode?: string;
|
||||
country?: string;
|
||||
}
|
||||
|
||||
interface Avatar {
|
||||
avatar: Attachment;
|
||||
isProfile: boolean;
|
||||
}
|
||||
|
||||
interface Attachment {
|
||||
path: string;
|
||||
}
|
||||
|
||||
export function contactSelector(
|
||||
contact: Contact,
|
||||
options: {
|
||||
regionCode: string;
|
||||
getAbsoluteAttachmentPath: (path: string) => string;
|
||||
}
|
||||
) {
|
||||
const { regionCode, getAbsoluteAttachmentPath } = options;
|
||||
|
||||
let { avatar } = contact;
|
||||
if (avatar && avatar.avatar && avatar.avatar.path) {
|
||||
avatar = {
|
||||
...avatar,
|
||||
avatar: {
|
||||
...avatar.avatar,
|
||||
path: getAbsoluteAttachmentPath(avatar.avatar.path),
|
||||
},
|
||||
};
|
||||
}
|
||||
return Object.assign({}, contact, {
|
||||
avatar,
|
||||
number:
|
||||
contact.number &&
|
||||
contact.number.map(item => ({
|
||||
...item,
|
||||
value: formatPhoneNumber(item.value, {
|
||||
ourRegionCode: regionCode,
|
||||
}),
|
||||
})),
|
||||
});
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
import { Attachment } from './Attachment';
|
||||
import { Contact } from './Contact';
|
||||
import { IndexableBoolean, IndexablePresence } from './IndexedDB';
|
||||
|
||||
export type Message = UserMessage | VerifiedChangeMessage;
|
||||
|
@ -21,6 +22,7 @@ export type IncomingMessage = Readonly<
|
|||
sourceDevice?: number;
|
||||
} & SharedMessageProperties &
|
||||
MessageSchemaVersion5 &
|
||||
MessageSchemaVersion6 &
|
||||
ExpirationTimerUpdate
|
||||
>;
|
||||
|
||||
|
@ -81,3 +83,9 @@ type MessageSchemaVersion5 = Partial<
|
|||
hasFileAttachments: IndexablePresence;
|
||||
}>
|
||||
>;
|
||||
|
||||
type MessageSchemaVersion6 = Partial<
|
||||
Readonly<{
|
||||
contact: Array<Contact>;
|
||||
}>
|
||||
>;
|
||||
|
|
27
ts/util/formatPhoneNumber.ts
Normal file
27
ts/util/formatPhoneNumber.ts
Normal file
|
@ -0,0 +1,27 @@
|
|||
import { toLogFormat } from '../../js/modules/types/errors';
|
||||
import { instance, PhoneNumberFormat } from './libphonenumberInstance';
|
||||
|
||||
export function formatPhoneNumber(
|
||||
number: string,
|
||||
options: {
|
||||
ourRegionCode: string;
|
||||
}
|
||||
) {
|
||||
try {
|
||||
const { ourRegionCode } = options;
|
||||
const parsedNumber = instance.parse(number);
|
||||
const regionCode = instance.getRegionCodeForNumber(parsedNumber);
|
||||
|
||||
if (ourRegionCode && regionCode === ourRegionCode) {
|
||||
return instance.format(parsedNumber, PhoneNumberFormat.NATIONAL);
|
||||
}
|
||||
|
||||
return instance.format(parsedNumber, PhoneNumberFormat.INTERNATIONAL);
|
||||
} catch (error) {
|
||||
console.log(
|
||||
'formatPhoneNumber - had problems formatting number:',
|
||||
toLogFormat(error)
|
||||
);
|
||||
return number;
|
||||
}
|
||||
}
|
6
ts/util/libphonenumberInstance.ts
Normal file
6
ts/util/libphonenumberInstance.ts
Normal file
|
@ -0,0 +1,6 @@
|
|||
import libphonenumber from 'google-libphonenumber';
|
||||
|
||||
const instance = libphonenumber.PhoneNumberUtil.getInstance();
|
||||
const PhoneNumberFormat = libphonenumber.PhoneNumberFormat;
|
||||
|
||||
export { instance, PhoneNumberFormat };
|
Loading…
Add table
Add a link
Reference in a new issue