Allow adding to a group by phone number

This commit is contained in:
Fedor Indutny 2022-04-04 17:38:22 -07:00 committed by GitHub
parent 76a1a805ef
commit 9568d5792e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
49 changed files with 1842 additions and 693 deletions

View file

@ -7,12 +7,13 @@ import { OneTimeModalState } from '../../groups/toggleSelectedContactForGroupAdd
export const defaultStartDirectConversationComposerState = {
step: ComposerStep.StartDirectConversation as const,
searchTerm: '',
isFetchingUsername: false,
uuidFetchState: {},
};
export const defaultChooseGroupMembersComposerState = {
step: ComposerStep.ChooseGroupMembers as const,
searchTerm: '',
uuidFetchState: {},
groupAvatar: undefined,
groupName: '',
groupExpireTimer: 0,

View file

@ -0,0 +1,103 @@
// Copyright 2022 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import { useState } from 'react';
import type {
UUIDFetchStateType,
UUIDFetchStateKeyType,
} from '../../util/uuidFetchState';
import type { lookupConversationWithoutUuid } from '../../util/lookupConversationWithoutUuid';
import { sleep } from '../../util/sleep';
import * as durations from '../../util/durations';
import type { ConversationType } from '../../state/ducks/conversations';
import { getDefaultConversation } from './getDefaultConversation';
const VALID_IDENTIFIERS = new Set<UUIDFetchStateKeyType>([
'e164:+12125551234',
'username:bobross',
]);
export function makeFakeLookupConversationWithoutUuid(
saveConversation?: (convo: ConversationType) => void
): typeof lookupConversationWithoutUuid {
const cache = new Map<UUIDFetchStateKeyType, ConversationType>();
return async options => {
const identifier: UUIDFetchStateKeyType =
options.type === 'e164'
? `e164:${options.e164}`
: `username:${options.username}`;
let result = cache.get(identifier);
if (result) {
return result.id;
}
if (VALID_IDENTIFIERS.has(identifier) && saveConversation) {
result = getDefaultConversation({
// We don't really know anything about the contact
firstName: undefined,
avatarPath: undefined,
name: undefined,
profileName: undefined,
...(options.type === 'e164'
? {
title: options.e164,
e164: options.e164,
phoneNumber: options.e164,
}
: {
title: `@${options.username}`,
username: options.username,
}),
});
cache.set(identifier, result);
saveConversation(result);
}
options.setIsFetchingUUID(identifier, true);
await sleep(durations.SECOND);
options.setIsFetchingUUID(identifier, false);
if (!result) {
options.showUserNotFoundModal(
options.type === 'username'
? options
: {
type: 'phoneNumber',
phoneNumber: options.phoneNumber,
}
);
return undefined;
}
return result.id;
};
}
type SetIsFetchingUUIDType = (
identifier: UUIDFetchStateKeyType,
isFetching: boolean
) => void;
export function useUuidFetchState(
initial: UUIDFetchStateType = {}
): [UUIDFetchStateType, SetIsFetchingUUIDType] {
const [uuidFetchState, setUuidFetchState] = useState(initial);
const setIsFetchingUUID: SetIsFetchingUUIDType = (key, value) => {
setUuidFetchState(prev => {
return {
...prev,
[key]: value,
};
});
};
return [uuidFetchState, setIsFetchingUUID];
}

View file

@ -977,8 +977,7 @@ describe('both/state/selectors/conversations', () => {
const result = getFilteredComposeContacts(state);
const ids = result.map(contact => contact.id);
// NOTE: convo-6 matches because you can't write "Sharing" without "in"
assert.deepEqual(ids, ['convo-1', 'convo-5', 'convo-6']);
assert.deepEqual(ids, ['convo-1', 'convo-5']);
});
it('can search for note to self', () => {

View file

@ -38,9 +38,11 @@ describe('filterAndSortConversationsByTitle', () => {
];
it('without a search term, sorts conversations by title (but puts no-name contacts at the bottom)', () => {
const titles = filterAndSortConversationsByTitle(conversations, '').map(
contact => contact.title
);
const titles = filterAndSortConversationsByTitle(
conversations,
'',
'US'
).map(contact => contact.title);
assert.deepEqual(titles, [
'Aaron Aardvark',
'Belinda Beetle',
@ -53,7 +55,8 @@ describe('filterAndSortConversationsByTitle', () => {
it('can search for contacts by title', () => {
const titles = filterAndSortConversationsByTitle(
conversations,
'belind'
'belind',
'US'
).map(contact => contact.title);
assert.sameMembers(titles, ['Belinda Beetle', 'Belinda Zephyr']);
});
@ -61,15 +64,26 @@ describe('filterAndSortConversationsByTitle', () => {
it('can search for contacts by phone number (and puts no-name contacts at the bottom)', () => {
const titles = filterAndSortConversationsByTitle(
conversations,
'650555'
'650555',
'US'
).map(contact => contact.title);
assert.sameMembers(titles, ['Carlos Santana', '+16505551234']);
});
it('can search for contacts by formatted phone number (and puts no-name contacts at the bottom)', () => {
const titles = filterAndSortConversationsByTitle(
conversations,
'(650)555 12-34',
'US'
).map(contact => contact.title);
assert.sameMembers(titles, ['+16505551234']);
});
it('can search for contacts by username', () => {
const titles = filterAndSortConversationsByTitle(
conversations,
'thisis'
'thisis',
'US'
).map(contact => contact.title);
assert.sameMembers(titles, ['Carlos Santana']);
});
@ -100,9 +114,11 @@ describe('filterAndSortConversationsByRecent', () => {
];
it('sorts by recency when no search term is provided', () => {
const titles = filterAndSortConversationsByRecent(conversations, '').map(
contact => contact.title
);
const titles = filterAndSortConversationsByRecent(
conversations,
'',
'US'
).map(contact => contact.title);
assert.sameMembers(titles, [
'+16505551234',
'George Washington',