Allow adding to a group by phone number
This commit is contained in:
parent
76a1a805ef
commit
9568d5792e
49 changed files with 1842 additions and 693 deletions
|
@ -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,
|
||||
|
|
103
ts/test-both/helpers/fakeLookupConversationWithoutUuid.ts
Normal file
103
ts/test-both/helpers/fakeLookupConversationWithoutUuid.ts
Normal 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];
|
||||
}
|
|
@ -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', () => {
|
||||
|
|
|
@ -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',
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue