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
|
@ -238,6 +238,12 @@
|
||||||
appView.openInbox();
|
appView.openInbox();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Whisper.events.on('showConversation', function(conversation) {
|
||||||
|
if (appView) {
|
||||||
|
appView.openConversation(conversation);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
Whisper.Notifications.on('click', function(conversation) {
|
Whisper.Notifications.on('click', function(conversation) {
|
||||||
showWindow();
|
showWindow();
|
||||||
if (conversation) {
|
if (conversation) {
|
||||||
|
|
1
js/modules/types/errors.d.ts
vendored
Normal file
1
js/modules/types/errors.d.ts
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export function toLogFormat(error: any): string;
|
|
@ -1007,15 +1007,17 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
showContactDetail(contact) {
|
showContactDetail(contact) {
|
||||||
console.log('showContactDetail', contact); // TODO
|
const regionCode = storage.get('regionCode');
|
||||||
|
const { contactSelector } = Signal.Types.Contact;
|
||||||
// TODO: need to run contact through selector to format email, get absolute path
|
const { getAbsoluteAttachmentPath } = window.Signal.Migrations;
|
||||||
// think it's probably time to move it to typescript
|
|
||||||
|
|
||||||
const view = new Whisper.ReactWrapperView({
|
const view = new Whisper.ReactWrapperView({
|
||||||
Component: Signal.Components.MediaGallery,
|
Component: Signal.Components.ContactDetail,
|
||||||
props: {
|
props: {
|
||||||
contact,
|
contact: contactSelector(contact, {
|
||||||
|
regionCode,
|
||||||
|
getAbsoluteAttachmentPath,
|
||||||
|
}),
|
||||||
hasSignalAccount: true,
|
hasSignalAccount: true,
|
||||||
onSendMessage: () => {
|
onSendMessage: () => {
|
||||||
const number =
|
const number =
|
||||||
|
@ -1032,13 +1034,11 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
async openConversation(number) {
|
async openConversation(number) {
|
||||||
console.log('openConversation', number); // TODO
|
|
||||||
|
|
||||||
const conversation = await window.ConversationController.getOrCreateAndWait(
|
const conversation = await window.ConversationController.getOrCreateAndWait(
|
||||||
number,
|
number,
|
||||||
'private'
|
'private'
|
||||||
);
|
);
|
||||||
window.Whisper.Events.trigger('click', conversation);
|
window.Whisper.events.trigger('showConversation', conversation);
|
||||||
},
|
},
|
||||||
|
|
||||||
listenBack(view) {
|
listenBack(view) {
|
||||||
|
@ -1244,7 +1244,6 @@
|
||||||
|
|
||||||
if (message) {
|
if (message) {
|
||||||
const quote = await this.model.makeQuote(this.quotedMessage);
|
const quote = await this.model.makeQuote(this.quotedMessage);
|
||||||
console.log({ quote });
|
|
||||||
this.quote = quote;
|
this.quote = quote;
|
||||||
|
|
||||||
this.focusMessageFieldAndClearDisabled();
|
this.focusMessageFieldAndClearDisabled();
|
||||||
|
|
|
@ -5,15 +5,17 @@
|
||||||
/* global emoji_util: false */
|
/* global emoji_util: false */
|
||||||
/* global Mustache: false */
|
/* global Mustache: false */
|
||||||
/* global $: false */
|
/* global $: false */
|
||||||
/* global libphonenumber: false */
|
|
||||||
/* global storage: false */
|
/* global storage: false */
|
||||||
|
/* global Signal: false */
|
||||||
|
|
||||||
// eslint-disable-next-line func-names
|
// eslint-disable-next-line func-names
|
||||||
(function() {
|
(function() {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const { Signal } = window;
|
const {
|
||||||
const { loadAttachmentData } = window.Signal.Migrations;
|
loadAttachmentData,
|
||||||
|
getAbsoluteAttachmentPath,
|
||||||
|
} = window.Signal.Migrations;
|
||||||
|
|
||||||
window.Whisper = window.Whisper || {};
|
window.Whisper = window.Whisper || {};
|
||||||
|
|
||||||
|
@ -441,46 +443,6 @@
|
||||||
});
|
});
|
||||||
this.$('.inner-bubble').prepend(this.quoteView.el);
|
this.$('.inner-bubble').prepend(this.quoteView.el);
|
||||||
},
|
},
|
||||||
formatPhoneNumber(number, options = {}) {
|
|
||||||
const { ourRegionCode } = options;
|
|
||||||
const parsedNumber = libphonenumber.parse(number);
|
|
||||||
const regionCode = libphonenumber.getRegionCodeForNumber(parsedNumber);
|
|
||||||
if (ourRegionCode && regionCode === ourRegionCode) {
|
|
||||||
return libphonenumber.format(
|
|
||||||
parsedNumber,
|
|
||||||
libphonenumber.PhoneNumberFormat.NATIONAL
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return libphonenumber.format(
|
|
||||||
parsedNumber,
|
|
||||||
libphonenumber.PhoneNumberFormat.INTERNATIONAL
|
|
||||||
);
|
|
||||||
},
|
|
||||||
contactSelector(contact) {
|
|
||||||
const { getAbsoluteAttachmentPath } = Signal.Migrations;
|
|
||||||
const region = storage.get('regionCode');
|
|
||||||
|
|
||||||
let { avatar } = contact;
|
|
||||||
if (avatar && avatar.avatar && avatar.avatar.path) {
|
|
||||||
avatar = Object.assign({}, avatar, {
|
|
||||||
avatar: Object.assign({}, avatar.avatar, {
|
|
||||||
path: getAbsoluteAttachmentPath(avatar.avatar.path),
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return Object.assign({}, contact, {
|
|
||||||
avatar,
|
|
||||||
number:
|
|
||||||
contact.number &&
|
|
||||||
contact.number.map(item =>
|
|
||||||
Object.assign({}, item, {
|
|
||||||
value: this.formatPhoneNumber(item.value, {
|
|
||||||
ourRegionCode: region,
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
),
|
|
||||||
});
|
|
||||||
},
|
|
||||||
renderContact() {
|
renderContact() {
|
||||||
const contacts = this.model.get('contact');
|
const contacts = this.model.get('contact');
|
||||||
if (!contacts || !contacts.length) {
|
if (!contacts || !contacts.length) {
|
||||||
|
@ -488,6 +450,9 @@
|
||||||
}
|
}
|
||||||
const contact = contacts[0];
|
const contact = contacts[0];
|
||||||
|
|
||||||
|
const regionCode = storage.get('regionCode');
|
||||||
|
const { contactSelector } = Signal.Types.Contact;
|
||||||
|
|
||||||
const number =
|
const number =
|
||||||
contact.number && contact.number[0] && contact.number[0].value;
|
contact.number && contact.number[0] && contact.number[0].value;
|
||||||
const haveConversation =
|
const haveConversation =
|
||||||
|
@ -503,14 +468,15 @@
|
||||||
this.model.trigger('show-contact-detail', contact);
|
this.model.trigger('show-contact-detail', contact);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getProps = () => {
|
const getProps = () => ({
|
||||||
return {
|
contact: contactSelector(contact, {
|
||||||
contact: this.contactSelector(contact),
|
regionCode,
|
||||||
hasSignalAccount,
|
getAbsoluteAttachmentPath,
|
||||||
onSendMessage,
|
}),
|
||||||
onOpenContact,
|
hasSignalAccount,
|
||||||
};
|
onSendMessage,
|
||||||
};
|
onOpenContact,
|
||||||
|
});
|
||||||
|
|
||||||
if (this.contactView) {
|
if (this.contactView) {
|
||||||
this.contactView.remove();
|
this.contactView.remove();
|
||||||
|
|
|
@ -172,10 +172,13 @@ const { Quote } = require('./ts/components/conversation/Quote');
|
||||||
const {
|
const {
|
||||||
EmbeddedContact,
|
EmbeddedContact,
|
||||||
} = require('./ts/components/conversation/EmbeddedContact');
|
} = require('./ts/components/conversation/EmbeddedContact');
|
||||||
|
const { ContactDetail } = require('./ts/components/conversation/ContactDetail');
|
||||||
|
|
||||||
const MediaGalleryMessage = require('./ts/components/conversation/media-gallery/types/Message');
|
const MediaGalleryMessage = require('./ts/components/conversation/media-gallery/types/Message');
|
||||||
|
|
||||||
window.Signal.Components = {
|
window.Signal.Components = {
|
||||||
|
ContactDetail,
|
||||||
|
EmbeddedContact,
|
||||||
Lightbox,
|
Lightbox,
|
||||||
LightboxGallery,
|
LightboxGallery,
|
||||||
MediaGallery,
|
MediaGallery,
|
||||||
|
@ -183,7 +186,6 @@ window.Signal.Components = {
|
||||||
Message: MediaGalleryMessage,
|
Message: MediaGalleryMessage,
|
||||||
},
|
},
|
||||||
Quote,
|
Quote,
|
||||||
EmbeddedContact,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
window.Signal.Migrations = {};
|
window.Signal.Migrations = {};
|
||||||
|
@ -210,6 +212,7 @@ window.Signal.Startup = require('./js/modules/startup');
|
||||||
|
|
||||||
window.Signal.Types = {};
|
window.Signal.Types = {};
|
||||||
window.Signal.Types.Attachment = Attachment;
|
window.Signal.Types.Attachment = Attachment;
|
||||||
|
window.Signal.Types.Contact = require('./ts/types/Contact');
|
||||||
window.Signal.Types.Conversation = require('./ts/types/Conversation');
|
window.Signal.Types.Conversation = require('./ts/types/Conversation');
|
||||||
window.Signal.Types.Errors = require('./js/modules/types/errors');
|
window.Signal.Types.Errors = require('./js/modules/types/errors');
|
||||||
|
|
||||||
|
|
|
@ -852,8 +852,11 @@ span.status {
|
||||||
|
|
||||||
.send-message {
|
.send-message {
|
||||||
color: white;
|
color: white;
|
||||||
border-top: 1px solid rgba(255, 255, 255, 0.5);
|
// We would like to use these border colors for incoming messages, but the version
|
||||||
border-bottom: 1px solid rgba(255, 255, 255, 0.5);
|
// of Chromium in our Electron version doesn't render these appropriately. Both
|
||||||
|
// borders disappear for some reason, and it seems to have to do with transparency.
|
||||||
|
// border-top: 1px solid rgba(255, 255, 255, 0.5);
|
||||||
|
// border-bottom: 1px solid rgba(255, 255, 255, 0.5);
|
||||||
|
|
||||||
.bubble-icon {
|
.bubble-icon {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
|
@ -963,6 +966,10 @@ span.status {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.conversation .contact-detail {
|
||||||
|
margin-top: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
.quoted-message {
|
.quoted-message {
|
||||||
@include message-replies-colors;
|
@include message-replies-colors;
|
||||||
@include twenty-percent-colors;
|
@include twenty-percent-colors;
|
||||||
|
|
|
@ -1,5 +1,13 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
|
import {
|
||||||
|
Contact,
|
||||||
|
ContactType,
|
||||||
|
AddressType,
|
||||||
|
Phone,
|
||||||
|
Email,
|
||||||
|
PostalAddress,
|
||||||
|
} from '../../types/Contact';
|
||||||
import { missingCaseError } from '../../util/missingCaseError';
|
import { missingCaseError } from '../../util/missingCaseError';
|
||||||
|
|
||||||
type Localizer = (key: string, values?: Array<string>) => string;
|
type Localizer = (key: string, values?: Array<string>) => string;
|
||||||
|
@ -11,70 +19,6 @@ interface Props {
|
||||||
onSendMessage: () => void;
|
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) {
|
function getLabelForContactMethod(method: Phone | Email, i18n: Localizer) {
|
||||||
switch (method.type) {
|
switch (method.type) {
|
||||||
case ContactType.CUSTOM:
|
case ContactType.CUSTOM:
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { Contact } from '../../types/Contact';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
contact: Contact;
|
contact: Contact;
|
||||||
|
@ -8,70 +9,6 @@ interface Props {
|
||||||
onOpenContact: () => void;
|
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 {
|
function getInitials(name: string): string {
|
||||||
return name.trim()[0] || '#';
|
return name.trim()[0] || '#';
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,8 @@ export { BackboneWrapper } from '../components/utility/BackboneWrapper';
|
||||||
|
|
||||||
import { Quote } from '../components/conversation/Quote';
|
import { Quote } from '../components/conversation/Quote';
|
||||||
import { EmbeddedContact } from '../components/conversation/EmbeddedContact';
|
import { EmbeddedContact } from '../components/conversation/EmbeddedContact';
|
||||||
|
import * as Contact from '../types/Contact';
|
||||||
|
|
||||||
import * as HTML from '../html';
|
import * as HTML from '../html';
|
||||||
|
|
||||||
import * as Attachment from '../../ts/types/Attachment';
|
import * as Attachment from '../../ts/types/Attachment';
|
||||||
|
@ -130,6 +132,7 @@ parent.ReactDOM = ReactDOM;
|
||||||
parent.Signal.HTML = HTML;
|
parent.Signal.HTML = HTML;
|
||||||
parent.Signal.Types.MIME = MIME;
|
parent.Signal.Types.MIME = MIME;
|
||||||
parent.Signal.Types.Attachment = Attachment;
|
parent.Signal.Types.Attachment = Attachment;
|
||||||
|
parent.Signal.Types.Contact = Contact;
|
||||||
parent.Signal.Components = {
|
parent.Signal.Components = {
|
||||||
Quote,
|
Quote,
|
||||||
EmbeddedContact,
|
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 { Attachment } from './Attachment';
|
||||||
|
import { Contact } from './Contact';
|
||||||
import { IndexableBoolean, IndexablePresence } from './IndexedDB';
|
import { IndexableBoolean, IndexablePresence } from './IndexedDB';
|
||||||
|
|
||||||
export type Message = UserMessage | VerifiedChangeMessage;
|
export type Message = UserMessage | VerifiedChangeMessage;
|
||||||
|
@ -21,6 +22,7 @@ export type IncomingMessage = Readonly<
|
||||||
sourceDevice?: number;
|
sourceDevice?: number;
|
||||||
} & SharedMessageProperties &
|
} & SharedMessageProperties &
|
||||||
MessageSchemaVersion5 &
|
MessageSchemaVersion5 &
|
||||||
|
MessageSchemaVersion6 &
|
||||||
ExpirationTimerUpdate
|
ExpirationTimerUpdate
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
@ -81,3 +83,9 @@ type MessageSchemaVersion5 = Partial<
|
||||||
hasFileAttachments: IndexablePresence;
|
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