Profile Management: Add Contact (#1519)
This commit is contained in:
parent
d82cdce9ef
commit
394b91533b
@ -28,7 +28,7 @@ export {
|
|||||||
export {
|
export {
|
||||||
fetchFullUser, fetchNearestCountry, fetchCountryList,
|
fetchFullUser, fetchNearestCountry, fetchCountryList,
|
||||||
fetchTopUsers, fetchContactList, fetchUsers,
|
fetchTopUsers, fetchContactList, fetchUsers,
|
||||||
updateContact, deleteUser, fetchProfilePhotos,
|
addContact, updateContact, deleteUser, fetchProfilePhotos,
|
||||||
} from './users';
|
} from './users';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
|||||||
@ -149,6 +149,27 @@ export function updateContact({
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function addContact({
|
||||||
|
id,
|
||||||
|
accessHash,
|
||||||
|
phoneNumber = '',
|
||||||
|
firstName = '',
|
||||||
|
lastName = '',
|
||||||
|
}: {
|
||||||
|
id: number;
|
||||||
|
accessHash?: string;
|
||||||
|
phoneNumber?: string;
|
||||||
|
firstName?: string;
|
||||||
|
lastName?: string;
|
||||||
|
}) {
|
||||||
|
return invokeRequest(new GramJs.contacts.AddContact({
|
||||||
|
id: buildInputEntity(id, accessHash) as GramJs.InputUser,
|
||||||
|
firstName,
|
||||||
|
lastName,
|
||||||
|
phone: phoneNumber,
|
||||||
|
}), true);
|
||||||
|
}
|
||||||
|
|
||||||
export async function deleteUser({
|
export async function deleteUser({
|
||||||
id,
|
id,
|
||||||
accessHash,
|
accessHash,
|
||||||
|
|||||||
@ -9,9 +9,13 @@ import { IAnchorPosition } from '../../types';
|
|||||||
|
|
||||||
import { IS_SINGLE_COLUMN_LAYOUT } from '../../util/environment';
|
import { IS_SINGLE_COLUMN_LAYOUT } from '../../util/environment';
|
||||||
import { disableScrolling, enableScrolling } from '../../util/scrollLock';
|
import { disableScrolling, enableScrolling } from '../../util/scrollLock';
|
||||||
import { selectChat, selectNotifySettings, selectNotifyExceptions } from '../../modules/selectors';
|
import {
|
||||||
|
selectChat, selectNotifySettings, selectNotifyExceptions, selectUser,
|
||||||
|
} from '../../modules/selectors';
|
||||||
import { pick } from '../../util/iteratees';
|
import { pick } from '../../util/iteratees';
|
||||||
import { isChatPrivate, getCanDeleteChat, selectIsChatMuted } from '../../modules/helpers';
|
import {
|
||||||
|
isChatPrivate, getCanDeleteChat, selectIsChatMuted, getCanAddContact,
|
||||||
|
} from '../../modules/helpers';
|
||||||
import useShowTransition from '../../hooks/useShowTransition';
|
import useShowTransition from '../../hooks/useShowTransition';
|
||||||
import useLang from '../../hooks/useLang';
|
import useLang from '../../hooks/useLang';
|
||||||
|
|
||||||
@ -23,7 +27,7 @@ import DeleteChatModal from '../common/DeleteChatModal';
|
|||||||
import './HeaderMenuContainer.scss';
|
import './HeaderMenuContainer.scss';
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, (
|
type DispatchProps = Pick<GlobalActions, (
|
||||||
'updateChatMutedState' | 'enterMessageSelectMode' | 'sendBotCommand' | 'restartBot' | 'openLinkedChat'
|
'updateChatMutedState' | 'enterMessageSelectMode' | 'sendBotCommand' | 'restartBot' | 'openLinkedChat' | 'addContact'
|
||||||
)>;
|
)>;
|
||||||
|
|
||||||
export type OwnProps = {
|
export type OwnProps = {
|
||||||
@ -48,6 +52,7 @@ type StateProps = {
|
|||||||
chat?: ApiChat;
|
chat?: ApiChat;
|
||||||
isPrivate?: boolean;
|
isPrivate?: boolean;
|
||||||
isMuted?: boolean;
|
isMuted?: boolean;
|
||||||
|
canAddContact?: boolean;
|
||||||
canDeleteChat?: boolean;
|
canDeleteChat?: boolean;
|
||||||
hasLinkedChat?: boolean;
|
hasLinkedChat?: boolean;
|
||||||
};
|
};
|
||||||
@ -68,6 +73,7 @@ const HeaderMenuContainer: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
isMuted,
|
isMuted,
|
||||||
canDeleteChat,
|
canDeleteChat,
|
||||||
hasLinkedChat,
|
hasLinkedChat,
|
||||||
|
canAddContact,
|
||||||
onSubscribeChannel,
|
onSubscribeChannel,
|
||||||
onSearchClick,
|
onSearchClick,
|
||||||
onClose,
|
onClose,
|
||||||
@ -77,6 +83,7 @@ const HeaderMenuContainer: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
sendBotCommand,
|
sendBotCommand,
|
||||||
restartBot,
|
restartBot,
|
||||||
openLinkedChat,
|
openLinkedChat,
|
||||||
|
addContact,
|
||||||
}) => {
|
}) => {
|
||||||
const [isMenuOpen, setIsMenuOpen] = useState(true);
|
const [isMenuOpen, setIsMenuOpen] = useState(true);
|
||||||
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
|
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
|
||||||
@ -117,6 +124,11 @@ const HeaderMenuContainer: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
closeMenu();
|
closeMenu();
|
||||||
}, [chatId, closeMenu, openLinkedChat]);
|
}, [chatId, closeMenu, openLinkedChat]);
|
||||||
|
|
||||||
|
const handleAddContactClick = useCallback(() => {
|
||||||
|
addContact({ userId: chatId });
|
||||||
|
closeMenu();
|
||||||
|
}, [addContact, chatId, closeMenu]);
|
||||||
|
|
||||||
const handleSubscribe = useCallback(() => {
|
const handleSubscribe = useCallback(() => {
|
||||||
onSubscribeChannel();
|
onSubscribeChannel();
|
||||||
closeMenu();
|
closeMenu();
|
||||||
@ -173,6 +185,14 @@ const HeaderMenuContainer: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
{lang(isChannel ? 'Subscribe' : 'Join Group')}
|
{lang(isChannel ? 'Subscribe' : 'Join Group')}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
)}
|
)}
|
||||||
|
{canAddContact && (
|
||||||
|
<MenuItem
|
||||||
|
icon="add-user"
|
||||||
|
onClick={handleAddContactClick}
|
||||||
|
>
|
||||||
|
{lang('AddContact')}
|
||||||
|
</MenuItem>
|
||||||
|
)}
|
||||||
{IS_SINGLE_COLUMN_LAYOUT && canSearch && (
|
{IS_SINGLE_COLUMN_LAYOUT && canSearch && (
|
||||||
<MenuItem
|
<MenuItem
|
||||||
icon="search"
|
icon="search"
|
||||||
@ -233,11 +253,15 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
if (!chat || chat.isRestricted) {
|
if (!chat || chat.isRestricted) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
const isPrivate = isChatPrivate(chat.id);
|
||||||
|
const user = isPrivate ? selectUser(global, chatId) : undefined;
|
||||||
|
const canAddContact = user && getCanAddContact(user);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
chat,
|
chat,
|
||||||
isMuted: selectIsChatMuted(chat, selectNotifySettings(global), selectNotifyExceptions(global)),
|
isMuted: selectIsChatMuted(chat, selectNotifySettings(global), selectNotifyExceptions(global)),
|
||||||
isPrivate: isChatPrivate(chat.id),
|
isPrivate,
|
||||||
|
canAddContact,
|
||||||
canDeleteChat: getCanDeleteChat(chat),
|
canDeleteChat: getCanDeleteChat(chat),
|
||||||
hasLinkedChat: Boolean(chat?.fullInfo?.linkedChatId),
|
hasLinkedChat: Boolean(chat?.fullInfo?.linkedChatId),
|
||||||
};
|
};
|
||||||
@ -248,5 +272,6 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
'sendBotCommand',
|
'sendBotCommand',
|
||||||
'restartBot',
|
'restartBot',
|
||||||
'openLinkedChat',
|
'openLinkedChat',
|
||||||
|
'addContact',
|
||||||
]),
|
]),
|
||||||
)(HeaderMenuContainer));
|
)(HeaderMenuContainer));
|
||||||
|
|||||||
@ -16,8 +16,14 @@ import {
|
|||||||
selectCurrentStickerSearch,
|
selectCurrentStickerSearch,
|
||||||
selectCurrentTextSearch,
|
selectCurrentTextSearch,
|
||||||
selectIsChatWithSelf,
|
selectIsChatWithSelf,
|
||||||
|
selectUser,
|
||||||
} from '../../modules/selectors';
|
} from '../../modules/selectors';
|
||||||
import { isChatAdmin, isChatChannel, isChatPrivate } from '../../modules/helpers';
|
import {
|
||||||
|
getCanAddContact,
|
||||||
|
isChatAdmin,
|
||||||
|
isChatChannel,
|
||||||
|
isChatPrivate,
|
||||||
|
} from '../../modules/helpers';
|
||||||
import useCurrentOrPrev from '../../hooks/useCurrentOrPrev';
|
import useCurrentOrPrev from '../../hooks/useCurrentOrPrev';
|
||||||
import useLang from '../../hooks/useLang';
|
import useLang from '../../hooks/useLang';
|
||||||
|
|
||||||
@ -44,8 +50,10 @@ type OwnProps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
type StateProps = {
|
type StateProps = {
|
||||||
|
canAddContact?: boolean;
|
||||||
canManage?: boolean;
|
canManage?: boolean;
|
||||||
isChannel?: boolean;
|
isChannel?: boolean;
|
||||||
|
userId?: number;
|
||||||
messageSearchQuery?: string;
|
messageSearchQuery?: string;
|
||||||
stickerSearchQuery?: string;
|
stickerSearchQuery?: string;
|
||||||
gifSearchQuery?: string;
|
gifSearchQuery?: string;
|
||||||
@ -53,7 +61,7 @@ type StateProps = {
|
|||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, (
|
type DispatchProps = Pick<GlobalActions, (
|
||||||
'setLocalTextSearchQuery' | 'setStickerSearchQuery' | 'setGifSearchQuery' |
|
'setLocalTextSearchQuery' | 'setStickerSearchQuery' | 'setGifSearchQuery' |
|
||||||
'searchTextMessagesLocal' | 'toggleManagement' | 'openHistoryCalendar'
|
'searchTextMessagesLocal' | 'toggleManagement' | 'openHistoryCalendar' | 'addContact'
|
||||||
)>;
|
)>;
|
||||||
|
|
||||||
const COLUMN_CLOSE_DELAY_MS = 300;
|
const COLUMN_CLOSE_DELAY_MS = 300;
|
||||||
@ -94,6 +102,8 @@ const RightHeader: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
isAddingChatMembers,
|
isAddingChatMembers,
|
||||||
profileState,
|
profileState,
|
||||||
managementScreen,
|
managementScreen,
|
||||||
|
canAddContact,
|
||||||
|
userId,
|
||||||
canManage,
|
canManage,
|
||||||
isChannel,
|
isChannel,
|
||||||
onClose,
|
onClose,
|
||||||
@ -107,6 +117,7 @@ const RightHeader: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
toggleManagement,
|
toggleManagement,
|
||||||
openHistoryCalendar,
|
openHistoryCalendar,
|
||||||
shouldSkipAnimation,
|
shouldSkipAnimation,
|
||||||
|
addContact,
|
||||||
}) => {
|
}) => {
|
||||||
// eslint-disable-next-line no-null/no-null
|
// eslint-disable-next-line no-null/no-null
|
||||||
const backButtonRef = useRef<HTMLDivElement>(null);
|
const backButtonRef = useRef<HTMLDivElement>(null);
|
||||||
@ -127,6 +138,10 @@ const RightHeader: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
setGifSearchQuery({ query });
|
setGifSearchQuery({ query });
|
||||||
}, [setGifSearchQuery]);
|
}, [setGifSearchQuery]);
|
||||||
|
|
||||||
|
const handleAddContact = useCallback(() => {
|
||||||
|
addContact({ userId });
|
||||||
|
}, [addContact, userId]);
|
||||||
|
|
||||||
const [shouldSkipTransition, setShouldSkipTransition] = useState(!isColumnOpen);
|
const [shouldSkipTransition, setShouldSkipTransition] = useState(!isColumnOpen);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -263,6 +278,17 @@ const RightHeader: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
<>
|
<>
|
||||||
<h3>Profile</h3>
|
<h3>Profile</h3>
|
||||||
<section className="tools">
|
<section className="tools">
|
||||||
|
{canAddContact && (
|
||||||
|
<Button
|
||||||
|
round
|
||||||
|
color="translucent"
|
||||||
|
size="smaller"
|
||||||
|
ariaLabel={lang('AddContact')}
|
||||||
|
onClick={handleAddContact}
|
||||||
|
>
|
||||||
|
<i className="icon-add-user" />
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
{canManage && (
|
{canManage && (
|
||||||
<Button
|
<Button
|
||||||
round
|
round
|
||||||
@ -323,10 +349,13 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
const { query: gifSearchQuery } = selectCurrentGifSearch(global) || {};
|
const { query: gifSearchQuery } = selectCurrentGifSearch(global) || {};
|
||||||
const chat = chatId ? selectChat(global, chatId) : undefined;
|
const chat = chatId ? selectChat(global, chatId) : undefined;
|
||||||
const isChannel = chat && isChatChannel(chat);
|
const isChannel = chat && isChatChannel(chat);
|
||||||
|
const user = isProfile && chatId && isChatPrivate(chatId) ? selectUser(global, chatId) : undefined;
|
||||||
|
|
||||||
|
const canAddContact = user && getCanAddContact(user);
|
||||||
const canManage = Boolean(
|
const canManage = Boolean(
|
||||||
!isManagement
|
!isManagement
|
||||||
&& isProfile
|
&& isProfile
|
||||||
|
&& !canAddContact
|
||||||
&& chat
|
&& chat
|
||||||
&& !selectIsChatWithSelf(global, chat.id)
|
&& !selectIsChatWithSelf(global, chat.id)
|
||||||
// chat.isCreator is for Basic Groups
|
// chat.isCreator is for Basic Groups
|
||||||
@ -335,7 +364,9 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
canManage,
|
canManage,
|
||||||
|
canAddContact,
|
||||||
isChannel,
|
isChannel,
|
||||||
|
userId: user?.id,
|
||||||
messageSearchQuery,
|
messageSearchQuery,
|
||||||
stickerSearchQuery,
|
stickerSearchQuery,
|
||||||
gifSearchQuery,
|
gifSearchQuery,
|
||||||
@ -348,5 +379,6 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
'searchTextMessagesLocal',
|
'searchTextMessagesLocal',
|
||||||
'toggleManagement',
|
'toggleManagement',
|
||||||
'openHistoryCalendar',
|
'openHistoryCalendar',
|
||||||
|
'addContact',
|
||||||
]),
|
]),
|
||||||
)(RightHeader));
|
)(RightHeader));
|
||||||
|
|||||||
@ -504,7 +504,7 @@ export type ActionTypes = (
|
|||||||
'acceptInviteConfirmation' |
|
'acceptInviteConfirmation' |
|
||||||
// users
|
// users
|
||||||
'loadFullUser' | 'openUserInfo' | 'loadNearestCountry' | 'loadCountryList' | 'loadTopUsers' | 'loadContactList' |
|
'loadFullUser' | 'openUserInfo' | 'loadNearestCountry' | 'loadCountryList' | 'loadTopUsers' | 'loadContactList' |
|
||||||
'loadCurrentUser' | 'updateProfile' | 'checkUsername' | 'updateContact' |
|
'loadCurrentUser' | 'updateProfile' | 'checkUsername' | 'addContact' | 'updateContact' |
|
||||||
'deleteUser' | 'loadUser' | 'setUserSearchQuery' |
|
'deleteUser' | 'loadUser' | 'setUserSearchQuery' |
|
||||||
// Channel / groups creation
|
// Channel / groups creation
|
||||||
'createChannel' | 'createGroupChat' | 'resetChatCreation' |
|
'createChannel' | 'createGroupChat' | 'resetChatCreation' |
|
||||||
|
|||||||
@ -36,5 +36,5 @@ if (DEBUG) {
|
|||||||
|
|
||||||
document.addEventListener('dblclick', () => {
|
document.addEventListener('dblclick', () => {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.log('GLOBAL STATE', getGlobal());
|
console.warn('GLOBAL STATE', getGlobal());
|
||||||
});
|
});
|
||||||
|
|||||||
@ -969,6 +969,7 @@ contacts.getBlocked#f57c350f offset:int limit:int = contacts.Blocked;
|
|||||||
contacts.search#11f812d8 q:string limit:int = contacts.Found;
|
contacts.search#11f812d8 q:string limit:int = contacts.Found;
|
||||||
contacts.resolveUsername#f93ccba3 username:string = contacts.ResolvedPeer;
|
contacts.resolveUsername#f93ccba3 username:string = contacts.ResolvedPeer;
|
||||||
contacts.getTopPeers#d4982db5 flags:# correspondents:flags.0?true bots_pm:flags.1?true bots_inline:flags.2?true phone_calls:flags.3?true forward_users:flags.4?true forward_chats:flags.5?true groups:flags.10?true channels:flags.15?true offset:int limit:int hash:int = contacts.TopPeers;
|
contacts.getTopPeers#d4982db5 flags:# correspondents:flags.0?true bots_pm:flags.1?true bots_inline:flags.2?true phone_calls:flags.3?true forward_users:flags.4?true forward_chats:flags.5?true groups:flags.10?true channels:flags.15?true offset:int limit:int hash:int = contacts.TopPeers;
|
||||||
|
contacts.addContact#e8f463d0 flags:# add_phone_privacy_exception:flags.0?true id:InputUser first_name:string last_name:string phone:string = Updates;
|
||||||
messages.getMessages#63c66506 id:Vector<InputMessage> = messages.Messages;
|
messages.getMessages#63c66506 id:Vector<InputMessage> = messages.Messages;
|
||||||
messages.getDialogs#a0ee3b73 flags:# exclude_pinned:flags.0?true folder_id:flags.1?int offset_date:int offset_id:int offset_peer:InputPeer limit:int hash:int = messages.Dialogs;
|
messages.getDialogs#a0ee3b73 flags:# exclude_pinned:flags.0?true folder_id:flags.1?int offset_date:int offset_id:int offset_peer:InputPeer limit:int hash:int = messages.Dialogs;
|
||||||
messages.getHistory#dcbb8260 peer:InputPeer offset_id:int offset_date:int add_offset:int limit:int max_id:int min_id:int hash:int = messages.Messages;
|
messages.getHistory#dcbb8260 peer:InputPeer offset_id:int offset_date:int add_offset:int limit:int max_id:int min_id:int hash:int = messages.Messages;
|
||||||
|
|||||||
@ -970,6 +970,7 @@ contacts.getBlocked#f57c350f offset:int limit:int = contacts.Blocked;
|
|||||||
contacts.search#11f812d8 q:string limit:int = contacts.Found;
|
contacts.search#11f812d8 q:string limit:int = contacts.Found;
|
||||||
contacts.resolveUsername#f93ccba3 username:string = contacts.ResolvedPeer;
|
contacts.resolveUsername#f93ccba3 username:string = contacts.ResolvedPeer;
|
||||||
contacts.getTopPeers#d4982db5 flags:# correspondents:flags.0?true bots_pm:flags.1?true bots_inline:flags.2?true phone_calls:flags.3?true forward_users:flags.4?true forward_chats:flags.5?true groups:flags.10?true channels:flags.15?true offset:int limit:int hash:int = contacts.TopPeers;
|
contacts.getTopPeers#d4982db5 flags:# correspondents:flags.0?true bots_pm:flags.1?true bots_inline:flags.2?true phone_calls:flags.3?true forward_users:flags.4?true forward_chats:flags.5?true groups:flags.10?true channels:flags.15?true offset:int limit:int hash:int = contacts.TopPeers;
|
||||||
|
contacts.addContact#e8f463d0 flags:# add_phone_privacy_exception:flags.0?true id:InputUser first_name:string last_name:string phone:string = Updates;
|
||||||
messages.getMessages#63c66506 id:Vector<InputMessage> = messages.Messages;
|
messages.getMessages#63c66506 id:Vector<InputMessage> = messages.Messages;
|
||||||
messages.getDialogs#a0ee3b73 flags:# exclude_pinned:flags.0?true folder_id:flags.1?int offset_date:int offset_id:int offset_peer:InputPeer limit:int hash:int = messages.Dialogs;
|
messages.getDialogs#a0ee3b73 flags:# exclude_pinned:flags.0?true folder_id:flags.1?int offset_date:int offset_id:int offset_peer:InputPeer limit:int hash:int = messages.Dialogs;
|
||||||
messages.getHistory#dcbb8260 peer:InputPeer offset_id:int offset_date:int add_offset:int limit:int max_id:int min_id:int hash:int = messages.Messages;
|
messages.getHistory#dcbb8260 peer:InputPeer offset_id:int offset_date:int add_offset:int limit:int max_id:int min_id:int hash:int = messages.Messages;
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import { ApiUser } from '../../../api/types';
|
|||||||
import { ManagementProgress } from '../../../types';
|
import { ManagementProgress } from '../../../types';
|
||||||
|
|
||||||
import { debounce, throttle } from '../../../util/schedulers';
|
import { debounce, throttle } from '../../../util/schedulers';
|
||||||
import { buildCollectionByKey } from '../../../util/iteratees';
|
import { buildCollectionByKey, pick } from '../../../util/iteratees';
|
||||||
import { isChatPrivate } from '../../helpers';
|
import { isChatPrivate } from '../../helpers';
|
||||||
import { callApi } from '../../../api/gramjs';
|
import { callApi } from '../../../api/gramjs';
|
||||||
import { selectChat, selectUser } from '../../selectors';
|
import { selectChat, selectUser } from '../../selectors';
|
||||||
@ -150,7 +150,19 @@ async function updateContact(
|
|||||||
|
|
||||||
setGlobal(updateManagementProgress(getGlobal(), ManagementProgress.InProgress));
|
setGlobal(updateManagementProgress(getGlobal(), ManagementProgress.InProgress));
|
||||||
|
|
||||||
const result = await callApi('updateContact', { phone: user.phoneNumber, firstName, lastName });
|
let result;
|
||||||
|
if (user.phoneNumber) {
|
||||||
|
result = await callApi('updateContact', { phone: user.phoneNumber, firstName, lastName });
|
||||||
|
} else {
|
||||||
|
const { id, accessHash } = user;
|
||||||
|
result = await callApi('addContact', {
|
||||||
|
id,
|
||||||
|
accessHash,
|
||||||
|
phoneNumber: '',
|
||||||
|
firstName,
|
||||||
|
lastName,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
setGlobal(updateUser(
|
setGlobal(updateUser(
|
||||||
@ -217,6 +229,16 @@ addReducer('setUserSearchQuery', (global, actions, payload) => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
addReducer('addContact', (global, actions, payload) => {
|
||||||
|
const { userId } = payload!;
|
||||||
|
const user = selectUser(global, userId);
|
||||||
|
if (!user) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void callApi('addContact', pick(user, ['id', 'accessHash', 'firstName', 'lastName', 'phoneNumber']));
|
||||||
|
});
|
||||||
|
|
||||||
async function searchUsers(query: string) {
|
async function searchUsers(query: string) {
|
||||||
const result = await callApi('searchChats', { query });
|
const result = await callApi('searchChats', { query });
|
||||||
|
|
||||||
|
|||||||
@ -183,6 +183,10 @@ export function isUserBot(user: ApiUser) {
|
|||||||
return user.type === 'userTypeBot';
|
return user.type === 'userTypeBot';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getCanAddContact(user: ApiUser) {
|
||||||
|
return !user.isContact && !isUserBot(user);
|
||||||
|
}
|
||||||
|
|
||||||
export function sortUserIds(
|
export function sortUserIds(
|
||||||
userIds: number[],
|
userIds: number[],
|
||||||
usersById: Record<number, ApiUser>,
|
usersById: Record<number, ApiUser>,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user