Compute from embedded contact's displayName

This commit is contained in:
Fedor Indutny 2024-10-01 14:46:56 -07:00 committed by GitHub
parent f730b0c82b
commit bb69f81b9f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 63 additions and 51 deletions

View file

@ -477,6 +477,7 @@ message ContactAttachment {
optional string prefix = 3; optional string prefix = 3;
optional string suffix = 4; optional string suffix = 4;
optional string middleName = 5; optional string middleName = 5;
optional string nickname = 6;
} }
message Phone { message Phone {

View file

@ -212,7 +212,8 @@ message DataMessage {
optional string prefix = 3; optional string prefix = 3;
optional string suffix = 4; optional string suffix = 4;
optional string middleName = 5; optional string middleName = 5;
optional string displayName = 6; reserved /* displayName */ 6;
optional string nickname = 7;
} }
message Phone { message Phone {

View file

@ -101,7 +101,6 @@ const fullContact = {
prefix: 'Dr.', prefix: 'Dr.',
suffix: 'Jr.', suffix: 'Jr.',
middleName: 'James', middleName: 'James',
displayName: 'Jerry Jordan',
}, },
number: [ number: [
{ {

View file

@ -1916,7 +1916,6 @@ const fullContact = {
prefix: 'Dr.', prefix: 'Dr.',
suffix: 'Jr.', suffix: 'Jr.',
middleName: 'James', middleName: 'James',
displayName: 'Jerry Jordan',
}, },
number: [ number: [
{ {
@ -1987,7 +1986,7 @@ export const EmbeddedContactLoadingAvatar = Template.bind({});
EmbeddedContactLoadingAvatar.args = { EmbeddedContactLoadingAvatar.args = {
contact: { contact: {
name: { name: {
displayName: 'Jerry Jordan', nickname: 'Jerry',
}, },
avatar: { avatar: {
avatar: fakeAttachment({ avatar: fakeAttachment({

View file

@ -47,21 +47,21 @@ describe('Contact', () => {
}; };
describe('getName', () => { describe('getName', () => {
it('returns displayName if provided', () => { it('returns displayName if available', () => {
const contact = { const contact = {
name: { name: {
displayName: 'displayName', nickname: 'nickname',
givenName: 'givenName', givenName: 'givenName',
familyName: 'familyName', familyName: 'familyName',
}, },
organization: 'Somewhere, Inc.', organization: 'Somewhere, Inc.',
}; };
const expected = 'displayName'; const expected = 'nickname';
const actual = getName(contact); const actual = getName(contact);
assert.strictEqual(actual, expected); assert.strictEqual(actual, expected);
}); });
it('returns organization if no displayName', () => { it('returns full name if no displayName', () => {
const contact = { const contact = {
name: { name: {
givenName: 'givenName', givenName: 'givenName',
@ -69,23 +69,21 @@ describe('Contact', () => {
}, },
organization: 'Somewhere, Inc.', organization: 'Somewhere, Inc.',
}; };
const expected = 'givenName familyName';
const actual = getName(contact);
assert.strictEqual(actual, expected);
});
it('returns organization if no displayName or full name', () => {
const contact = {
name: {},
organization: 'Somewhere, Inc.',
};
const expected = 'Somewhere, Inc.'; const expected = 'Somewhere, Inc.';
const actual = getName(contact); const actual = getName(contact);
assert.strictEqual(actual, expected); assert.strictEqual(actual, expected);
}); });
it('returns givenName + familyName if no displayName or organization', () => {
const contact = {
name: {
givenName: 'givenName',
familyName: 'familyName',
},
};
const expected = 'givenName familyName';
const actual = getName(contact);
assert.strictEqual(actual, expected);
});
it('returns just givenName', () => { it('returns just givenName', () => {
const contact = { const contact = {
name: { name: {
@ -117,7 +115,7 @@ describe('Contact', () => {
it('eliminates avatar if it has had an attachment download error', () => { it('eliminates avatar if it has had an attachment download error', () => {
const contact = { const contact = {
name: { name: {
displayName: 'displayName', nickname: 'nickname',
givenName: 'givenName', givenName: 'givenName',
familyName: 'familyName', familyName: 'familyName',
}, },
@ -132,7 +130,7 @@ describe('Contact', () => {
}; };
const expected = { const expected = {
name: { name: {
displayName: 'displayName', nickname: 'nickname',
givenName: 'givenName', givenName: 'givenName',
familyName: 'familyName', familyName: 'familyName',
}, },
@ -153,7 +151,7 @@ describe('Contact', () => {
it('does not calculate absolute path if avatar is pending', () => { it('does not calculate absolute path if avatar is pending', () => {
const contact = { const contact = {
name: { name: {
displayName: 'displayName', nickname: 'nickname',
givenName: 'givenName', givenName: 'givenName',
familyName: 'familyName', familyName: 'familyName',
}, },
@ -169,7 +167,7 @@ describe('Contact', () => {
}; };
const expected = { const expected = {
name: { name: {
displayName: 'displayName', nickname: 'nickname',
givenName: 'givenName', givenName: 'givenName',
familyName: 'familyName', familyName: 'familyName',
}, },
@ -199,7 +197,7 @@ describe('Contact', () => {
const contact = { const contact = {
name: { name: {
displayName: 'displayName', nickname: 'nickname',
givenName: 'givenName', givenName: 'givenName',
familyName: 'familyName', familyName: 'familyName',
}, },
@ -214,7 +212,7 @@ describe('Contact', () => {
}; };
const expected = { const expected = {
name: { name: {
displayName: 'displayName', nickname: 'nickname',
givenName: 'givenName', givenName: 'givenName',
familyName: 'familyName', familyName: 'familyName',
}, },
@ -251,7 +249,7 @@ describe('Contact', () => {
contact: [ contact: [
{ {
name: { name: {
displayName: 'Someone Somewhere', nickname: 'Someone Somewhere',
}, },
number: [ number: [
{ {
@ -282,7 +280,7 @@ describe('Contact', () => {
contact: [ contact: [
{ {
name: { name: {
displayName: 'Someone Somewhere', nickname: 'Someone Somewhere',
}, },
number: [ number: [
{ {
@ -295,7 +293,7 @@ describe('Contact', () => {
}; };
const expected = { const expected = {
name: { name: {
displayName: 'Someone Somewhere', nickname: 'Someone Somewhere',
}, },
number: [ number: [
{ {
@ -324,7 +322,7 @@ describe('Contact', () => {
contact: [ contact: [
{ {
name: { name: {
displayName: 'Someone Somewhere', nickname: 'Someone Somewhere',
}, },
number: [ number: [
{ {
@ -340,7 +338,7 @@ describe('Contact', () => {
}; };
const expected = { const expected = {
name: { name: {
displayName: 'Someone Somewhere', nickname: 'Someone Somewhere',
}, },
number: [ number: [
{ {
@ -372,7 +370,7 @@ describe('Contact', () => {
contact: [ contact: [
{ {
name: { name: {
displayName: 'Someone Somewhere', nickname: 'Someone Somewhere',
}, },
number: [ number: [
{ {
@ -404,7 +402,7 @@ describe('Contact', () => {
}; };
const expected = { const expected = {
name: { name: {
displayName: 'Someone Somewhere', nickname: 'Someone Somewhere',
}, },
number: [ number: [
{ {
@ -454,7 +452,7 @@ describe('Contact', () => {
contact: [ contact: [
{ {
name: { name: {
displayName: 'Someone Somewhere', nickname: 'Someone Somewhere',
}, },
number: [ number: [
{ {
@ -472,7 +470,7 @@ describe('Contact', () => {
}; };
const expected = { const expected = {
name: { name: {
displayName: 'Someone Somewhere', nickname: 'Someone Somewhere',
}, },
email: [ email: [
{ {
@ -501,7 +499,7 @@ describe('Contact', () => {
contact: [ contact: [
{ {
name: { name: {
displayName: 'Someone Somewhere', nickname: 'Someone Somewhere',
}, },
number: [ number: [
{ {
@ -519,7 +517,7 @@ describe('Contact', () => {
}; };
const expected = { const expected = {
name: { name: {
displayName: 'Someone Somewhere', nickname: 'Someone Somewhere',
}, },
number: [ number: [
{ {
@ -551,7 +549,7 @@ describe('Contact', () => {
contact: [ contact: [
{ {
name: { name: {
displayName: 'Someone Somewhere', nickname: 'Someone Somewhere',
}, },
number: [ number: [
{ {
@ -568,7 +566,7 @@ describe('Contact', () => {
}; };
const expected = { const expected = {
name: { name: {
displayName: 'Someone Somewhere', nickname: 'Someone Somewhere',
}, },
}; };
const result = await upgradeVersion(message.contact[0], { const result = await upgradeVersion(message.contact[0], {
@ -635,7 +633,7 @@ describe('Contact', () => {
const messageId = 'the-message-id'; const messageId = 'the-message-id';
const contact = { const contact = {
name: { name: {
displayName: 'Someone Somewhere', nickname: 'Someone Somewhere',
}, },
number: [], number: [],
email: [], email: [],

View file

@ -673,7 +673,7 @@ describe('Message', () => {
contact: [ contact: [
{ {
name: { name: {
displayName: 'Someone somewhere', nickname: 'Someone somewhere',
}, },
}, },
], ],
@ -683,7 +683,7 @@ describe('Message', () => {
contact: [ contact: [
{ {
name: { name: {
displayName: 'Someone somewhere', nickname: 'Someone somewhere',
}, },
}, },
], ],

View file

@ -435,7 +435,7 @@ class Message {
prefix: contact.name.prefix, prefix: contact.name.prefix,
suffix: contact.name.suffix, suffix: contact.name.suffix,
middleName: contact.name.middleName, middleName: contact.name.middleName,
displayName: contact.name.displayName, nickname: contact.name.nickname,
}; };
contactProto.name = new Proto.DataMessage.Contact.Name(nameProto); contactProto.name = new Proto.DataMessage.Contact.Name(nameProto);
} }

View file

@ -49,7 +49,7 @@ type Name = {
prefix?: string; prefix?: string;
suffix?: string; suffix?: string;
middleName?: string; middleName?: string;
displayName?: string; nickname?: string;
}; };
export enum ContactFormType { export enum ContactFormType {
@ -190,17 +190,31 @@ export function embeddedContactSelector(
}; };
} }
export function getDisplayName({
name,
organization,
}: ReadonlyDeep<EmbeddedContactType>): string | undefined {
// See https://github.com/signalapp/Signal-iOS-Private/blob/210a46037f12cdc6ad97ac6dceb64fbc43469f67/SignalServiceKit/Messages/Interactions/ContactShare/OWSContactName.swift#L87-L104
if (name?.nickname) {
return name.nickname;
}
if (name?.givenName && name?.familyName) {
return `${name.givenName} ${name.familyName}`;
}
if (organization) {
return organization;
}
return undefined;
}
export function getName( export function getName(
contact: ReadonlyDeep<EmbeddedContactType> contact: ReadonlyDeep<EmbeddedContactType>
): string | undefined { ): string | undefined {
const { name, organization } = contact; const { name } = contact;
const displayName = (name && name.displayName) || undefined;
const givenName = (name && name.givenName) || undefined; const givenName = (name && name.givenName) || undefined;
const familyName = (name && name.familyName) || undefined; const familyName = (name && name.familyName) || undefined;
const backupName =
(givenName && familyName && `${givenName} ${familyName}`) || undefined;
return displayName || organization || backupName || givenName || familyName; return getDisplayName(contact) || givenName || familyName;
} }
export function parseAndWriteAvatar( export function parseAndWriteAvatar(
@ -292,9 +306,9 @@ export function _validate(
contact: EmbeddedContactType, contact: EmbeddedContactType,
{ messageId }: { messageId: string } { messageId }: { messageId: string }
): Error | undefined { ): Error | undefined {
const { name, number, email, address, organization } = contact; const { number, email, address, organization } = contact;
if ((!name || !name.displayName) && !organization) { if (!getDisplayName(contact) && !organization) {
return new Error( return new Error(
`Message ${messageId}: Contact had neither 'displayName' nor 'organization'` `Message ${messageId}: Contact had neither 'displayName' nor 'organization'`
); );