Use ContactRecord.systemNickname

This commit is contained in:
Fedor Indutny 2023-02-13 14:40:11 -08:00 committed by GitHub
parent 949efca190
commit 1f95c2299e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 91 additions and 57 deletions

View file

@ -192,7 +192,7 @@
"@babel/preset-typescript": "7.17.12",
"@electron/fuses": "1.5.0",
"@mixer/parallel-prettier": "2.0.1",
"@signalapp/mock-server": "2.14.0",
"@signalapp/mock-server": "2.15.0",
"@storybook/addon-a11y": "6.5.6",
"@storybook/addon-actions": "6.5.6",
"@storybook/addon-controls": "6.5.6",

View file

@ -95,6 +95,7 @@ message ContactRecord {
optional uint64 unregisteredAtTimestamp = 16;
optional string systemGivenName = 17;
optional string systemFamilyName = 18;
optional string systemNickname = 19;
}
message GroupV1Record {

1
ts/model-types.d.ts vendored
View file

@ -327,6 +327,7 @@ export type ConversationAttributesType = {
name?: string;
systemGivenName?: string;
systemFamilyName?: string;
systemNickname?: string;
needsStorageServiceSync?: boolean;
needsVerification?: boolean;
profileSharing?: boolean;

View file

@ -352,7 +352,8 @@ export class ConversationModel extends window.Backbone
this.on('newmessage', this.onNewMessage);
this.on('change:profileKey', this.onChangeProfileKey);
this.on(
'change:name change:profileName change:profileFamilyName change:e164',
'change:name change:profileName change:profileFamilyName change:e164 ' +
'change:systemGivenName change:systemFamilyName change:systemNickname',
() => this.maybeClearUsername()
);
@ -1910,6 +1911,7 @@ export class ConversationModel extends window.Backbone
name: this.get('name'),
systemGivenName: this.get('systemGivenName'),
systemFamilyName: this.get('systemFamilyName'),
systemNickname: this.get('systemNickname'),
phoneNumber: this.getNumber(),
profileName: this.getProfileName(),
profileSharing: this.get('profileSharing'),

View file

@ -198,6 +198,10 @@ export async function toContactRecord(
if (systemFamilyName) {
contactRecord.systemFamilyName = systemFamilyName;
}
const systemNickname = conversation.get('systemNickname');
if (systemNickname) {
contactRecord.systemNickname = systemNickname;
}
contactRecord.blocked = conversation.isBlocked();
contactRecord.whitelisted = Boolean(conversation.get('profileSharing'));
contactRecord.archived = Boolean(conversation.get('isArchived'));
@ -1033,6 +1037,7 @@ export async function mergeContactRecord(
conversation.set({
systemGivenName: dropNull(contactRecord.systemGivenName),
systemFamilyName: dropNull(contactRecord.systemFamilyName),
systemNickname: dropNull(contactRecord.systemNickname),
});
// https://github.com/signalapp/Signal-Android/blob/fc3db538bcaa38dc149712a483d3032c9c1f3998/app/src/main/java/org/thoughtcrime/securesms/database/RecipientDatabase.kt#L921-L936

View file

@ -193,6 +193,7 @@ export type ConversationType = ReadonlyDeep<
name?: string;
systemGivenName?: string;
systemFamilyName?: string;
systemNickname?: string;
familyName?: string;
firstName?: string;
profileName?: string;

View file

@ -80,60 +80,75 @@ describe('pnp/username', function needsName() {
await bootstrap.teardown();
});
it('drops username when contact name becomes known', async () => {
const { phone } = bootstrap;
for (const type of ['profile', 'system']) {
// eslint-disable-next-line no-loop-func
it(`drops username when contact's ${type} name becomes known`, async () => {
const { phone } = bootstrap;
const window = await app.getWindow();
const leftPane = window.locator('.left-pane-wrapper');
const window = await app.getWindow();
const leftPane = window.locator('.left-pane-wrapper');
debug('find username in the left pane');
await leftPane
.locator(
`[data-testid="${usernameContact.device.uuid}"] >> "${USERNAME}"`
)
.waitFor();
debug('find username in the left pane');
await leftPane
.locator(
`[data-testid="${usernameContact.device.uuid}"] >> "${USERNAME}"`
)
.waitFor();
debug('adding profile key for username contact');
let state = await phone.expectStorageState('consistency check');
state = state.updateContact(usernameContact, {
profileKey: usernameContact.profileKey.serialize(),
});
await phone.setStorageState(state);
await phone.sendFetchStorage({
timestamp: bootstrap.getTimestamp(),
});
let state = await phone.expectStorageState('consistency check');
debug('find profile name in the left pane');
await leftPane
.locator(
`[data-testid="${usernameContact.device.uuid}"] >> ` +
`"${usernameContact.profileName}"`
)
.waitFor();
debug('verify that storage service state is updated');
{
const newState = await phone.waitForStorageState({
after: state,
if (type === 'profile') {
debug('adding profile key for username contact');
state = state.updateContact(usernameContact, {
profileKey: usernameContact.profileKey.serialize(),
});
} else {
debug('adding nickname for username contact');
state = state.updateContact(usernameContact, {
systemNickname: usernameContact.profileName,
});
}
await phone.setStorageState(state);
await phone.sendFetchStorage({
timestamp: bootstrap.getTimestamp(),
});
const { added, removed } = newState.diff(state);
assert.strictEqual(added.length, 1, 'only one record must be added');
assert.strictEqual(removed.length, 1, 'only one record must be removed');
debug('find profile name in the left pane');
await leftPane
.locator(
`[data-testid="${usernameContact.device.uuid}"] >> ` +
`"${usernameContact.profileName}"`
)
.waitFor();
assert.strictEqual(
added[0].contact?.serviceUuid,
usernameContact.device.uuid
);
assert.strictEqual(added[0].contact?.username, '');
debug('verify that storage service state is updated');
{
const newState = await phone.waitForStorageState({
after: state,
});
assert.strictEqual(
removed[0].contact?.serviceUuid,
usernameContact.device.uuid
);
assert.strictEqual(removed[0].contact?.username, USERNAME);
}
});
const { added, removed } = newState.diff(state);
assert.strictEqual(added.length, 1, 'only one record must be added');
assert.strictEqual(
removed.length,
1,
'only one record must be removed'
);
assert.strictEqual(
added[0].contact?.serviceUuid,
usernameContact.device.uuid
);
assert.strictEqual(added[0].contact?.username, '');
assert.strictEqual(
removed[0].contact?.serviceUuid,
usernameContact.device.uuid
);
assert.strictEqual(removed[0].contact?.username, USERNAME);
}
});
}
it('reserves/confirms/deletes username', async () => {
const { phone, server } = bootstrap;

View file

@ -49,7 +49,16 @@ export function getTitleNoDefault(
export function canHaveUsername(
attributes: Pick<
ConversationAttributesType,
'id' | 'type' | 'name' | 'profileName' | 'profileFamilyName' | 'e164'
| 'id'
| 'type'
| 'name'
| 'profileName'
| 'profileFamilyName'
| 'e164'
| 'systemGivenName'
| 'systemFamilyName'
| 'systemNickname'
| 'type'
>,
ourConversationId: string | undefined
): boolean {
@ -84,13 +93,13 @@ export function getProfileName(
export function getSystemName(
attributes: Pick<
ConversationAttributesType,
'systemGivenName' | 'systemFamilyName' | 'type'
'systemGivenName' | 'systemFamilyName' | 'systemNickname' | 'type'
>
): string | undefined {
if (isDirectConversation(attributes)) {
return combineNames(
attributes.systemGivenName,
attributes.systemFamilyName
return (
attributes.systemNickname ||
combineNames(attributes.systemGivenName, attributes.systemFamilyName)
);
}

View file

@ -2170,10 +2170,10 @@
node-gyp-build "^4.2.3"
uuid "^8.3.0"
"@signalapp/mock-server@2.14.0":
version "2.14.0"
resolved "https://registry.yarnpkg.com/@signalapp/mock-server/-/mock-server-2.14.0.tgz#6309d944cf46e58f6141df45075de882d964ae0a"
integrity sha512-NSLnfjho4HCyrz4Y6cyoIK0f+iuhOrxEFmaabdVUepOaSHPZi1MTyYYo0d6NzD/PGREAQFJuzqNaE+7zhSiPEQ==
"@signalapp/mock-server@2.15.0":
version "2.15.0"
resolved "https://registry.yarnpkg.com/@signalapp/mock-server/-/mock-server-2.15.0.tgz#de86ddc4c3f7cbe1e91941832c4b317946e90364"
integrity sha512-bxu4hpnEAAvDT7Yg2LZQNIL/9ciNrGG0hPJlj+dT2iwsHo2AAP8Ej4sLfAiy0O2kYbf2bKcvfTE9C+XwkdAW+w==
dependencies:
"@signalapp/libsignal-client" "^0.22.0"
debug "^4.3.2"