From 6807009831f864cc19f9a4008889ce5aaffeda7f Mon Sep 17 00:00:00 2001 From: Alexander Zinchuk Date: Tue, 10 Jan 2023 02:07:39 +0100 Subject: [PATCH] [Refactoring] Store users from all responses (#2238) --- src/api/gramjs/methods/bots.ts | 1 + src/api/gramjs/methods/calls.ts | 24 ++++- src/api/gramjs/methods/chats.ts | 13 ++- src/api/gramjs/methods/management.ts | 14 ++- src/api/gramjs/methods/messages.ts | 6 ++ src/api/gramjs/methods/payments.ts | 8 +- src/api/gramjs/methods/settings.ts | 42 ++++++-- src/api/gramjs/methods/statistics.ts | 19 +++- src/api/gramjs/methods/users.ts | 5 + .../left/settings/SettingsLanguage.tsx | 5 +- src/global/actions/api/accounts.ts | 14 ++- src/global/actions/api/bots.ts | 3 +- src/global/actions/api/calls.async.ts | 14 ++- src/global/actions/api/chats.ts | 18 +++- src/global/actions/api/initial.ts | 12 ++- src/global/actions/api/management.ts | 12 ++- src/global/actions/api/messages.ts | 8 +- src/global/actions/api/payments.ts | 6 +- src/global/actions/api/settings.ts | 98 ++++++++++--------- src/global/actions/api/statistics.ts | 16 +-- src/global/actions/api/users.ts | 5 +- src/global/actions/apiUpdaters/calls.async.ts | 10 +- 22 files changed, 249 insertions(+), 104 deletions(-) diff --git a/src/api/gramjs/methods/bots.ts b/src/api/gramjs/methods/bots.ts index d71a306c5..2fceb95a9 100644 --- a/src/api/gramjs/methods/bots.ts +++ b/src/api/gramjs/methods/bots.ts @@ -273,6 +273,7 @@ export async function loadAttachBots({ return { hash: result.hash.toString(), bots: buildCollectionByKey(result.bots.map(buildApiAttachBot), 'id'), + users: result.users.map(buildApiUser).filter(Boolean), }; } return undefined; diff --git a/src/api/gramjs/methods/calls.ts b/src/api/gramjs/methods/calls.ts index 53d22c65b..639652277 100644 --- a/src/api/gramjs/methods/calls.ts +++ b/src/api/gramjs/methods/calls.ts @@ -276,7 +276,7 @@ export async function requestCall({ })); if (!result) { - return false; + return undefined; } const call = buildPhoneCall(result.phoneCall); @@ -286,7 +286,11 @@ export async function requestCall({ call, }); - return true; + addEntitiesWithPhotosToLocalDb(result.users); + + return { + users: result.users.map(buildApiUser).filter(Boolean), + }; } export function setCallRating({ @@ -323,7 +327,7 @@ export async function acceptCall({ })); if (!result) { - return; + return undefined; } call = buildPhoneCall(result.phoneCall); @@ -332,6 +336,12 @@ export async function acceptCall({ '@type': 'updatePhoneCall', call, }); + + addEntitiesWithPhotosToLocalDb(result.users); + + return { + users: result.users.map(buildApiUser).filter(Boolean), + }; } export async function confirmCall({ @@ -347,7 +357,7 @@ export async function confirmCall({ })); if (!result) { - return; + return undefined; } call = buildPhoneCall(result.phoneCall); @@ -356,6 +366,12 @@ export async function confirmCall({ '@type': 'updatePhoneCall', call, }); + + addEntitiesWithPhotosToLocalDb(result.users); + + return { + users: result.users.map(buildApiUser).filter(Boolean), + }; } export function sendSignalingData({ diff --git a/src/api/gramjs/methods/chats.ts b/src/api/gramjs/methods/chats.ts index b50532d1c..a6269fbcb 100644 --- a/src/api/gramjs/methods/chats.ts +++ b/src/api/gramjs/methods/chats.ts @@ -215,7 +215,12 @@ export async function fetchChatSettings(chat: ApiChat) { return undefined; } - return buildApiChatSettings(result.settings); + addEntitiesWithPhotosToLocalDb(result.users); + + return { + users: result.users.map(buildApiUser).filter(Boolean), + settings: buildApiChatSettings(result.settings), + }; } export async function searchChats({ query }: { query: string }) { @@ -393,6 +398,7 @@ async function getFullChatInfo(chatId: string): Promise isAdmin || isOwner) : undefined; const botCommands = botInfo ? buildApiChatBotCommands(botInfo) : undefined; + const inviteLink = exportedInvite instanceof GramJs.ChatInviteExported ? exportedInvite.link : undefined; const { users, userStatusesById } = buildApiUsersAndStatuses(result.users); return { @@ -403,10 +409,7 @@ async function getFullChatInfo(chatId: string): Promise invite instanceof GramJs.ChatInviteExported)) .map(buildApiExportedInvite); + + return { + invites, + users: exportedInvites.users.map(buildApiUser).filter(Boolean), + }; } export async function editExportedChatInvite({ @@ -119,7 +123,6 @@ export async function editExportedChatInvite({ isRequestNeeded?: boolean; title?: string; }) { - // TODO Verify Exported Invite logic const invite = await invokeRequest(new GramJs.messages.EditExportedChatInvite({ link, peer: buildInputPeer(peer.id, peer.accessHash), @@ -138,6 +141,7 @@ export async function editExportedChatInvite({ return { oldInvite: replaceInvite, newInvite: replaceInvite, + users: invite.users.map(buildApiUser).filter(Boolean), }; } @@ -149,6 +153,7 @@ export async function editExportedChatInvite({ return { oldInvite, newInvite, + users: invite.users.map(buildApiUser).filter(Boolean), }; } return undefined; @@ -171,7 +176,6 @@ export async function exportChatInvite({ title, })); - // TODO Verify Exported Invite logic if (!(invite instanceof GramJs.ChatInviteExported)) return undefined; return buildApiExportedInvite(invite); } diff --git a/src/api/gramjs/methods/messages.ts b/src/api/gramjs/methods/messages.ts index a51416c3e..3ea3b5615 100644 --- a/src/api/gramjs/methods/messages.ts +++ b/src/api/gramjs/methods/messages.ts @@ -908,8 +908,14 @@ export async function requestThreadInfoUpdate({ }); } + addEntitiesWithPhotosToLocalDb(topMessageResult.users); + addEntitiesWithPhotosToLocalDb(topMessageResult.chats); + + const users = topMessageResult.users.map(buildApiUser).filter(Boolean); + return { discussionChatId, + users, }; } diff --git a/src/api/gramjs/methods/payments.ts b/src/api/gramjs/methods/payments.ts index 89c0f79cd..929190f81 100644 --- a/src/api/gramjs/methods/payments.ts +++ b/src/api/gramjs/methods/payments.ts @@ -126,6 +126,7 @@ export async function getPaymentForm(inputInvoice: ApiRequestInputInvoice) { return { form: buildApiPaymentForm(result), invoice: buildApiInvoiceFromForm(result), + users: result.users.map(buildApiUser).filter(Boolean), }; } @@ -139,7 +140,12 @@ export async function getReceipt(chat: ApiChat, msgId: number) { return undefined; } - return buildApiReceipt(result); + addEntitiesWithPhotosToLocalDb(result.users); + + return { + receipt: buildApiReceipt(result), + users: result.users.map(buildApiUser).filter(Boolean), + }; } export async function fetchPremiumPromo() { diff --git a/src/api/gramjs/methods/settings.ts b/src/api/gramjs/methods/settings.ts index 69689ab86..7b93fe7a8 100644 --- a/src/api/gramjs/methods/settings.ts +++ b/src/api/gramjs/methods/settings.ts @@ -87,18 +87,36 @@ export async function updateProfilePhoto(photo?: ApiPhoto) { const result = await invokeRequest(new GramJs.photos.UpdateProfilePhoto({ id: photoId, })); - if (result?.photo instanceof GramJs.Photo) { + if (!result) return undefined; + + addEntitiesWithPhotosToLocalDb(result.users); + if (result.photo instanceof GramJs.Photo) { addPhotoToLocalDb(result.photo); - return buildApiPhoto(result.photo); + return { + users: result.users.map(buildApiUser).filter(Boolean), + photo: buildApiPhoto(result.photo), + }; } return undefined; } export async function uploadProfilePhoto(file: File) { const inputFile = await uploadFile(file); - return invokeRequest(new GramJs.photos.UploadProfilePhoto({ + const result = await invokeRequest(new GramJs.photos.UploadProfilePhoto({ file: inputFile, - }), true); + })); + + if (!result) return undefined; + + addEntitiesWithPhotosToLocalDb(result.users); + if (result.photo instanceof GramJs.Photo) { + addPhotoToLocalDb(result.photo); + return { + users: result.users.map(buildApiUser).filter(Boolean), + photo: buildApiPhoto(result.photo), + }; + } + return undefined; } export async function deleteProfilePhotos(photos: ApiPhoto[]) { @@ -217,8 +235,12 @@ export async function fetchWebAuthorizations() { if (!result) { return undefined; } + addEntitiesWithPhotosToLocalDb(result.users); - return buildCollectionByKey(result.authorizations.map(buildApiWebSession), 'hash'); + return { + users: result.users.map(buildApiUser).filter(Boolean), + webAuthorizations: buildCollectionByKey(result.authorizations.map(buildApiWebSession), 'hash'), + }; } export function terminateWebAuthorization(hash: string) { @@ -401,7 +423,10 @@ export async function fetchPrivacySettings(privacyKey: ApiPrivacyKey) { updateLocalDb(result); - return buildPrivacyRules(result.rules); + return { + users: result.users.map(buildApiUser).filter(Boolean), + rules: buildPrivacyRules(result.rules), + }; } export function registerDevice(token: string) { @@ -476,7 +501,10 @@ export async function setPrivacySettings( updateLocalDb(result); - return buildPrivacyRules(result.rules); + return { + users: result.users.map(buildApiUser).filter(Boolean), + rules: buildPrivacyRules(result.rules), + }; } export async function updateIsOnline(isOnline: boolean) { diff --git a/src/api/gramjs/methods/statistics.ts b/src/api/gramjs/methods/statistics.ts index 9b6e2a1e1..20eb53c5f 100644 --- a/src/api/gramjs/methods/statistics.ts +++ b/src/api/gramjs/methods/statistics.ts @@ -2,7 +2,7 @@ import BigInt from 'big-integer'; import { Api as GramJs } from '../../../lib/gramjs'; import type { - ApiChat, ApiChannelStatistics, ApiGroupStatistics, ApiMessageStatistics, ApiMessagePublicForward, StatisticsGraph, + ApiChat, ApiMessageStatistics, ApiMessagePublicForward, StatisticsGraph, } from '../../types'; import { invokeRequest } from './client'; @@ -11,10 +11,11 @@ import { buildInputEntity } from '../gramjsBuilders'; import { buildChannelStatistics, buildGroupStatistics, buildMessageStatistics, buildMessagePublicForwards, buildGraph, } from '../apiBuilders/statistics'; +import { buildApiUser } from '../apiBuilders/users'; export async function fetchChannelStatistics({ chat, -}: { chat: ApiChat }): Promise { +}: { chat: ApiChat }) { const result = await invokeRequest(new GramJs.stats.GetBroadcastStats({ channel: buildInputEntity(chat.id, chat.accessHash) as GramJs.InputChannel, }), undefined, undefined, undefined, chat.fullInfo!.statisticsDcId); @@ -23,12 +24,15 @@ export async function fetchChannelStatistics({ return undefined; } - return buildChannelStatistics(result); + return { + stats: buildChannelStatistics(result), + users: [], + }; } export async function fetchGroupStatistics({ chat, -}: { chat: ApiChat }): Promise { +}: { chat: ApiChat }) { const result = await invokeRequest(new GramJs.stats.GetMegagroupStats({ channel: buildInputEntity(chat.id, chat.accessHash) as GramJs.InputChannel, }), undefined, undefined, undefined, chat.fullInfo!.statisticsDcId); @@ -37,7 +41,12 @@ export async function fetchGroupStatistics({ return undefined; } - return buildGroupStatistics(result); + addEntitiesWithPhotosToLocalDb(result.users); + + return { + users: result.users.map(buildApiUser).filter(Boolean), + stats: buildGroupStatistics(result), + }; } export async function fetchMessageStatistics({ diff --git a/src/api/gramjs/methods/users.ts b/src/api/gramjs/methods/users.ts index e2873f836..cb588cb37 100644 --- a/src/api/gramjs/methods/users.ts +++ b/src/api/gramjs/methods/users.ts @@ -252,6 +252,7 @@ export async function fetchProfilePhotos(user?: ApiUser, chat?: ApiChat) { photos: result.photos .filter((photo): photo is GramJs.Photo => photo instanceof GramJs.Photo) .map(buildApiPhoto), + users: result.users.map(buildApiUser).filter(Boolean), }; } @@ -289,4 +290,8 @@ function updateLocalDb(result: (GramJs.photos.Photos | GramJs.photos.PhotosSlice if ('photos' in result) { result.photos.forEach(addPhotoToLocalDb); } + + if ('users' in result) { + addEntitiesWithPhotosToLocalDb(result.users); + } } diff --git a/src/components/left/settings/SettingsLanguage.tsx b/src/components/left/settings/SettingsLanguage.tsx index ce8cf5e84..24efee8e3 100644 --- a/src/components/left/settings/SettingsLanguage.tsx +++ b/src/components/left/settings/SettingsLanguage.tsx @@ -29,6 +29,7 @@ const SettingsLanguage: FC = ({ }) => { const { loadLanguages, + loadAttachBots, setSettingOption, } = getActions(); @@ -48,8 +49,10 @@ const SettingsLanguage: FC = ({ unmarkIsLoading(); setSettingOption({ language: langCode }); + + loadAttachBots(); // Should be refetched every language change }); - }, [markIsLoading, unmarkIsLoading, setSettingOption]); + }, [markIsLoading, unmarkIsLoading, setSettingOption, loadAttachBots]); const options = useMemo(() => { return languages ? buildOptions(languages) : undefined; diff --git a/src/global/actions/api/accounts.ts b/src/global/actions/api/accounts.ts index 52ead588c..05cebc30b 100644 --- a/src/global/actions/api/accounts.ts +++ b/src/global/actions/api/accounts.ts @@ -2,6 +2,8 @@ import { addActionHandler, getGlobal, setGlobal } from '../../index'; import { selectChat } from '../../selectors'; import { callApi } from '../../../api/gramjs'; import { getTranslation } from '../../../util/langProvider'; +import { addUsers } from '../../reducers'; +import { buildCollectionByKey } from '../../../util/iteratees'; addActionHandler('reportPeer', async (global, actions, payload) => { const { @@ -171,17 +173,21 @@ addActionHandler('changeSessionTtl', async (global, actions, payload) => { }); }); -addActionHandler('loadWebAuthorizations', async () => { +addActionHandler('loadWebAuthorizations', async (global) => { const result = await callApi('fetchWebAuthorizations'); if (!result) { return; } + const { users, webAuthorizations } = result; + global = getGlobal(); + + global = addUsers(global, buildCollectionByKey(users, 'id')); setGlobal({ - ...getGlobal(), + ...global, activeWebSessions: { - byHash: result, - orderedHashes: Object.keys(result), + byHash: webAuthorizations, + orderedHashes: Object.keys(webAuthorizations), }, }); }); diff --git a/src/global/actions/api/bots.ts b/src/global/actions/api/bots.ts index 7ad751aa9..023ea62c1 100644 --- a/src/global/actions/api/bots.ts +++ b/src/global/actions/api/bots.ts @@ -579,7 +579,8 @@ async function loadAttachBots(hash?: string) { return; } - const global = getGlobal(); + let global = getGlobal(); + global = addUsers(global, buildCollectionByKey(result.users, 'id')); setGlobal({ ...global, attachMenu: { diff --git a/src/global/actions/api/calls.async.ts b/src/global/actions/api/calls.async.ts index 8e485cfa6..8d63270a5 100644 --- a/src/global/actions/api/calls.async.ts +++ b/src/global/actions/api/calls.async.ts @@ -20,6 +20,8 @@ import { } from '../../reducers/calls'; import { getGroupCallAudioContext, getGroupCallAudioElement, removeGroupCallAudioElement } from '../ui/calls'; import { loadFullChat } from './chats'; +import { addUsers } from '../../reducers'; +import { buildCollectionByKey } from '../../../util/iteratees'; addActionHandler('leaveGroupCall', async (global, actions, payload) => { const { @@ -233,7 +235,11 @@ addActionHandler('connectToActivePhoneCall', async (global, actions) => { if (!result) { actions.hangUp(); + return; } + global = getGlobal(); + global = addUsers(global, buildCollectionByKey(result.users, 'id')); + setGlobal(global); }); addActionHandler('acceptCall', async (global) => { @@ -247,7 +253,13 @@ addActionHandler('acceptCall', async (global) => { await callApi('createPhoneCallState', [false]); const gB = await callApi('acceptPhoneCall', [dhConfig])!; - callApi('acceptCall', { call: phoneCall, gB }); + const result = await callApi('acceptCall', { call: phoneCall, gB }); + if (!result) { + return; + } + global = getGlobal(); + global = addUsers(global, buildCollectionByKey(result.users, 'id')); + setGlobal(global); }); addActionHandler('sendSignalingData', (global, actions, payload) => { diff --git a/src/global/actions/api/chats.ts b/src/global/actions/api/chats.ts index bc4c94a44..048f347c9 100644 --- a/src/global/actions/api/chats.ts +++ b/src/global/actions/api/chats.ts @@ -170,6 +170,9 @@ addActionHandler('focusMessageInComments', async (global, actions, payload) => { if (!result) { return; } + global = getGlobal(); + global = addUsers(global, buildCollectionByKey(result.users, 'id')); + setGlobal(global); actions.focusMessage({ chatId, threadId, messageId }); }); @@ -1255,10 +1258,14 @@ addActionHandler('loadChatSettings', async (global, actions, payload) => { const chat = selectChat(global, chatId); if (!chat) return; - const settings = await callApi('fetchChatSettings', chat); - if (!settings) return; + const result = await callApi('fetchChatSettings', chat); + if (!result) return; + const { settings, users } = result; + global = getGlobal(); - setGlobal(updateChat(getGlobal(), chat.id, { settings })); + global = addUsers(global, buildCollectionByKey(users, 'id')); + + setGlobal(updateChat(global, chat.id, { settings })); }); addActionHandler('toggleJoinToSend', async (global, actions, payload) => { @@ -1981,7 +1988,7 @@ async function openCommentsByUsername( if (!chat) return; - const global = getGlobal(); + let global = getGlobal(); const threadInfo = selectThreadInfo(global, chat.id, messageId); let discussionChatId: string | undefined; @@ -1989,6 +1996,9 @@ async function openCommentsByUsername( if (!threadInfo) { const result = await callApi('requestThreadInfoUpdate', { chat, threadId: messageId }); if (!result) return; + global = getGlobal(); + global = addUsers(global, buildCollectionByKey(result.users, 'id')); + setGlobal(global); discussionChatId = result.discussionChatId; } else { diff --git a/src/global/actions/api/initial.ts b/src/global/actions/api/initial.ts index 1c7c46ab8..3b0026851 100644 --- a/src/global/actions/api/initial.ts +++ b/src/global/actions/api/initial.ts @@ -27,10 +27,11 @@ import { clearLegacySessions, } from '../../../util/sessions'; import { forceWebsync } from '../../../util/websync'; -import { clearGlobalForLockScreen, updatePasscodeSettings } from '../../reducers'; +import { addUsers, clearGlobalForLockScreen, updatePasscodeSettings } from '../../reducers'; import { clearEncryptedSession, encryptSession, forgetPasscode } from '../../../util/passcode'; import { serializeGlobal } from '../../cache'; import { parseInitialLocationHash } from '../../../util/routing'; +import { buildCollectionByKey } from '../../../util/iteratees'; addActionHandler('initApi', async (global, actions) => { if (!IS_TEST) { @@ -90,10 +91,15 @@ addActionHandler('setAuthPassword', (global, actions, payload) => { }; }); -addActionHandler('uploadProfilePhoto', (global, actions, payload) => { +addActionHandler('uploadProfilePhoto', async (global, actions, payload) => { const { file } = payload!; - void callApi('uploadProfilePhoto', file); + const result = await callApi('uploadProfilePhoto', file); + if (!result) return; + + global = getGlobal(); + global = addUsers(global, buildCollectionByKey(result.users, 'id')); + setGlobal(global); }); addActionHandler('signUp', (global, actions, payload) => { diff --git a/src/global/actions/api/management.ts b/src/global/actions/api/management.ts index 58e6efc37..a0dac05f2 100644 --- a/src/global/actions/api/management.ts +++ b/src/global/actions/api/management.ts @@ -9,6 +9,7 @@ import { import { selectChat, selectCurrentMessageList, selectUser } from '../../selectors'; import { migrateChat } from './chats'; import { isChatBasicGroup } from '../../helpers'; +import { buildCollectionByKey } from '../../../util/iteratees'; addActionHandler('checkPublicLink', async (global, actions, payload) => { const { chatId } = selectCurrentMessageList(global) || {}; @@ -116,10 +117,13 @@ addActionHandler('loadExportedChatInvites', async (global, actions, payload) => if (!result) { return; } + global = getGlobal(); + const { invites, users } = result; - const update = isRevoked ? { revokedInvites: result } : { invites: result }; + global = addUsers(global, buildCollectionByKey(users, 'id')); - setGlobal(updateManagement(getGlobal(), chatId, update)); + const update = isRevoked ? { revokedInvites: invites } : { invites }; + setGlobal(updateManagement(global, chatId, update)); }); addActionHandler('editExportedChatInvite', async (global, actions, payload) => { @@ -142,7 +146,7 @@ addActionHandler('editExportedChatInvite', async (global, actions, payload) => { return; } - const { oldInvite, newInvite } = result; + const { oldInvite, newInvite, users } = result; global = getGlobal(); const invites = (global.management.byChatId[chatId].invites || []) @@ -155,6 +159,8 @@ addActionHandler('editExportedChatInvite', async (global, actions, payload) => { invites.push(newInvite); } + global = addUsers(global, buildCollectionByKey(users, 'id')); + setGlobal(updateManagement(global, chatId, { invites, revokedInvites, diff --git a/src/global/actions/api/messages.ts b/src/global/actions/api/messages.ts index 9c7f65b64..0f2590674 100644 --- a/src/global/actions/api/messages.ts +++ b/src/global/actions/api/messages.ts @@ -751,14 +751,18 @@ addActionHandler('rescheduleMessage', (global, actions, payload) => { }); }); -addActionHandler('requestThreadInfoUpdate', (global, actions, payload) => { +addActionHandler('requestThreadInfoUpdate', async (global, actions, payload) => { const { chatId, threadId } = payload; const chat = selectThreadOriginChat(global, chatId, threadId); if (!chat) { return; } - void callApi('requestThreadInfoUpdate', { chat, threadId }); + const result = await callApi('requestThreadInfoUpdate', { chat, threadId }); + if (!result) return; + global = getGlobal(); + global = addUsers(global, buildCollectionByKey(result.users, 'id')); + setGlobal(global); }); addActionHandler('transcribeAudio', async (global, actions, payload) => { diff --git a/src/global/actions/api/payments.ts b/src/global/actions/api/payments.ts index 85c156952..9bcb1f4d3 100644 --- a/src/global/actions/api/payments.ts +++ b/src/global/actions/api/payments.ts @@ -92,10 +92,11 @@ async function getPaymentForm(inputInvoice: ApiRequestInputInvoice): Promise { if (photo) { const result = await callApi('uploadProfilePhoto', photo); if (result) { + global = getGlobal(); + setGlobal(addUsers(global, buildCollectionByKey(result.users, 'id'))); actions.loadProfilePhotos({ profileId: currentUserId }); } } @@ -106,18 +108,23 @@ addActionHandler('updateProfilePhoto', async (global, actions, payload) => { profilePhoto: undefined, }, })); - const newPhoto = await callApi('updateProfilePhoto', photo); - if (newPhoto) { - setGlobal(updateUser(getGlobal(), currentUserId, { - avatarHash: newPhoto.id, - fullInfo: { - ...currentUser.fullInfo, - profilePhoto: newPhoto, - }, - })); - actions.loadFullUser({ userId: currentUserId }); - actions.loadProfilePhotos({ profileId: currentUserId }); - } + const result = await callApi('updateProfilePhoto', photo); + if (!result) return; + + const { photo: newPhoto, users } = result; + global = getGlobal(); + global = addUsers(global, buildCollectionByKey(users, 'id')); + + setGlobal(updateUser(global, currentUserId, { + avatarHash: newPhoto.id, + fullInfo: { + ...currentUser.fullInfo, + profilePhoto: newPhoto, + }, + })); + + actions.loadFullUser({ userId: currentUserId }); + actions.loadProfilePhotos({ profileId: currentUserId }); }); addActionHandler('deleteProfilePhoto', async (global, actions, payload) => { @@ -375,16 +382,7 @@ addActionHandler('loadLanguages', async () => { }); addActionHandler('loadPrivacySettings', async (global) => { - const [ - phoneNumberSettings, - lastSeenSettings, - profilePhotoSettings, - forwardsSettings, - chatInviteSettings, - phoneCallSettings, - phoneP2PSettings, - voiceMessagesSettings, - ] = await Promise.all([ + const result = await Promise.all([ callApi('fetchPrivacySettings', 'phoneNumber'), callApi('fetchPrivacySettings', 'lastSeen'), callApi('fetchPrivacySettings', 'profilePhoto'), @@ -395,34 +393,42 @@ addActionHandler('loadPrivacySettings', async (global) => { callApi('fetchPrivacySettings', 'voiceMessages'), ]); - if ( - !phoneNumberSettings - || !lastSeenSettings - || !profilePhotoSettings - || !forwardsSettings - || !chatInviteSettings - || !phoneCallSettings - || !phoneP2PSettings - || !voiceMessagesSettings - ) { + if (result.some((e) => e === undefined)) { return; } + const [ + phoneNumberSettings, + lastSeenSettings, + profilePhotoSettings, + forwardsSettings, + chatInviteSettings, + phoneCallSettings, + phoneP2PSettings, + voiceMessagesSettings, + ] = result as { + users: ApiUser[]; + rules: ApiPrivacySettings; + }[]; + + const allUsers = result.flatMap((e) => e!.users); + global = getGlobal(); + global = addUsers(global, buildCollectionByKey(allUsers, 'id')); setGlobal({ ...global, settings: { ...global.settings, privacy: { ...global.settings.privacy, - phoneNumber: phoneNumberSettings, - lastSeen: lastSeenSettings, - profilePhoto: profilePhotoSettings, - forwards: forwardsSettings, - chatInvite: chatInviteSettings, - phoneCall: phoneCallSettings, - phoneP2P: phoneP2PSettings, - voiceMessages: voiceMessagesSettings, + phoneNumber: phoneNumberSettings.rules, + lastSeen: lastSeenSettings.rules, + profilePhoto: profilePhotoSettings.rules, + forwards: forwardsSettings.rules, + chatInvite: chatInviteSettings.rules, + phoneCall: phoneCallSettings.rules, + phoneP2P: phoneP2PSettings.rules, + voiceMessages: voiceMessagesSettings.rules, }, }, }); @@ -451,14 +457,14 @@ addActionHandler('setPrivacyVisibility', async (global, actions, payload) => { } global = getGlobal(); - + global = addUsers(global, buildCollectionByKey(result.users, 'id')); setGlobal({ ...global, settings: { ...global.settings, privacy: { ...global.settings.privacy, - [privacyKey]: result, + [privacyKey]: result.rules, }, }, }); @@ -486,14 +492,14 @@ addActionHandler('setPrivacySettings', async (global, actions, payload) => { } global = getGlobal(); - + global = addUsers(global, buildCollectionByKey(result.users, 'id')); setGlobal({ ...global, settings: { ...global.settings, privacy: { ...global.settings.privacy, - [privacyKey]: result, + [privacyKey]: result.rules, }, }, }); diff --git a/src/global/actions/api/statistics.ts b/src/global/actions/api/statistics.ts index aa38c2cce..f6c763485 100644 --- a/src/global/actions/api/statistics.ts +++ b/src/global/actions/api/statistics.ts @@ -1,9 +1,11 @@ import { addActionHandler, getGlobal, setGlobal } from '../../index'; -import type { ApiChannelStatistics } from '../../../api/types'; import { callApi } from '../../../api/gramjs'; -import { updateStatistics, updateMessageStatistics, updateStatisticsGraph } from '../../reducers'; +import { + updateStatistics, updateMessageStatistics, updateStatisticsGraph, addUsers, +} from '../../reducers'; import { selectChatMessages, selectChat } from '../../selectors'; +import { buildCollectionByKey } from '../../../util/iteratees'; addActionHandler('loadStatistics', async (global, actions, payload) => { const { chatId, isGroup } = payload; @@ -18,15 +20,17 @@ addActionHandler('loadStatistics', async (global, actions, payload) => { } global = getGlobal(); + const { stats, users } = result; - if ((result as ApiChannelStatistics).recentTopMessages?.length) { + global = addUsers(global, buildCollectionByKey(users, 'id')); + + if ('recentTopMessages' in stats && stats.recentTopMessages.length) { const messages = selectChatMessages(global, chatId); - (result as ApiChannelStatistics).recentTopMessages = (result as ApiChannelStatistics).recentTopMessages - .map((message) => ({ ...message, ...messages[message.msgId] })); + stats.recentTopMessages = stats.recentTopMessages.map((message) => ({ ...message, ...messages[message.msgId] })); } - setGlobal(updateStatistics(global, chatId, result)); + setGlobal(updateStatistics(global, chatId, stats)); }); addActionHandler('loadMessageStatistics', async (global, actions, payload) => { diff --git a/src/global/actions/api/users.ts b/src/global/actions/api/users.ts index ff7a5e23f..ea5b15f98 100644 --- a/src/global/actions/api/users.ts +++ b/src/global/actions/api/users.ts @@ -252,13 +252,14 @@ addActionHandler('loadProfilePhotos', async (global, actions, payload) => { global = getGlobal(); const userOrChat = user || chat; - const { photos } = result; + const { photos, users } = result; photos.sort((a) => (a.id === userOrChat?.avatarHash ? -1 : 1)); + global = addUsers(global, buildCollectionByKey(users, 'id')); + if (isPrivate) { global = updateUser(global, profileId, { photos }); } else { - global = addUsers(global, buildCollectionByKey(result.users!, 'id')); global = updateChat(global, profileId, { photos }); } diff --git a/src/global/actions/apiUpdaters/calls.async.ts b/src/global/actions/apiUpdaters/calls.async.ts index 752c6e1bb..cef586eb2 100644 --- a/src/global/actions/apiUpdaters/calls.async.ts +++ b/src/global/actions/apiUpdaters/calls.async.ts @@ -1,7 +1,7 @@ import { addActionHandler, getGlobal, setGlobal } from '../../index'; import { selectActiveGroupCall, selectGroupCallParticipant, selectPhoneCallUser } from '../../selectors/calls'; import { updateGroupCall, updateGroupCallParticipant } from '../../reducers/calls'; -import { omit } from '../../../util/iteratees'; +import { buildCollectionByKey, omit } from '../../../util/iteratees'; import type { ApiCallProtocol } from '../../../lib/secret-sauce'; import { handleUpdateGroupCallConnection, @@ -13,6 +13,7 @@ import { ARE_CALLS_SUPPORTED } from '../../../util/environment'; import { callApi } from '../../../api/gramjs'; import * as langProvider from '../../../util/langProvider'; import { EMOJI_DATA, EMOJI_OFFSETS } from '../../../util/phoneCallEmojiConstants'; +import { addUsers } from '../../reducers'; addActionHandler('apiUpdate', (global, actions, update) => { const { activeGroupCallId } = global.groupCalls; @@ -133,9 +134,14 @@ addActionHandler('apiUpdate', (global, actions, update) => { phoneCall: newCall, }); - callApi('confirmCall', { + const result = await callApi('confirmCall', { call, gA, keyFingerprint, }); + if (result) { + global = getGlobal(); + global = addUsers(global, buildCollectionByKey(result.users, 'id')); + setGlobal(global); + } })(); } else if (state === 'active' && connections && phoneCall?.state !== 'active') { if (!isOutgoing) {