[Refactoring] Updater: Process chats, users and messages lists in one place (#4948)
This commit is contained in:
parent
d12dae8dda
commit
7d73682aa7
@ -128,27 +128,16 @@ export function buildApiUserStatus(mtpStatus?: GramJs.TypeUserStatus): ApiUserSt
|
||||
}
|
||||
}
|
||||
|
||||
export function buildApiUsersAndStatuses(mtpUsers: GramJs.TypeUser[]) {
|
||||
export function buildApiUserStatuses(mtpUsers: GramJs.TypeUser[]) {
|
||||
const userStatusesById: Record<string, ApiUserStatus> = {};
|
||||
const usersById: Record<string, ApiUser> = {};
|
||||
|
||||
mtpUsers.forEach((mtpUser) => {
|
||||
const user = buildApiUser(mtpUser);
|
||||
if (!user) {
|
||||
return;
|
||||
}
|
||||
|
||||
const duplicateUser = usersById[user.id];
|
||||
if (!duplicateUser || duplicateUser.isMin) {
|
||||
usersById[user.id] = user;
|
||||
}
|
||||
|
||||
if ('status' in mtpUser) {
|
||||
userStatusesById[user.id] = buildApiUserStatus(mtpUser.status);
|
||||
const userId = buildApiPeerId(mtpUser.id, 'user');
|
||||
userStatusesById[userId] = buildApiUserStatus(mtpUser.status);
|
||||
}
|
||||
});
|
||||
|
||||
return { users: Object.values(usersById), userStatusesById };
|
||||
return userStatusesById;
|
||||
}
|
||||
|
||||
export function buildApiPremiumGiftOption(option: GramJs.TypePremiumGiftOption): ApiPremiumGiftOption {
|
||||
|
||||
@ -199,16 +199,6 @@ export function addUserToLocalDb(user: GramJs.User) {
|
||||
localDb.users[id] = user;
|
||||
}
|
||||
|
||||
export function addEntitiesToLocalDb(entities: (GramJs.TypeUser | GramJs.TypeChat)[]) {
|
||||
entities.forEach((entity) => {
|
||||
if (entity instanceof GramJs.User) {
|
||||
addUserToLocalDb(entity);
|
||||
} else if ((entity instanceof GramJs.Chat || entity instanceof GramJs.Channel)) {
|
||||
addChatToLocalDb(entity);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function addWebDocumentToLocalDb(webDocument: GramJs.TypeWebDocument) {
|
||||
localDb.webDocuments[webDocument.url] = webDocument;
|
||||
}
|
||||
|
||||
@ -5,9 +5,7 @@ import type {
|
||||
ApiPeer, ApiPhoto, ApiReportReason,
|
||||
} from '../../types';
|
||||
|
||||
import { buildApiChatFromPreview } from '../apiBuilders/chats';
|
||||
import { buildApiChatLink } from '../apiBuilders/misc';
|
||||
import { buildApiUser } from '../apiBuilders/users';
|
||||
import { buildInputPeer, buildInputPhoto, buildInputReportReason } from '../gramjsBuilders';
|
||||
import { invokeRequest } from './client';
|
||||
|
||||
@ -83,14 +81,9 @@ export async function resolveBusinessChatLink({ slug } : { slug: string }) {
|
||||
});
|
||||
if (!result) return undefined;
|
||||
|
||||
const users = result.users.map(buildApiUser).filter(Boolean);
|
||||
const chats = result.chats.map((c) => buildApiChatFromPreview(c)).filter(Boolean);
|
||||
|
||||
const chatLink = buildApiChatLink(result);
|
||||
|
||||
return {
|
||||
users,
|
||||
chats,
|
||||
chatLink,
|
||||
};
|
||||
}
|
||||
|
||||
@ -5,10 +5,10 @@ import type {
|
||||
ApiUpdateAuthorizationStateType,
|
||||
ApiUser,
|
||||
ApiUserFullInfo,
|
||||
OnApiUpdate,
|
||||
} from '../../types';
|
||||
|
||||
import { DEBUG } from '../../../config';
|
||||
import { sendApiUpdate } from '../updates/apiUpdateEmitter';
|
||||
|
||||
const ApiErrors: { [k: string]: string } = {
|
||||
PHONE_NUMBER_INVALID: 'Invalid phone number.',
|
||||
@ -23,20 +23,14 @@ const authController: {
|
||||
reject?: Function;
|
||||
} = {};
|
||||
|
||||
let onUpdate: OnApiUpdate;
|
||||
|
||||
export function init(_onUpdate: OnApiUpdate) {
|
||||
onUpdate = _onUpdate;
|
||||
}
|
||||
|
||||
export function onWebAuthTokenFailed() {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateWebAuthTokenFailed',
|
||||
});
|
||||
}
|
||||
|
||||
export function onRequestPhoneNumber() {
|
||||
onUpdate(buildAuthStateUpdate('authorizationStateWaitPhoneNumber'));
|
||||
sendApiUpdate(buildAuthStateUpdate('authorizationStateWaitPhoneNumber'));
|
||||
|
||||
return new Promise<string>((resolve, reject) => {
|
||||
authController.resolve = resolve;
|
||||
@ -45,7 +39,7 @@ export function onRequestPhoneNumber() {
|
||||
}
|
||||
|
||||
export function onRequestCode(isCodeViaApp = false) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
...buildAuthStateUpdate('authorizationStateWaitCode'),
|
||||
isCodeViaApp,
|
||||
});
|
||||
@ -57,7 +51,7 @@ export function onRequestCode(isCodeViaApp = false) {
|
||||
}
|
||||
|
||||
export function onRequestPassword(hint?: string, noReset?: boolean) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
...buildAuthStateUpdate('authorizationStateWaitPassword'),
|
||||
hint,
|
||||
noReset,
|
||||
@ -69,7 +63,7 @@ export function onRequestPassword(hint?: string, noReset?: boolean) {
|
||||
}
|
||||
|
||||
export function onRequestRegistration() {
|
||||
onUpdate(buildAuthStateUpdate('authorizationStateWaitRegistration'));
|
||||
sendApiUpdate(buildAuthStateUpdate('authorizationStateWaitRegistration'));
|
||||
|
||||
return new Promise<[string, string?]>((resolve) => {
|
||||
authController.resolve = resolve;
|
||||
@ -77,7 +71,7 @@ export function onRequestRegistration() {
|
||||
}
|
||||
|
||||
export function onRequestQrCode(qrCode: { token: Buffer; expires: number }) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
...buildAuthStateUpdate('authorizationStateWaitQrCode'),
|
||||
qrCode: {
|
||||
token: btoa(String.fromCharCode(...qrCode.token)).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, ''),
|
||||
@ -109,18 +103,18 @@ export function onAuthError(err: Error) {
|
||||
}
|
||||
}
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateAuthorizationError',
|
||||
message,
|
||||
});
|
||||
}
|
||||
|
||||
export function onAuthReady() {
|
||||
onUpdate(buildAuthStateUpdate('authorizationStateReady'));
|
||||
sendApiUpdate(buildAuthStateUpdate('authorizationStateReady'));
|
||||
}
|
||||
|
||||
export function onCurrentUserUpdate(currentUser: ApiUser, currentUserFullInfo: ApiUserFullInfo) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateCurrentUser',
|
||||
currentUser,
|
||||
currentUserFullInfo,
|
||||
|
||||
@ -9,7 +9,6 @@ import type {
|
||||
ApiPeer,
|
||||
ApiThemeParameters,
|
||||
ApiUser,
|
||||
OnApiUpdate,
|
||||
} from '../../types';
|
||||
|
||||
import { WEB_APP_PLATFORM } from '../../../config';
|
||||
@ -37,20 +36,14 @@ import {
|
||||
} from '../gramjsBuilders';
|
||||
import {
|
||||
addDocumentToLocalDb,
|
||||
addEntitiesToLocalDb,
|
||||
addPhotoToLocalDb,
|
||||
addUserToLocalDb,
|
||||
addWebDocumentToLocalDb,
|
||||
deserializeBytes,
|
||||
} from '../helpers';
|
||||
import { sendApiUpdate } from '../updates/apiUpdateEmitter';
|
||||
import { invokeRequest } from './client';
|
||||
|
||||
let onUpdate: OnApiUpdate;
|
||||
|
||||
export function init(_onUpdate: OnApiUpdate) {
|
||||
onUpdate = _onUpdate;
|
||||
}
|
||||
|
||||
export async function answerCallbackButton({
|
||||
chatId, accessHash, messageId, data, isGame,
|
||||
}: {
|
||||
@ -80,7 +73,6 @@ export async function fetchTopInlineBots() {
|
||||
|
||||
return {
|
||||
ids,
|
||||
users,
|
||||
};
|
||||
}
|
||||
|
||||
@ -98,7 +90,6 @@ export async function fetchTopBotApps() {
|
||||
|
||||
return {
|
||||
ids,
|
||||
users,
|
||||
};
|
||||
}
|
||||
|
||||
@ -140,15 +131,12 @@ export async function fetchInlineBotResults({
|
||||
return undefined;
|
||||
}
|
||||
|
||||
addEntitiesToLocalDb(result.users);
|
||||
|
||||
return {
|
||||
isGallery: Boolean(result.gallery),
|
||||
help: bot.botPlaceholder,
|
||||
nextOffset: getInlineBotResultsNextOffset(bot.usernames![0].username, result.nextOffset),
|
||||
switchPm: buildBotSwitchPm(result.switchPm),
|
||||
switchWebview: buildBotSwitchWebview(result.switchWebview),
|
||||
users: result.users.map(buildApiUser).filter(Boolean),
|
||||
results: processInlineBotResult(String(result.queryId), result.results),
|
||||
cacheTime: result.cacheTime,
|
||||
};
|
||||
@ -394,11 +382,9 @@ export async function loadAttachBots({
|
||||
}));
|
||||
|
||||
if (result instanceof GramJs.AttachMenuBots) {
|
||||
addEntitiesToLocalDb(result.users);
|
||||
return {
|
||||
hash: result.hash.toString(),
|
||||
bots: buildCollectionByKey(result.bots.map(buildApiAttachBot), 'id'),
|
||||
users: result.users.map(buildApiUser).filter(Boolean),
|
||||
};
|
||||
}
|
||||
return undefined;
|
||||
@ -414,10 +400,8 @@ export async function loadAttachBot({
|
||||
}));
|
||||
|
||||
if (result instanceof GramJs.AttachMenuBotsBot) {
|
||||
addEntitiesToLocalDb(result.users);
|
||||
return {
|
||||
bot: buildApiAttachBot(result.bot),
|
||||
users: result.users.map(buildApiUser).filter(Boolean),
|
||||
};
|
||||
}
|
||||
return undefined;
|
||||
@ -456,7 +440,7 @@ export async function requestBotUrlAuth({
|
||||
|
||||
const authResult = buildApiUrlAuthResult(result);
|
||||
if (authResult?.type === 'request') {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateUser',
|
||||
id: authResult.bot.id,
|
||||
user: authResult.bot,
|
||||
@ -487,7 +471,7 @@ export async function acceptBotUrlAuth({
|
||||
|
||||
const authResult = buildApiUrlAuthResult(result);
|
||||
if (authResult?.type === 'request') {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateUser',
|
||||
id: authResult.bot.id,
|
||||
user: authResult.bot,
|
||||
@ -505,7 +489,7 @@ export async function requestLinkUrlAuth({ url }: { url: string }) {
|
||||
|
||||
const authResult = buildApiUrlAuthResult(result);
|
||||
if (authResult?.type === 'request') {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateUser',
|
||||
id: authResult.bot.id,
|
||||
user: authResult.bot,
|
||||
@ -524,7 +508,7 @@ export async function acceptLinkUrlAuth({ url, isWriteAllowed }: { url: string;
|
||||
|
||||
const authResult = buildApiUrlAuthResult(result);
|
||||
if (authResult?.type === 'request') {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateUser',
|
||||
id: authResult.bot.id,
|
||||
user: authResult.bot,
|
||||
@ -663,14 +647,11 @@ export async function fetchPopularAppBots({
|
||||
return undefined;
|
||||
}
|
||||
|
||||
addEntitiesToLocalDb(result.users);
|
||||
|
||||
const users = result.users.map(buildApiUser).filter(Boolean);
|
||||
const chats = result.users.map((c) => buildApiChatFromPreview(c)).filter(Boolean);
|
||||
const peerIds = users.map(({ id }) => id);
|
||||
|
||||
return {
|
||||
users,
|
||||
chats,
|
||||
peerIds,
|
||||
nextOffset: result.nextOffset,
|
||||
};
|
||||
}
|
||||
|
||||
@ -3,8 +3,7 @@ import { Api as GramJs } from '../../../lib/gramjs';
|
||||
|
||||
import type { JoinGroupCallPayload } from '../../../lib/secret-sauce';
|
||||
import type {
|
||||
ApiChat, ApiGroupCall, ApiPhoneCall,
|
||||
ApiUser, OnApiUpdate,
|
||||
ApiChat, ApiGroupCall, ApiPhoneCall, ApiUser,
|
||||
} from '../../types';
|
||||
|
||||
import { GROUP_CALL_PARTICIPANTS_LIMIT } from '../../../config';
|
||||
@ -13,20 +12,12 @@ import {
|
||||
buildApiGroupCallParticipant, buildCallProtocol,
|
||||
buildPhoneCall,
|
||||
} from '../apiBuilders/calls';
|
||||
import { buildApiChatFromPreview } from '../apiBuilders/chats';
|
||||
import { buildApiUser } from '../apiBuilders/users';
|
||||
import {
|
||||
buildInputGroupCall, buildInputPeer, buildInputPhoneCall, generateRandomInt,
|
||||
} from '../gramjsBuilders';
|
||||
import { addEntitiesToLocalDb } from '../helpers';
|
||||
import { sendApiUpdate } from '../updates/apiUpdateEmitter';
|
||||
import { invokeRequest, invokeRequestBeacon } from './client';
|
||||
|
||||
let onUpdate: OnApiUpdate;
|
||||
|
||||
export function init(_onUpdate: OnApiUpdate) {
|
||||
onUpdate = _onUpdate;
|
||||
}
|
||||
|
||||
export async function getGroupCall({
|
||||
call,
|
||||
}: {
|
||||
@ -40,16 +31,8 @@ export async function getGroupCall({
|
||||
return undefined;
|
||||
}
|
||||
|
||||
addEntitiesToLocalDb(result.users);
|
||||
addEntitiesToLocalDb(result.chats);
|
||||
|
||||
const users = result.users.map(buildApiUser).filter(Boolean);
|
||||
const chats = result.chats.map((c) => buildApiChatFromPreview(c)).filter(Boolean);
|
||||
|
||||
return {
|
||||
groupCall: buildApiGroupCall(result.call),
|
||||
users,
|
||||
chats,
|
||||
};
|
||||
}
|
||||
|
||||
@ -130,25 +113,15 @@ export async function fetchGroupCallParticipants({
|
||||
}));
|
||||
|
||||
if (!result) {
|
||||
return undefined;
|
||||
return;
|
||||
}
|
||||
|
||||
addEntitiesToLocalDb(result.users);
|
||||
addEntitiesToLocalDb(result.chats);
|
||||
|
||||
const users = result.users.map(buildApiUser).filter(Boolean);
|
||||
const chats = result.chats.map((c) => buildApiChatFromPreview(c)).filter(Boolean);
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateGroupCallParticipants',
|
||||
groupCallId: call.id,
|
||||
participants: result.participants.map(buildApiGroupCallParticipant),
|
||||
nextOffset: result.nextOffset,
|
||||
});
|
||||
|
||||
return {
|
||||
users, chats,
|
||||
};
|
||||
}
|
||||
|
||||
export function leaveGroupCall({
|
||||
@ -316,16 +289,12 @@ export async function requestCall({
|
||||
|
||||
const call = buildPhoneCall(result.phoneCall);
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updatePhoneCall',
|
||||
call,
|
||||
});
|
||||
|
||||
addEntitiesToLocalDb(result.users);
|
||||
|
||||
return {
|
||||
users: result.users.map(buildApiUser).filter(Boolean),
|
||||
};
|
||||
return true;
|
||||
}
|
||||
|
||||
export function setCallRating({
|
||||
@ -369,16 +338,12 @@ export async function acceptCall({
|
||||
|
||||
call = buildPhoneCall(result.phoneCall);
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updatePhoneCall',
|
||||
call,
|
||||
});
|
||||
|
||||
addEntitiesToLocalDb(result.users);
|
||||
|
||||
return {
|
||||
users: result.users.map(buildApiUser).filter(Boolean),
|
||||
};
|
||||
return true;
|
||||
}
|
||||
|
||||
export async function confirmCall({
|
||||
@ -399,16 +364,12 @@ export async function confirmCall({
|
||||
|
||||
call = buildPhoneCall(result.phoneCall);
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updatePhoneCall',
|
||||
call,
|
||||
});
|
||||
|
||||
addEntitiesToLocalDb(result.users);
|
||||
|
||||
return {
|
||||
users: result.users.map(buildApiUser).filter(Boolean),
|
||||
};
|
||||
return true;
|
||||
}
|
||||
|
||||
export function sendSignalingData({
|
||||
|
||||
@ -17,7 +17,6 @@ import type {
|
||||
ApiTopic,
|
||||
ApiUser,
|
||||
ApiUserStatus,
|
||||
OnApiUpdate,
|
||||
} from '../../types';
|
||||
|
||||
import {
|
||||
@ -54,7 +53,7 @@ import { buildApiPhoto } from '../apiBuilders/common';
|
||||
import { buildApiMessage, buildMessageDraft } from '../apiBuilders/messages';
|
||||
import { buildApiPeerId, getApiChatIdFromMtpPeer } from '../apiBuilders/peers';
|
||||
import { buildStickerSet } from '../apiBuilders/symbols';
|
||||
import { buildApiUser, buildApiUsersAndStatuses } from '../apiBuilders/users';
|
||||
import { buildApiUser, buildApiUserStatuses } from '../apiBuilders/users';
|
||||
import {
|
||||
buildChatAdminRights,
|
||||
buildChatBannedRights,
|
||||
@ -68,22 +67,19 @@ import {
|
||||
generateRandomBigInt,
|
||||
} from '../gramjsBuilders';
|
||||
import {
|
||||
addEntitiesToLocalDb,
|
||||
addMessageToLocalDb,
|
||||
addPhotoToLocalDb,
|
||||
deserializeBytes,
|
||||
isChatFolder,
|
||||
} from '../helpers';
|
||||
import { scheduleMutedChatUpdate } from '../scheduleUnmute';
|
||||
import { sendApiUpdate } from '../updates/apiUpdateEmitter';
|
||||
import {
|
||||
applyState, processAffectedHistory, updateChannelState,
|
||||
} from '../updates/updateManager';
|
||||
import { dispatchThreadInfoUpdates } from '../updates/updater';
|
||||
import { handleGramJsUpdate, invokeRequest, uploadFile } from './client';
|
||||
|
||||
type FullChatData = {
|
||||
fullInfo: ApiChatFullInfo;
|
||||
users: ApiUser[];
|
||||
chats: ApiChat[];
|
||||
userStatusesById: { [userId: string]: ApiUserStatus };
|
||||
groupCall?: Partial<ApiGroupCall>;
|
||||
@ -106,12 +102,6 @@ type ChatListData = {
|
||||
nextOffsetDate?: number;
|
||||
};
|
||||
|
||||
let onUpdate: OnApiUpdate;
|
||||
|
||||
export function init(_onUpdate: OnApiUpdate) {
|
||||
onUpdate = _onUpdate;
|
||||
}
|
||||
|
||||
export async function fetchChats({
|
||||
limit,
|
||||
offsetDate,
|
||||
@ -147,13 +137,6 @@ export async function fetchChats({
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (resultPinned) {
|
||||
dispatchThreadInfoUpdates(resultPinned.messages);
|
||||
updateLocalDb(resultPinned);
|
||||
}
|
||||
dispatchThreadInfoUpdates(result.messages);
|
||||
updateLocalDb(result);
|
||||
|
||||
const messages = (resultPinned ? resultPinned.messages : [])
|
||||
.concat(result.messages)
|
||||
.map(buildApiMessage)
|
||||
@ -167,7 +150,7 @@ export async function fetchChats({
|
||||
const chats: ApiChat[] = [];
|
||||
const draftsById: Record<string, ApiDraft> = {};
|
||||
|
||||
const dialogs = (resultPinned ? resultPinned.dialogs : []).concat(result.dialogs);
|
||||
const dialogs = (resultPinned?.dialogs || []).concat(result.dialogs);
|
||||
|
||||
const orderedPinnedIds: string[] = [];
|
||||
const lastMessageByChatId: Record<string, number> = {};
|
||||
@ -202,7 +185,7 @@ export async function fetchChats({
|
||||
|
||||
chats.push(chat);
|
||||
|
||||
scheduleMutedChatUpdate(chat.id, chat.muteUntil, onUpdate);
|
||||
scheduleMutedChatUpdate(chat.id, chat.muteUntil, sendApiUpdate);
|
||||
|
||||
if (withPinned && dialog.pinned) {
|
||||
orderedPinnedIds.push(chat.id);
|
||||
@ -218,7 +201,8 @@ export async function fetchChats({
|
||||
|
||||
const chatIds = chats.map((chat) => chat.id);
|
||||
|
||||
const { users, userStatusesById } = buildApiUsersAndStatuses((resultPinned?.users || []).concat(result.users));
|
||||
const users = result.users.map(buildApiUser).filter(Boolean);
|
||||
const userStatusesById = buildApiUserStatuses((resultPinned?.users || []).concat(result.users));
|
||||
|
||||
let totalChatCount: number;
|
||||
if (result instanceof GramJs.messages.DialogsSlice) {
|
||||
@ -281,13 +265,6 @@ export async function fetchSavedChats({
|
||||
|
||||
const hasPinned = resultPinned && !(resultPinned instanceof GramJs.messages.SavedDialogsNotModified);
|
||||
|
||||
if (hasPinned) {
|
||||
updateLocalDb(resultPinned);
|
||||
}
|
||||
updateLocalDb(result);
|
||||
|
||||
dispatchThreadInfoUpdates(result.messages);
|
||||
|
||||
const messages = (hasPinned ? resultPinned.messages : [])
|
||||
.concat(result.messages)
|
||||
.map(buildApiMessage)
|
||||
@ -321,7 +298,8 @@ export async function fetchSavedChats({
|
||||
chats.push(chat);
|
||||
});
|
||||
|
||||
const { users, userStatusesById } = buildApiUsersAndStatuses((hasPinned ? resultPinned.users : [])
|
||||
const users = result.users.map(buildApiUser).filter(Boolean);
|
||||
const userStatusesById = buildApiUserStatuses((hasPinned ? resultPinned.users : [])
|
||||
.concat(result.users));
|
||||
|
||||
let totalChatCount: number;
|
||||
@ -377,10 +355,7 @@ export async function fetchChatSettings(chat: ApiChat) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
addEntitiesToLocalDb(result.users);
|
||||
|
||||
return {
|
||||
users: result.users.map(buildApiUser).filter(Boolean),
|
||||
settings: buildApiChatSettings(result.settings),
|
||||
};
|
||||
}
|
||||
@ -391,22 +366,13 @@ export async function searchChats({ query }: { query: string }) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
updateLocalDb(result);
|
||||
|
||||
const accountPeerIds = result.myResults.map(getApiChatIdFromMtpPeer);
|
||||
const globalPeerIds = result.results.map(getApiChatIdFromMtpPeer)
|
||||
.filter((id) => !accountPeerIds.includes(id));
|
||||
|
||||
const chats = result.chats.concat(result.users)
|
||||
.map((user) => buildApiChatFromPreview(user))
|
||||
.filter(Boolean);
|
||||
const users = result.users.map(buildApiUser).filter(Boolean);
|
||||
|
||||
return {
|
||||
accountResultIds: accountPeerIds,
|
||||
globalResultIds: globalPeerIds,
|
||||
chats,
|
||||
users,
|
||||
};
|
||||
}
|
||||
|
||||
@ -444,7 +410,7 @@ export async function fetchChat({
|
||||
return undefined;
|
||||
}
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateChat',
|
||||
id: chat.id,
|
||||
chat,
|
||||
@ -483,10 +449,7 @@ export async function requestChatUpdate({
|
||||
return;
|
||||
}
|
||||
|
||||
updateLocalDb(result);
|
||||
|
||||
const lastRemoteMessage = buildApiMessage(result.messages[0]);
|
||||
dispatchThreadInfoUpdates(result.messages);
|
||||
|
||||
const lastMessage = lastLocalMessage && (!lastRemoteMessage || (lastLocalMessage.date > lastRemoteMessage.date))
|
||||
? lastLocalMessage
|
||||
@ -494,14 +457,14 @@ export async function requestChatUpdate({
|
||||
|
||||
const chatUpdate = buildApiChatFromDialog(dialog, peerEntity);
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateChat',
|
||||
id,
|
||||
chat: chatUpdate,
|
||||
});
|
||||
|
||||
if (!noLastMessage && lastMessage) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateChatLastMessage',
|
||||
id,
|
||||
lastMessage,
|
||||
@ -510,7 +473,7 @@ export async function requestChatUpdate({
|
||||
|
||||
applyState(result.state);
|
||||
|
||||
scheduleMutedChatUpdate(chatUpdate.id, chatUpdate.muteUntil, onUpdate);
|
||||
scheduleMutedChatUpdate(chatUpdate.id, chatUpdate.muteUntil, sendApiUpdate);
|
||||
}
|
||||
|
||||
export function saveDraft({
|
||||
@ -537,8 +500,6 @@ async function getFullChatInfo(chatId: string): Promise<FullChatData | undefined
|
||||
return undefined;
|
||||
}
|
||||
|
||||
updateLocalDb(result);
|
||||
|
||||
const {
|
||||
about,
|
||||
participants,
|
||||
@ -561,7 +522,7 @@ async function getFullChatInfo(chatId: string): Promise<FullChatData | undefined
|
||||
const adminMembers = members ? members.filter(({ isAdmin, isOwner }) => isAdmin || isOwner) : undefined;
|
||||
const botCommands = botInfo ? buildApiChatBotCommands(botInfo) : undefined;
|
||||
const inviteLink = exportedInvite instanceof GramJs.ChatInviteExported ? exportedInvite.link : undefined;
|
||||
const { users, userStatusesById } = buildApiUsersAndStatuses(result.users);
|
||||
const userStatusesById = buildApiUserStatuses(result.users);
|
||||
const chats = result.chats.map((chat) => buildApiChatFromPreview(chat)).filter(Boolean);
|
||||
|
||||
return {
|
||||
@ -581,7 +542,6 @@ async function getFullChatInfo(chatId: string): Promise<FullChatData | undefined
|
||||
isTranslationDisabled: translationsDisabled,
|
||||
isPreHistoryHidden: true,
|
||||
},
|
||||
users,
|
||||
chats,
|
||||
userStatusesById,
|
||||
groupCall: call ? {
|
||||
@ -652,11 +612,11 @@ async function getFullChannelInfo(
|
||||
? exportedInvite.link
|
||||
: undefined;
|
||||
|
||||
const { members, users, userStatusesById } = (canViewParticipants && await fetchMembers(id, accessHash)) || {};
|
||||
const { members: kickedMembers, users: bannedUsers, userStatusesById: bannedStatusesById } = (
|
||||
const { members, userStatusesById } = (canViewParticipants && await fetchMembers(id, accessHash)) || {};
|
||||
const { members: kickedMembers, userStatusesById: bannedStatusesById } = (
|
||||
canViewParticipants && adminRights && await fetchMembers(id, accessHash, 'kicked')
|
||||
) || {};
|
||||
const { members: adminMembers, users: adminUsers, userStatusesById: adminStatusesById } = (
|
||||
const { members: adminMembers, userStatusesById: adminStatusesById } = (
|
||||
canViewParticipants && await fetchMembers(id, accessHash, 'admin')
|
||||
) || {};
|
||||
const botCommands = botInfo ? buildApiChatBotCommands(botInfo) : undefined;
|
||||
@ -672,12 +632,10 @@ async function getFullChannelInfo(
|
||||
const chats = result.chats.map((c) => buildApiChatFromPreview(c)).filter(Boolean);
|
||||
|
||||
if (result?.chats?.length > 1) {
|
||||
updateLocalDb(result);
|
||||
|
||||
const [, mtpLinkedChat] = result.chats;
|
||||
const linkedChat = buildApiChatFromPreview(mtpLinkedChat);
|
||||
if (linkedChat) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateChat',
|
||||
id: linkedChat.id,
|
||||
chat: linkedChat,
|
||||
@ -734,7 +692,6 @@ async function getFullChannelInfo(
|
||||
boostsApplied,
|
||||
boostsToUnrestrict: boostsUnrestrict,
|
||||
},
|
||||
users: [...(users || []), ...(bannedUsers || []), ...(adminUsers || [])],
|
||||
chats,
|
||||
userStatusesById: statusesById,
|
||||
groupCall: call ? {
|
||||
@ -767,7 +724,7 @@ export async function updateChatMutedState({
|
||||
settings: new GramJs.InputPeerNotifySettings({ muteUntil }),
|
||||
}));
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateNotifyExceptions',
|
||||
chatId: chat.id,
|
||||
isMuted,
|
||||
@ -795,7 +752,7 @@ export async function updateTopicMutedState({
|
||||
settings: new GramJs.InputPeerNotifySettings({ muteUntil }),
|
||||
}));
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateTopicNotifyExceptions',
|
||||
chatId: chat.id,
|
||||
topicId,
|
||||
@ -999,7 +956,7 @@ export async function toggleChatPinned({
|
||||
}));
|
||||
|
||||
if (isActionSuccessful) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateChatPinned',
|
||||
id: chat.id,
|
||||
isPinned: shouldBePinned,
|
||||
@ -1023,7 +980,7 @@ export async function toggleSavedDialogPinned({
|
||||
}));
|
||||
|
||||
if (isActionSuccessful) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateSavedDialogPinned',
|
||||
id: chat.id,
|
||||
isPinned: shouldBePinned,
|
||||
@ -1101,7 +1058,7 @@ export async function editChatFolder({
|
||||
}));
|
||||
|
||||
if (isActionSuccessful) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateChatFolder',
|
||||
id,
|
||||
folder: folderUpdate,
|
||||
@ -1117,14 +1074,14 @@ export async function deleteChatFolder(id: number) {
|
||||
const recommendedChatFolders = await fetchRecommendedChatFolders();
|
||||
|
||||
if (isActionSuccessful) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateChatFolder',
|
||||
id,
|
||||
folder: undefined,
|
||||
});
|
||||
}
|
||||
if (recommendedChatFolders) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateRecommendedChatFolders',
|
||||
folders: recommendedChatFolders,
|
||||
});
|
||||
@ -1152,7 +1109,7 @@ export async function toggleDialogUnread({
|
||||
}));
|
||||
|
||||
if (isActionSuccessful) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateChat',
|
||||
id: chat.id,
|
||||
chat: { hasUnreadMark },
|
||||
@ -1191,8 +1148,6 @@ function processResolvedPeer(result?: GramJs.contacts.TypeResolvedPeer) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
updateLocalDb(result);
|
||||
|
||||
return {
|
||||
chat,
|
||||
user: buildApiUser(users[0]),
|
||||
@ -1285,7 +1240,7 @@ export async function updateChatAbout(chat: ApiChat, about: string) {
|
||||
return;
|
||||
}
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateChatFullInfo',
|
||||
id: chat.id,
|
||||
fullInfo: {
|
||||
@ -1351,12 +1306,10 @@ export async function fetchMembers(
|
||||
return undefined;
|
||||
}
|
||||
|
||||
updateLocalDb(result);
|
||||
const { users, userStatusesById } = buildApiUsersAndStatuses(result.users);
|
||||
const userStatusesById = buildApiUserStatuses(result.users);
|
||||
|
||||
return {
|
||||
members: buildChatMembers(result),
|
||||
users,
|
||||
userStatusesById,
|
||||
};
|
||||
}
|
||||
@ -1381,10 +1334,7 @@ export async function fetchMember({
|
||||
return undefined;
|
||||
}
|
||||
|
||||
updateLocalDb(result);
|
||||
|
||||
const { users, userStatusesById } = buildApiUsersAndStatuses(result.users);
|
||||
const chats = result.chats.map((c) => buildApiChatFromPreview(c)).filter(Boolean);
|
||||
const userStatusesById = buildApiUserStatuses(result.users);
|
||||
const member = buildChatMember(result.participant);
|
||||
|
||||
if (!member) {
|
||||
@ -1393,9 +1343,7 @@ export async function fetchMember({
|
||||
|
||||
return {
|
||||
member,
|
||||
users,
|
||||
userStatusesById,
|
||||
chats,
|
||||
};
|
||||
}
|
||||
|
||||
@ -1406,8 +1354,6 @@ export async function fetchGroupsForDiscussion() {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
updateLocalDb(result);
|
||||
|
||||
return result.chats.map((chat) => buildApiChatFromPreview(chat));
|
||||
}
|
||||
|
||||
@ -1446,8 +1392,6 @@ export async function migrateChat(chat: ApiChat) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
updateLocalDb(result);
|
||||
|
||||
const newChannelId = result.updates
|
||||
.find((update): update is GramJs.UpdateChannel => update instanceof GramJs.UpdateChannel)!.channelId;
|
||||
|
||||
@ -1476,7 +1420,7 @@ export async function openChatByInvite(hash: string) {
|
||||
addPhotoToLocalDb(result.photo);
|
||||
}
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'showInvite',
|
||||
data: {
|
||||
title,
|
||||
@ -1492,7 +1436,7 @@ export async function openChatByInvite(hash: string) {
|
||||
chat = buildApiChatFromPreview(result.chat);
|
||||
|
||||
if (chat) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateChat',
|
||||
id: chat.id,
|
||||
chat,
|
||||
@ -1534,7 +1478,7 @@ export async function addChatMembers(chat: ApiChat, users: ApiUser[]) {
|
||||
return addChatUsersResult.flat().filter(Boolean);
|
||||
}
|
||||
} catch (err) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'error',
|
||||
error: {
|
||||
message: (err as Error).message,
|
||||
@ -1631,28 +1575,6 @@ function preparePeers(
|
||||
return store;
|
||||
}
|
||||
|
||||
function updateLocalDb(result: (
|
||||
GramJs.messages.Dialogs | GramJs.messages.DialogsSlice | GramJs.messages.PeerDialogs |
|
||||
GramJs.messages.SavedDialogs | GramJs.messages.SavedDialogsSlice |
|
||||
GramJs.messages.ChatFull | GramJs.contacts.Found |
|
||||
GramJs.contacts.ResolvedPeer | GramJs.channels.ChannelParticipants |
|
||||
GramJs.messages.Chats | GramJs.messages.ChatsSlice | GramJs.TypeUpdates | GramJs.messages.ForumTopics
|
||||
)) {
|
||||
if ('users' in result) {
|
||||
addEntitiesToLocalDb(result.users);
|
||||
}
|
||||
|
||||
if ('chats' in result) {
|
||||
addEntitiesToLocalDb(result.chats);
|
||||
}
|
||||
|
||||
if ('messages' in result) {
|
||||
result.messages.forEach((message) => {
|
||||
addMessageToLocalDb(message);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export async function importChatInvite({ hash }: { hash: string }) {
|
||||
const updates = await invokeRequest(new GramJs.messages.ImportChatInvite({ hash }));
|
||||
if (!(updates instanceof GramJs.Updates) || !updates.chats.length) {
|
||||
@ -1758,8 +1680,6 @@ export async function fetchTopics({
|
||||
}): Promise<{
|
||||
topics: ApiTopic[];
|
||||
messages: ApiMessage[];
|
||||
users: ApiUser[];
|
||||
chats: ApiChat[];
|
||||
count: number;
|
||||
shouldOrderByCreateDate?: boolean;
|
||||
draftsById: Record<number, ReturnType<typeof buildMessageDraft>>;
|
||||
@ -1778,15 +1698,10 @@ export async function fetchTopics({
|
||||
|
||||
if (!result) return undefined;
|
||||
|
||||
updateLocalDb(result);
|
||||
|
||||
const { count, orderByCreateDate } = result;
|
||||
|
||||
const topics = result.topics.map(buildApiTopic).filter(Boolean);
|
||||
const messages = result.messages.map(buildApiMessage).filter(Boolean);
|
||||
dispatchThreadInfoUpdates(result.messages);
|
||||
const users = result.users.map(buildApiUser).filter(Boolean);
|
||||
const chats = result.chats.map((c) => buildApiChatFromPreview(c)).filter(Boolean);
|
||||
const draftsById = result.topics.reduce((acc, topic) => {
|
||||
if (topic instanceof GramJs.ForumTopic && topic.draft) {
|
||||
acc[topic.id] = buildMessageDraft(topic.draft);
|
||||
@ -1803,8 +1718,6 @@ export async function fetchTopics({
|
||||
return {
|
||||
topics,
|
||||
messages,
|
||||
users,
|
||||
chats,
|
||||
// Include general topic
|
||||
count: count + 1,
|
||||
shouldOrderByCreateDate: orderByCreateDate,
|
||||
@ -1821,8 +1734,6 @@ export async function fetchTopicById({
|
||||
}): Promise<{
|
||||
topic: ApiTopic;
|
||||
messages: ApiMessage[];
|
||||
users: ApiUser[];
|
||||
chats: ApiChat[];
|
||||
} | undefined> {
|
||||
const { id, accessHash } = chat;
|
||||
|
||||
@ -1835,18 +1746,11 @@ export async function fetchTopicById({
|
||||
return undefined;
|
||||
}
|
||||
|
||||
updateLocalDb(result);
|
||||
|
||||
const messages = result.messages.map(buildApiMessage).filter(Boolean);
|
||||
dispatchThreadInfoUpdates(result.messages);
|
||||
const users = result.users.map(buildApiUser).filter(Boolean);
|
||||
const chats = result.chats.map((c) => buildApiChatFromPreview(c)).filter(Boolean);
|
||||
|
||||
return {
|
||||
topic: buildApiTopic(result.topics[0])!,
|
||||
messages,
|
||||
users,
|
||||
chats,
|
||||
};
|
||||
}
|
||||
|
||||
@ -1927,12 +1831,8 @@ export async function checkChatlistInvite({
|
||||
|
||||
if (!result || !invite) return undefined;
|
||||
|
||||
updateLocalDb(result);
|
||||
|
||||
return {
|
||||
invite,
|
||||
users: result.users.map(buildApiUser).filter(Boolean),
|
||||
chats: result.chats.map((c) => buildApiChatFromPreview(c)).filter(Boolean),
|
||||
};
|
||||
}
|
||||
|
||||
@ -2060,12 +1960,8 @@ export async function fetchChatlistInvites({
|
||||
|
||||
if (!result) return undefined;
|
||||
|
||||
updateLocalDb(result);
|
||||
|
||||
return {
|
||||
invites: result.invites.map(buildApiChatlistExportedInvite).filter(Boolean),
|
||||
users: result.users.map(buildApiUser).filter(Boolean),
|
||||
chats: result.chats.map((c) => buildApiChatFromPreview(c)).filter(Boolean),
|
||||
};
|
||||
}
|
||||
|
||||
@ -2101,8 +1997,6 @@ export async function fetchChannelRecommendations({ chat }: { chat?: ApiChat })
|
||||
return undefined;
|
||||
}
|
||||
|
||||
updateLocalDb(result);
|
||||
|
||||
const similarChannels = result?.chats
|
||||
.map((c) => buildApiChatFromPreview(c))
|
||||
.filter(Boolean);
|
||||
|
||||
@ -12,7 +12,6 @@ import type {
|
||||
ApiMediaFormat,
|
||||
ApiOnProgress,
|
||||
ApiSessionData,
|
||||
OnApiUpdate,
|
||||
} from '../../types';
|
||||
|
||||
import {
|
||||
@ -20,15 +19,20 @@ import {
|
||||
DEBUG, DEBUG_GRAMJS, IS_TEST, UPLOAD_WORKERS,
|
||||
} from '../../../config';
|
||||
import { pause } from '../../../util/schedulers';
|
||||
import { buildApiMessage, setMessageBuilderCurrentUserId } from '../apiBuilders/messages';
|
||||
import {
|
||||
buildApiMessage,
|
||||
setMessageBuilderCurrentUserId,
|
||||
} from '../apiBuilders/messages';
|
||||
import { buildApiPeerId } from '../apiBuilders/peers';
|
||||
import { buildApiStory } from '../apiBuilders/stories';
|
||||
import { buildApiUser, buildApiUserFullInfo } from '../apiBuilders/users';
|
||||
import { buildInputPeerFromLocalDb, getEntityTypeById } from '../gramjsBuilders';
|
||||
import {
|
||||
addEntitiesToLocalDb, addMessageToLocalDb, addStoryToLocalDb, addUserToLocalDb, isResponseUpdate, log,
|
||||
addStoryToLocalDb, addUserToLocalDb, isResponseUpdate, log,
|
||||
} from '../helpers';
|
||||
import localDb, { clearLocalDb, type RepairInfo } from '../localDb';
|
||||
import { sendApiUpdate } from '../updates/apiUpdateEmitter';
|
||||
import { processAndUpdateEntities, processMessageAndUpdateThreadInfo } from '../updates/entityProcessor';
|
||||
import {
|
||||
getDifference,
|
||||
init as initUpdatesManager,
|
||||
@ -55,18 +59,15 @@ const gramJsUpdateEventBuilder = { build: (update: object) => update };
|
||||
const CHAT_ABORT_CONTROLLERS = new Map<string, ChatAbortController>();
|
||||
const ABORT_CONTROLLERS = new Map<string, AbortController>();
|
||||
|
||||
let onUpdate: OnApiUpdate;
|
||||
let client: TelegramClient;
|
||||
let currentUserId: string | undefined;
|
||||
|
||||
export async function init(_onUpdate: OnApiUpdate, initialArgs: ApiInitialArgs) {
|
||||
export async function init(initialArgs: ApiInitialArgs) {
|
||||
if (DEBUG) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('>>> START INIT API');
|
||||
}
|
||||
|
||||
onUpdate = _onUpdate;
|
||||
|
||||
const {
|
||||
userAgent, platform, sessionData, isTest, isWebmSupported, maxBufferSize, webAuthToken, dcId,
|
||||
mockScenario, shouldForceHttpTransport, shouldAllowHttpTransport,
|
||||
@ -130,7 +131,7 @@ export async function init(_onUpdate: OnApiUpdate, initialArgs: ApiInitialArgs)
|
||||
console.error(err);
|
||||
|
||||
if (err.message !== 'Disconnect' && err.message !== 'Cannot send requests while disconnected') {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateConnectionState',
|
||||
connectionState: 'connectionStateBroken',
|
||||
});
|
||||
@ -147,7 +148,7 @@ export async function init(_onUpdate: OnApiUpdate, initialArgs: ApiInitialArgs)
|
||||
|
||||
onAuthReady();
|
||||
onSessionUpdate(session.getSessionData());
|
||||
onUpdate({ '@type': 'updateApiReady' });
|
||||
sendApiUpdate({ '@type': 'updateApiReady' });
|
||||
|
||||
initUpdatesManager(invokeRequest);
|
||||
|
||||
@ -191,7 +192,7 @@ export function getClient() {
|
||||
}
|
||||
|
||||
function onSessionUpdate(sessionData: ApiSessionData) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateSession',
|
||||
sessionData,
|
||||
});
|
||||
@ -276,6 +277,8 @@ export async function invokeRequest<T extends GramJs.AnyRequest>(
|
||||
|
||||
const result = await client.invoke(request, dcId, abortSignal, shouldRetryOnTimeout);
|
||||
|
||||
processAndUpdateEntities(result);
|
||||
|
||||
if (DEBUG) {
|
||||
log('RESPONSE', request.className, result);
|
||||
}
|
||||
@ -414,7 +417,7 @@ export function dispatchErrorUpdate<T extends GramJs.AnyRequest>(err: Error, req
|
||||
|
||||
const { message } = err;
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'error',
|
||||
error: {
|
||||
message,
|
||||
@ -433,7 +436,7 @@ async function handleTerminatedSession() {
|
||||
});
|
||||
} catch (err: any) {
|
||||
if (err.message === 'AUTH_KEY_UNREGISTERED' || err.message === 'SESSION_REVOKED') {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateConnectionState',
|
||||
connectionState: 'connectionStateBroken',
|
||||
});
|
||||
@ -503,13 +506,12 @@ async function repairMessageMedia(peerId: string, messageId: number) {
|
||||
|
||||
const message = result.messages[0];
|
||||
if (message instanceof GramJs.MessageEmpty) return false;
|
||||
addEntitiesToLocalDb(result.users);
|
||||
addEntitiesToLocalDb(result.chats);
|
||||
addMessageToLocalDb(message);
|
||||
|
||||
processMessageAndUpdateThreadInfo(message);
|
||||
|
||||
const apiMessage = buildApiMessage(message);
|
||||
if (apiMessage) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateMessage',
|
||||
chatId: apiMessage.chatId,
|
||||
id: apiMessage.id,
|
||||
@ -531,13 +533,12 @@ async function repairStoryMedia(peerId: string, storyId: number) {
|
||||
});
|
||||
if (!result) return false;
|
||||
|
||||
addEntitiesToLocalDb(result.users);
|
||||
result.stories.forEach((story) => {
|
||||
const apiStory = buildApiStory(peerId, story);
|
||||
if (!apiStory || 'isDeleted' in apiStory) return;
|
||||
|
||||
addStoryToLocalDb(story, peerId);
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateStory',
|
||||
peerId,
|
||||
story: apiStory,
|
||||
|
||||
@ -3,106 +3,42 @@ export {
|
||||
setForceHttpTransport, setShouldDebugExportedSenders, setAllowHttpTransport, requestChannelDifference,
|
||||
} from './client';
|
||||
|
||||
export * from './account';
|
||||
|
||||
export {
|
||||
provideAuthPhoneNumber, provideAuthCode, provideAuthPassword, provideAuthRegistration, restartAuth, restartAuthWithQr,
|
||||
} from './auth';
|
||||
|
||||
export {
|
||||
fetchChats, fetchFullChat, searchChats, requestChatUpdate, fetchChatSettings,
|
||||
saveDraft, fetchChat, updateChatMutedState, updateTopicMutedState, fetchMember,
|
||||
createChannel, joinChannel, deleteChatUser, deleteChat, leaveChannel, deleteChannel, createGroupChat, editChatPhoto,
|
||||
toggleChatPinned, toggleChatArchived, toggleDialogUnread, setChatEnabledReactions,
|
||||
fetchChatFolders, editChatFolder, deleteChatFolder, sortChatFolders, fetchRecommendedChatFolders,
|
||||
getChatByUsername, togglePreHistoryHidden, updateChatDefaultBannedRights, updateChatMemberBannedRights,
|
||||
updateChatTitle, updateChatAbout, toggleSignatures, updateChatAdmin, fetchGroupsForDiscussion, setDiscussionGroup,
|
||||
migrateChat, openChatByInvite, fetchMembers, importChatInvite, addChatMembers, deleteChatMember, toggleIsProtected,
|
||||
getChatByPhoneNumber, toggleJoinToSend, toggleJoinRequest, fetchTopics, deleteTopic, togglePinnedTopic,
|
||||
editTopic, toggleForum, fetchTopicById, createTopic, toggleParticipantsHidden, checkChatlistInvite,
|
||||
joinChatlistInvite, createChalistInvite, editChatlistInvite, deleteChatlistInvite, fetchChatlistInvites,
|
||||
fetchLeaveChatlistSuggestions, leaveChatlist, togglePeerTranslations, setViewForumAsMessages,
|
||||
fetchChannelRecommendations, fetchSavedChats, toggleSavedDialogPinned, reportSponsoredMessage,
|
||||
} from './chats';
|
||||
|
||||
export {
|
||||
fetchMessages, fetchMessage, sendMessage, pinMessage, unpinAllMessages, deleteMessages, deleteHistory,
|
||||
markMessageListRead, markMessagesRead, searchMessagesInChat, searchMessagesGlobal, searchHashtagPosts,
|
||||
fetchWebPagePreview, editMessage, forwardMessages, loadPollOptionResults, sendPollVote, findFirstMessageIdAfterDate,
|
||||
fetchPinnedMessages, fetchScheduledHistory, sendScheduledMessages, rescheduleMessage, deleteScheduledMessages,
|
||||
reportMessages, sendMessageAction, fetchSeenBy, fetchSponsoredMessages, viewSponsoredMessage, fetchSendAs,
|
||||
saveDefaultSendAs, fetchUnreadReactions, readAllReactions, fetchUnreadMentions, readAllMentions, transcribeAudio,
|
||||
closePoll, fetchExtendedMedia, translateText, fetchMessageViews, fetchDiscussionMessage, clickSponsoredMessage,
|
||||
fetchOutboxReadDate, exportMessageLink, fetchQuickReplies, sendQuickReply, fetchFactChecks,
|
||||
deleteSavedHistory,
|
||||
} from './messages';
|
||||
|
||||
export {
|
||||
fetchFullUser, fetchNearestCountry, fetchTopUsers, fetchContactList, fetchUsers,
|
||||
updateContact, importContact, deleteContact, fetchProfilePhotos, fetchCommonChats, reportSpam, updateEmojiStatus,
|
||||
saveCloseFriends,
|
||||
} from './users';
|
||||
|
||||
export {
|
||||
fetchStickerSets, fetchRecentStickers, fetchFavoriteStickers, fetchFeaturedStickers, fetchRecentEmojiStatuses,
|
||||
faveSticker, fetchStickers, fetchSavedGifs, saveGif, searchStickers, installStickerSet, uninstallStickerSet,
|
||||
searchGifs, fetchAnimatedEmojis, fetchStickersForEmoji, fetchEmojiKeywords, fetchAnimatedEmojiEffects,
|
||||
removeRecentSticker, clearRecentStickers, fetchCustomEmoji, fetchPremiumGifts, fetchCustomEmojiSets,
|
||||
fetchFeaturedEmojiStickers, fetchGenericEmojiEffects, fetchDefaultTopicIcons, fetchDefaultStatusEmojis,
|
||||
} from './symbols';
|
||||
|
||||
export {
|
||||
checkChatUsername, setChatUsername, updatePrivateLink, deactivateAllUsernames,
|
||||
fetchExportedChatInvites, editExportedChatInvite, exportChatInvite, deleteExportedChatInvite,
|
||||
deleteRevokedExportedChatInvites, fetchChatInviteImporters, hideChatJoinRequest, hideAllChatJoinRequests,
|
||||
hideChatReportPanel,
|
||||
} from './management';
|
||||
|
||||
export * from './settings';
|
||||
|
||||
export {
|
||||
getPasswordInfo, checkPassword, clearPassword, updatePassword, updateRecoveryEmail, provideRecoveryEmailCode,
|
||||
} from './twoFaSettings';
|
||||
|
||||
export {
|
||||
answerCallbackButton, setBotInfo, fetchTopInlineBots, fetchPreviewMedias, fetchInlineBot, fetchInlineBotResults,
|
||||
sendInlineBotResult, startBot, requestMainWebView, fetchPopularAppBots, fetchTopBotApps,
|
||||
requestWebView, requestSimpleWebView, sendWebViewData, prolongWebView, loadAttachBots, toggleAttachBot, fetchBotApp,
|
||||
requestBotUrlAuth, requestLinkUrlAuth, acceptBotUrlAuth, acceptLinkUrlAuth, loadAttachBot, requestAppWebView,
|
||||
allowBotSendMessages, fetchBotCanSendMessage, invokeWebViewCustomMethod,
|
||||
} from './bots';
|
||||
|
||||
export {
|
||||
getGroupCall, joinGroupCall, discardGroupCall, createGroupCall,
|
||||
editGroupCallTitle, editGroupCallParticipant, exportGroupCallInvite, fetchGroupCallParticipants,
|
||||
joinGroupCallPresentation, leaveGroupCall, leaveGroupCallPresentation, toggleGroupCallStartSubscription,
|
||||
requestCall, getDhConfig, confirmCall, sendSignalingData, acceptCall, discardCall, setCallRating, receivedCall,
|
||||
} from './calls';
|
||||
|
||||
export * from './reactions';
|
||||
|
||||
export {
|
||||
fetchChannelStatistics, fetchGroupStatistics, fetchMessageStatistics,
|
||||
fetchMessagePublicForwards, fetchStatisticsAsyncGraph, fetchStoryStatistics, fetchStoryPublicForwards,
|
||||
fetchChannelMonetizationStatistics,
|
||||
} from './statistics';
|
||||
|
||||
export {
|
||||
acceptPhoneCall, confirmPhoneCall, requestPhoneCall, decodePhoneCallData, createPhoneCallState,
|
||||
destroyPhoneCallState, encodePhoneCallData,
|
||||
} from './phoneCallState';
|
||||
|
||||
export {
|
||||
broadcastLocalDbUpdateFull,
|
||||
} from '../localDb';
|
||||
|
||||
export * from './account';
|
||||
|
||||
export * from './chats';
|
||||
|
||||
export * from './messages';
|
||||
|
||||
export * from './users';
|
||||
|
||||
export * from './symbols';
|
||||
|
||||
export * from './management';
|
||||
|
||||
export * from './settings';
|
||||
|
||||
export * from './twoFaSettings';
|
||||
|
||||
export * from './bots';
|
||||
|
||||
export * from './calls';
|
||||
|
||||
export * from './reactions';
|
||||
|
||||
export * from './statistics';
|
||||
|
||||
export * from './phoneCallState';
|
||||
|
||||
export * from './stories';
|
||||
|
||||
export {
|
||||
validateRequestedInfo, sendPaymentForm, getPaymentForm, getReceipt, fetchPremiumPromo, fetchTemporaryPaymentPassword,
|
||||
applyBoost, fetchBoostList, fetchBoostStatus, fetchGiveawayInfo, fetchMyBoosts, applyGiftCode, checkGiftCode,
|
||||
getPremiumGiftCodeOptions, launchPrepaidGiveaway, fetchStarsStatus, fetchStarsTopupOptions, fetchStarsTransactions,
|
||||
sendStarPaymentForm, getStarsGiftOptions, fetchStarsTransactionById,
|
||||
} from './payments';
|
||||
export * from './payments';
|
||||
|
||||
export * from './fragment';
|
||||
|
||||
@ -1,49 +1,22 @@
|
||||
import type {
|
||||
ApiInitialArgs,
|
||||
ApiOnProgress,
|
||||
ApiUpdate,
|
||||
OnApiUpdate,
|
||||
} from '../../types';
|
||||
import type { LocalDb } from '../localDb';
|
||||
import type { MethodArgs, MethodResponse, Methods } from './types';
|
||||
|
||||
import { API_THROTTLE_RESET_UPDATES, API_UPDATE_THROTTLE } from '../../../config';
|
||||
import { throttle, throttleWithTickEnd } from '../../../util/schedulers';
|
||||
import { updateFullLocalDb } from '../localDb';
|
||||
import { init as initUpdater } from '../updates/updater';
|
||||
import { init as initAuth } from './auth';
|
||||
import { init as initBots } from './bots';
|
||||
import { init as initCalls } from './calls';
|
||||
import { init as initChats } from './chats';
|
||||
import { init as initUpdateEmitter } from '../updates/apiUpdateEmitter';
|
||||
import { init as initClient } from './client';
|
||||
import * as methods from './index';
|
||||
import { init as initManagement } from './management';
|
||||
import { init as initMessages } from './messages';
|
||||
import { init as initPayments } from './payments';
|
||||
import { init as initStickers } from './symbols';
|
||||
import { init as initTwoFaSettings } from './twoFaSettings';
|
||||
import { init as initUsers } from './users';
|
||||
|
||||
let onUpdate: OnApiUpdate;
|
||||
|
||||
export function initApi(_onUpdate: OnApiUpdate, initialArgs: ApiInitialArgs, initialLocalDb?: LocalDb) {
|
||||
onUpdate = _onUpdate;
|
||||
|
||||
initUpdater(handleUpdate);
|
||||
initAuth(handleUpdate);
|
||||
initChats(handleUpdate);
|
||||
initMessages(handleUpdate);
|
||||
initUsers(handleUpdate);
|
||||
initStickers(handleUpdate);
|
||||
initManagement(handleUpdate);
|
||||
initTwoFaSettings(handleUpdate);
|
||||
initBots(handleUpdate);
|
||||
initCalls(handleUpdate);
|
||||
initPayments(handleUpdate);
|
||||
initUpdateEmitter(_onUpdate);
|
||||
|
||||
if (initialLocalDb) updateFullLocalDb(initialLocalDb);
|
||||
|
||||
initClient(handleUpdate, initialArgs);
|
||||
initClient(initialArgs);
|
||||
}
|
||||
|
||||
export function callApi<T extends keyof Methods>(fnName: T, ...args: MethodArgs<T>): MethodResponse<T> {
|
||||
@ -54,35 +27,3 @@ export function callApi<T extends keyof Methods>(fnName: T, ...args: MethodArgs<
|
||||
export function cancelApiProgress(progressCallback: ApiOnProgress) {
|
||||
progressCallback.isCanceled = true;
|
||||
}
|
||||
|
||||
const flushUpdatesOnTickEnd = throttleWithTickEnd(flushUpdates);
|
||||
|
||||
let flushUpdatesThrottled: typeof flushUpdatesOnTickEnd | undefined;
|
||||
let currentThrottleId: number | undefined;
|
||||
|
||||
let pendingUpdates: ApiUpdate[] | undefined;
|
||||
|
||||
function handleUpdate(update: ApiUpdate) {
|
||||
if (!pendingUpdates) {
|
||||
pendingUpdates = [update];
|
||||
} else {
|
||||
pendingUpdates.push(update);
|
||||
}
|
||||
|
||||
if (!flushUpdatesThrottled || API_THROTTLE_RESET_UPDATES.has(update['@type'])) {
|
||||
flushUpdatesThrottled = throttle(flushUpdatesOnTickEnd, API_UPDATE_THROTTLE, true);
|
||||
currentThrottleId = Math.random();
|
||||
}
|
||||
|
||||
flushUpdatesThrottled(currentThrottleId!);
|
||||
}
|
||||
|
||||
function flushUpdates(throttleId: number) {
|
||||
if (!pendingUpdates || throttleId !== currentThrottleId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const currentUpdates = pendingUpdates!;
|
||||
pendingUpdates = undefined;
|
||||
currentUpdates.forEach(onUpdate);
|
||||
}
|
||||
|
||||
@ -1,25 +1,15 @@
|
||||
import { Api as GramJs } from '../../../lib/gramjs';
|
||||
|
||||
import type {
|
||||
ApiChat, ApiError, ApiUser, ApiUsername, OnApiUpdate,
|
||||
ApiChat, ApiError, ApiUser, ApiUsername,
|
||||
} from '../../types';
|
||||
|
||||
import { USERNAME_PURCHASE_ERROR } from '../../../config';
|
||||
import { buildCollectionByKey } from '../../../util/iteratees';
|
||||
import { ACCEPTABLE_USERNAME_ERRORS } from '../../../config';
|
||||
import { buildApiExportedInvite, buildChatInviteImporter } from '../apiBuilders/chats';
|
||||
import { buildApiUser } from '../apiBuilders/users';
|
||||
import { buildInputEntity, buildInputPeer } from '../gramjsBuilders';
|
||||
import { addEntitiesToLocalDb } from '../helpers';
|
||||
import { sendApiUpdate } from '../updates/apiUpdateEmitter';
|
||||
import { invokeRequest } from './client';
|
||||
|
||||
let onUpdate: OnApiUpdate;
|
||||
|
||||
export const ACCEPTABLE_USERNAME_ERRORS = new Set([USERNAME_PURCHASE_ERROR, 'USERNAME_INVALID']);
|
||||
|
||||
export function init(_onUpdate: OnApiUpdate) {
|
||||
onUpdate = _onUpdate;
|
||||
}
|
||||
|
||||
export async function checkChatUsername({ username }: { username: string }) {
|
||||
try {
|
||||
const result = await invokeRequest(new GramJs.channels.CheckUsername({
|
||||
@ -59,7 +49,7 @@ export async function setChatUsername(
|
||||
}
|
||||
|
||||
if (result) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateChat',
|
||||
id: chat.id,
|
||||
chat: { usernames: usernames.length ? usernames : undefined },
|
||||
@ -82,7 +72,7 @@ export async function deactivateAllUsernames({ chat }: { chat: ApiChat }) {
|
||||
.filter((u) => u.username)
|
||||
: undefined;
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateChat',
|
||||
id: chat.id,
|
||||
chat: { usernames },
|
||||
@ -105,7 +95,7 @@ export async function updatePrivateLink({
|
||||
|
||||
if (!(result instanceof GramJs.ChatInviteExported)) return undefined;
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateChatFullInfo',
|
||||
id: chat.id,
|
||||
fullInfo: {
|
||||
@ -129,7 +119,6 @@ export async function fetchExportedChatInvites({
|
||||
});
|
||||
|
||||
if (!exportedInvites) return undefined;
|
||||
addEntitiesToLocalDb(exportedInvites.users);
|
||||
|
||||
const invites = (exportedInvites.invites
|
||||
.filter((invite): invite is GramJs.ChatInviteExported => invite instanceof GramJs.ChatInviteExported))
|
||||
@ -137,7 +126,6 @@ export async function fetchExportedChatInvites({
|
||||
|
||||
return {
|
||||
invites,
|
||||
users: exportedInvites.users.map(buildApiUser).filter(Boolean),
|
||||
};
|
||||
}
|
||||
|
||||
@ -164,13 +152,11 @@ export async function editExportedChatInvite({
|
||||
|
||||
if (!invite) return undefined;
|
||||
|
||||
addEntitiesToLocalDb(invite.users);
|
||||
if (invite instanceof GramJs.messages.ExportedChatInvite && invite.invite instanceof GramJs.ChatInviteExported) {
|
||||
const replaceInvite = buildApiExportedInvite(invite.invite);
|
||||
return {
|
||||
oldInvite: replaceInvite,
|
||||
newInvite: replaceInvite,
|
||||
users: invite.users.map(buildApiUser).filter(Boolean),
|
||||
};
|
||||
}
|
||||
|
||||
@ -182,7 +168,6 @@ export async function editExportedChatInvite({
|
||||
return {
|
||||
oldInvite,
|
||||
newInvite,
|
||||
users: invite.users.map(buildApiUser).filter(Boolean),
|
||||
};
|
||||
}
|
||||
return undefined;
|
||||
@ -253,11 +238,9 @@ export async function fetchChatInviteImporters({
|
||||
});
|
||||
|
||||
if (!result) return undefined;
|
||||
const users = result.users.map((user) => buildApiUser(user)).filter(Boolean);
|
||||
addEntitiesToLocalDb(result.users);
|
||||
|
||||
return {
|
||||
importers: result.importers.map((importer) => buildChatInviteImporter(importer)),
|
||||
users: buildCollectionByKey(users, 'id'),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -22,11 +22,9 @@ import type {
|
||||
ApiSticker,
|
||||
ApiStory,
|
||||
ApiStorySkipped,
|
||||
ApiUser,
|
||||
ApiUserStatus,
|
||||
ApiVideo,
|
||||
MediaContent,
|
||||
OnApiUpdate,
|
||||
} from '../../types';
|
||||
import { MAIN_THREAD_ID, MESSAGE_DELETED } from '../../types';
|
||||
|
||||
@ -62,7 +60,7 @@ import {
|
||||
buildUploadingMedia,
|
||||
} from '../apiBuilders/messages';
|
||||
import { getApiChatIdFromMtpPeer } from '../apiBuilders/peers';
|
||||
import { buildApiUser, buildApiUsersAndStatuses } from '../apiBuilders/users';
|
||||
import { buildApiUser, buildApiUserStatuses } from '../apiBuilders/users';
|
||||
import {
|
||||
buildInputEntity,
|
||||
buildInputMediaDocument,
|
||||
@ -82,13 +80,12 @@ import {
|
||||
getEntityTypeById,
|
||||
} from '../gramjsBuilders';
|
||||
import {
|
||||
addEntitiesToLocalDb,
|
||||
addMessageToLocalDb,
|
||||
deserializeBytes,
|
||||
resolveMessageApiChatId,
|
||||
} from '../helpers';
|
||||
import { sendApiUpdate } from '../updates/apiUpdateEmitter';
|
||||
import { processMessageAndUpdateThreadInfo } from '../updates/entityProcessor';
|
||||
import { processAffectedHistory, updateChannelState } from '../updates/updateManager';
|
||||
import { dispatchThreadInfoUpdates } from '../updates/updater';
|
||||
import { requestChatUpdate } from './chats';
|
||||
import { handleGramJsUpdate, invokeRequest, uploadFile } from './client';
|
||||
|
||||
@ -106,21 +103,13 @@ type TranslateTextParams = ({
|
||||
|
||||
type SearchResults = {
|
||||
messages: ApiMessage[];
|
||||
users: ApiUser[];
|
||||
userStatusesById: Record<number, ApiUserStatus>;
|
||||
chats: ApiChat[];
|
||||
totalCount: number;
|
||||
nextOffsetRate?: number;
|
||||
nextOffsetPeerId?: string;
|
||||
nextOffsetId?: number;
|
||||
};
|
||||
|
||||
let onUpdate: OnApiUpdate;
|
||||
|
||||
export function init(_onUpdate: OnApiUpdate) {
|
||||
onUpdate = _onUpdate;
|
||||
}
|
||||
|
||||
export async function fetchMessages({
|
||||
chat,
|
||||
threadId,
|
||||
@ -158,7 +147,7 @@ export async function fetchMessages({
|
||||
});
|
||||
} catch (err: any) {
|
||||
if (err.message === 'CHANNEL_PRIVATE') {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateChat',
|
||||
id: chat.id,
|
||||
chat: {
|
||||
@ -176,13 +165,10 @@ export async function fetchMessages({
|
||||
return undefined;
|
||||
}
|
||||
|
||||
updateLocalDb(result);
|
||||
|
||||
const messages = result.messages.map(buildApiMessage).filter(Boolean);
|
||||
const users = result.users.map(buildApiUser).filter(Boolean);
|
||||
const chats = result.chats.map((c) => buildApiChatFromPreview(c)).filter(Boolean);
|
||||
const count = !(result instanceof GramJs.messages.Messages) && result.count;
|
||||
dispatchThreadInfoUpdates(result.messages);
|
||||
|
||||
return {
|
||||
messages,
|
||||
@ -217,7 +203,7 @@ export async function fetchMessage({ chat, messageId }: { chat: ApiChat; message
|
||||
// When fetching messages for the bot @replies, there may be situations when the user was banned
|
||||
// in the comment group or this group was deleted
|
||||
if (message !== 'CHANNEL_PRIVATE') {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'error',
|
||||
error: {
|
||||
message,
|
||||
@ -245,18 +231,14 @@ export async function fetchMessage({ chat, messageId }: { chat: ApiChat; message
|
||||
return MESSAGE_DELETED;
|
||||
}
|
||||
|
||||
const message = mtpMessage && buildApiMessage(mtpMessage);
|
||||
dispatchThreadInfoUpdates([mtpMessage]);
|
||||
processMessageAndUpdateThreadInfo(mtpMessage);
|
||||
const message = buildApiMessage(mtpMessage);
|
||||
|
||||
if (!message) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
addMessageToLocalDb(mtpMessage);
|
||||
|
||||
const users = result.users.map(buildApiUser).filter(Boolean);
|
||||
|
||||
return { message, users };
|
||||
return { message };
|
||||
}
|
||||
|
||||
let mediaQueue = Promise.resolve();
|
||||
@ -326,7 +308,7 @@ export function sendMessage(
|
||||
effectId,
|
||||
);
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': localMessage.isScheduled ? 'newScheduledMessage' : 'newMessage',
|
||||
id: localMessage.id,
|
||||
chatId: chat.id,
|
||||
@ -337,7 +319,7 @@ export function sendMessage(
|
||||
// This is expected to arrive after `updateMessageSendSucceeded` which replaces the local ID,
|
||||
// so in most cases this will be simply ignored
|
||||
const timeout = setTimeout(() => {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': localMessage.isScheduled ? 'updateScheduledMessage' : 'updateMessage',
|
||||
id: localMessage.id,
|
||||
chatId: chat.id,
|
||||
@ -419,10 +401,10 @@ export function sendMessage(
|
||||
if (update) handleLocalMessageUpdate(localMessage, update);
|
||||
} catch (error: any) {
|
||||
if (error.message === 'PRIVACY_PREMIUM_REQUIRED') {
|
||||
onUpdate({ '@type': 'updateRequestUserUpdate', id: chat.id });
|
||||
sendApiUpdate({ '@type': 'updateRequestUserUpdate', id: chat.id });
|
||||
}
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateMessageSendFailed',
|
||||
chatId: chat.id,
|
||||
localId: localMessage.id,
|
||||
@ -624,7 +606,7 @@ export async function editMessage({
|
||||
isInvertedMedia,
|
||||
};
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': isScheduled ? 'updateScheduledMessage' : 'updateMessage',
|
||||
id: message.id,
|
||||
chatId: chat.id,
|
||||
@ -657,7 +639,7 @@ export async function editMessage({
|
||||
|
||||
const { message: messageErr } = err as Error;
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'error',
|
||||
error: {
|
||||
message: messageErr,
|
||||
@ -666,7 +648,7 @@ export async function editMessage({
|
||||
});
|
||||
|
||||
// Rollback changes
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': isScheduled ? 'updateScheduledMessage' : 'updateMessage',
|
||||
id: message.id,
|
||||
chatId: chat.id,
|
||||
@ -823,7 +805,7 @@ export async function deleteMessages({
|
||||
|
||||
processAffectedHistory(chat, result);
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'deleteMessages',
|
||||
ids: messageIds,
|
||||
...(isChannel && { chatId: chat.id }),
|
||||
@ -872,7 +854,7 @@ export async function deleteHistory({
|
||||
}
|
||||
}
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'deleteHistory',
|
||||
chatId: chat.id,
|
||||
});
|
||||
@ -898,7 +880,7 @@ export async function deleteSavedHistory({
|
||||
return;
|
||||
}
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'deleteSavedHistory',
|
||||
chatId: chat.id,
|
||||
});
|
||||
@ -984,7 +966,7 @@ export async function markMessageListRead({
|
||||
if (threadId === MAIN_THREAD_ID) {
|
||||
void requestChatUpdate({ chat, noLastMessage: true });
|
||||
} else if (chat.isForum) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateTopic',
|
||||
chatId: chat.id,
|
||||
topicId: Number(threadId),
|
||||
@ -1018,7 +1000,7 @@ export async function markMessagesRead({
|
||||
processAffectedHistory(chat, result);
|
||||
}
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
...(isChannel ? {
|
||||
'@type': 'updateChannelMessages',
|
||||
channelId: chat.id,
|
||||
@ -1052,8 +1034,6 @@ export async function fetchMessageViews({
|
||||
if (!results || results.some((result) => !result)) return undefined;
|
||||
|
||||
const viewsList = results.flatMap((result) => result!.views);
|
||||
const users = results.flatMap((result) => result!.users);
|
||||
const chats = results.flatMap((result) => result!.chats);
|
||||
|
||||
const viewsInfo = ids.map((id, index) => {
|
||||
const { views, forwards, replies } = viewsList[index];
|
||||
@ -1067,8 +1047,6 @@ export async function fetchMessageViews({
|
||||
|
||||
return {
|
||||
viewsInfo,
|
||||
users: users.map(buildApiUser).filter(Boolean),
|
||||
chats: chats.map((c) => buildApiChatFromPreview(c)).filter(Boolean),
|
||||
};
|
||||
}
|
||||
|
||||
@ -1116,27 +1094,17 @@ export async function fetchDiscussionMessage({
|
||||
|
||||
if (!result || !replies) return undefined;
|
||||
|
||||
updateLocalDb(result);
|
||||
|
||||
const chats = result.chats.map((c) => buildApiChatFromPreview(c)).filter(Boolean)
|
||||
.concat(replies.chats);
|
||||
const users = result.users.map(buildApiUser).filter(Boolean)
|
||||
.concat(replies.users);
|
||||
const topMessages = result.messages.map(buildApiMessage).filter(Boolean);
|
||||
const messages = topMessages.concat(replies.messages);
|
||||
const threadId = result.messages[result.messages.length - 1]?.id;
|
||||
|
||||
if (!threadId) return undefined;
|
||||
|
||||
dispatchThreadInfoUpdates(result.messages);
|
||||
|
||||
const {
|
||||
unreadCount, maxId, readInboxMaxId, readOutboxMaxId,
|
||||
} = result;
|
||||
|
||||
return {
|
||||
chats,
|
||||
users,
|
||||
messages,
|
||||
topMessages,
|
||||
unreadCount,
|
||||
@ -1215,12 +1183,8 @@ export async function searchMessagesInChat({
|
||||
return undefined;
|
||||
}
|
||||
|
||||
updateLocalDb(result);
|
||||
|
||||
const chats = result.chats.map((c) => buildApiChatFromPreview(c)).filter(Boolean);
|
||||
const { users, userStatusesById } = buildApiUsersAndStatuses(result.users);
|
||||
const userStatusesById = buildApiUserStatuses(result.users);
|
||||
const messages = result.messages.map(buildApiMessage).filter(Boolean);
|
||||
dispatchThreadInfoUpdates(result.messages);
|
||||
|
||||
let totalCount = messages.length;
|
||||
let nextOffsetId: number | undefined;
|
||||
@ -1233,8 +1197,6 @@ export async function searchMessagesInChat({
|
||||
}
|
||||
|
||||
return {
|
||||
chats,
|
||||
users,
|
||||
userStatusesById,
|
||||
messages,
|
||||
totalCount,
|
||||
@ -1304,12 +1266,8 @@ export async function searchMessagesGlobal({
|
||||
return undefined;
|
||||
}
|
||||
|
||||
updateLocalDb(result);
|
||||
|
||||
const chats = result.chats.map((c) => buildApiChatFromPreview(c)).filter(Boolean);
|
||||
const { users, userStatusesById } = buildApiUsersAndStatuses(result.users);
|
||||
const userStatusesById = buildApiUserStatuses(result.users);
|
||||
const messages = result.messages.map(buildApiMessage).filter(Boolean);
|
||||
dispatchThreadInfoUpdates(result.messages);
|
||||
|
||||
let totalCount = messages.length;
|
||||
if (result instanceof GramJs.messages.MessagesSlice || result instanceof GramJs.messages.ChannelMessages) {
|
||||
@ -1325,9 +1283,7 @@ export async function searchMessagesGlobal({
|
||||
|
||||
return {
|
||||
messages,
|
||||
users,
|
||||
userStatusesById,
|
||||
chats,
|
||||
totalCount,
|
||||
nextOffsetRate,
|
||||
nextOffsetPeerId,
|
||||
@ -1357,12 +1313,8 @@ export async function searchHashtagPosts({
|
||||
return undefined;
|
||||
}
|
||||
|
||||
updateLocalDb(result);
|
||||
|
||||
const chats = result.chats.map((c) => buildApiChatFromPreview(c)).filter(Boolean);
|
||||
const { users, userStatusesById } = buildApiUsersAndStatuses(result.users);
|
||||
const userStatusesById = buildApiUserStatuses(result.users);
|
||||
const messages = result.messages.map(buildApiMessage).filter(Boolean);
|
||||
dispatchThreadInfoUpdates(result.messages);
|
||||
|
||||
let totalCount = messages.length;
|
||||
if (result instanceof GramJs.messages.MessagesSlice || result instanceof GramJs.messages.ChannelMessages) {
|
||||
@ -1378,9 +1330,7 @@ export async function searchHashtagPosts({
|
||||
|
||||
return {
|
||||
messages,
|
||||
users,
|
||||
userStatusesById,
|
||||
chats,
|
||||
totalCount,
|
||||
nextOffsetRate,
|
||||
nextOffsetPeerId,
|
||||
@ -1458,14 +1408,6 @@ export async function loadPollOptionResults({
|
||||
return undefined;
|
||||
}
|
||||
|
||||
updateLocalDb({
|
||||
chats: result.chats,
|
||||
users: result.users,
|
||||
messages: [] as GramJs.Message[],
|
||||
} as GramJs.messages.Messages);
|
||||
|
||||
const users = result.users.map(buildApiUser).filter(Boolean);
|
||||
const chats = result.chats.map((c) => buildApiChatFromPreview(c)).filter(Boolean);
|
||||
const votes = result.votes.map((vote) => ({
|
||||
peerId: getApiChatIdFromMtpPeer(vote.peer),
|
||||
date: vote.date,
|
||||
@ -1474,8 +1416,6 @@ export async function loadPollOptionResults({
|
||||
return {
|
||||
count: result.count,
|
||||
votes,
|
||||
chats,
|
||||
users,
|
||||
nextOffset: result.nextOffset,
|
||||
shouldResetVoters,
|
||||
};
|
||||
@ -1539,7 +1479,7 @@ export async function forwardMessages({
|
||||
});
|
||||
localMessages[randomIds[index].toString()] = localMessage;
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': localMessage.isScheduled ? 'newScheduledMessage' : 'newMessage',
|
||||
id: localMessage.id,
|
||||
chatId: toChat.id,
|
||||
@ -1568,7 +1508,7 @@ export async function forwardMessages({
|
||||
if (update) handleMultipleLocalMessagesUpdate(localMessages, update);
|
||||
} catch (error: any) {
|
||||
Object.values(localMessages).forEach((localMessage) => {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateMessageSendFailed',
|
||||
chatId: toChat.id,
|
||||
localId: localMessage.id,
|
||||
@ -1620,10 +1560,7 @@ export async function fetchScheduledHistory({ chat }: { chat: ApiChat }) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
updateLocalDb(result);
|
||||
|
||||
const messages = result.messages.map(buildApiMessage).filter(Boolean);
|
||||
dispatchThreadInfoUpdates(result.messages);
|
||||
|
||||
return {
|
||||
messages,
|
||||
@ -1639,18 +1576,6 @@ export async function sendScheduledMessages({ chat, ids }: { chat: ApiChat; ids:
|
||||
}));
|
||||
}
|
||||
|
||||
function updateLocalDb(result: (
|
||||
GramJs.messages.MessagesSlice | GramJs.messages.Messages | GramJs.messages.ChannelMessages |
|
||||
GramJs.messages.DiscussionMessage | GramJs.messages.SponsoredMessages | GramJs.messages.QuickReplies
|
||||
)) {
|
||||
addEntitiesToLocalDb(result.users);
|
||||
addEntitiesToLocalDb(result.chats);
|
||||
|
||||
result.messages.forEach((message) => {
|
||||
addMessageToLocalDb(message);
|
||||
});
|
||||
}
|
||||
|
||||
export async function fetchPinnedMessages({ chat, threadId }: { chat: ApiChat; threadId: ThreadId }) {
|
||||
const result = await invokeRequest(new GramJs.messages.Search(
|
||||
{
|
||||
@ -1673,17 +1598,10 @@ export async function fetchPinnedMessages({ chat, threadId }: { chat: ApiChat; t
|
||||
return undefined;
|
||||
}
|
||||
|
||||
updateLocalDb(result);
|
||||
|
||||
const chats = result.chats.map((c) => buildApiChatFromPreview(c)).filter(Boolean);
|
||||
const users = result.users.map(buildApiUser).filter(Boolean);
|
||||
const messages = result.messages.map(buildApiMessage).filter(Boolean);
|
||||
dispatchThreadInfoUpdates(result.messages);
|
||||
|
||||
return {
|
||||
messages,
|
||||
users,
|
||||
chats,
|
||||
};
|
||||
}
|
||||
|
||||
@ -1718,15 +1636,7 @@ export async function fetchSendAs({
|
||||
return undefined;
|
||||
}
|
||||
|
||||
addEntitiesToLocalDb(result.users);
|
||||
addEntitiesToLocalDb(result.chats);
|
||||
|
||||
const users = result.users.map(buildApiUser).filter(Boolean);
|
||||
const chats = result.chats.map((c) => buildApiChatFromPreview(c)).filter(Boolean);
|
||||
|
||||
return {
|
||||
users,
|
||||
chats,
|
||||
sendAs: result.peers.map(buildApiSendAsPeerId),
|
||||
};
|
||||
}
|
||||
@ -1751,16 +1661,10 @@ export async function fetchSponsoredMessages({ chat }: { chat: ApiChat }) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
updateLocalDb(result);
|
||||
|
||||
const messages = result.messages.map(buildApiSponsoredMessage).filter(Boolean);
|
||||
const users = result.users.map(buildApiUser).filter(Boolean);
|
||||
const chats = result.chats.map((c) => buildApiChatFromPreview(c)).filter(Boolean);
|
||||
|
||||
return {
|
||||
messages,
|
||||
users,
|
||||
chats,
|
||||
};
|
||||
}
|
||||
|
||||
@ -1837,17 +1741,10 @@ export async function fetchUnreadMentions({
|
||||
return undefined;
|
||||
}
|
||||
|
||||
updateLocalDb(result);
|
||||
|
||||
const messages = result.messages.map(buildApiMessage).filter(Boolean);
|
||||
dispatchThreadInfoUpdates(result.messages);
|
||||
const users = result.users.map(buildApiUser).filter(Boolean);
|
||||
const chats = result.chats.map((c) => buildApiChatFromPreview(c)).filter(Boolean);
|
||||
|
||||
return {
|
||||
messages,
|
||||
users,
|
||||
chats,
|
||||
};
|
||||
}
|
||||
|
||||
@ -1874,17 +1771,10 @@ export async function fetchUnreadReactions({
|
||||
return undefined;
|
||||
}
|
||||
|
||||
updateLocalDb(result);
|
||||
|
||||
const messages = result.messages.map(buildApiMessage).filter(Boolean);
|
||||
dispatchThreadInfoUpdates(result.messages);
|
||||
const users = result.users.map(buildApiUser).filter(Boolean);
|
||||
const chats = result.chats.map((c) => buildApiChatFromPreview(c)).filter(Boolean);
|
||||
|
||||
return {
|
||||
messages,
|
||||
users,
|
||||
chats,
|
||||
};
|
||||
}
|
||||
|
||||
@ -1900,7 +1790,7 @@ export async function transcribeAudio({
|
||||
|
||||
if (!result) return undefined;
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateTranscribedAudio',
|
||||
isPending: result.pending,
|
||||
transcriptionId: result.transcriptionId.toString(),
|
||||
@ -1933,7 +1823,7 @@ export async function translateText(params: TranslateTextParams) {
|
||||
const formattedText = result.result.map((r) => buildApiFormattedText(r));
|
||||
|
||||
if (isMessageTranslation) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateMessageTranslations',
|
||||
chatId: params.chat.id,
|
||||
messageIds: params.messageIds,
|
||||
@ -1993,13 +1883,13 @@ function handleLocalMessageUpdate(localMessage: ApiMessage, update: GramJs.TypeU
|
||||
}
|
||||
|
||||
const mtpMessage = buildMessageFromUpdate(messageUpdate.id, localMessage.chatId, messageUpdate);
|
||||
addMessageToLocalDb(mtpMessage);
|
||||
processMessageAndUpdateThreadInfo(mtpMessage);
|
||||
}
|
||||
|
||||
// Edge case for "Send When Online"
|
||||
const isSentBefore = 'date' in messageUpdate && messageUpdate.date * 1000 < Date.now() + getServerTimeOffset() * 1000;
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': localMessage.isScheduled && !isSentBefore
|
||||
? 'updateScheduledMessageSendSucceeded'
|
||||
: 'updateMessageSendSucceeded',
|
||||
@ -2040,20 +1930,12 @@ export async function fetchQuickReplies() {
|
||||
const result = await invokeRequest(new GramJs.messages.GetQuickReplies({}));
|
||||
if (!result || result instanceof GramJs.messages.QuickRepliesNotModified) return undefined;
|
||||
|
||||
updateLocalDb(result);
|
||||
|
||||
const messages = result.messages.map(buildApiMessage).filter(Boolean);
|
||||
dispatchThreadInfoUpdates(result.messages);
|
||||
|
||||
const chats = result.chats.map((c) => buildApiChatFromPreview(c)).filter(Boolean);
|
||||
const users = result.users.map(buildApiUser).filter(Boolean);
|
||||
|
||||
const quickReplies = result.quickReplies.map(buildApiQuickReply);
|
||||
|
||||
return {
|
||||
messages,
|
||||
chats,
|
||||
users,
|
||||
quickReplies,
|
||||
};
|
||||
}
|
||||
|
||||
@ -4,11 +4,9 @@ import { Api as GramJs } from '../../../lib/gramjs';
|
||||
import type {
|
||||
ApiChat, ApiInputStorePaymentPurpose, ApiPeer, ApiRequestInputInvoice,
|
||||
ApiThemeParameters,
|
||||
OnApiUpdate,
|
||||
} from '../../types';
|
||||
|
||||
import { DEBUG } from '../../../config';
|
||||
import { buildApiChatFromPreview } from '../apiBuilders/chats';
|
||||
import {
|
||||
buildApiBoost,
|
||||
buildApiBoostsStatus,
|
||||
@ -24,26 +22,19 @@ import {
|
||||
buildApiStarTopupOption,
|
||||
buildShippingOptions,
|
||||
} from '../apiBuilders/payments';
|
||||
import { buildApiUser } from '../apiBuilders/users';
|
||||
import {
|
||||
buildInputInvoice, buildInputPeer, buildInputStorePaymentPurpose, buildInputThemeParams, buildShippingInfo,
|
||||
} from '../gramjsBuilders';
|
||||
import {
|
||||
addEntitiesToLocalDb,
|
||||
addWebDocumentToLocalDb,
|
||||
deserializeBytes,
|
||||
serializeBytes,
|
||||
} from '../helpers';
|
||||
import localDb from '../localDb';
|
||||
import { sendApiUpdate } from '../updates/apiUpdateEmitter';
|
||||
import { handleGramJsUpdate, invokeRequest } from './client';
|
||||
import { getTemporaryPaymentPassword } from './twoFaSettings';
|
||||
|
||||
let onUpdate: OnApiUpdate;
|
||||
|
||||
export function init(_onUpdate: OnApiUpdate) {
|
||||
onUpdate = _onUpdate;
|
||||
}
|
||||
|
||||
export async function validateRequestedInfo({
|
||||
inputInvoice,
|
||||
requestInfo,
|
||||
@ -116,7 +107,7 @@ export async function sendPaymentForm({
|
||||
if (!result) return false;
|
||||
|
||||
if (result instanceof GramJs.payments.PaymentVerificationNeeded) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updatePaymentVerificationNeeded',
|
||||
url: result.url,
|
||||
});
|
||||
@ -171,12 +162,9 @@ export async function getPaymentForm(inputInvoice: ApiRequestInputInvoice, theme
|
||||
addWebDocumentToLocalDb(result.photo);
|
||||
}
|
||||
|
||||
addEntitiesToLocalDb(result.users);
|
||||
|
||||
return {
|
||||
form: buildApiPaymentForm(result),
|
||||
invoice: buildApiInvoiceFromForm(result),
|
||||
users: result.users.map(buildApiUser).filter(Boolean),
|
||||
};
|
||||
}
|
||||
|
||||
@ -190,11 +178,8 @@ export async function getReceipt(chat: ApiChat, msgId: number) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
addEntitiesToLocalDb(result.users);
|
||||
|
||||
return {
|
||||
receipt: buildApiReceipt(result),
|
||||
users: result.users.map(buildApiUser).filter(Boolean),
|
||||
};
|
||||
}
|
||||
|
||||
@ -202,9 +187,6 @@ export async function fetchPremiumPromo() {
|
||||
const result = await invokeRequest(new GramJs.help.GetPremiumPromo());
|
||||
if (!result) return undefined;
|
||||
|
||||
addEntitiesToLocalDb(result.users);
|
||||
|
||||
const users = result.users.map(buildApiUser).filter(Boolean);
|
||||
result.videos.forEach((video) => {
|
||||
if (video instanceof GramJs.Document) {
|
||||
localDb.documents[video.id.toString()] = video;
|
||||
@ -213,7 +195,6 @@ export async function fetchPremiumPromo() {
|
||||
|
||||
return {
|
||||
promo: buildApiPremiumPromo(result),
|
||||
users,
|
||||
};
|
||||
}
|
||||
|
||||
@ -239,16 +220,9 @@ export async function fetchMyBoosts() {
|
||||
|
||||
if (!result) return undefined;
|
||||
|
||||
addEntitiesToLocalDb(result.users);
|
||||
addEntitiesToLocalDb(result.chats);
|
||||
|
||||
const users = result.users.map(buildApiUser).filter(Boolean);
|
||||
const chats = result.chats.map((c) => buildApiChatFromPreview(c)).filter(Boolean);
|
||||
const boosts = result.myBoosts.map(buildApiMyBoost);
|
||||
|
||||
return {
|
||||
users,
|
||||
chats,
|
||||
boosts,
|
||||
};
|
||||
}
|
||||
@ -267,16 +241,9 @@ export async function applyBoost({
|
||||
|
||||
if (!result) return undefined;
|
||||
|
||||
addEntitiesToLocalDb(result.users);
|
||||
addEntitiesToLocalDb(result.chats);
|
||||
|
||||
const users = result.users.map(buildApiUser).filter(Boolean);
|
||||
const chats = result.chats.map((c) => buildApiChatFromPreview(c)).filter(Boolean);
|
||||
const boosts = result.myBoosts.map(buildApiMyBoost);
|
||||
|
||||
return {
|
||||
users,
|
||||
chats,
|
||||
boosts,
|
||||
};
|
||||
}
|
||||
@ -319,16 +286,11 @@ export async function fetchBoostList({
|
||||
return undefined;
|
||||
}
|
||||
|
||||
addEntitiesToLocalDb(result.users);
|
||||
|
||||
const users = result.users.map(buildApiUser).filter(Boolean);
|
||||
|
||||
const boostList = result.boosts.map(buildApiBoost);
|
||||
|
||||
return {
|
||||
count: result.count,
|
||||
boostList,
|
||||
users,
|
||||
nextOffset: result.nextOffset,
|
||||
};
|
||||
}
|
||||
@ -365,13 +327,8 @@ export async function checkGiftCode({
|
||||
return undefined;
|
||||
}
|
||||
|
||||
addEntitiesToLocalDb(result.users);
|
||||
addEntitiesToLocalDb(result.chats);
|
||||
|
||||
return {
|
||||
code: buildApiCheckedGiftCode(result),
|
||||
users: result.users.map(buildApiUser).filter(Boolean),
|
||||
chats: result.chats.map((c) => buildApiChatFromPreview(c)).filter(Boolean),
|
||||
};
|
||||
}
|
||||
|
||||
@ -446,12 +403,7 @@ export async function fetchStarsStatus() {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const users = result.users.map(buildApiUser).filter(Boolean);
|
||||
const chats = result.chats.map((c) => buildApiChatFromPreview(c)).filter(Boolean);
|
||||
|
||||
return {
|
||||
users,
|
||||
chats,
|
||||
nextOffset: result.nextOffset,
|
||||
history: result.history?.map(buildApiStarsTransaction),
|
||||
balance: result.balance.toJSNumber(),
|
||||
@ -481,12 +433,7 @@ export async function fetchStarsTransactions({
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const users = result.users.map(buildApiUser).filter(Boolean);
|
||||
const chats = result.chats.map((c) => buildApiChatFromPreview(c)).filter(Boolean);
|
||||
|
||||
return {
|
||||
users,
|
||||
chats,
|
||||
nextOffset: result.nextOffset,
|
||||
history: result.history?.map(buildApiStarsTransaction),
|
||||
balance: result.balance.toJSNumber(),
|
||||
@ -511,12 +458,7 @@ export async function fetchStarsTransactionById({
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const users = result.users.map(buildApiUser).filter(Boolean);
|
||||
const chats = result.chats.map((c) => buildApiChatFromPreview(c)).filter(Boolean);
|
||||
|
||||
return {
|
||||
users,
|
||||
chats,
|
||||
transaction: buildApiStarsTransaction(result.history[0]),
|
||||
};
|
||||
}
|
||||
|
||||
@ -129,7 +129,7 @@ function computeEmojiIndex(bytes: Uint8Array) {
|
||||
.or((BigInt(bytes[7])));
|
||||
}
|
||||
|
||||
export async function generateEmojiFingerprint(
|
||||
async function generateEmojiFingerprint(
|
||||
authKey: Uint8Array, gA: Uint8Array, emojiData: Uint16Array, emojiOffsets: number[],
|
||||
) {
|
||||
const hash = await Helpers.sha256(Buffer.concat([new Uint8Array(authKey), new Uint8Array(gA)]));
|
||||
|
||||
@ -12,7 +12,6 @@ import {
|
||||
TOP_REACTIONS_LIMIT,
|
||||
} from '../../../config';
|
||||
import { split } from '../../../util/iteratees';
|
||||
import { buildApiChatFromPreview } from '../apiBuilders/chats';
|
||||
import {
|
||||
buildApiAvailableEffect,
|
||||
buildApiAvailableReaction,
|
||||
@ -21,9 +20,7 @@ import {
|
||||
buildMessagePeerReaction,
|
||||
} from '../apiBuilders/reactions';
|
||||
import { buildStickerFromDocument } from '../apiBuilders/symbols';
|
||||
import { buildApiUser } from '../apiBuilders/users';
|
||||
import { buildInputPeer, buildInputReaction } from '../gramjsBuilders';
|
||||
import { addEntitiesToLocalDb } from '../helpers';
|
||||
import localDb from '../localDb';
|
||||
import { invokeRequest } from './client';
|
||||
|
||||
@ -187,14 +184,9 @@ export async function fetchMessageReactionsList({
|
||||
return undefined;
|
||||
}
|
||||
|
||||
addEntitiesToLocalDb(result.users);
|
||||
addEntitiesToLocalDb(result.chats);
|
||||
|
||||
const { nextOffset, reactions, count } = result;
|
||||
|
||||
return {
|
||||
users: result.users.map(buildApiUser).filter(Boolean),
|
||||
chats: result.chats.map((c) => buildApiChatFromPreview(c)).filter(Boolean),
|
||||
nextOffset,
|
||||
reactions: reactions.map(buildMessagePeerReaction).filter(Boolean),
|
||||
count,
|
||||
|
||||
@ -13,11 +13,12 @@ import type {
|
||||
ApiUser,
|
||||
} from '../../types';
|
||||
|
||||
import { BLOCKED_LIST_LIMIT, DEFAULT_LANG_PACK, MAX_INT_32 } from '../../../config';
|
||||
import {
|
||||
ACCEPTABLE_USERNAME_ERRORS, BLOCKED_LIST_LIMIT, DEFAULT_LANG_PACK, MAX_INT_32,
|
||||
} from '../../../config';
|
||||
import { buildCollectionByKey } from '../../../util/iteratees';
|
||||
import { getServerTime } from '../../../util/serverTime';
|
||||
import { buildAppConfig } from '../apiBuilders/appConfig';
|
||||
import { buildApiChatFromPreview } from '../apiBuilders/chats';
|
||||
import { buildApiPhoto, buildPrivacyRules } from '../apiBuilders/common';
|
||||
import {
|
||||
buildApiConfig,
|
||||
@ -34,16 +35,14 @@ import {
|
||||
oldBuildLangPackString,
|
||||
} from '../apiBuilders/misc';
|
||||
import { getApiChatIdFromMtpPeer } from '../apiBuilders/peers';
|
||||
import { buildApiUser } from '../apiBuilders/users';
|
||||
import {
|
||||
buildInputEntity, buildInputPeer, buildInputPhoto,
|
||||
buildInputPrivacyKey,
|
||||
buildInputPrivacyRules,
|
||||
} from '../gramjsBuilders';
|
||||
import { addEntitiesToLocalDb, addPhotoToLocalDb } from '../helpers';
|
||||
import { addPhotoToLocalDb } from '../helpers';
|
||||
import localDb from '../localDb';
|
||||
import { getClient, invokeRequest, uploadFile } from './client';
|
||||
import { ACCEPTABLE_USERNAME_ERRORS } from './management';
|
||||
|
||||
const BETA_LANG_CODES = ['ar', 'fa', 'id', 'ko', 'uz', 'en'];
|
||||
|
||||
@ -102,11 +101,9 @@ export async function updateProfilePhoto(photo?: ApiPhoto, isFallback?: boolean)
|
||||
}));
|
||||
if (!result) return undefined;
|
||||
|
||||
addEntitiesToLocalDb(result.users);
|
||||
if (result.photo instanceof GramJs.Photo) {
|
||||
addPhotoToLocalDb(result.photo);
|
||||
return {
|
||||
users: result.users.map(buildApiUser).filter(Boolean),
|
||||
photo: buildApiPhoto(result.photo),
|
||||
};
|
||||
}
|
||||
@ -125,11 +122,9 @@ export async function uploadProfilePhoto(
|
||||
|
||||
if (!result) return undefined;
|
||||
|
||||
addEntitiesToLocalDb(result.users);
|
||||
if (result.photo instanceof GramJs.Photo) {
|
||||
addPhotoToLocalDb(result.photo);
|
||||
return {
|
||||
users: result.users.map(buildApiUser).filter(Boolean),
|
||||
photo: buildApiPhoto(result.photo),
|
||||
};
|
||||
}
|
||||
@ -152,20 +147,14 @@ export async function uploadContactProfilePhoto({
|
||||
|
||||
if (!result) return undefined;
|
||||
|
||||
addEntitiesToLocalDb(result.users);
|
||||
|
||||
const users = result.users.map(buildApiUser).filter(Boolean);
|
||||
|
||||
if (result.photo instanceof GramJs.Photo) {
|
||||
addPhotoToLocalDb(result.photo);
|
||||
return {
|
||||
users,
|
||||
photo: buildApiPhoto(result.photo),
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
users,
|
||||
photo: undefined,
|
||||
};
|
||||
}
|
||||
@ -246,11 +235,7 @@ export async function fetchBlockedUsers({
|
||||
return undefined;
|
||||
}
|
||||
|
||||
updateLocalDb(result);
|
||||
|
||||
return {
|
||||
users: result.users.map(buildApiUser).filter(Boolean),
|
||||
chats: result.chats.map((chat) => buildApiChatFromPreview(chat)).filter(Boolean),
|
||||
blockedIds: result.blocked.map((blocked) => getApiChatIdFromMtpPeer(blocked.peerId)),
|
||||
totalCount: result instanceof GramJs.contacts.BlockedSlice ? result.count : result.blocked.length,
|
||||
};
|
||||
@ -307,10 +292,8 @@ export async function fetchWebAuthorizations() {
|
||||
if (!result) {
|
||||
return undefined;
|
||||
}
|
||||
addEntitiesToLocalDb(result.users);
|
||||
|
||||
return {
|
||||
users: result.users.map(buildApiUser).filter(Boolean),
|
||||
webAuthorizations: buildCollectionByKey(result.authorizations.map(buildApiWebSession), 'hash'),
|
||||
};
|
||||
}
|
||||
@ -334,8 +317,6 @@ export async function fetchNotificationExceptions() {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
updateLocalDb(result);
|
||||
|
||||
return result.updates.reduce((acc, update) => {
|
||||
if (!(update instanceof GramJs.UpdateNotifySettings && update.peer instanceof GramJs.NotifyPeer)) {
|
||||
return acc;
|
||||
@ -555,10 +536,7 @@ export async function fetchPrivacySettings(privacyKey: ApiPrivacyKey) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
updateLocalDb(result);
|
||||
|
||||
return {
|
||||
users: result.users.map(buildApiUser).filter(Boolean),
|
||||
rules: buildPrivacyRules(result.rules),
|
||||
};
|
||||
}
|
||||
@ -595,10 +573,7 @@ export async function setPrivacySettings(
|
||||
return undefined;
|
||||
}
|
||||
|
||||
updateLocalDb(result);
|
||||
|
||||
return {
|
||||
users: result.users.map(buildApiUser).filter(Boolean),
|
||||
rules: buildPrivacyRules(result.rules),
|
||||
};
|
||||
}
|
||||
@ -671,16 +646,6 @@ export async function fetchTimezones(hash?: number) {
|
||||
};
|
||||
}
|
||||
|
||||
function updateLocalDb(
|
||||
result: (
|
||||
GramJs.account.PrivacyRules | GramJs.contacts.Blocked | GramJs.contacts.BlockedSlice |
|
||||
GramJs.Updates | GramJs.UpdatesCombined
|
||||
),
|
||||
) {
|
||||
addEntitiesToLocalDb(result.users);
|
||||
addEntitiesToLocalDb(result.chats);
|
||||
}
|
||||
|
||||
export async function fetchCountryList({ langCode = 'en' }: { langCode?: LangCode }) {
|
||||
const countryList = await invokeRequest(new GramJs.help.GetCountriesList({
|
||||
langCode,
|
||||
|
||||
@ -2,11 +2,10 @@ import BigInt from 'big-integer';
|
||||
import { Api as GramJs } from '../../../lib/gramjs';
|
||||
|
||||
import type {
|
||||
ApiChat, ApiMessagePublicForward, ApiPostStatistics, ApiStoryPublicForward, ApiUser, StatisticsGraph,
|
||||
ApiChat, ApiMessagePublicForward, ApiPostStatistics, ApiStoryPublicForward, StatisticsGraph,
|
||||
} from '../../types';
|
||||
|
||||
import { STATISTICS_PUBLIC_FORWARDS_LIMIT } from '../../../config';
|
||||
import { buildApiChatFromPreview } from '../apiBuilders/chats';
|
||||
import {
|
||||
buildChannelMonetizationStatistics,
|
||||
buildChannelStatistics,
|
||||
@ -16,9 +15,7 @@ import {
|
||||
buildPostsStatistics,
|
||||
buildStoryPublicForwards,
|
||||
} from '../apiBuilders/statistics';
|
||||
import { buildApiUser } from '../apiBuilders/users';
|
||||
import { buildInputEntity, buildInputPeer } from '../gramjsBuilders';
|
||||
import { addEntitiesToLocalDb } from '../helpers';
|
||||
import { invokeRequest } from './client';
|
||||
|
||||
export async function fetchChannelStatistics({
|
||||
@ -69,10 +66,7 @@ export async function fetchGroupStatistics({
|
||||
return undefined;
|
||||
}
|
||||
|
||||
addEntitiesToLocalDb(result.users);
|
||||
|
||||
return {
|
||||
users: result.users.map(buildApiUser).filter(Boolean),
|
||||
stats: buildGroupStatistics(result),
|
||||
};
|
||||
}
|
||||
@ -114,8 +108,6 @@ export async function fetchMessagePublicForwards({
|
||||
forwards?: ApiMessagePublicForward[];
|
||||
count?: number;
|
||||
nextOffset?: string;
|
||||
chats: ApiChat[];
|
||||
users: ApiUser[];
|
||||
} | undefined> {
|
||||
const result = await invokeRequest(new GramJs.stats.GetMessagePublicForwards({
|
||||
channel: buildInputEntity(chat.id, chat.accessHash) as GramJs.InputChannel,
|
||||
@ -130,15 +122,10 @@ export async function fetchMessagePublicForwards({
|
||||
return undefined;
|
||||
}
|
||||
|
||||
addEntitiesToLocalDb(result.chats);
|
||||
addEntitiesToLocalDb(result.users);
|
||||
|
||||
return {
|
||||
forwards: buildMessagePublicForwards(result),
|
||||
count: result.count,
|
||||
nextOffset: result.nextOffset,
|
||||
chats: result.chats.map((c) => buildApiChatFromPreview(c)).filter(Boolean),
|
||||
users: result.users.map(buildApiUser).filter(Boolean),
|
||||
};
|
||||
}
|
||||
|
||||
@ -202,8 +189,6 @@ export async function fetchStoryPublicForwards({
|
||||
offset?: string;
|
||||
}): Promise<{
|
||||
publicForwards: (ApiMessagePublicForward | ApiStoryPublicForward)[] | undefined;
|
||||
users: ApiUser[];
|
||||
chats: ApiChat[];
|
||||
count?: number;
|
||||
nextOffset?: string;
|
||||
} | undefined> {
|
||||
@ -220,13 +205,8 @@ export async function fetchStoryPublicForwards({
|
||||
return undefined;
|
||||
}
|
||||
|
||||
addEntitiesToLocalDb(result.chats);
|
||||
addEntitiesToLocalDb(result.users);
|
||||
|
||||
return {
|
||||
publicForwards: buildStoryPublicForwards(result),
|
||||
users: result.users.map(buildApiUser).filter(Boolean),
|
||||
chats: result.chats.map((c) => buildApiChatFromPreview(c)).filter(Boolean),
|
||||
count: result.count,
|
||||
nextOffset: result.nextOffset,
|
||||
};
|
||||
|
||||
@ -2,19 +2,16 @@ import { Api as GramJs } from '../../../lib/gramjs';
|
||||
|
||||
import type { ApiInputPrivacyRules } from '../../../types';
|
||||
import type {
|
||||
ApiChat,
|
||||
ApiPeer,
|
||||
ApiPeerStories,
|
||||
ApiReaction,
|
||||
ApiReportReason,
|
||||
ApiStealthMode,
|
||||
ApiTypeStory,
|
||||
ApiUser,
|
||||
} from '../../types';
|
||||
|
||||
import { STORY_LIST_LIMIT } from '../../../config';
|
||||
import { buildCollectionByCallback } from '../../../util/iteratees';
|
||||
import { buildApiChatFromPreview } from '../apiBuilders/chats';
|
||||
import { getApiChatIdFromMtpPeer } from '../apiBuilders/peers';
|
||||
import {
|
||||
buildApiPeerStories,
|
||||
@ -23,14 +20,13 @@ import {
|
||||
buildApiStoryView,
|
||||
buildApiStoryViews,
|
||||
} from '../apiBuilders/stories';
|
||||
import { buildApiUser } from '../apiBuilders/users';
|
||||
import {
|
||||
buildInputPeer,
|
||||
buildInputPrivacyRules,
|
||||
buildInputReaction,
|
||||
buildInputReportReason,
|
||||
} from '../gramjsBuilders';
|
||||
import { addEntitiesToLocalDb, addStoryToLocalDb } from '../helpers';
|
||||
import { addStoryToLocalDb } from '../helpers';
|
||||
import { invokeRequest } from './client';
|
||||
|
||||
export async function fetchAllStories({
|
||||
@ -45,8 +41,6 @@ export async function fetchAllStories({
|
||||
undefined
|
||||
| { state: string; stealthMode: ApiStealthMode }
|
||||
| {
|
||||
users: ApiUser[];
|
||||
chats: ApiChat[];
|
||||
peerStories: Record<string, ApiPeerStories>;
|
||||
hasMore?: true;
|
||||
state: string;
|
||||
@ -68,9 +62,6 @@ export async function fetchAllStories({
|
||||
};
|
||||
}
|
||||
|
||||
addEntitiesToLocalDb(result.users);
|
||||
addEntitiesToLocalDb(result.chats);
|
||||
|
||||
const allUserStories = result.peerStories.reduce<Record<string, ApiPeerStories>>((acc, peerStories) => {
|
||||
const peerId = getApiChatIdFromMtpPeer(peerStories.peer);
|
||||
const stories = buildApiPeerStories(peerStories);
|
||||
@ -117,8 +108,6 @@ export async function fetchAllStories({
|
||||
));
|
||||
|
||||
return {
|
||||
users: result.users.map(buildApiUser).filter(Boolean),
|
||||
chats: result.chats.map((c) => buildApiChatFromPreview(c)).filter(Boolean),
|
||||
peerStories: allUserStories,
|
||||
hasMore: result.hasMore,
|
||||
state: result.state,
|
||||
@ -139,10 +128,6 @@ export async function fetchPeerStories({
|
||||
return undefined;
|
||||
}
|
||||
|
||||
addEntitiesToLocalDb(result.users);
|
||||
|
||||
const users = result.users.map(buildApiUser).filter(Boolean);
|
||||
const chats = result.chats.map((c) => buildApiChatFromPreview(c)).filter(Boolean);
|
||||
const stories = buildCollectionByCallback(result.stories.stories, (story) => (
|
||||
[story.id, buildApiStory(peer.id, story)]
|
||||
));
|
||||
@ -151,8 +136,6 @@ export async function fetchPeerStories({
|
||||
result.stories.stories.forEach((story) => addStoryToLocalDb(story, peer.id));
|
||||
|
||||
return {
|
||||
chats,
|
||||
users,
|
||||
stories,
|
||||
lastReadStoryId: result.stories.maxReadId,
|
||||
};
|
||||
@ -201,11 +184,6 @@ export async function fetchPeerStoriesByIds({ peer, ids }: { peer: ApiPeer; ids:
|
||||
return undefined;
|
||||
}
|
||||
|
||||
addEntitiesToLocalDb(result.users);
|
||||
addEntitiesToLocalDb(result.chats);
|
||||
|
||||
const users = result.users.map(buildApiUser).filter(Boolean);
|
||||
const chats = result.chats.map((c) => buildApiChatFromPreview(c)).filter(Boolean);
|
||||
const stories = ids.reduce<Record<string, ApiTypeStory>>((acc, id) => {
|
||||
const story = result.stories.find(({ id: currentId }) => currentId === id);
|
||||
if (story) {
|
||||
@ -225,8 +203,6 @@ export async function fetchPeerStoriesByIds({ peer, ids }: { peer: ApiPeer; ids:
|
||||
result.stories.forEach((story) => addStoryToLocalDb(story, peer.id));
|
||||
|
||||
return {
|
||||
chats,
|
||||
users,
|
||||
pinnedIds: result.pinnedToTop,
|
||||
stories,
|
||||
};
|
||||
@ -307,15 +283,9 @@ export async function fetchStoryViewList({
|
||||
return undefined;
|
||||
}
|
||||
|
||||
addEntitiesToLocalDb(result.users);
|
||||
addEntitiesToLocalDb(result.chats);
|
||||
const users = result.users.map(buildApiUser).filter(Boolean);
|
||||
const chats = result.chats.map((c) => buildApiChatFromPreview(c)).filter(Boolean);
|
||||
const views = result.views.map(buildApiStoryView).filter(Boolean);
|
||||
|
||||
return {
|
||||
users,
|
||||
chats,
|
||||
views,
|
||||
nextOffset: result.nextOffset,
|
||||
reactionsCount: result.reactionsCount,
|
||||
@ -339,14 +309,10 @@ export async function fetchStoriesViews({
|
||||
return undefined;
|
||||
}
|
||||
|
||||
addEntitiesToLocalDb(result.users);
|
||||
|
||||
const views = buildApiStoryViews(result.views[0]);
|
||||
const users = result.users.map(buildApiUser).filter(Boolean);
|
||||
|
||||
return {
|
||||
views,
|
||||
users,
|
||||
};
|
||||
}
|
||||
|
||||
@ -430,11 +396,6 @@ async function fetchCommonStoriesRequest({ method, peerId }: {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
addEntitiesToLocalDb(result.users);
|
||||
addEntitiesToLocalDb(result.chats);
|
||||
|
||||
const users = result.users.map(buildApiUser).filter(Boolean);
|
||||
const chats = result.chats.map((c) => buildApiChatFromPreview(c)).filter(Boolean);
|
||||
const stories = buildCollectionByCallback(result.stories, (story) => (
|
||||
[story.id, buildApiStory(peerId, story)]
|
||||
));
|
||||
@ -443,8 +404,6 @@ async function fetchCommonStoriesRequest({ method, peerId }: {
|
||||
result.stories.forEach((story) => addStoryToLocalDb(story, peerId));
|
||||
|
||||
return {
|
||||
users,
|
||||
chats,
|
||||
stories,
|
||||
pinnedIds: result.pinnedToTop,
|
||||
};
|
||||
|
||||
@ -2,7 +2,7 @@ import BigInt from 'big-integer';
|
||||
import { Api as GramJs } from '../../../lib/gramjs';
|
||||
|
||||
import type {
|
||||
ApiSticker, ApiStickerSetInfo, ApiVideo, OnApiUpdate,
|
||||
ApiSticker, ApiStickerSetInfo, ApiVideo,
|
||||
} from '../../types';
|
||||
|
||||
import { DEFAULT_GIF_SEARCH_BOT_USERNAME, RECENT_STATUS_LIMIT, RECENT_STICKERS_LIMIT } from '../../../config';
|
||||
@ -13,14 +13,9 @@ import {
|
||||
} from '../apiBuilders/symbols';
|
||||
import { buildInputDocument, buildInputStickerSet, buildInputStickerSetShortName } from '../gramjsBuilders';
|
||||
import localDb from '../localDb';
|
||||
import { sendApiUpdate } from '../updates/apiUpdateEmitter';
|
||||
import { invokeRequest } from './client';
|
||||
|
||||
let onUpdate: OnApiUpdate;
|
||||
|
||||
export function init(_onUpdate: OnApiUpdate) {
|
||||
onUpdate = _onUpdate;
|
||||
}
|
||||
|
||||
export async function fetchCustomEmojiSets({ hash = '0' }: { hash?: string }) {
|
||||
const allStickers = await invokeRequest(new GramJs.messages.GetEmojiStickers({ hash: BigInt(hash) }));
|
||||
|
||||
@ -132,7 +127,7 @@ export async function faveSticker({
|
||||
|
||||
const result = await invokeRequest(request);
|
||||
if (result) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateFavoriteStickers',
|
||||
});
|
||||
}
|
||||
@ -325,7 +320,7 @@ export async function installStickerSet({ stickerSetId, accessHash }: { stickerS
|
||||
}));
|
||||
|
||||
if (result) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateStickerSet',
|
||||
id: stickerSetId,
|
||||
stickerSet: { installedDate: Date.now() },
|
||||
@ -339,7 +334,7 @@ export async function uninstallStickerSet({ stickerSetId, accessHash }: { sticke
|
||||
}));
|
||||
|
||||
if (result) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateStickerSet',
|
||||
id: stickerSetId,
|
||||
stickerSet: { installedDate: undefined },
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
import { Api as GramJs, errors } from '../../../lib/gramjs';
|
||||
|
||||
import type { OnApiUpdate } from '../../types';
|
||||
|
||||
import { DEBUG } from '../../../config';
|
||||
import { sendApiUpdate } from '../updates/apiUpdateEmitter';
|
||||
import { getTmpPassword, invokeRequest, updateTwoFaSettings } from './client';
|
||||
|
||||
const ApiErrors: { [k: string]: string } = {
|
||||
@ -19,12 +18,6 @@ const emailCodeController: {
|
||||
reject?: Function;
|
||||
} = {};
|
||||
|
||||
let onUpdate: OnApiUpdate;
|
||||
|
||||
export function init(_onUpdate: OnApiUpdate) {
|
||||
onUpdate = _onUpdate;
|
||||
}
|
||||
|
||||
export async function getPasswordInfo() {
|
||||
const result = await invokeRequest(new GramJs.account.GetPassword());
|
||||
if (!result) {
|
||||
@ -37,7 +30,7 @@ export async function getPasswordInfo() {
|
||||
}
|
||||
|
||||
function onRequestEmailCode(length: number) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateTwoFaStateWaitCode',
|
||||
length,
|
||||
});
|
||||
@ -136,7 +129,7 @@ function onError(err: Error) {
|
||||
}
|
||||
}
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateTwoFaError',
|
||||
message,
|
||||
});
|
||||
|
||||
@ -2,15 +2,14 @@ import BigInt from 'big-integer';
|
||||
import { Api as GramJs } from '../../../lib/gramjs';
|
||||
|
||||
import type {
|
||||
ApiChat, ApiPeer, ApiSticker,
|
||||
ApiUser, OnApiUpdate,
|
||||
ApiChat, ApiPeer, ApiSticker, ApiUser,
|
||||
} from '../../types';
|
||||
|
||||
import { COMMON_CHATS_LIMIT } from '../../../config';
|
||||
import { buildApiChatFromPreview } from '../apiBuilders/chats';
|
||||
import { buildApiPhoto } from '../apiBuilders/common';
|
||||
import { buildApiPeerId } from '../apiBuilders/peers';
|
||||
import { buildApiUser, buildApiUserFullInfo, buildApiUsersAndStatuses } from '../apiBuilders/users';
|
||||
import { buildApiUser, buildApiUserFullInfo, buildApiUserStatuses } from '../apiBuilders/users';
|
||||
import {
|
||||
buildInputContact,
|
||||
buildInputEmojiStatus,
|
||||
@ -19,17 +18,12 @@ import {
|
||||
buildMtpPeerId,
|
||||
getEntityTypeById,
|
||||
} from '../gramjsBuilders';
|
||||
import { addEntitiesToLocalDb, addPhotoToLocalDb, addUserToLocalDb } from '../helpers';
|
||||
import { addPhotoToLocalDb, addUserToLocalDb } from '../helpers';
|
||||
import localDb from '../localDb';
|
||||
import { sendApiUpdate } from '../updates/apiUpdateEmitter';
|
||||
import { invokeRequest } from './client';
|
||||
import { searchMessagesInChat } from './messages';
|
||||
|
||||
let onUpdate: OnApiUpdate;
|
||||
|
||||
export function init(_onUpdate: OnApiUpdate) {
|
||||
onUpdate = _onUpdate;
|
||||
}
|
||||
|
||||
export async function fetchFullUser({
|
||||
id,
|
||||
accessHash,
|
||||
@ -48,10 +42,6 @@ export async function fetchFullUser({
|
||||
return undefined;
|
||||
}
|
||||
|
||||
updateLocalDb(result);
|
||||
addEntitiesToLocalDb(result.users);
|
||||
addEntitiesToLocalDb(result.chats);
|
||||
|
||||
if (result.fullUser.profilePhoto) {
|
||||
addPhotoToLocalDb(result.fullUser.profilePhoto);
|
||||
}
|
||||
@ -82,7 +72,7 @@ export async function fetchFullUser({
|
||||
|
||||
const user = users.find(({ id: userId }) => userId === id)!;
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateUser',
|
||||
id,
|
||||
user,
|
||||
@ -108,21 +98,10 @@ export async function fetchCommonChats(id: string, accessHash?: string, maxId?:
|
||||
return undefined;
|
||||
}
|
||||
|
||||
updateLocalDb(commonChats);
|
||||
const chats = commonChats.chats.map((c) => buildApiChatFromPreview(c)).filter(Boolean);
|
||||
const chatIds = chats.map(({ id: chatId }) => chatId);
|
||||
|
||||
const chatIds: string[] = [];
|
||||
const chats: ApiChat[] = [];
|
||||
|
||||
commonChats.chats.forEach((mtpChat) => {
|
||||
const chat = buildApiChatFromPreview(mtpChat);
|
||||
|
||||
if (chat) {
|
||||
chats.push(chat);
|
||||
chatIds.push(chat.id);
|
||||
}
|
||||
});
|
||||
|
||||
return { chats, chatIds, isFullyLoaded: chatIds.length < COMMON_CHATS_LIMIT };
|
||||
return { chatIds, isFullyLoaded: chatIds.length < COMMON_CHATS_LIMIT };
|
||||
}
|
||||
|
||||
export async function fetchNearestCountry() {
|
||||
@ -144,7 +123,6 @@ export async function fetchTopUsers() {
|
||||
|
||||
return {
|
||||
ids,
|
||||
users,
|
||||
};
|
||||
}
|
||||
|
||||
@ -154,14 +132,12 @@ export async function fetchContactList() {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
addEntitiesToLocalDb(result.users);
|
||||
|
||||
const { users, userStatusesById } = buildApiUsersAndStatuses(result.users);
|
||||
const users = result.users.map(buildApiUser).filter(Boolean) as ApiUser[];
|
||||
const userStatusesById = buildApiUserStatuses(result.users);
|
||||
|
||||
return {
|
||||
users,
|
||||
userStatusesById,
|
||||
chats: result.users.map((user) => buildApiChatFromPreview(user)).filter(Boolean),
|
||||
};
|
||||
}
|
||||
|
||||
@ -173,9 +149,13 @@ export async function fetchUsers({ users }: { users: ApiUser[] }) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
addEntitiesToLocalDb(result);
|
||||
const apiUsers = result.map(buildApiUser).filter(Boolean) as ApiUser[];
|
||||
const userStatusesById = buildApiUserStatuses(result);
|
||||
|
||||
return buildApiUsersAndStatuses(result);
|
||||
return {
|
||||
users: apiUsers,
|
||||
userStatusesById,
|
||||
};
|
||||
}
|
||||
|
||||
export async function importContact({
|
||||
@ -246,7 +226,7 @@ export async function deleteContact({
|
||||
return;
|
||||
}
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'deleteContact',
|
||||
id,
|
||||
});
|
||||
@ -277,7 +257,7 @@ export async function fetchProfilePhotos({
|
||||
return undefined;
|
||||
}
|
||||
|
||||
updateLocalDb(result);
|
||||
result.photos.forEach(addPhotoToLocalDb);
|
||||
|
||||
const count = result instanceof GramJs.photos.PhotosSlice ? result.count : result.photos.length;
|
||||
const proposedNextOffsetId = offset + result.photos.length;
|
||||
@ -288,7 +268,6 @@ export async function fetchProfilePhotos({
|
||||
photos: result.photos
|
||||
.filter((photo): photo is GramJs.Photo => photo instanceof GramJs.Photo)
|
||||
.map((photo) => buildApiPhoto(photo)),
|
||||
users: result.users.map(buildApiUser).filter(Boolean),
|
||||
nextOffsetId,
|
||||
};
|
||||
}
|
||||
@ -306,13 +285,12 @@ export async function fetchProfilePhotos({
|
||||
}
|
||||
|
||||
const {
|
||||
messages, users, totalCount, nextOffsetId,
|
||||
messages, totalCount, nextOffsetId,
|
||||
} = result;
|
||||
|
||||
return {
|
||||
count: totalCount,
|
||||
photos: messages.map((message) => message.content.action!.photo).filter(Boolean),
|
||||
users,
|
||||
nextOffsetId,
|
||||
};
|
||||
}
|
||||
@ -342,17 +320,3 @@ export function saveCloseFriends(userIds: string[]) {
|
||||
shouldReturnTrue: true,
|
||||
});
|
||||
}
|
||||
|
||||
function updateLocalDb(result: (GramJs.photos.Photos | GramJs.photos.PhotosSlice | GramJs.messages.Chats)) {
|
||||
if ('chats' in result) {
|
||||
addEntitiesToLocalDb(result.chats);
|
||||
}
|
||||
|
||||
if ('photos' in result) {
|
||||
result.photos.forEach(addPhotoToLocalDb);
|
||||
}
|
||||
|
||||
if ('users' in result) {
|
||||
addEntitiesToLocalDb(result.users);
|
||||
}
|
||||
}
|
||||
|
||||
50
src/api/gramjs/updates/apiUpdateEmitter.ts
Normal file
50
src/api/gramjs/updates/apiUpdateEmitter.ts
Normal file
@ -0,0 +1,50 @@
|
||||
import type { ApiUpdate, OnApiUpdate } from '../../types';
|
||||
|
||||
import { API_THROTTLE_RESET_UPDATES, API_UPDATE_THROTTLE } from '../../../config';
|
||||
import { throttle, throttleWithTickEnd } from '../../../util/schedulers';
|
||||
|
||||
let onUpdate: OnApiUpdate;
|
||||
|
||||
export function init(_onUpdate: OnApiUpdate) {
|
||||
onUpdate = _onUpdate;
|
||||
}
|
||||
|
||||
export function sendApiUpdate(update: ApiUpdate) {
|
||||
queueUpdate(update);
|
||||
}
|
||||
|
||||
export function sendImmediateApiUpdate(update: ApiUpdate) {
|
||||
onUpdate(update);
|
||||
}
|
||||
|
||||
const flushUpdatesOnTickEnd = throttleWithTickEnd(flushUpdates);
|
||||
|
||||
let flushUpdatesThrottled: typeof flushUpdatesOnTickEnd | undefined;
|
||||
let currentThrottleId: number | undefined;
|
||||
|
||||
let pendingUpdates: ApiUpdate[] | undefined;
|
||||
|
||||
function queueUpdate(update: ApiUpdate) {
|
||||
if (!pendingUpdates) {
|
||||
pendingUpdates = [update];
|
||||
} else {
|
||||
pendingUpdates.push(update);
|
||||
}
|
||||
|
||||
if (!flushUpdatesThrottled || API_THROTTLE_RESET_UPDATES.has(update['@type'])) {
|
||||
flushUpdatesThrottled = throttle(flushUpdatesOnTickEnd, API_UPDATE_THROTTLE, true);
|
||||
currentThrottleId = Math.random();
|
||||
}
|
||||
|
||||
flushUpdatesThrottled(currentThrottleId!);
|
||||
}
|
||||
|
||||
function flushUpdates(throttleId: number) {
|
||||
if (!pendingUpdates || throttleId !== currentThrottleId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const currentUpdates = pendingUpdates!;
|
||||
pendingUpdates = undefined;
|
||||
currentUpdates.forEach(onUpdate);
|
||||
}
|
||||
69
src/api/gramjs/updates/entityProcessor.ts
Normal file
69
src/api/gramjs/updates/entityProcessor.ts
Normal file
@ -0,0 +1,69 @@
|
||||
import { Api as GramJs } from '../../../lib/gramjs';
|
||||
|
||||
import type { ApiChat, ApiThreadInfo, ApiUser } from '../../types';
|
||||
|
||||
import { buildCollectionByKey } from '../../../util/iteratees';
|
||||
import { buildApiChatFromPreview } from '../apiBuilders/chats';
|
||||
import { buildApiThreadInfoFromMessage } from '../apiBuilders/messages';
|
||||
import { buildApiUser } from '../apiBuilders/users';
|
||||
import { addChatToLocalDb, addMessageToLocalDb, addUserToLocalDb } from '../helpers';
|
||||
import { sendImmediateApiUpdate } from './apiUpdateEmitter';
|
||||
|
||||
const TYPE_USER = new Set(['User', 'UserEmpty']);
|
||||
const TYPE_CHAT = new Set(['ChatEmpty', 'Chat', 'ChatForbidden', 'Channel', 'ChannelForbidden']);
|
||||
const TYPE_MESSAGE = new Set(['Message', 'MessageEmpty', 'MessageService']);
|
||||
|
||||
export function processAndUpdateEntities(response?: GramJs.AnyRequest['__response']) {
|
||||
if (!response || typeof response !== 'object') return;
|
||||
if (!('users' in response || 'chats' in response || 'messages' in response)) return;
|
||||
|
||||
let userById: Record<string, ApiUser> | undefined;
|
||||
let chatById: Record<string, ApiChat> | undefined;
|
||||
let threadInfos: ApiThreadInfo[] | undefined;
|
||||
|
||||
if ('users' in response && Array.isArray(response.users) && TYPE_USER.has(response.users[0]?.className)) {
|
||||
const users = response.users.map((user) => {
|
||||
if (user instanceof GramJs.User) {
|
||||
addUserToLocalDb(user);
|
||||
}
|
||||
return buildApiUser(user);
|
||||
}).filter(Boolean);
|
||||
userById = buildCollectionByKey(users, 'id');
|
||||
}
|
||||
|
||||
if ('chats' in response && Array.isArray(response.chats) && TYPE_CHAT.has(response.chats[0]?.className)) {
|
||||
const chats = response.chats.map((chat) => {
|
||||
if ((chat instanceof GramJs.Chat || chat instanceof GramJs.Channel)) {
|
||||
addChatToLocalDb(chat);
|
||||
}
|
||||
return buildApiChatFromPreview(chat);
|
||||
}).filter(Boolean);
|
||||
chatById = buildCollectionByKey(chats, 'id');
|
||||
}
|
||||
|
||||
if ('messages' in response && Array.isArray(response.messages) && TYPE_MESSAGE.has(response.messages[0]?.className)) {
|
||||
threadInfos = response.messages.map((message) => {
|
||||
addMessageToLocalDb(message);
|
||||
return buildApiThreadInfoFromMessage(message);
|
||||
}).filter(Boolean);
|
||||
}
|
||||
|
||||
if (!userById && !chatById && !threadInfos) return;
|
||||
|
||||
sendImmediateApiUpdate({
|
||||
'@type': 'updateEntities',
|
||||
users: userById,
|
||||
chats: chatById,
|
||||
threadInfos,
|
||||
});
|
||||
}
|
||||
|
||||
export function processMessageAndUpdateThreadInfo(message: GramJs.TypeMessage) {
|
||||
addMessageToLocalDb(message);
|
||||
const threadInfo = buildApiThreadInfoFromMessage(message);
|
||||
if (!threadInfo) return;
|
||||
sendImmediateApiUpdate({
|
||||
'@type': 'updateThreadInfo',
|
||||
threadInfo,
|
||||
});
|
||||
}
|
||||
@ -3,11 +3,13 @@ import { Api as GramJs, connection } from '../../../lib/gramjs';
|
||||
import type { GroupCallConnectionData } from '../../../lib/secret-sauce';
|
||||
import type {
|
||||
ApiMessage, ApiStory, ApiStorySkipped,
|
||||
ApiUpdate, ApiUpdateConnectionStateType, OnApiUpdate,
|
||||
ApiUpdateConnectionStateType,
|
||||
} from '../../types';
|
||||
|
||||
import { DEBUG, GENERAL_TOPIC_ID } from '../../../config';
|
||||
import { compact, omit, pick } from '../../../util/iteratees';
|
||||
import {
|
||||
omit, pick,
|
||||
} from '../../../util/iteratees';
|
||||
import { getServerTimeOffset, setServerTimeOffset } from '../../../util/serverTime';
|
||||
import { buildApiBotMenuButton } from '../apiBuilders/bots';
|
||||
import {
|
||||
@ -40,7 +42,6 @@ import {
|
||||
buildApiMessageFromShort,
|
||||
buildApiMessageFromShortChat,
|
||||
buildApiQuickReply,
|
||||
buildApiThreadInfoFromMessage,
|
||||
buildMessageDraft,
|
||||
} from '../apiBuilders/messages';
|
||||
import {
|
||||
@ -64,8 +65,6 @@ import {
|
||||
buildMessageFromUpdate,
|
||||
} from '../gramjsBuilders';
|
||||
import {
|
||||
addEntitiesToLocalDb,
|
||||
addMessageToLocalDb,
|
||||
addPhotoToLocalDb,
|
||||
addStoryToLocalDb,
|
||||
isChatFolder,
|
||||
@ -75,6 +74,8 @@ import {
|
||||
} from '../helpers';
|
||||
import localDb from '../localDb';
|
||||
import { scheduleMutedChatUpdate, scheduleMutedTopicUpdate } from '../scheduleUnmute';
|
||||
import { sendApiUpdate } from './apiUpdateEmitter';
|
||||
import { processMessageAndUpdateThreadInfo } from './entityProcessor';
|
||||
|
||||
import LocalUpdatePremiumFloodWait from './UpdatePremiumFloodWait';
|
||||
import { LocalUpdateChannelPts, LocalUpdatePts, type UpdatePts } from './UpdatePts';
|
||||
@ -83,68 +84,13 @@ export type Update = (
|
||||
(GramJs.TypeUpdate | GramJs.TypeUpdates) & { _entities?: (GramJs.TypeUser | GramJs.TypeChat)[] }
|
||||
) | typeof connection.UpdateConnectionState | UpdatePts | LocalUpdatePremiumFloodWait;
|
||||
|
||||
let onUpdate: OnApiUpdate;
|
||||
|
||||
export function init(_onUpdate: OnApiUpdate) {
|
||||
onUpdate = _onUpdate;
|
||||
}
|
||||
|
||||
const sentMessageIds = new Set();
|
||||
|
||||
export function dispatchUserAndChatUpdates(entities: (GramJs.TypeUser | GramJs.TypeChat)[]) {
|
||||
entities
|
||||
.filter((e) => e instanceof GramJs.User)
|
||||
.map(buildApiUser)
|
||||
.forEach((user) => {
|
||||
if (!user) {
|
||||
return;
|
||||
}
|
||||
|
||||
onUpdate({
|
||||
'@type': 'updateUser',
|
||||
id: user.id,
|
||||
user,
|
||||
});
|
||||
});
|
||||
|
||||
entities
|
||||
.filter((e) => (
|
||||
e instanceof GramJs.Chat || e instanceof GramJs.ChatForbidden
|
||||
|| e instanceof GramJs.Channel || e instanceof GramJs.ChannelForbidden
|
||||
))
|
||||
.map((e) => buildApiChatFromPreview(e))
|
||||
.forEach((chat) => {
|
||||
if (!chat) {
|
||||
return;
|
||||
}
|
||||
|
||||
onUpdate({
|
||||
'@type': 'updateChat',
|
||||
id: chat.id,
|
||||
chat,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function dispatchThreadInfoUpdates(messages: (GramJs.TypeMessage | undefined)[]) {
|
||||
const threadInfoUpdates = compact(messages).map(buildApiThreadInfoFromMessage).filter(Boolean);
|
||||
if (!threadInfoUpdates.length) return;
|
||||
|
||||
onUpdate({
|
||||
'@type': 'updateThreadInfos',
|
||||
threadInfoUpdates,
|
||||
});
|
||||
}
|
||||
|
||||
export function sendUpdate(update: ApiUpdate) {
|
||||
onUpdate(update);
|
||||
}
|
||||
|
||||
export function updater(update: Update) {
|
||||
if (update instanceof connection.UpdateServerTimeOffset) {
|
||||
setServerTimeOffset(update.timeOffset);
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateServerTimeOffset',
|
||||
serverTimeOffset: update.timeOffset,
|
||||
});
|
||||
@ -164,7 +110,7 @@ export function updater(update: Update) {
|
||||
break;
|
||||
}
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateConnectionState',
|
||||
connectionState,
|
||||
});
|
||||
@ -180,13 +126,6 @@ export function updater(update: Update) {
|
||||
let message: ApiMessage | undefined;
|
||||
let shouldForceReply: boolean | undefined;
|
||||
|
||||
// eslint-disable-next-line no-underscore-dangle
|
||||
const entities = update._entities;
|
||||
if (entities) {
|
||||
addEntitiesToLocalDb(entities);
|
||||
dispatchUserAndChatUpdates(entities);
|
||||
}
|
||||
|
||||
if (update instanceof GramJs.UpdateShortChatMessage) {
|
||||
message = buildApiMessageFromShortChat(update);
|
||||
} else if (update instanceof GramJs.UpdateShortMessage) {
|
||||
@ -202,10 +141,9 @@ export function updater(update: Update) {
|
||||
return;
|
||||
}
|
||||
|
||||
addMessageToLocalDb(update.message);
|
||||
processMessageAndUpdateThreadInfo(update.message);
|
||||
|
||||
message = buildApiMessage(update.message)!;
|
||||
dispatchThreadInfoUpdates([update.message]);
|
||||
|
||||
shouldForceReply = 'replyMarkup' in update.message
|
||||
&& update.message?.replyMarkup instanceof GramJs.ReplyKeyboardForceReply
|
||||
@ -213,7 +151,7 @@ export function updater(update: Update) {
|
||||
}
|
||||
|
||||
if (update instanceof GramJs.UpdateNewScheduledMessage) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': sentMessageIds.has(message.id) ? 'updateScheduledMessage' : 'newScheduledMessage',
|
||||
id: message.id,
|
||||
chatId: message.chatId,
|
||||
@ -222,7 +160,7 @@ export function updater(update: Update) {
|
||||
} else {
|
||||
// We don't have preview for action or 'via bot' messages, so `newMessage` update here is required
|
||||
const hasLocalCopy = sentMessageIds.has(message.id) && !message.viaBotId && !message.content.action;
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': hasLocalCopy ? 'updateMessage' : 'newMessage',
|
||||
id: message.id,
|
||||
chatId: message.chatId,
|
||||
@ -237,7 +175,7 @@ export function updater(update: Update) {
|
||||
const { action } = update.message;
|
||||
|
||||
if (action instanceof GramJs.MessageActionChatEditTitle) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateChat',
|
||||
id: message.chatId,
|
||||
chat: {
|
||||
@ -256,7 +194,7 @@ export function updater(update: Update) {
|
||||
}
|
||||
addPhotoToLocalDb(action.photo);
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateNewProfilePhoto',
|
||||
peerId: message.chatId,
|
||||
photo: apiPhoto,
|
||||
@ -267,7 +205,7 @@ export function updater(update: Update) {
|
||||
localDb.chats[localDbChatId].photo = new GramJs.ChatPhotoEmpty();
|
||||
}
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateDeleteProfilePhoto',
|
||||
peerId: message.chatId,
|
||||
});
|
||||
@ -276,7 +214,7 @@ export function updater(update: Update) {
|
||||
if (update._entities && update._entities.some((e): e is GramJs.User => (
|
||||
e instanceof GramJs.User && Boolean(e.self) && e.id === action.userId
|
||||
))) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateChat',
|
||||
id: message.chatId,
|
||||
chat: {
|
||||
@ -290,14 +228,14 @@ export function updater(update: Update) {
|
||||
if (update._entities && update._entities.some((e): e is GramJs.User => (
|
||||
e instanceof GramJs.User && Boolean(e.self) && action.users.includes(e.id)
|
||||
))) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateChatJoin',
|
||||
id: message.chatId,
|
||||
});
|
||||
}
|
||||
} else if (action instanceof GramJs.MessageActionGroupCall) {
|
||||
if (!action.duration && action.call) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateGroupCallChatId',
|
||||
chatId: message.chatId,
|
||||
call: {
|
||||
@ -315,13 +253,13 @@ export function updater(update: Update) {
|
||||
} = replyTo || {};
|
||||
const topicId = !isTopicReply ? GENERAL_TOPIC_ID : replyToTopId || replyToMsgId || GENERAL_TOPIC_ID;
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateTopic',
|
||||
chatId: getApiChatIdFromMtpPeer(update.message.peerId!),
|
||||
topicId,
|
||||
});
|
||||
} else if (action instanceof GramJs.MessageActionTopicCreate) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateTopics',
|
||||
chatId: getApiChatIdFromMtpPeer(update.message.peerId!),
|
||||
});
|
||||
@ -331,31 +269,31 @@ export function updater(update: Update) {
|
||||
const message = buildApiMessage(update.message);
|
||||
if (!message) return;
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateQuickReplyMessage',
|
||||
id: message.id,
|
||||
message,
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdateDeleteQuickReplyMessages) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'deleteQuickReplyMessages',
|
||||
quickReplyId: update.shortcutId,
|
||||
messageIds: update.messages,
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdateQuickReplies) {
|
||||
const quickReplies = update.quickReplies.map(buildApiQuickReply);
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateQuickReplies',
|
||||
quickReplies,
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdateNewQuickReply) {
|
||||
const quickReply = buildApiQuickReply(update.quickReply);
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateQuickReplies',
|
||||
quickReplies: [quickReply],
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdateDeleteQuickReply) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'deleteQuickReply',
|
||||
quickReplyId: update.shortcutId,
|
||||
});
|
||||
@ -373,20 +311,19 @@ export function updater(update: Update) {
|
||||
return;
|
||||
}
|
||||
|
||||
addMessageToLocalDb(update.message);
|
||||
processMessageAndUpdateThreadInfo(update.message);
|
||||
|
||||
// Workaround for a weird server behavior when own message is marked as incoming
|
||||
const message = omit(buildApiMessage(update.message)!, ['isOutgoing']);
|
||||
dispatchThreadInfoUpdates([update.message]);
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateMessage',
|
||||
id: message.id,
|
||||
chatId: message.chatId,
|
||||
message,
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdateMessageReactions) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateMessageReactions',
|
||||
id: update.msgId,
|
||||
chatId: getApiChatIdFromMtpPeer(update.peer),
|
||||
@ -400,7 +337,7 @@ export function updater(update: Update) {
|
||||
|
||||
if (!boughtMedia?.length) return;
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateMessageExtendedMedia',
|
||||
id: update.msgId,
|
||||
chatId,
|
||||
@ -417,19 +354,19 @@ export function updater(update: Update) {
|
||||
|
||||
if (!previewMedia?.length) return;
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateMessageExtendedMedia',
|
||||
id: update.msgId,
|
||||
chatId,
|
||||
extendedMedia: previewMedia,
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdateDeleteMessages) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'deleteMessages',
|
||||
ids: update.messages,
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdateDeleteScheduledMessages) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'deleteScheduledMessages',
|
||||
ids: update.messages,
|
||||
chatId: getApiChatIdFromMtpPeer(update.peer),
|
||||
@ -437,14 +374,14 @@ export function updater(update: Update) {
|
||||
} else if (update instanceof GramJs.UpdateDeleteChannelMessages) {
|
||||
const chatId = buildApiPeerId(update.channelId, 'channel');
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'deleteMessages',
|
||||
ids: update.messages,
|
||||
chatId,
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdateServiceNotification) {
|
||||
if (update.popup) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'error',
|
||||
error: {
|
||||
message: update.message,
|
||||
@ -454,9 +391,9 @@ export function updater(update: Update) {
|
||||
const currentDate = Date.now() / 1000 + getServerTimeOffset();
|
||||
const message = buildApiMessageFromNotification(update, currentDate);
|
||||
|
||||
addMessageToLocalDb(buildMessageFromUpdate(message.id, message.chatId, update));
|
||||
processMessageAndUpdateThreadInfo(buildMessageFromUpdate(message.id, message.chatId, update));
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateServiceNotification',
|
||||
message,
|
||||
});
|
||||
@ -464,7 +401,7 @@ export function updater(update: Update) {
|
||||
} else if (update instanceof GramJs.UpdateMessageID || update instanceof GramJs.UpdateShortSentMessage) {
|
||||
sentMessageIds.add(update.id);
|
||||
} else if (update instanceof GramJs.UpdateReadMessagesContents) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateCommonBoxMessages',
|
||||
ids: update.messages,
|
||||
messageUpdate: {
|
||||
@ -473,7 +410,7 @@ export function updater(update: Update) {
|
||||
},
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdateChannelReadMessagesContents) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateChannelMessages',
|
||||
channelId: buildApiPeerId(update.channelId, 'channel'),
|
||||
ids: update.messages,
|
||||
@ -487,28 +424,28 @@ export function updater(update: Update) {
|
||||
if (poll) {
|
||||
const apiPoll = buildPoll(poll, results);
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateMessagePoll',
|
||||
pollId: String(pollId),
|
||||
pollUpdate: apiPoll,
|
||||
});
|
||||
} else {
|
||||
const pollResults = buildPollResults(results);
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateMessagePoll',
|
||||
pollId: String(pollId),
|
||||
pollUpdate: { results: pollResults },
|
||||
});
|
||||
}
|
||||
} else if (update instanceof GramJs.UpdateMessagePollVote) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateMessagePollVote',
|
||||
pollId: String(update.pollId),
|
||||
peerId: getApiChatIdFromMtpPeer(update.peer),
|
||||
options: update.options.map(serializeBytes),
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdateChannelMessageViews) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateMessage',
|
||||
chatId: buildApiPeerId(update.channelId, 'channel'),
|
||||
id: update.id,
|
||||
@ -517,7 +454,7 @@ export function updater(update: Update) {
|
||||
|
||||
// Chats
|
||||
} else if (update instanceof GramJs.UpdateReadHistoryInbox) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateChatInbox',
|
||||
id: getApiChatIdFromMtpPeer(update.peer),
|
||||
chat: {
|
||||
@ -526,7 +463,7 @@ export function updater(update: Update) {
|
||||
},
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdateReadHistoryOutbox) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateChat',
|
||||
id: getApiChatIdFromMtpPeer(update.peer),
|
||||
chat: {
|
||||
@ -534,7 +471,7 @@ export function updater(update: Update) {
|
||||
},
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdateReadChannelInbox) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateChat',
|
||||
id: buildApiPeerId(update.channelId, 'channel'),
|
||||
chat: {
|
||||
@ -543,7 +480,7 @@ export function updater(update: Update) {
|
||||
},
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdateReadChannelOutbox) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateChat',
|
||||
id: buildApiPeerId(update.channelId, 'channel'),
|
||||
chat: {
|
||||
@ -551,16 +488,16 @@ export function updater(update: Update) {
|
||||
},
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdateReadChannelDiscussionInbox) {
|
||||
onUpdate({
|
||||
'@type': 'updateThreadInfos',
|
||||
threadInfoUpdates: [{
|
||||
sendApiUpdate({
|
||||
'@type': 'updateThreadInfo',
|
||||
threadInfo: {
|
||||
chatId: buildApiPeerId(update.channelId, 'channel'),
|
||||
threadId: update.topMsgId,
|
||||
lastReadInboxMessageId: update.readMaxId,
|
||||
}],
|
||||
},
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdateReadChannelDiscussionOutbox) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateChat',
|
||||
id: buildApiPeerId(update.channelId, 'channel'),
|
||||
chat: {
|
||||
@ -571,7 +508,7 @@ export function updater(update: Update) {
|
||||
update instanceof GramJs.UpdateDialogPinned
|
||||
&& update.peer instanceof GramJs.DialogPeer
|
||||
) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateChatPinned',
|
||||
id: getApiChatIdFromMtpPeer(update.peer.peer),
|
||||
isPinned: update.pinned || false,
|
||||
@ -583,7 +520,7 @@ export function updater(update: Update) {
|
||||
.map((dp) => getApiChatIdFromMtpPeer(dp.peer))
|
||||
: [];
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updatePinnedChatIds',
|
||||
ids,
|
||||
folderId: update.folderId || undefined,
|
||||
@ -592,7 +529,7 @@ export function updater(update: Update) {
|
||||
update instanceof GramJs.UpdateSavedDialogPinned
|
||||
&& update.peer instanceof GramJs.DialogPeer
|
||||
) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateSavedDialogPinned',
|
||||
id: getApiChatIdFromMtpPeer(update.peer.peer),
|
||||
isPinned: update.pinned || false,
|
||||
@ -604,7 +541,7 @@ export function updater(update: Update) {
|
||||
.map((dp) => getApiChatIdFromMtpPeer(dp.peer))
|
||||
: [];
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updatePinnedSavedDialogIds',
|
||||
ids,
|
||||
});
|
||||
@ -612,7 +549,7 @@ export function updater(update: Update) {
|
||||
update.folderPeers.forEach((folderPeer) => {
|
||||
const { folderId, peer } = folderPeer;
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateChatListType',
|
||||
id: getApiChatIdFromMtpPeer(peer),
|
||||
folderId,
|
||||
@ -622,20 +559,20 @@ export function updater(update: Update) {
|
||||
const { id, filter } = update;
|
||||
const folder = isChatFolder(filter) ? buildApiChatFolder(filter) : undefined;
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateChatFolder',
|
||||
id,
|
||||
folder,
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdateDialogFilterOrder) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateChatFoldersOrder',
|
||||
orderedIds: update.order,
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdateChatParticipants) {
|
||||
const replacedMembers = buildChatMembers(update.participants);
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateChatMembers',
|
||||
id: buildApiPeerId(update.participants.chatId, 'chat'),
|
||||
replacedMembers,
|
||||
@ -645,13 +582,13 @@ export function updater(update: Update) {
|
||||
pick(update, ['userId', 'inviterId', 'date']) as GramJs.ChatParticipant,
|
||||
);
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateChatMembers',
|
||||
id: buildApiPeerId(update.chatId, 'chat'),
|
||||
addedMember,
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdateChatParticipantDelete) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateChatMembers',
|
||||
id: buildApiPeerId(update.chatId, 'chat'),
|
||||
deletedMemberId: buildApiPeerId(update.userId, 'user'),
|
||||
@ -664,7 +601,7 @@ export function updater(update: Update) {
|
||||
? getApiChatIdFromMtpPeer(update.peer)
|
||||
: buildApiPeerId(update.channelId, 'channel');
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updatePinnedIds',
|
||||
chatId,
|
||||
messageIds: update.messages,
|
||||
@ -675,8 +612,8 @@ export function updater(update: Update) {
|
||||
&& update.peer instanceof GramJs.NotifyPeer
|
||||
) {
|
||||
const payload = buildApiNotifyException(update.notifySettings, update.peer.peer);
|
||||
scheduleMutedChatUpdate(payload.chatId, payload.muteUntil, onUpdate);
|
||||
onUpdate({
|
||||
scheduleMutedChatUpdate(payload.chatId, payload.muteUntil, sendApiUpdate);
|
||||
sendApiUpdate({
|
||||
'@type': 'updateNotifyExceptions',
|
||||
...payload,
|
||||
});
|
||||
@ -687,8 +624,8 @@ export function updater(update: Update) {
|
||||
const payload = buildApiNotifyExceptionTopic(
|
||||
update.notifySettings, update.peer.peer, update.peer.topMsgId,
|
||||
);
|
||||
scheduleMutedTopicUpdate(payload.chatId, payload.topicId, payload.muteUntil, onUpdate);
|
||||
onUpdate({
|
||||
scheduleMutedTopicUpdate(payload.chatId, payload.topicId, payload.muteUntil, sendApiUpdate);
|
||||
sendApiUpdate({
|
||||
'@type': 'updateTopicNotifyExceptions',
|
||||
...payload,
|
||||
});
|
||||
@ -701,7 +638,7 @@ export function updater(update: Update) {
|
||||
: buildApiPeerId(update.chatId, 'chat');
|
||||
|
||||
if (update.action instanceof GramJs.SendMessageEmojiInteraction) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateStartEmojiInteraction',
|
||||
id,
|
||||
emoji: update.action.emoticon,
|
||||
@ -709,7 +646,7 @@ export function updater(update: Update) {
|
||||
interaction: buildApiEmojiInteraction(JSON.parse(update.action.interaction.data)),
|
||||
});
|
||||
} else {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateChatTypingStatus',
|
||||
id,
|
||||
typingStatus: buildChatTypingStatus(update),
|
||||
@ -718,7 +655,7 @@ export function updater(update: Update) {
|
||||
} else if (update instanceof GramJs.UpdateChannelUserTyping) {
|
||||
const id = buildApiPeerId(update.channelId, 'channel');
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateChatTypingStatus',
|
||||
id,
|
||||
threadId: update.topMsgId,
|
||||
@ -738,13 +675,13 @@ export function updater(update: Update) {
|
||||
if (channel instanceof GramJs.Channel) {
|
||||
const chat = buildApiChatFromPreview(channel);
|
||||
if (chat) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateChat',
|
||||
id: chat.id,
|
||||
chat,
|
||||
});
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': chat.isNotJoined ? 'updateChatLeave' : 'updateChatJoin',
|
||||
id: buildApiPeerId(update.channelId, 'channel'),
|
||||
});
|
||||
@ -752,7 +689,7 @@ export function updater(update: Update) {
|
||||
} else if (channel instanceof GramJs.ChannelForbidden) {
|
||||
const chatId = buildApiPeerId(update.channelId, 'channel');
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateChat',
|
||||
id: chatId,
|
||||
chat: {
|
||||
@ -760,14 +697,14 @@ export function updater(update: Update) {
|
||||
},
|
||||
});
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateChatLeave',
|
||||
id: chatId,
|
||||
});
|
||||
} else if (_entities.length === 0) {
|
||||
// The link to the discussion group may have been changed.
|
||||
// No corresponding update available at this moment https://core.telegram.org/type/Updates
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'resetMessages',
|
||||
id: buildApiPeerId(update.channelId, 'channel'),
|
||||
});
|
||||
@ -776,7 +713,7 @@ export function updater(update: Update) {
|
||||
update instanceof GramJs.UpdateDialogUnreadMark
|
||||
&& update.peer instanceof GramJs.DialogPeer
|
||||
) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateChat',
|
||||
id: getApiChatIdFromMtpPeer(update.peer.peer),
|
||||
chat: {
|
||||
@ -784,7 +721,7 @@ export function updater(update: Update) {
|
||||
},
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdateChatDefaultBannedRights) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateChat',
|
||||
id: getApiChatIdFromMtpPeer(update.peer),
|
||||
chat: {
|
||||
@ -794,19 +731,19 @@ export function updater(update: Update) {
|
||||
|
||||
// Users
|
||||
} else if (update instanceof GramJs.UpdateUserStatus) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateUserStatus',
|
||||
userId: buildApiPeerId(update.userId, 'user'),
|
||||
status: buildApiUserStatus(update.status),
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdateUser) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateRequestUserUpdate',
|
||||
id: buildApiPeerId(update.userId, 'user'),
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdateUserEmojiStatus) {
|
||||
const emojiStatus = buildApiEmojiStatus(update.emojiStatus);
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateUserEmojiStatus',
|
||||
userId: buildApiPeerId(update.userId, 'user'),
|
||||
emojiStatus,
|
||||
@ -821,7 +758,7 @@ export function updater(update: Update) {
|
||||
|
||||
const usernames = buildApiUsernames(update);
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateUser',
|
||||
id: apiUserId,
|
||||
user: {
|
||||
@ -832,7 +769,7 @@ export function updater(update: Update) {
|
||||
} else if (update instanceof GramJs.UpdateUserPhone) {
|
||||
const { userId, phone } = update;
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateUser',
|
||||
id: buildApiPeerId(userId, 'user'),
|
||||
user: { phoneNumber: phone },
|
||||
@ -848,7 +785,7 @@ export function updater(update: Update) {
|
||||
_entities
|
||||
.filter((e) => e instanceof GramJs.User && !e.contact)
|
||||
.forEach((user) => {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'deleteContact',
|
||||
id: buildApiPeerId(user.id, 'user'),
|
||||
});
|
||||
@ -862,7 +799,7 @@ export function updater(update: Update) {
|
||||
return;
|
||||
}
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateUser',
|
||||
id: user.id,
|
||||
user: {
|
||||
@ -896,7 +833,7 @@ export function updater(update: Update) {
|
||||
return;
|
||||
}
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateNotifySettings',
|
||||
peerType,
|
||||
isSilent: Boolean(silent
|
||||
@ -904,7 +841,7 @@ export function updater(update: Update) {
|
||||
shouldShowPreviews: Boolean(showPreviews),
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdatePeerBlocked) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updatePeerBlocked',
|
||||
id: getApiChatIdFromMtpPeer(update.peerId),
|
||||
isBlocked: update.blocked,
|
||||
@ -913,7 +850,7 @@ export function updater(update: Update) {
|
||||
} else if (update instanceof GramJs.UpdatePrivacy) {
|
||||
const key = buildPrivacyKey(update.key);
|
||||
if (key) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updatePrivacy',
|
||||
key,
|
||||
rules: buildPrivacyRules(update.rules),
|
||||
@ -922,35 +859,35 @@ export function updater(update: Update) {
|
||||
|
||||
// Misc
|
||||
} else if (update instanceof GramJs.UpdateDraftMessage) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'draftMessage',
|
||||
chatId: getApiChatIdFromMtpPeer(update.peer),
|
||||
threadId: update.topMsgId,
|
||||
draft: buildMessageDraft(update.draft),
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdateContactsReset) {
|
||||
onUpdate({ '@type': 'updateResetContactList' });
|
||||
sendApiUpdate({ '@type': 'updateResetContactList' });
|
||||
} else if (update instanceof GramJs.UpdateFavedStickers) {
|
||||
onUpdate({ '@type': 'updateFavoriteStickers' });
|
||||
sendApiUpdate({ '@type': 'updateFavoriteStickers' });
|
||||
} else if (update instanceof GramJs.UpdateRecentStickers) {
|
||||
onUpdate({ '@type': 'updateRecentStickers' });
|
||||
sendApiUpdate({ '@type': 'updateRecentStickers' });
|
||||
} else if (update instanceof GramJs.UpdateRecentReactions) {
|
||||
onUpdate({ '@type': 'updateRecentReactions' });
|
||||
sendApiUpdate({ '@type': 'updateRecentReactions' });
|
||||
} else if (update instanceof GramJs.UpdateSavedReactionTags) {
|
||||
onUpdate({ '@type': 'updateSavedReactionTags' });
|
||||
sendApiUpdate({ '@type': 'updateSavedReactionTags' });
|
||||
} else if (update instanceof GramJs.UpdateMoveStickerSetToTop) {
|
||||
if (!update.masks) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateMoveStickerSetToTop',
|
||||
isCustomEmoji: update.emojis,
|
||||
id: update.stickerset.toString(),
|
||||
});
|
||||
}
|
||||
} else if (update instanceof GramJs.UpdateStickerSets) {
|
||||
onUpdate({ '@type': 'updateStickerSets' });
|
||||
sendApiUpdate({ '@type': 'updateStickerSets' });
|
||||
} else if (update instanceof GramJs.UpdateStickerSetsOrder) {
|
||||
if (!update.masks) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateStickerSetsOrder',
|
||||
order: update.order.map((n) => n.toString()),
|
||||
isCustomEmoji: update.emojis,
|
||||
@ -959,73 +896,45 @@ export function updater(update: Update) {
|
||||
} else if (update instanceof GramJs.UpdateNewStickerSet) {
|
||||
if (update.stickerset instanceof GramJs.messages.StickerSet) {
|
||||
const stickerSet = buildStickerSet(update.stickerset.set);
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateStickerSet',
|
||||
id: stickerSet.id,
|
||||
stickerSet,
|
||||
});
|
||||
}
|
||||
} else if (update instanceof GramJs.UpdateSavedGifs) {
|
||||
onUpdate({ '@type': 'updateSavedGifs' });
|
||||
sendApiUpdate({ '@type': 'updateSavedGifs' });
|
||||
} else if (update instanceof GramJs.UpdateGroupCall) {
|
||||
// eslint-disable-next-line no-underscore-dangle
|
||||
const entities = update._entities;
|
||||
if (entities) {
|
||||
addEntitiesToLocalDb(entities);
|
||||
dispatchUserAndChatUpdates(entities);
|
||||
}
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateGroupCall',
|
||||
call: buildApiGroupCall(update.call),
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdateGroupCallConnection) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateGroupCallConnection',
|
||||
data: JSON.parse(update.params.data) as GroupCallConnectionData,
|
||||
presentation: Boolean(update.presentation),
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdateGroupCallParticipants) {
|
||||
// eslint-disable-next-line no-underscore-dangle
|
||||
const entities = update._entities;
|
||||
if (entities) {
|
||||
addEntitiesToLocalDb(entities);
|
||||
dispatchUserAndChatUpdates(entities);
|
||||
}
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateGroupCallParticipants',
|
||||
groupCallId: getGroupCallId(update.call),
|
||||
participants: update.participants.map(buildApiGroupCallParticipant),
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdatePendingJoinRequests) {
|
||||
// eslint-disable-next-line no-underscore-dangle
|
||||
const entities = update._entities;
|
||||
if (entities) {
|
||||
addEntitiesToLocalDb(entities);
|
||||
dispatchUserAndChatUpdates(entities);
|
||||
}
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updatePendingJoinRequests',
|
||||
chatId: getApiChatIdFromMtpPeer(update.peer),
|
||||
recentRequesterIds: update.recentRequesters.map((id) => buildApiPeerId(id, 'user')),
|
||||
requestsPending: update.requestsPending,
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdatePhoneCall) {
|
||||
// eslint-disable-next-line no-underscore-dangle
|
||||
const entities = update._entities;
|
||||
if (entities) {
|
||||
addEntitiesToLocalDb(entities);
|
||||
dispatchUserAndChatUpdates(entities);
|
||||
}
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updatePhoneCall',
|
||||
call: buildPhoneCall(update.phoneCall),
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdatePhoneCallSignalingData) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updatePhoneCallSignalingData',
|
||||
callId: update.phoneCallId.toString(),
|
||||
data: Array.from(update.data),
|
||||
@ -1033,7 +942,7 @@ export function updater(update: Update) {
|
||||
} else if (update instanceof GramJs.UpdateWebViewResultSent) {
|
||||
const { queryId } = update;
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateWebViewResultSent',
|
||||
queryId: queryId.toString(),
|
||||
});
|
||||
@ -1045,98 +954,78 @@ export function updater(update: Update) {
|
||||
|
||||
const id = buildApiPeerId(botId, 'user');
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateBotMenuButton',
|
||||
botId: id,
|
||||
button: buildApiBotMenuButton(button),
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdateTranscribedAudio) {
|
||||
// eslint-disable-next-line no-underscore-dangle
|
||||
const entities = update._entities;
|
||||
if (entities) {
|
||||
addEntitiesToLocalDb(entities);
|
||||
dispatchUserAndChatUpdates(entities);
|
||||
}
|
||||
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateTranscribedAudio',
|
||||
transcriptionId: update.transcriptionId.toString(),
|
||||
text: update.text,
|
||||
isPending: update.pending,
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdateConfig) {
|
||||
// eslint-disable-next-line no-underscore-dangle
|
||||
const entities = update._entities;
|
||||
if (entities) {
|
||||
addEntitiesToLocalDb(entities);
|
||||
dispatchUserAndChatUpdates(entities);
|
||||
}
|
||||
onUpdate({ '@type': 'updateConfig' });
|
||||
sendApiUpdate({ '@type': 'updateConfig' });
|
||||
} else if (update instanceof GramJs.UpdateChannelPinnedTopic) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updatePinnedTopic',
|
||||
chatId: buildApiPeerId(update.channelId, 'channel'),
|
||||
topicId: update.topicId,
|
||||
isPinned: Boolean(update.pinned),
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdateChannelPinnedTopics) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updatePinnedTopicsOrder',
|
||||
chatId: buildApiPeerId(update.channelId, 'channel'),
|
||||
order: update.order || [],
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdateRecentEmojiStatuses) {
|
||||
onUpdate({ '@type': 'updateRecentEmojiStatuses' });
|
||||
sendApiUpdate({ '@type': 'updateRecentEmojiStatuses' });
|
||||
} else if (update instanceof GramJs.UpdateStory) {
|
||||
// eslint-disable-next-line no-underscore-dangle
|
||||
const entities = update._entities;
|
||||
if (entities) {
|
||||
addEntitiesToLocalDb(entities);
|
||||
dispatchUserAndChatUpdates(entities);
|
||||
}
|
||||
|
||||
const { story } = update;
|
||||
const peerId = getApiChatIdFromMtpPeer(update.peer);
|
||||
const apiStory = buildApiStory(peerId, story) as ApiStory | ApiStorySkipped;
|
||||
addStoryToLocalDb(story, peerId); // Add after building to prevent repair info overwrite
|
||||
|
||||
if (story instanceof GramJs.StoryItemDeleted) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'deleteStory',
|
||||
peerId,
|
||||
storyId: story.id,
|
||||
});
|
||||
} else {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateStory',
|
||||
peerId,
|
||||
story: apiStory,
|
||||
});
|
||||
}
|
||||
} else if (update instanceof GramJs.UpdateReadStories) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateReadStories',
|
||||
peerId: getApiChatIdFromMtpPeer(update.peer),
|
||||
lastReadId: update.maxId,
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdateSentStoryReaction) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateSentStoryReaction',
|
||||
peerId: getApiChatIdFromMtpPeer(update.peer),
|
||||
storyId: update.storyId,
|
||||
reaction: buildApiReaction(update.reaction),
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdateStoriesStealthMode) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateStealthMode',
|
||||
stealthMode: buildApiStealthMode(update.stealthMode),
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdateAttachMenuBots) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateAttachMenuBots',
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdateNewAuthorization) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateNewAuthorization',
|
||||
hash: update.hash.toString(),
|
||||
date: update.date,
|
||||
@ -1145,18 +1034,18 @@ export function updater(update: Update) {
|
||||
isUnconfirmed: update.unconfirmed,
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdateChannelViewForumAsMessages) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateViewForumAsMessages',
|
||||
chatId: buildApiPeerId(update.channelId, 'channel'),
|
||||
isEnabled: update.enabled ? true : undefined,
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdateStarsBalance) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateStarsBalance',
|
||||
balance: update.balance.toJSNumber(),
|
||||
});
|
||||
} else if (update instanceof LocalUpdatePremiumFloodWait) {
|
||||
onUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updatePremiumFloodWait',
|
||||
isUpload: update.isUpload,
|
||||
});
|
||||
@ -3,15 +3,15 @@ import { UpdateConnectionState, UpdateServerTimeOffset } from '../../../lib/gram
|
||||
|
||||
import type { ApiChat } from '../../types';
|
||||
import type { invokeRequest } from '../methods/client';
|
||||
import type { Update } from './updater';
|
||||
|
||||
import { DEBUG } from '../../../config';
|
||||
import SortedQueue from '../../../util/SortedQueue';
|
||||
import { buildApiPeerId } from '../apiBuilders/peers';
|
||||
import { buildInputEntity, buildMtpPeerId } from '../gramjsBuilders';
|
||||
import { addEntitiesToLocalDb } from '../helpers';
|
||||
import localDb from '../localDb';
|
||||
import { dispatchUserAndChatUpdates, sendUpdate, updater } from './updater';
|
||||
import { sendApiUpdate } from './apiUpdateEmitter';
|
||||
import { processAndUpdateEntities } from './entityProcessor';
|
||||
import { type Update, updater } from './mtpUpdateHandler';
|
||||
|
||||
import { buildLocalUpdatePts, type UpdatePts } from './UpdatePts';
|
||||
|
||||
@ -139,6 +139,7 @@ function applyUpdate(updateObject: SeqUpdate | PtsUpdate) {
|
||||
}
|
||||
|
||||
if (updateObject instanceof GramJs.UpdatesCombined || updateObject instanceof GramJs.Updates) {
|
||||
processAndUpdateEntities(updateObject);
|
||||
const entities = updateObject.users.concat(updateObject.chats);
|
||||
|
||||
updateObject.updates.forEach((update) => {
|
||||
@ -277,7 +278,7 @@ export async function getDifference() {
|
||||
return;
|
||||
}
|
||||
|
||||
sendUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateFetchingDifference',
|
||||
isFetching: true,
|
||||
});
|
||||
@ -296,7 +297,7 @@ export async function getDifference() {
|
||||
if (response instanceof GramJs.updates.DifferenceEmpty) {
|
||||
localDb.commonBoxState.seq = response.seq;
|
||||
localDb.commonBoxState.date = response.date;
|
||||
sendUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateFetchingDifference',
|
||||
isFetching: false,
|
||||
});
|
||||
@ -313,7 +314,7 @@ export async function getDifference() {
|
||||
return;
|
||||
}
|
||||
|
||||
sendUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'updateFetchingDifference',
|
||||
isFetching: false,
|
||||
});
|
||||
@ -366,7 +367,7 @@ async function getChannelDifference(channelId: string) {
|
||||
function forceSync() {
|
||||
reset();
|
||||
|
||||
sendUpdate({
|
||||
sendApiUpdate({
|
||||
'@type': 'requestSync',
|
||||
});
|
||||
|
||||
@ -425,11 +426,7 @@ function processDifference(
|
||||
}));
|
||||
});
|
||||
|
||||
addEntitiesToLocalDb(difference.users);
|
||||
addEntitiesToLocalDb(difference.chats);
|
||||
|
||||
dispatchUserAndChatUpdates(difference.users);
|
||||
dispatchUserAndChatUpdates(difference.chats);
|
||||
processAndUpdateEntities(difference);
|
||||
|
||||
// Ignore `pts`/`seq` holes when applying updates from difference
|
||||
// BUT, if we got an `UpdateChannelTooLong`, make sure to process other updates after receiving `ChannelDifference`
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
import type { DebugLevel } from '../../../util/debugConsole';
|
||||
import type { ApiInitialArgs, ApiUpdate } from '../../types';
|
||||
import type {
|
||||
ApiInitialArgs, ApiUpdate,
|
||||
} from '../../types';
|
||||
import type { LocalDb } from '../localDb';
|
||||
import type { MethodArgs, MethodResponse, Methods } from '../methods/types';
|
||||
|
||||
|
||||
@ -41,6 +41,7 @@ handleErrors();
|
||||
|
||||
let pendingPayloads: WorkerPayload[] = [];
|
||||
let pendingTransferables: Transferable[] = [];
|
||||
let pendingUpdates: ApiUpdate[] = [];
|
||||
|
||||
const callbackState = new Map<string, ApiOnProgress>();
|
||||
|
||||
@ -158,31 +159,18 @@ function handleErrors() {
|
||||
});
|
||||
}
|
||||
|
||||
let pendingUpdates: ApiUpdate[] = [];
|
||||
|
||||
const sendUpdatesOnTickEnd = throttleWithTickEnd(() => {
|
||||
const currentUpdates = pendingUpdates;
|
||||
pendingUpdates = [];
|
||||
|
||||
sendToOrigin({
|
||||
type: 'updates',
|
||||
updates: currentUpdates,
|
||||
});
|
||||
});
|
||||
|
||||
function onUpdate(update: ApiUpdate) {
|
||||
if (DEBUG && update['@type'] !== 'updateUserStatus' && update['@type'] !== 'updateServerTimeOffset') {
|
||||
log('UPDATE', update['@type'], update);
|
||||
const sendToOriginOnTickEnd = throttleWithTickEnd(() => {
|
||||
if (pendingUpdates.length) {
|
||||
pendingPayloads.unshift({
|
||||
type: 'updates',
|
||||
updates: pendingUpdates,
|
||||
});
|
||||
}
|
||||
|
||||
pendingUpdates.push(update);
|
||||
sendUpdatesOnTickEnd();
|
||||
}
|
||||
|
||||
const sendToOriginOnTickEnd = throttleWithTickEnd(() => {
|
||||
const data = { payloads: pendingPayloads };
|
||||
const transferables = pendingTransferables;
|
||||
|
||||
pendingUpdates = [];
|
||||
pendingPayloads = [];
|
||||
pendingTransferables = [];
|
||||
|
||||
@ -202,3 +190,12 @@ function sendToOrigin(payload: WorkerPayload, transferable?: Transferable) {
|
||||
|
||||
sendToOriginOnTickEnd();
|
||||
}
|
||||
|
||||
function onUpdate(update: ApiUpdate) {
|
||||
if (DEBUG && update['@type'] !== 'updateUserStatus' && update['@type'] !== 'updateServerTimeOffset') {
|
||||
log('UPDATE', update['@type'], update);
|
||||
}
|
||||
|
||||
pendingUpdates.push(update);
|
||||
sendToOriginOnTickEnd();
|
||||
}
|
||||
|
||||
@ -745,7 +745,7 @@ interface ApiBaseThreadInfo {
|
||||
|
||||
export interface ApiCommentsInfo extends ApiBaseThreadInfo {
|
||||
isCommentsInfo: true;
|
||||
threadId?: ThreadId;
|
||||
threadId?: never;
|
||||
originChannelId: string;
|
||||
originMessageId: number;
|
||||
}
|
||||
|
||||
@ -264,9 +264,9 @@ export type ApiUpdatePinnedMessageIds = {
|
||||
messageIds: number[];
|
||||
};
|
||||
|
||||
export type ApiUpdateThreadInfos = {
|
||||
'@type': 'updateThreadInfos';
|
||||
threadInfoUpdates: Partial<ApiThreadInfo>[];
|
||||
export type ApiUpdateThreadInfo = {
|
||||
'@type': 'updateThreadInfo';
|
||||
threadInfo: Partial<ApiThreadInfo>;
|
||||
};
|
||||
|
||||
export type ApiUpdateScheduledMessageSendSucceeded = {
|
||||
@ -753,13 +753,20 @@ export type ApiUpdateNewProfilePhoto = {
|
||||
photo: ApiPhoto;
|
||||
};
|
||||
|
||||
export type ApiUpdateEntities = {
|
||||
'@type': 'updateEntities';
|
||||
users?: Record<string, ApiUser>;
|
||||
chats?: Record<string, ApiChat>;
|
||||
threadInfos?: ApiThreadInfo[];
|
||||
};
|
||||
|
||||
export type ApiUpdate = (
|
||||
ApiUpdateReady | ApiUpdateSession | ApiUpdateWebAuthTokenFailed | ApiUpdateRequestUserUpdate |
|
||||
ApiUpdateAuthorizationState | ApiUpdateAuthorizationError | ApiUpdateConnectionState | ApiUpdateCurrentUser |
|
||||
ApiUpdateChat | ApiUpdateChatInbox | ApiUpdateChatTypingStatus | ApiUpdateChatFullInfo | ApiUpdatePinnedChatIds |
|
||||
ApiUpdateChatMembers | ApiUpdateChatJoin | ApiUpdateChatLeave | ApiUpdateChatPinned | ApiUpdatePinnedMessageIds |
|
||||
ApiUpdateChatListType | ApiUpdateChatFolder | ApiUpdateChatFoldersOrder | ApiUpdateRecommendedChatFolders |
|
||||
ApiUpdateNewMessage | ApiUpdateMessage | ApiUpdateThreadInfos | ApiUpdateCommonBoxMessages |
|
||||
ApiUpdateNewMessage | ApiUpdateMessage | ApiUpdateThreadInfo | ApiUpdateCommonBoxMessages |
|
||||
ApiUpdateDeleteMessages | ApiUpdateMessagePoll | ApiUpdateMessagePollVote | ApiUpdateDeleteHistory |
|
||||
ApiUpdateMessageSendSucceeded | ApiUpdateMessageSendFailed | ApiUpdateServiceNotification |
|
||||
ApiDeleteContact | ApiUpdateUser | ApiUpdateUserStatus | ApiUpdateUserFullInfo |
|
||||
@ -785,7 +792,7 @@ export type ApiUpdate = (
|
||||
ApiUpdateViewForumAsMessages | ApiUpdateSavedDialogPinned | ApiUpdatePinnedSavedDialogIds | ApiUpdateChatLastMessage |
|
||||
ApiUpdateDeleteSavedHistory | ApiUpdatePremiumFloodWait | ApiUpdateStarsBalance |
|
||||
ApiUpdateQuickReplyMessage | ApiUpdateQuickReplies | ApiDeleteQuickReply | ApiUpdateDeleteQuickReplyMessages |
|
||||
ApiUpdateDeleteProfilePhoto | ApiUpdateNewProfilePhoto
|
||||
ApiUpdateDeleteProfilePhoto | ApiUpdateNewProfilePhoto | ApiUpdateEntities
|
||||
);
|
||||
|
||||
export type OnApiUpdate = (update: ApiUpdate) => void;
|
||||
|
||||
@ -450,7 +450,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
const isForum = chat?.isForum;
|
||||
const isMuted = chat && selectIsChatMuted(chat, selectNotifySettings(global), selectNotifyExceptions(global));
|
||||
const { threadId } = selectCurrentMessageList(global) || {};
|
||||
const topicId = isForum ? Number(threadId) : undefined;
|
||||
const topicId = isForum && threadId ? Number(threadId) : undefined;
|
||||
|
||||
const chatFullInfo = chat && selectChatFullInfo(global, chat.id);
|
||||
const userFullInfo = user && selectUserFullInfo(global, user.id);
|
||||
|
||||
@ -178,7 +178,6 @@ export const FAST_SMOOTH_SHORT_TRANSITION_MAX_DISTANCE = 300; // px
|
||||
export const API_UPDATE_THROTTLE = Math.round((FAST_SMOOTH_MIN_DURATION + FAST_SMOOTH_MAX_DURATION) / 2);
|
||||
export const API_THROTTLE_RESET_UPDATES = new Set([
|
||||
'newMessage', 'newScheduledMessage', 'deleteMessages', 'deleteScheduledMessages', 'deleteHistory',
|
||||
'updateThreadInfos',
|
||||
]);
|
||||
|
||||
export const LOCK_SCREEN_ANIMATION_DURATION_MS = 200;
|
||||
@ -287,6 +286,7 @@ export const TME_LINK_PREFIX = 'https://t.me/';
|
||||
export const BOT_FATHER_USERNAME = 'botfather';
|
||||
export const USERNAME_PURCHASE_ERROR = 'USERNAME_PURCHASE_AVAILABLE';
|
||||
export const PURCHASE_USERNAME = 'auction';
|
||||
export const ACCEPTABLE_USERNAME_ERRORS = new Set([USERNAME_PURCHASE_ERROR, 'USERNAME_INVALID']);
|
||||
export const TME_WEB_DOMAINS = new Set(['t.me', 'web.t.me', 'a.t.me', 'k.t.me', 'z.t.me']);
|
||||
export const WEB_APP_PLATFORM = 'weba';
|
||||
|
||||
|
||||
@ -1,9 +1,7 @@
|
||||
import { getCurrentTabId } from '../../../util/establishMultitabRole';
|
||||
import { buildCollectionByKey } from '../../../util/iteratees';
|
||||
import { oldTranslate } from '../../../util/oldLangProvider';
|
||||
import { callApi } from '../../../api/gramjs';
|
||||
import { addActionHandler, getGlobal, setGlobal } from '../../index';
|
||||
import { addUsers } from '../../reducers';
|
||||
import { selectChat } from '../../selectors';
|
||||
|
||||
addActionHandler('reportPeer', async (global, actions, payload): Promise<void> => {
|
||||
@ -193,11 +191,9 @@ addActionHandler('loadWebAuthorizations', async (global): Promise<void> => {
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
const { users, webAuthorizations } = result;
|
||||
const { webAuthorizations } = result;
|
||||
global = getGlobal();
|
||||
|
||||
global = addUsers(global, buildCollectionByKey(users, 'id'));
|
||||
|
||||
global = {
|
||||
...global,
|
||||
activeWebSessions: {
|
||||
|
||||
@ -9,7 +9,6 @@ import { ManagementProgress } from '../../../types';
|
||||
|
||||
import { BOT_FATHER_USERNAME, GENERAL_REFETCH_INTERVAL } from '../../../config';
|
||||
import { getCurrentTabId } from '../../../util/establishMultitabRole';
|
||||
import { buildCollectionByKey } from '../../../util/iteratees';
|
||||
import { oldTranslate } from '../../../util/oldLangProvider';
|
||||
import PopupManager from '../../../util/PopupManager';
|
||||
import requestActionTimeout from '../../../util/requestActionTimeout';
|
||||
@ -21,7 +20,7 @@ import {
|
||||
addActionHandler, getGlobal, setGlobal,
|
||||
} from '../../index';
|
||||
import {
|
||||
addChats, addUsers, removeBlockedUser, updateManagementProgress, updateUser, updateUserFullInfo,
|
||||
removeBlockedUser, updateManagementProgress, updateUser, updateUserFullInfo,
|
||||
} from '../../reducers';
|
||||
import { replaceInlineBotSettings, replaceInlineBotsIsLoading } from '../../reducers/bots';
|
||||
import { updateTabState } from '../../reducers/tabs';
|
||||
@ -224,10 +223,9 @@ addActionHandler('loadTopInlineBots', async (global): Promise<void> => {
|
||||
return;
|
||||
}
|
||||
|
||||
const { ids, users } = result;
|
||||
const { ids } = result;
|
||||
|
||||
global = getGlobal();
|
||||
global = addUsers(global, buildCollectionByKey(users, 'id'));
|
||||
global = {
|
||||
...global,
|
||||
topInlineBots: {
|
||||
@ -250,10 +248,9 @@ addActionHandler('loadTopBotApps', async (global): Promise<void> => {
|
||||
return;
|
||||
}
|
||||
|
||||
const { ids, users } = result;
|
||||
const { ids } = result;
|
||||
|
||||
global = getGlobal();
|
||||
global = addUsers(global, buildCollectionByKey(users, 'id'));
|
||||
global = {
|
||||
...global,
|
||||
topBotApps: {
|
||||
@ -285,8 +282,6 @@ addActionHandler('queryInlineBot', async (global, actions, payload): Promise<voi
|
||||
return;
|
||||
}
|
||||
|
||||
global = addUsers(global, { [inlineBot.id]: inlineBot });
|
||||
global = addChats(global, { [chat.id]: chat });
|
||||
inlineBotData = {
|
||||
id: inlineBot.id,
|
||||
query: '',
|
||||
@ -689,11 +684,9 @@ addActionHandler('requestAppWebView', async (global, actions, payload): Promise<
|
||||
bot,
|
||||
});
|
||||
if (result) {
|
||||
const attachBot = result.bot;
|
||||
global = getGlobal();
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
setGlobal(global);
|
||||
|
||||
const attachBot = result.bot;
|
||||
const shouldAskForTos = attachBot.isDisclaimerNeeded || attachBot.isForAttachMenu || attachBot.isForSideMenu;
|
||||
|
||||
if (shouldAskForTos) {
|
||||
@ -886,7 +879,6 @@ async function loadAttachBots<T extends GlobalState>(global: T, hash?: string) {
|
||||
}
|
||||
|
||||
global = getGlobal();
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
global = {
|
||||
...global,
|
||||
attachMenu: {
|
||||
|
||||
@ -10,10 +10,8 @@ import {
|
||||
toggleStream,
|
||||
} from '../../../lib/secret-sauce';
|
||||
import { getCurrentTabId } from '../../../util/establishMultitabRole';
|
||||
import { buildCollectionByKey } from '../../../util/iteratees';
|
||||
import { callApi } from '../../../api/gramjs';
|
||||
import { addActionHandler, getGlobal, setGlobal } from '../../index';
|
||||
import { addUsers } from '../../reducers';
|
||||
import {
|
||||
removeGroupCall,
|
||||
updateActiveGroupCall,
|
||||
@ -263,11 +261,7 @@ addActionHandler('connectToActivePhoneCall', async (global, actions): Promise<vo
|
||||
|
||||
if (!result) {
|
||||
if ('hangUp' in actions) actions.hangUp({ tabId: getCurrentTabId() });
|
||||
return;
|
||||
}
|
||||
global = getGlobal();
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
setGlobal(global);
|
||||
});
|
||||
|
||||
addActionHandler('acceptCall', async (global): Promise<void> => {
|
||||
@ -281,13 +275,7 @@ addActionHandler('acceptCall', async (global): Promise<void> => {
|
||||
await callApi('createPhoneCallState', [false]);
|
||||
|
||||
const gB = await callApi('acceptPhoneCall', [dhConfig])!;
|
||||
const result = await callApi('acceptCall', { call: phoneCall, gB });
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
global = getGlobal();
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
setGlobal(global);
|
||||
await callApi('acceptCall', { call: phoneCall, gB });
|
||||
});
|
||||
|
||||
addActionHandler('sendSignalingData', (global, actions, payload): ActionReturnType => {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import type {
|
||||
ApiChat, ApiChatFolder, ApiChatlistExportedInvite,
|
||||
ApiChatMember, ApiError, ApiMissingInvitedUser, ApiUser,
|
||||
ApiChatMember, ApiError, ApiMissingInvitedUser,
|
||||
} from '../../../api/types';
|
||||
import type { RequiredGlobalActions } from '../../index';
|
||||
import type {
|
||||
@ -21,7 +21,6 @@ import {
|
||||
ARCHIVED_FOLDER_ID,
|
||||
CHAT_LIST_LOAD_SLICE,
|
||||
DEBUG,
|
||||
GLOBAL_STATE_CACHE_ARCHIVED_CHAT_LIST_LIMIT,
|
||||
GLOBAL_SUGGESTED_CHANNELS_ID,
|
||||
RE_TG_LINK,
|
||||
SAVED_FOLDER_ID,
|
||||
@ -57,10 +56,8 @@ import {
|
||||
} from '../../index';
|
||||
import {
|
||||
addChatMembers,
|
||||
addChats,
|
||||
addMessages,
|
||||
addSimilarChannels,
|
||||
addUsers,
|
||||
addUserStatuses,
|
||||
deleteChatMessages,
|
||||
deletePeerPhoto,
|
||||
@ -70,9 +67,7 @@ import {
|
||||
replaceChatFullInfo,
|
||||
replaceChatListIds,
|
||||
replaceChatListLoadingParameters,
|
||||
replaceChats,
|
||||
replaceThreadParam,
|
||||
replaceUsers,
|
||||
replaceUserStatuses,
|
||||
toggleSimilarChannels,
|
||||
updateChat,
|
||||
@ -91,6 +86,7 @@ import {
|
||||
updateTopic,
|
||||
updateTopics,
|
||||
updateUser,
|
||||
updateUsers,
|
||||
} from '../../reducers';
|
||||
import { updateGroupCall } from '../../reducers/calls';
|
||||
import { updateTabState } from '../../reducers/tabs';
|
||||
@ -118,7 +114,6 @@ import {
|
||||
selectThreadInfo,
|
||||
selectUser,
|
||||
selectUserByPhoneNumber,
|
||||
selectVisibleUsers,
|
||||
} from '../../selectors';
|
||||
import { selectGroupCall } from '../../selectors/calls';
|
||||
import { selectCurrentLimit } from '../../selectors/limits';
|
||||
@ -126,13 +121,6 @@ import { selectCurrentLimit } from '../../selectors/limits';
|
||||
const TOP_CHAT_MESSAGES_PRELOAD_INTERVAL = 100;
|
||||
const INFINITE_LOOP_MARKER = 100;
|
||||
|
||||
const SERVICE_NOTIFICATIONS_USER_MOCK: ApiUser = {
|
||||
id: SERVICE_NOTIFICATIONS_USER_ID,
|
||||
accessHash: '0',
|
||||
type: 'userTypeRegular',
|
||||
isMin: true,
|
||||
phoneNumber: '',
|
||||
};
|
||||
const CHATLIST_LIMIT_ERROR_LIST = new Set([
|
||||
'FILTERS_TOO_MUCH',
|
||||
'CHATLISTS_TOO_MUCH',
|
||||
@ -404,8 +392,6 @@ addActionHandler('openThread', async (global, actions, payload): Promise<void> =
|
||||
}
|
||||
|
||||
global = getGlobal();
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
global = addChats(global, buildCollectionByKey(result.chats, 'id'));
|
||||
global = addMessages(global, result.messages);
|
||||
if (isComments) {
|
||||
global = updateThreadInfo(global, loadingChatId, loadingThreadId, {
|
||||
@ -509,12 +495,12 @@ addActionHandler('openSupportChat', async (global, actions, payload): Promise<vo
|
||||
});
|
||||
|
||||
addActionHandler('loadAllChats', async (global, actions, payload): Promise<void> => {
|
||||
const { onFirstBatchDone } = payload;
|
||||
const listType = payload.listType;
|
||||
const { onReplace } = payload;
|
||||
let { shouldReplace } = payload;
|
||||
let isCallbackFired = false;
|
||||
let i = 0;
|
||||
|
||||
while (shouldReplace || !global.chats.isFullyLoaded[listType]) {
|
||||
while (!global.chats.isFullyLoaded[listType]) {
|
||||
if (i++ >= INFINITE_LOOP_MARKER) {
|
||||
if (DEBUG) {
|
||||
// eslint-disable-next-line no-console
|
||||
@ -532,13 +518,12 @@ addActionHandler('loadAllChats', async (global, actions, payload): Promise<void>
|
||||
|
||||
await loadChats(
|
||||
listType,
|
||||
shouldReplace,
|
||||
true,
|
||||
);
|
||||
|
||||
if (shouldReplace) {
|
||||
onReplace?.();
|
||||
shouldReplace = false;
|
||||
if (!isCallbackFired) {
|
||||
onFirstBatchDone?.();
|
||||
isCallbackFired = true;
|
||||
}
|
||||
|
||||
global = getGlobal();
|
||||
@ -608,8 +593,6 @@ addActionHandler('requestSavedDialogUpdate', async (global, actions, payload): P
|
||||
global = getGlobal();
|
||||
|
||||
global = addMessages(global, result.messages);
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
global = addChats(global, buildCollectionByKey(result.chats, 'id'));
|
||||
|
||||
if (result.messages.length) {
|
||||
global = updateChatLastMessageId(global, chatId, result.messages[0].id, 'saved');
|
||||
@ -1792,7 +1775,6 @@ addActionHandler('loadGroupsForDiscussion', async (global): Promise<void> => {
|
||||
}, {} as Record<string, ApiChat>);
|
||||
|
||||
global = getGlobal();
|
||||
global = addChats(global, addedById);
|
||||
global = {
|
||||
...global,
|
||||
chats: {
|
||||
@ -1900,13 +1882,12 @@ addActionHandler('loadMoreMembers', async (global, actions, payload): Promise<vo
|
||||
return;
|
||||
}
|
||||
|
||||
const { members, users, userStatusesById } = result;
|
||||
const { members, userStatusesById } = result;
|
||||
if (!members || !members.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
global = getGlobal();
|
||||
global = addUsers(global, buildCollectionByKey(users, 'id'));
|
||||
global = addUserStatuses(global, userStatusesById);
|
||||
global = addChatMembers(global, chat, members);
|
||||
setGlobal(global);
|
||||
@ -2000,11 +1981,10 @@ addActionHandler('loadChatSettings', async (global, actions, payload): Promise<v
|
||||
|
||||
const result = await callApi('fetchChatSettings', chat);
|
||||
if (!result) return;
|
||||
const { settings, users } = result;
|
||||
|
||||
const { settings } = result;
|
||||
|
||||
global = getGlobal();
|
||||
|
||||
global = addUsers(global, buildCollectionByKey(users, 'id'));
|
||||
|
||||
global = updateChat(global, chat.id, { settings });
|
||||
setGlobal(global);
|
||||
});
|
||||
@ -2117,8 +2097,6 @@ addActionHandler('loadTopics', async (global, actions, payload): Promise<void> =
|
||||
if (!result) return;
|
||||
|
||||
global = getGlobal();
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
global = addChats(global, buildCollectionByKey(result.chats, 'id'));
|
||||
global = addMessages(global, result.messages);
|
||||
global = updateTopics(global, chatId, result.count, result.topics);
|
||||
global = updateListedTopicIds(global, chatId, result.topics.map((topic) => topic.id));
|
||||
@ -2149,8 +2127,6 @@ addActionHandler('loadTopicById', async (global, actions, payload): Promise<void
|
||||
}
|
||||
|
||||
global = getGlobal();
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
global = addChats(global, buildCollectionByKey(result.chats, 'id'));
|
||||
global = addMessages(global, result.messages);
|
||||
global = updateTopic(global, chatId, topicId, result.topic);
|
||||
|
||||
@ -2313,9 +2289,6 @@ addActionHandler('checkChatlistInvite', async (global, actions, payload): Promis
|
||||
|
||||
global = getGlobal();
|
||||
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
global = addChats(global, buildCollectionByKey(result.chats, 'id'));
|
||||
|
||||
global = updateTabState(global, {
|
||||
chatlistModal: {
|
||||
invite: result.invite,
|
||||
@ -2379,8 +2352,6 @@ addActionHandler('loadChatlistInvites', async (global, actions, payload): Promis
|
||||
|
||||
global = getGlobal();
|
||||
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
global = addChats(global, buildCollectionByKey(result.chats, 'id'));
|
||||
global = {
|
||||
...global,
|
||||
chatFolders: {
|
||||
@ -2639,7 +2610,6 @@ addActionHandler('loadChannelRecommendations', async (global, actions, payload):
|
||||
const chatsById = buildCollectionByKey(similarChannels, 'id');
|
||||
|
||||
global = getGlobal();
|
||||
global = addChats(global, chatsById);
|
||||
global = addSimilarChannels(global, chatId || GLOBAL_SUGGESTED_CHANNELS_ID, Object.keys(chatsById), count);
|
||||
setGlobal(global);
|
||||
});
|
||||
@ -2667,12 +2637,7 @@ addActionHandler('resolveBusinessChatLink', async (global, actions, payload): Pr
|
||||
return;
|
||||
}
|
||||
|
||||
const { users, chats, chatLink } = result;
|
||||
|
||||
global = getGlobal();
|
||||
global = addUsers(global, buildCollectionByKey(users, 'id'));
|
||||
global = addChats(global, buildCollectionByKey(chats, 'id'));
|
||||
setGlobal(global);
|
||||
const { chatLink } = result;
|
||||
|
||||
actions.openChatWithDraft({
|
||||
chatId: chatLink.chatId,
|
||||
@ -2715,7 +2680,6 @@ addActionHandler('requestCollectibleInfo', async (global, actions, payload): Pro
|
||||
|
||||
async function loadChats(
|
||||
listType: ChatListType,
|
||||
shouldReplace = false,
|
||||
isFullDraftSync?: boolean,
|
||||
) {
|
||||
// eslint-disable-next-line eslint-multitab-tt/no-immediate-global
|
||||
@ -2723,24 +2687,25 @@ async function loadChats(
|
||||
let lastLocalServiceMessageId = selectLastServiceNotification(global)?.id;
|
||||
|
||||
const params = selectChatListLoadingParameters(global, listType);
|
||||
const offsetPeer = !shouldReplace && params.nextOffsetPeerId
|
||||
? selectPeer(global, params.nextOffsetPeerId) : undefined;
|
||||
const offsetDate = !shouldReplace ? params.nextOffsetDate : undefined;
|
||||
const offsetId = !shouldReplace ? params.nextOffsetId : undefined;
|
||||
const offsetPeer = params.nextOffsetPeerId ? selectPeer(global, params.nextOffsetPeerId) : undefined;
|
||||
const offsetDate = params.nextOffsetDate;
|
||||
const offsetId = params.nextOffsetId;
|
||||
|
||||
const isFirstBatch = !offsetPeer && !offsetDate && !offsetId;
|
||||
|
||||
const result = listType === 'saved' ? await callApi('fetchSavedChats', {
|
||||
limit: CHAT_LIST_LOAD_SLICE,
|
||||
offsetDate,
|
||||
offsetId,
|
||||
offsetPeer,
|
||||
withPinned: shouldReplace,
|
||||
withPinned: isFirstBatch,
|
||||
}) : await callApi('fetchChats', {
|
||||
limit: CHAT_LIST_LOAD_SLICE,
|
||||
offsetDate,
|
||||
offsetId,
|
||||
offsetPeer,
|
||||
archived: listType === 'archived',
|
||||
withPinned: shouldReplace,
|
||||
withPinned: isFirstBatch,
|
||||
lastLocalServiceMessageId,
|
||||
});
|
||||
|
||||
@ -2753,64 +2718,16 @@ async function loadChats(
|
||||
global = getGlobal();
|
||||
lastLocalServiceMessageId = selectLastServiceNotification(global)?.id;
|
||||
|
||||
if (shouldReplace) {
|
||||
if (listType === 'active') {
|
||||
// Always include service notifications chat
|
||||
if (!chatIds.includes(SERVICE_NOTIFICATIONS_USER_ID)) {
|
||||
const result2 = await callApi('fetchChat', {
|
||||
type: 'user',
|
||||
user: SERVICE_NOTIFICATIONS_USER_MOCK,
|
||||
});
|
||||
const newChats = buildCollectionByKey(result.chats, 'id');
|
||||
|
||||
global = getGlobal();
|
||||
|
||||
const notificationsChat = result2 && selectChat(global, result2.chatId);
|
||||
if (notificationsChat) {
|
||||
chatIds.unshift(notificationsChat.id);
|
||||
result.chats.unshift(notificationsChat);
|
||||
if (lastLocalServiceMessageId) {
|
||||
result.lastMessageByChatId[notificationsChat.id] = lastLocalServiceMessageId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const tabStates = Object.values(global.byTabId);
|
||||
const topArchivedChats = getOrderedIds(ARCHIVED_FOLDER_ID)
|
||||
?.slice(0, GLOBAL_STATE_CACHE_ARCHIVED_CHAT_LIST_LIMIT)
|
||||
.map((chatId) => selectChat(global, chatId))
|
||||
.filter(Boolean);
|
||||
const visibleChats = tabStates.flatMap(({ id: tabId }) => {
|
||||
const currentChat = selectCurrentChat(global, tabId);
|
||||
return currentChat ? [currentChat] : [];
|
||||
});
|
||||
const chatsToSave = visibleChats.concat(topArchivedChats || []);
|
||||
|
||||
const visibleUsers = tabStates.flatMap(({ id: tabId }) => {
|
||||
return selectVisibleUsers(global, tabId) || [];
|
||||
});
|
||||
|
||||
if (global.currentUserId && global.users.byId[global.currentUserId]) {
|
||||
visibleUsers.push(global.users.byId[global.currentUserId]);
|
||||
}
|
||||
|
||||
global = replaceUsers(global, buildCollectionByKey(visibleUsers.concat(result.users), 'id'));
|
||||
global = replaceUserStatuses(global, result.userStatusesById);
|
||||
global = replaceChats(global, buildCollectionByKey(chatsToSave.concat(result.chats), 'id'));
|
||||
global = replaceChatListIds(global, listType, chatIds);
|
||||
} else {
|
||||
// Archived and Saved
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
global = addUserStatuses(global, result.userStatusesById);
|
||||
global = updateChats(global, buildCollectionByKey(result.chats, 'id'));
|
||||
global = replaceChatListIds(global, listType, chatIds);
|
||||
}
|
||||
global = updateUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
global = updateChats(global, newChats);
|
||||
if (isFirstBatch) {
|
||||
global = replaceChatListIds(global, listType, chatIds);
|
||||
global = replaceUserStatuses(global, result.userStatusesById);
|
||||
} else {
|
||||
const newChats = buildCollectionByKey(result.chats, 'id');
|
||||
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
global = addUserStatuses(global, result.userStatusesById);
|
||||
global = updateChats(global, newChats);
|
||||
global = updateChatListIds(global, listType, chatIds);
|
||||
global = addUserStatuses(global, result.userStatusesById);
|
||||
}
|
||||
|
||||
global = updateChatListSecondaryInfo(global, listType, result);
|
||||
@ -2860,11 +2777,10 @@ export async function loadFullChat<T extends GlobalState>(
|
||||
}
|
||||
|
||||
const {
|
||||
chats, users, userStatusesById, fullInfo, groupCall, membersCount, isForumAsMessages,
|
||||
chats, userStatusesById, fullInfo, groupCall, membersCount, isForumAsMessages,
|
||||
} = result;
|
||||
|
||||
global = getGlobal();
|
||||
global = addUsers(global, buildCollectionByKey(users, 'id'));
|
||||
global = updateChats(global, buildCollectionByKey(chats, 'id'));
|
||||
|
||||
if (userStatusesById) {
|
||||
@ -3024,8 +2940,6 @@ async function getAttachBotOrNotify<T extends GlobalState>(
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
setGlobal(global);
|
||||
|
||||
return result.bot;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import type {
|
||||
ApiChat, ApiGlobalMessageSearchType, ApiMessage, ApiTopic, ApiUser,
|
||||
ApiChat, ApiGlobalMessageSearchType, ApiMessage, ApiTopic,
|
||||
ApiUserStatus,
|
||||
} from '../../../api/types';
|
||||
import type { ActionReturnType, GlobalState, TabArgs } from '../../types';
|
||||
@ -8,15 +8,12 @@ import { GLOBAL_SEARCH_SLICE, GLOBAL_TOPIC_SEARCH_SLICE } from '../../../config'
|
||||
import { timestampPlusDay } from '../../../util/dates/dateFormat';
|
||||
import { isDeepLink, tryParseDeepLink } from '../../../util/deepLinkParser';
|
||||
import { getCurrentTabId } from '../../../util/establishMultitabRole';
|
||||
import { buildCollectionByKey } from '../../../util/iteratees';
|
||||
import { throttle } from '../../../util/schedulers';
|
||||
import { callApi } from '../../../api/gramjs';
|
||||
import { isChatChannel, isChatGroup, toChannelId } from '../../helpers/chats';
|
||||
import { addActionHandler, getGlobal, setGlobal } from '../../index';
|
||||
import {
|
||||
addChats,
|
||||
addMessages,
|
||||
addUsers,
|
||||
addUserStatuses,
|
||||
updateGlobalSearch,
|
||||
updateGlobalSearchFetchingStatus,
|
||||
@ -46,13 +43,9 @@ addActionHandler('setGlobalSearchQuery', (global, actions, payload): ActionRetur
|
||||
}
|
||||
|
||||
const {
|
||||
accountResultIds, globalResultIds, users, chats,
|
||||
accountResultIds, globalResultIds,
|
||||
} = result;
|
||||
|
||||
global = addChats(global, buildCollectionByKey(chats, 'id'));
|
||||
|
||||
global = addUsers(global, buildCollectionByKey(users, 'id'));
|
||||
|
||||
global = updateGlobalSearchFetchingStatus(global, { chats: false }, tabId);
|
||||
global = updateGlobalSearch(global, {
|
||||
localResults: {
|
||||
@ -137,12 +130,9 @@ addActionHandler('searchPopularBotApps', async (global, actions, payload): Promi
|
||||
return;
|
||||
}
|
||||
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
global = addChats(global, buildCollectionByKey(result.chats, 'id'));
|
||||
const peerIds = result.users.map(({ id }) => id);
|
||||
global = updateGlobalSearch(global, {
|
||||
popularBotApps: {
|
||||
peerIds: [...(popularBotApps?.peerIds || []), ...peerIds],
|
||||
peerIds: [...(popularBotApps?.peerIds || []), ...result.peerIds],
|
||||
nextOffset: result.nextOffset,
|
||||
},
|
||||
}, tabId);
|
||||
@ -167,9 +157,7 @@ async function searchMessagesGlobal<T extends GlobalState>(global: T, params: {
|
||||
} = params;
|
||||
let result: {
|
||||
messages: ApiMessage[];
|
||||
users: ApiUser[];
|
||||
userStatusesById?: Record<number, ApiUserStatus>;
|
||||
chats: ApiChat[];
|
||||
topics?: ApiTopic[];
|
||||
totalTopicsCount?: number;
|
||||
totalCount: number;
|
||||
@ -200,7 +188,7 @@ async function searchMessagesGlobal<T extends GlobalState>(global: T, params: {
|
||||
|
||||
if (inChatResult) {
|
||||
const {
|
||||
messages, users, totalCount, nextOffsetId,
|
||||
messages, totalCount, nextOffsetId,
|
||||
} = inChatResult;
|
||||
|
||||
const { topics: localTopics, count } = topics || {};
|
||||
@ -209,8 +197,6 @@ async function searchMessagesGlobal<T extends GlobalState>(global: T, params: {
|
||||
topics: localTopics,
|
||||
totalTopicsCount: count,
|
||||
messages,
|
||||
users,
|
||||
chats: [],
|
||||
totalCount,
|
||||
nextOffsetId,
|
||||
};
|
||||
@ -249,17 +235,9 @@ async function searchMessagesGlobal<T extends GlobalState>(global: T, params: {
|
||||
}
|
||||
|
||||
const {
|
||||
messages, users, chats, userStatusesById, totalCount, nextOffsetRate, nextOffsetId, nextOffsetPeerId,
|
||||
messages, userStatusesById, totalCount, nextOffsetRate, nextOffsetId, nextOffsetPeerId,
|
||||
} = result;
|
||||
|
||||
if (chats.length) {
|
||||
global = addChats(global, buildCollectionByKey(chats, 'id'));
|
||||
}
|
||||
|
||||
if (users.length) {
|
||||
global = addUsers(global, buildCollectionByKey(users, 'id'));
|
||||
}
|
||||
|
||||
if (userStatusesById) {
|
||||
global = addUserStatuses(global, userStatusesById);
|
||||
}
|
||||
|
||||
@ -13,7 +13,6 @@ import { updateAppBadge } from '../../../util/appBadge';
|
||||
import { MAIN_IDB_STORE, PASSCODE_IDB_STORE } from '../../../util/browser/idb';
|
||||
import * as cacheApi from '../../../util/cacheApi';
|
||||
import { getCurrentTabId } from '../../../util/establishMultitabRole';
|
||||
import { buildCollectionByKey } from '../../../util/iteratees';
|
||||
import { unsubscribe } from '../../../util/notifications';
|
||||
import { clearEncryptedSession, encryptSession, forgetPasscode } from '../../../util/passcode';
|
||||
import { parseInitialLocationHash, resetInitialLocationHash, resetLocationHash } from '../../../util/routing';
|
||||
@ -35,7 +34,7 @@ import {
|
||||
addActionHandler, getGlobal, setGlobal,
|
||||
} from '../../index';
|
||||
import {
|
||||
addUsers, clearGlobalForLockScreen, updateManagementProgress, updatePasscodeSettings,
|
||||
clearGlobalForLockScreen, updateManagementProgress, updatePasscodeSettings,
|
||||
} from '../../reducers';
|
||||
|
||||
addActionHandler('initApi', (global, actions): ActionReturnType => {
|
||||
@ -109,7 +108,6 @@ addActionHandler('uploadProfilePhoto', async (global, actions, payload): Promise
|
||||
if (!result) return;
|
||||
|
||||
global = getGlobal();
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
global = updateManagementProgress(global, ManagementProgress.Complete, tabId);
|
||||
setGlobal(global);
|
||||
|
||||
|
||||
@ -2,13 +2,12 @@ import type { ActionReturnType } from '../../types';
|
||||
import { ManagementProgress } from '../../../types';
|
||||
|
||||
import { getCurrentTabId } from '../../../util/establishMultitabRole';
|
||||
import { buildCollectionByKey } from '../../../util/iteratees';
|
||||
import * as langProvider from '../../../util/oldLangProvider';
|
||||
import { callApi } from '../../../api/gramjs';
|
||||
import { getUserFirstOrLastName } from '../../helpers';
|
||||
import { addActionHandler, getGlobal, setGlobal } from '../../index';
|
||||
import {
|
||||
addUsers, updateChat, updateChatFullInfo, updateManagement, updateManagementProgress,
|
||||
updateChat, updateChatFullInfo, updateManagement, updateManagementProgress,
|
||||
} from '../../reducers';
|
||||
import {
|
||||
selectChat, selectCurrentMessageList, selectTabState, selectUser,
|
||||
@ -124,9 +123,7 @@ addActionHandler('loadExportedChatInvites', async (global, actions, payload): Pr
|
||||
return;
|
||||
}
|
||||
global = getGlobal();
|
||||
const { invites, users } = result;
|
||||
|
||||
global = addUsers(global, buildCollectionByKey(users, 'id'));
|
||||
const { invites } = result;
|
||||
|
||||
const update = isRevoked ? { revokedInvites: invites } : { invites };
|
||||
global = updateManagement(global, chatId, update, tabId);
|
||||
@ -153,7 +150,7 @@ addActionHandler('editExportedChatInvite', async (global, actions, payload): Pro
|
||||
return;
|
||||
}
|
||||
|
||||
const { oldInvite, newInvite, users } = result;
|
||||
const { oldInvite, newInvite } = result;
|
||||
|
||||
global = getGlobal();
|
||||
const { management } = selectTabState(global, tabId);
|
||||
@ -167,8 +164,6 @@ addActionHandler('editExportedChatInvite', async (global, actions, payload): Pro
|
||||
invites.push(newInvite);
|
||||
}
|
||||
|
||||
global = addUsers(global, buildCollectionByKey(users, 'id'));
|
||||
|
||||
global = updateManagement(global, chatId, {
|
||||
invites,
|
||||
revokedInvites,
|
||||
@ -269,7 +264,7 @@ addActionHandler('loadChatInviteImporters', async (
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
const { importers, users } = result;
|
||||
const { importers } = result;
|
||||
|
||||
global = getGlobal();
|
||||
const currentInviteInfo = selectTabState(global, tabId).management.byChatId[chatId]?.inviteInfo;
|
||||
@ -283,7 +278,6 @@ addActionHandler('loadChatInviteImporters', async (
|
||||
importers,
|
||||
},
|
||||
}, tabId);
|
||||
global = addUsers(global, users);
|
||||
setGlobal(global);
|
||||
});
|
||||
|
||||
@ -308,7 +302,7 @@ addActionHandler('loadChatInviteRequesters', async (
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
const { importers, users } = result;
|
||||
const { importers } = result;
|
||||
|
||||
global = getGlobal();
|
||||
const currentInviteInfo = selectTabState(global, tabId).management.byChatId[chatId]?.inviteInfo;
|
||||
@ -321,7 +315,6 @@ addActionHandler('loadChatInviteRequesters', async (
|
||||
requesters: importers,
|
||||
},
|
||||
}, tabId);
|
||||
global = addUsers(global, users);
|
||||
setGlobal(global);
|
||||
});
|
||||
|
||||
@ -343,11 +336,10 @@ addActionHandler('loadChatJoinRequests', async (global, actions, payload): Promi
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
const { importers, users } = result;
|
||||
const { importers } = result;
|
||||
|
||||
global = getGlobal();
|
||||
global = updateChat(global, chatId, { joinRequests: importers });
|
||||
global = addUsers(global, users);
|
||||
setGlobal(global);
|
||||
});
|
||||
|
||||
@ -443,7 +435,6 @@ addActionHandler('uploadContactProfilePhoto', async (global, actions, payload):
|
||||
}
|
||||
|
||||
global = getGlobal();
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
setGlobal(global);
|
||||
|
||||
const { id, accessHash } = user;
|
||||
|
||||
@ -66,9 +66,7 @@ import {
|
||||
} from '../../index';
|
||||
import {
|
||||
addChatMessagesById,
|
||||
addChats,
|
||||
addUnreadMentions,
|
||||
addUsers,
|
||||
deleteSponsoredMessage,
|
||||
removeOutlyingList,
|
||||
removeRequestedMessageTranslation,
|
||||
@ -81,7 +79,6 @@ import {
|
||||
updateChat,
|
||||
updateChatFullInfo,
|
||||
updateChatMessage,
|
||||
updateChats,
|
||||
updateListedIds,
|
||||
updateMessageTranslation,
|
||||
updateOutlyingLists,
|
||||
@ -95,7 +92,6 @@ import {
|
||||
updateTopic,
|
||||
updateUploadByMessageKey,
|
||||
updateUserFullInfo,
|
||||
updateUsers,
|
||||
} from '../../reducers';
|
||||
import { updateTabState } from '../../reducers/tabs';
|
||||
import {
|
||||
@ -1014,9 +1010,6 @@ addActionHandler('loadPollOptionResults', async (global, actions, payload): Prom
|
||||
|
||||
global = getGlobal();
|
||||
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
global = addChats(global, buildCollectionByKey(result.chats, 'id'));
|
||||
|
||||
const tabState = selectTabState(global, tabId);
|
||||
const { pollResults } = tabState;
|
||||
const { voters } = tabState.pollResults;
|
||||
@ -1301,7 +1294,7 @@ async function loadViewportMessages<T extends GlobalState>(
|
||||
}
|
||||
|
||||
const {
|
||||
messages, users, chats, count,
|
||||
messages, count,
|
||||
} = result;
|
||||
|
||||
global = getGlobal();
|
||||
@ -1325,9 +1318,6 @@ async function loadViewportMessages<T extends GlobalState>(
|
||||
? updateOutlyingLists(global, chatId, threadId, ids)
|
||||
: updateListedIds(global, chatId, threadId, ids);
|
||||
|
||||
global = addUsers(global, buildCollectionByKey(users, 'id'));
|
||||
global = addChats(global, buildCollectionByKey(chats, 'id'));
|
||||
|
||||
let listedIds = selectListedIds(global, chatId, threadId);
|
||||
const outlyingList = offsetId ? selectOutlyingListByMessageId(global, chatId, threadId, offsetId) : undefined;
|
||||
|
||||
@ -1382,7 +1372,6 @@ async function loadMessage<T extends GlobalState>(
|
||||
|
||||
global = getGlobal();
|
||||
global = updateChatMessage(global, chat.id, messageId, result.message);
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
setGlobal(global);
|
||||
|
||||
return result.message;
|
||||
@ -1498,7 +1487,7 @@ addActionHandler('loadPinnedMessages', async (global, actions, payload): Promise
|
||||
return;
|
||||
}
|
||||
|
||||
const { messages, chats, users } = result;
|
||||
const { messages } = result;
|
||||
|
||||
const byId = buildCollectionByKey(messages, 'id');
|
||||
const ids = Object.keys(byId).map(Number).sort((a, b) => b - a);
|
||||
@ -1506,8 +1495,6 @@ addActionHandler('loadPinnedMessages', async (global, actions, payload): Promise
|
||||
global = getGlobal();
|
||||
global = addChatMessagesById(global, chat.id, byId);
|
||||
global = safeReplacePinnedIds(global, chat.id, threadId, ids);
|
||||
global = addUsers(global, buildCollectionByKey(users, 'id'));
|
||||
global = addChats(global, buildCollectionByKey(chats, 'id'));
|
||||
setGlobal(global);
|
||||
});
|
||||
|
||||
@ -1562,8 +1549,6 @@ addActionHandler('loadSendAs', async (global, actions, payload): Promise<void> =
|
||||
}
|
||||
|
||||
global = getGlobal();
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
global = addChats(global, buildCollectionByKey(result.chats, 'id'));
|
||||
global = updateChat(global, chatId, { sendAsPeerIds: result.sendAs });
|
||||
setGlobal(global);
|
||||
});
|
||||
@ -1582,8 +1567,6 @@ addActionHandler('loadSponsoredMessages', async (global, actions, payload): Prom
|
||||
|
||||
global = getGlobal();
|
||||
global = updateSponsoredMessage(global, chatId, result.messages[0]);
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
global = addChats(global, buildCollectionByKey(result.chats, 'id'));
|
||||
setGlobal(global);
|
||||
});
|
||||
|
||||
@ -1695,15 +1678,13 @@ async function fetchUnreadMentions<T extends GlobalState>(global: T, chatId: str
|
||||
|
||||
if (!result) return;
|
||||
|
||||
const { messages, chats, users } = result;
|
||||
const { messages } = result;
|
||||
|
||||
const byId = buildCollectionByKey(messages, 'id');
|
||||
const ids = Object.keys(byId).map(Number);
|
||||
|
||||
global = getGlobal();
|
||||
global = addChatMessagesById(global, chat.id, byId);
|
||||
global = addUsers(global, buildCollectionByKey(users, 'id'));
|
||||
global = addChats(global, buildCollectionByKey(chats, 'id'));
|
||||
global = addUnreadMentions(global, chatId, chat, ids);
|
||||
|
||||
setGlobal(global);
|
||||
@ -2073,8 +2054,6 @@ addActionHandler('loadMessageViews', async (global, actions, payload): Promise<v
|
||||
if (!result) return;
|
||||
|
||||
global = getGlobal();
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
global = addChats(global, buildCollectionByKey(result.chats, 'id'));
|
||||
result.viewsInfo.forEach((update) => {
|
||||
global = updateChatMessage(global, chatId, update.id, {
|
||||
viewsCount: update.views,
|
||||
@ -2155,8 +2134,6 @@ addActionHandler('loadQuickReplies', async (global): Promise<void> => {
|
||||
if (!result) return;
|
||||
|
||||
global = getGlobal();
|
||||
global = updateUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
global = updateChats(global, buildCollectionByKey(result.chats, 'id'));
|
||||
global = updateQuickReplyMessages(global, buildCollectionByKey(result.messages, 'id'));
|
||||
global = updateQuickReplies(global, result.quickReplies);
|
||||
|
||||
|
||||
@ -18,9 +18,7 @@ import {
|
||||
} from '../../index';
|
||||
import {
|
||||
addChatMessagesById,
|
||||
addChats,
|
||||
addMessages,
|
||||
addUsers,
|
||||
addUserStatuses,
|
||||
initializeChatMediaSearchResults,
|
||||
mergeWithChatMediaSearchSegment,
|
||||
@ -126,7 +124,7 @@ addActionHandler('performMiddleSearch', async (global, actions, payload): Promis
|
||||
}
|
||||
|
||||
const {
|
||||
chats, users, userStatusesById, messages, totalCount, nextOffsetId, nextOffsetRate, nextOffsetPeerId,
|
||||
userStatusesById, messages, totalCount, nextOffsetId, nextOffsetRate, nextOffsetPeerId,
|
||||
} = result;
|
||||
|
||||
const newFoundIds = messages.map(getSearchResultKey);
|
||||
@ -142,8 +140,6 @@ addActionHandler('performMiddleSearch', async (global, actions, payload): Promis
|
||||
|
||||
const resultChatId = isSavedDialog ? currentUserId : chat.id;
|
||||
|
||||
global = addChats(global, buildCollectionByKey(chats, 'id'));
|
||||
global = addUsers(global, buildCollectionByKey(users, 'id'));
|
||||
global = addUserStatuses(global, userStatusesById);
|
||||
global = addMessages(global, messages);
|
||||
global = updateMiddleSearch(global, resultChatId, threadId, {
|
||||
@ -300,7 +296,7 @@ async function searchSharedMedia<T extends GlobalState>(
|
||||
}
|
||||
|
||||
const {
|
||||
chats, users, messages, totalCount, nextOffsetId,
|
||||
userStatusesById, messages, totalCount, nextOffsetId,
|
||||
} = result;
|
||||
|
||||
const byId = buildCollectionByKey(messages, 'id');
|
||||
@ -313,8 +309,7 @@ async function searchSharedMedia<T extends GlobalState>(
|
||||
return;
|
||||
}
|
||||
|
||||
global = addChats(global, buildCollectionByKey(chats, 'id'));
|
||||
global = addUsers(global, buildCollectionByKey(users, 'id'));
|
||||
global = addUserStatuses(global, userStatusesById);
|
||||
global = addChatMessagesById(global, resultChatId, byId);
|
||||
global = updateSharedMediaSearchResults(
|
||||
global, resultChatId, threadId, type, newFoundIds, totalCount, nextOffsetId, tabId,
|
||||
@ -469,14 +464,13 @@ async function searchChatMedia<T extends GlobalState>(
|
||||
}
|
||||
|
||||
const {
|
||||
chats, users, messages,
|
||||
messages, userStatusesById,
|
||||
} = result;
|
||||
|
||||
const byId = buildCollectionByKey(messages, 'id');
|
||||
const newFoundIds = Object.keys(byId).map(Number);
|
||||
|
||||
global = addChats(global, buildCollectionByKey(chats, 'id'));
|
||||
global = addUsers(global, buildCollectionByKey(users, 'id'));
|
||||
global = addUserStatuses(global, userStatusesById);
|
||||
global = addChatMessagesById(global, resultChatId, byId);
|
||||
|
||||
const loadingState = calcLoadingState(direction, limit, newFoundIds.length, currentSegment);
|
||||
|
||||
@ -5,7 +5,6 @@ import { PaymentStep } from '../../../types';
|
||||
|
||||
import { DEBUG_PAYMENT_SMART_GLOCAL } from '../../../config';
|
||||
import { getCurrentTabId } from '../../../util/establishMultitabRole';
|
||||
import { buildCollectionByKey } from '../../../util/iteratees';
|
||||
import * as langProvider from '../../../util/oldLangProvider';
|
||||
import { getStripeError } from '../../../util/payments/stripe';
|
||||
import { buildQueryString } from '../../../util/requestQuery';
|
||||
@ -15,8 +14,7 @@ import { isChatChannel, isChatSuperGroup } from '../../helpers';
|
||||
import { getRequestInputInvoice, getStarsTransactionFromGift } from '../../helpers/payments';
|
||||
import { addActionHandler, getGlobal, setGlobal } from '../../index';
|
||||
import {
|
||||
addChats,
|
||||
addUsers, appendStarsTransactions, closeInvoice,
|
||||
appendStarsTransactions, closeInvoice,
|
||||
openStarsTransactionFromReceipt,
|
||||
openStarsTransactionModal,
|
||||
setInvoiceInfo, setPaymentForm,
|
||||
@ -105,12 +103,11 @@ async function getPaymentForm<T extends GlobalState>(
|
||||
}
|
||||
|
||||
const {
|
||||
form, invoice, users,
|
||||
form, invoice,
|
||||
} = result;
|
||||
|
||||
global = getGlobal();
|
||||
|
||||
global = addUsers(global, buildCollectionByKey(users, 'id'));
|
||||
global = setPaymentForm(global, form, tabId);
|
||||
global = setPaymentStep(global, PaymentStep.Checkout, tabId);
|
||||
setGlobal(global);
|
||||
@ -133,7 +130,6 @@ addActionHandler('getReceipt', async (global, actions, payload): Promise<void> =
|
||||
}
|
||||
|
||||
global = getGlobal();
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
if (result.receipt.type === 'stars') {
|
||||
global = openStarsTransactionFromReceipt(global, result.receipt, tabId);
|
||||
} else {
|
||||
@ -430,7 +426,6 @@ addActionHandler('openPremiumModal', async (global, actions, payload): Promise<v
|
||||
if (!result) return;
|
||||
|
||||
global = getGlobal();
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
|
||||
global = updateTabState(global, {
|
||||
premiumModal: {
|
||||
@ -559,7 +554,6 @@ addActionHandler('openPremiumGiftModal', async (global, actions, payload): Promi
|
||||
if (!result) return;
|
||||
|
||||
global = getGlobal();
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
|
||||
const gifts = await callApi('getPremiumGiftCodeOptions', {});
|
||||
|
||||
@ -686,8 +680,6 @@ addActionHandler('openBoostModal', async (global, actions, payload): Promise<voi
|
||||
const tabState = selectTabState(global, tabId);
|
||||
if (!tabState.boostModal) return;
|
||||
|
||||
global = addChats(global, buildCollectionByKey(myBoosts.chats, 'id'));
|
||||
global = addUsers(global, buildCollectionByKey(myBoosts.users, 'id'));
|
||||
global = updateTabState(global, {
|
||||
boostModal: {
|
||||
...tabState.boostModal,
|
||||
@ -726,8 +718,6 @@ addActionHandler('openBoostStatistics', async (global, actions, payload): Promis
|
||||
return;
|
||||
}
|
||||
|
||||
const totalBoostUserList = [...boostListResult.users, ...boostListGiftResult.users];
|
||||
global = addUsers(global, buildCollectionByKey(totalBoostUserList, 'id'));
|
||||
global = updateTabState(global, {
|
||||
boostStatistics: {
|
||||
chatId,
|
||||
@ -784,7 +774,6 @@ addActionHandler('loadMoreBoosters', async (global, actions, payload): Promise<v
|
||||
if (!result) return;
|
||||
|
||||
global = getGlobal();
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
|
||||
tabState = selectTabState(global, tabId);
|
||||
if (!tabState.boostStatistics) return;
|
||||
@ -895,8 +884,6 @@ addActionHandler('applyBoost', async (global, actions, payload): Promise<void> =
|
||||
}
|
||||
|
||||
tabState = selectTabState(global, tabId);
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
global = addChats(global, buildCollectionByKey(result.chats, 'id'));
|
||||
if (oldChatFullInfo) {
|
||||
global = updateChatFullInfo(global, chatId, {
|
||||
boostsApplied: oldBoostsApplied + slots.length,
|
||||
@ -930,8 +917,6 @@ addActionHandler('checkGiftCode', async (global, actions, payload): Promise<void
|
||||
}
|
||||
|
||||
global = getGlobal();
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
global = addChats(global, buildCollectionByKey(result.chats, 'id'));
|
||||
global = updateTabState(global, {
|
||||
giftCodeModal: {
|
||||
slug,
|
||||
@ -1003,8 +988,6 @@ addActionHandler('loadStarStatus', async (global): Promise<void> => {
|
||||
}
|
||||
|
||||
global = getGlobal();
|
||||
global = addChats(global, buildCollectionByKey(status.chats, 'id'));
|
||||
global = addUsers(global, buildCollectionByKey(status.users, 'id'));
|
||||
|
||||
global = {
|
||||
...global,
|
||||
@ -1043,8 +1026,6 @@ addActionHandler('loadStarsTransactions', async (global, actions, payload): Prom
|
||||
}
|
||||
|
||||
global = getGlobal();
|
||||
global = addChats(global, buildCollectionByKey(result.chats, 'id'));
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
|
||||
global = updateStarsBalance(global, result.balance);
|
||||
if (result.history) {
|
||||
|
||||
@ -20,7 +20,7 @@ import {
|
||||
} from '../../helpers';
|
||||
import { addActionHandler, getGlobal, setGlobal } from '../../index';
|
||||
import {
|
||||
addChatMessagesById, addChats, addUsers, updateChat, updateChatMessage,
|
||||
addChatMessagesById, updateChat, updateChatMessage,
|
||||
} from '../../reducers';
|
||||
import { addMessageReaction, subtractXForEmojiInteraction, updateUnreadReactions } from '../../reducers/reactions';
|
||||
import { updateTabState } from '../../reducers/tabs';
|
||||
@ -336,10 +336,6 @@ addActionHandler('loadReactors', async (global, actions, payload): Promise<void>
|
||||
}
|
||||
|
||||
global = getGlobal();
|
||||
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
global = addChats(global, buildCollectionByKey(result.chats, 'id'));
|
||||
|
||||
global = updateChatMessage(global, chatId, messageId, {
|
||||
reactors: result,
|
||||
});
|
||||
@ -409,15 +405,13 @@ addActionHandler('fetchUnreadReactions', async (global, actions, payload): Promi
|
||||
return;
|
||||
}
|
||||
|
||||
const { messages, chats, users } = result;
|
||||
const { messages } = result;
|
||||
|
||||
const byId = buildCollectionByKey(messages, 'id');
|
||||
const ids = Object.keys(byId).map(Number);
|
||||
|
||||
global = getGlobal();
|
||||
global = addChatMessagesById(global, chat.id, byId);
|
||||
global = addUsers(global, buildCollectionByKey(users, 'id'));
|
||||
global = addChats(global, buildCollectionByKey(chats, 'id'));
|
||||
global = updateUnreadReactions(global, chatId, {
|
||||
unreadReactions: unique([...(chat.unreadReactions || []), ...ids]).sort((a, b) => b - a),
|
||||
});
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import type { ApiUser, ApiUsername } from '../../../api/types';
|
||||
import type { ApiUsername } from '../../../api/types';
|
||||
import type {
|
||||
ApiPrivacySettings,
|
||||
} from '../../../types';
|
||||
@ -19,8 +19,8 @@ import { callApi } from '../../../api/gramjs';
|
||||
import { buildApiInputPrivacyRules } from '../../helpers';
|
||||
import { addActionHandler, getGlobal, setGlobal } from '../../index';
|
||||
import {
|
||||
addBlockedUser, addNotifyExceptions, addUsers, deletePeerPhoto,
|
||||
removeBlockedUser, replaceSettings, updateChat, updateChats,
|
||||
addBlockedUser, addNotifyExceptions, deletePeerPhoto,
|
||||
removeBlockedUser, replaceSettings, updateChat,
|
||||
updateNotifySettings, updateUser, updateUserFullInfo,
|
||||
} from '../../reducers';
|
||||
import { updateTabState } from '../../reducers/tabs';
|
||||
@ -47,12 +47,7 @@ addActionHandler('updateProfile', async (global, actions, payload): Promise<void
|
||||
setGlobal(global);
|
||||
|
||||
if (photo) {
|
||||
const result = await callApi('uploadProfilePhoto', photo);
|
||||
if (result) {
|
||||
global = getGlobal();
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
setGlobal(global);
|
||||
}
|
||||
await callApi('uploadProfilePhoto', photo);
|
||||
}
|
||||
|
||||
if (firstName || lastName || about) {
|
||||
@ -119,10 +114,6 @@ addActionHandler('updateProfilePhoto', async (global, actions, payload): Promise
|
||||
const result = await callApi('updateProfilePhoto', photo, isFallback);
|
||||
if (!result) return;
|
||||
|
||||
const { users } = result;
|
||||
global = getGlobal();
|
||||
global = addUsers(global, buildCollectionByKey(users, 'id'));
|
||||
setGlobal(global);
|
||||
actions.loadFullUser({ userId: currentUserId, withPhotos: true });
|
||||
});
|
||||
|
||||
@ -261,13 +252,6 @@ addActionHandler('loadBlockedUsers', async (global): Promise<void> => {
|
||||
|
||||
global = getGlobal();
|
||||
|
||||
if (result.users?.length) {
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
}
|
||||
if (result.chats?.length) {
|
||||
global = updateChats(global, buildCollectionByKey(result.chats, 'id'));
|
||||
}
|
||||
|
||||
global = {
|
||||
...global,
|
||||
blocked: {
|
||||
@ -425,14 +409,10 @@ addActionHandler('loadPrivacySettings', async (global): Promise<void> => {
|
||||
bioSettings,
|
||||
birthdaySettings,
|
||||
] = result as {
|
||||
users: ApiUser[];
|
||||
rules: ApiPrivacySettings;
|
||||
}[];
|
||||
|
||||
const allUsers = result.flatMap((e) => e!.users);
|
||||
|
||||
global = getGlobal();
|
||||
global = addUsers(global, buildCollectionByKey(allUsers, 'id'));
|
||||
global = {
|
||||
...global,
|
||||
settings: {
|
||||
@ -466,7 +446,6 @@ addActionHandler('setPrivacyVisibility', async (global, actions, payload): Promi
|
||||
}
|
||||
|
||||
global = getGlobal();
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
global = {
|
||||
...global,
|
||||
settings: {
|
||||
@ -502,7 +481,6 @@ addActionHandler('setPrivacyVisibility', async (global, actions, payload): Promi
|
||||
onSuccess?.();
|
||||
|
||||
global = getGlobal();
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
global = {
|
||||
...global,
|
||||
settings: {
|
||||
@ -542,7 +520,6 @@ addActionHandler('setPrivacySettings', async (global, actions, payload): Promise
|
||||
}
|
||||
|
||||
global = getGlobal();
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
global = {
|
||||
...global,
|
||||
settings: {
|
||||
|
||||
@ -1,11 +1,8 @@
|
||||
import { areDeepEqual } from '../../../util/areDeepEqual';
|
||||
import { getCurrentTabId } from '../../../util/establishMultitabRole';
|
||||
import { buildCollectionByKey } from '../../../util/iteratees';
|
||||
import { callApi } from '../../../api/gramjs';
|
||||
import { addActionHandler, getGlobal, setGlobal } from '../../index';
|
||||
import {
|
||||
addChats,
|
||||
addUsers,
|
||||
updateChannelMonetizationStatistics,
|
||||
updateMessageStatistics,
|
||||
updateStatistics,
|
||||
@ -36,10 +33,8 @@ addActionHandler('loadStatistics', async (global, actions, payload): Promise<voi
|
||||
return;
|
||||
}
|
||||
|
||||
const { stats } = result;
|
||||
global = getGlobal();
|
||||
const { stats, users } = result;
|
||||
|
||||
global = addUsers(global, buildCollectionByKey(users, 'id'));
|
||||
global = updateStatistics(global, chatId, stats, tabId);
|
||||
setGlobal(global);
|
||||
});
|
||||
@ -212,8 +207,6 @@ addActionHandler('loadStoryPublicForwards', async (global, actions, payload): Pr
|
||||
|
||||
const {
|
||||
publicForwards,
|
||||
users,
|
||||
chats,
|
||||
count,
|
||||
nextOffset,
|
||||
} = await callApi('fetchStoryPublicForwards', {
|
||||
@ -221,13 +214,6 @@ addActionHandler('loadStoryPublicForwards', async (global, actions, payload): Pr
|
||||
}) || {};
|
||||
|
||||
global = getGlobal();
|
||||
|
||||
if (chats) {
|
||||
global = addChats(global, buildCollectionByKey(chats, 'id'));
|
||||
}
|
||||
if (users) {
|
||||
global = addUsers(global, buildCollectionByKey(users, 'id'));
|
||||
}
|
||||
global = updateStoryStatistics(global, {
|
||||
...stats,
|
||||
publicForwards: count || publicForwards?.length,
|
||||
|
||||
@ -2,17 +2,14 @@ import type { ActionReturnType } from '../../types';
|
||||
|
||||
import { DEBUG } from '../../../config';
|
||||
import { getCurrentTabId } from '../../../util/establishMultitabRole';
|
||||
import { buildCollectionByKey } from '../../../util/iteratees';
|
||||
import { oldTranslate } from '../../../util/oldLangProvider';
|
||||
import { getServerTime } from '../../../util/serverTime';
|
||||
import { callApi } from '../../../api/gramjs';
|
||||
import { buildApiInputPrivacyRules } from '../../helpers';
|
||||
import { addActionHandler, getGlobal, setGlobal } from '../../index';
|
||||
import {
|
||||
addChats,
|
||||
addStories,
|
||||
addStoriesForPeer,
|
||||
addUsers,
|
||||
removePeerStory,
|
||||
updateLastReadStoryForPeer,
|
||||
updateLastViewedStoryForPeer,
|
||||
@ -67,8 +64,6 @@ addActionHandler('loadAllStories', async (global): Promise<void> => {
|
||||
global.stories.stateHash = result.state;
|
||||
|
||||
if ('peerStories' in result) {
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
global = addChats(global, buildCollectionByKey(result.chats, 'id'));
|
||||
global = addStories(global, result.peerStories);
|
||||
global = updatePeersWithStories(global, result.peerStories);
|
||||
global = updateStealthMode(global, result.stealthMode);
|
||||
@ -112,8 +107,6 @@ addActionHandler('loadAllHiddenStories', async (global): Promise<void> => {
|
||||
global.stories.archiveStateHash = result.state;
|
||||
|
||||
if ('peerStories' in result) {
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
global = addChats(global, buildCollectionByKey(result.chats, 'id'));
|
||||
global = addStories(global, result.peerStories);
|
||||
global = updatePeersWithStories(global, result.peerStories);
|
||||
global = updateStealthMode(global, result.stealthMode);
|
||||
@ -153,8 +146,6 @@ addActionHandler('loadPeerSkippedStories', async (global, actions, payload): Pro
|
||||
}
|
||||
|
||||
global = getGlobal();
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
global = addChats(global, buildCollectionByKey(result.chats, 'id'));
|
||||
global = addStoriesForPeer(global, peerId, result.stories, result.pinnedIds);
|
||||
setGlobal(global);
|
||||
});
|
||||
@ -295,8 +286,6 @@ addActionHandler('loadPeerStories', async (global, actions, payload): Promise<vo
|
||||
}
|
||||
|
||||
global = getGlobal();
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
global = addChats(global, buildCollectionByKey(result.chats, 'id'));
|
||||
global = addStoriesForPeer(global, peerId, result.stories);
|
||||
if (result.lastReadStoryId) {
|
||||
global = updateLastReadStoryForPeer(global, peerId, result.lastReadStoryId);
|
||||
@ -322,8 +311,6 @@ addActionHandler('loadPeerProfileStories', async (global, actions, payload): Pro
|
||||
global = updatePeerStoriesFullyLoaded(global, peerId, true);
|
||||
}
|
||||
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
global = addChats(global, buildCollectionByKey(result.chats, 'id'));
|
||||
global = addStoriesForPeer(global, peerId, result.stories, result.pinnedIds);
|
||||
setGlobal(global);
|
||||
});
|
||||
@ -343,8 +330,6 @@ addActionHandler('loadStoriesArchive', async (global, actions, payload): Promise
|
||||
if (Object.values(result.stories).length === 0) {
|
||||
global = updatePeerStoriesFullyLoaded(global, peerId, true, true);
|
||||
}
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
global = addChats(global, buildCollectionByKey(result.chats, 'id'));
|
||||
global = addStoriesForPeer(global, peerId, result.stories, undefined, true);
|
||||
setGlobal(global);
|
||||
});
|
||||
@ -362,8 +347,6 @@ addActionHandler('loadPeerStoriesByIds', async (global, actions, payload): Promi
|
||||
}
|
||||
|
||||
global = getGlobal();
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
global = addChats(global, buildCollectionByKey(result.chats, 'id'));
|
||||
global = addStoriesForPeer(global, peerId, result.stories);
|
||||
setGlobal(global);
|
||||
});
|
||||
@ -382,7 +365,6 @@ addActionHandler('loadStoryViews', async (global, actions, payload): Promise<voi
|
||||
}
|
||||
|
||||
global = getGlobal();
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
global = updatePeerStoryViews(global, peerId, storyId, result.views);
|
||||
setGlobal(global);
|
||||
});
|
||||
@ -424,8 +406,6 @@ addActionHandler('loadStoryViewList', async (global, actions, payload): Promise<
|
||||
}
|
||||
|
||||
global = getGlobal();
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
global = addChats(global, buildCollectionByKey(result.chats, 'id'));
|
||||
global = updateStoryViews(global, storyId, result.views, result.nextOffset, tabId);
|
||||
setGlobal(global);
|
||||
});
|
||||
|
||||
@ -72,8 +72,7 @@ addActionHandler('sync', (global, actions): ActionReturnType => {
|
||||
|
||||
loadAllChats({
|
||||
listType: 'active',
|
||||
shouldReplace: true,
|
||||
onReplace: async () => {
|
||||
onFirstBatchDone: async () => {
|
||||
await loadAndReplaceMessages(global, actions);
|
||||
|
||||
global = getGlobal();
|
||||
@ -90,8 +89,8 @@ addActionHandler('sync', (global, actions): ActionReturnType => {
|
||||
console.log('>>> FINISH SYNC');
|
||||
}
|
||||
|
||||
loadAllChats({ listType: 'archived', shouldReplace: true });
|
||||
loadAllChats({ listType: 'saved', shouldReplace: true });
|
||||
loadAllChats({ listType: 'archived' });
|
||||
loadAllChats({ listType: 'saved' });
|
||||
preloadTopChatMessages();
|
||||
loadAllStories();
|
||||
loadAllHiddenStories();
|
||||
|
||||
@ -15,8 +15,6 @@ import {
|
||||
setGlobal,
|
||||
} from '../../index';
|
||||
import {
|
||||
addChats,
|
||||
addUsers,
|
||||
addUserStatuses,
|
||||
closeNewContactDialog,
|
||||
replaceUserStatuses,
|
||||
@ -113,10 +111,9 @@ addActionHandler('loadTopUsers', async (global): Promise<void> => {
|
||||
return;
|
||||
}
|
||||
|
||||
const { ids, users } = result;
|
||||
const { ids } = result;
|
||||
|
||||
global = getGlobal();
|
||||
global = addUsers(global, buildCollectionByKey(users, 'id'));
|
||||
global = {
|
||||
...global,
|
||||
topPeers: {
|
||||
@ -135,8 +132,6 @@ addActionHandler('loadContactList', async (global): Promise<void> => {
|
||||
}
|
||||
|
||||
global = getGlobal();
|
||||
global = addUsers(global, buildCollectionByKey(contactList.users, 'id'));
|
||||
global = addChats(global, buildCollectionByKey(contactList.chats, 'id'));
|
||||
global = addUserStatuses(global, contactList.userStatusesById);
|
||||
|
||||
// Sort contact list by Last Name (or First Name), with latin names being placed first
|
||||
@ -174,12 +169,9 @@ addActionHandler('loadCommonChats', async (global, actions, payload): Promise<vo
|
||||
return;
|
||||
}
|
||||
|
||||
const { chats, chatIds, isFullyLoaded } = result;
|
||||
const { chatIds, isFullyLoaded } = result;
|
||||
|
||||
global = getGlobal();
|
||||
if (chats.length) {
|
||||
global = addChats(global, buildCollectionByKey(chats, 'id'));
|
||||
}
|
||||
global = updateUser(global, user.id, {
|
||||
commonChats: {
|
||||
maxId: chatIds.length ? chatIds[chatIds.length - 1] : '0',
|
||||
@ -315,11 +307,9 @@ addActionHandler('loadMoreProfilePhotos', async (global, actions, payload): Prom
|
||||
global = getGlobal();
|
||||
|
||||
const {
|
||||
photos, users, count, nextOffsetId,
|
||||
photos, count, nextOffsetId,
|
||||
} = result;
|
||||
|
||||
global = addUsers(global, buildCollectionByKey(users, 'id'));
|
||||
|
||||
global = updatePeerPhotos(global, peerId, {
|
||||
newPhotos: photos,
|
||||
count,
|
||||
@ -349,12 +339,9 @@ addActionHandler('setUserSearchQuery', (global, actions, payload): ActionReturnT
|
||||
}
|
||||
|
||||
const {
|
||||
users, chats, accountResultIds, globalResultIds,
|
||||
accountResultIds, globalResultIds,
|
||||
} = result;
|
||||
|
||||
global = addUsers(global, buildCollectionByKey(users, 'id'));
|
||||
global = addChats(global, buildCollectionByKey(chats, 'id'));
|
||||
|
||||
const localUserIds = accountResultIds.filter(isUserId);
|
||||
const globalUserIds = globalResultIds.filter(isUserId);
|
||||
|
||||
|
||||
@ -8,13 +8,12 @@ import {
|
||||
joinPhoneCall, processSignalingMessage,
|
||||
} from '../../../lib/secret-sauce';
|
||||
import { getCurrentTabId } from '../../../util/establishMultitabRole';
|
||||
import { buildCollectionByKey, omit } from '../../../util/iteratees';
|
||||
import { omit } from '../../../util/iteratees';
|
||||
import * as langProvider from '../../../util/oldLangProvider';
|
||||
import { EMOJI_DATA, EMOJI_OFFSETS } from '../../../util/phoneCallEmojiConstants';
|
||||
import { ARE_CALLS_SUPPORTED } from '../../../util/windowEnvironment';
|
||||
import { callApi } from '../../../api/gramjs';
|
||||
import { addActionHandler, getGlobal, setGlobal } from '../../index';
|
||||
import { addUsers } from '../../reducers';
|
||||
import { updateGroupCall, updateGroupCallParticipant } from '../../reducers/calls';
|
||||
import { updateTabState } from '../../reducers/tabs';
|
||||
import { selectActiveGroupCall, selectGroupCallParticipant, selectPhoneCallUser } from '../../selectors/calls';
|
||||
@ -143,14 +142,9 @@ addActionHandler('apiUpdate', (global, actions, update): ActionReturnType => {
|
||||
};
|
||||
setGlobal(global);
|
||||
|
||||
const result = await callApi('confirmCall', {
|
||||
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) {
|
||||
|
||||
@ -45,7 +45,8 @@ const TYPING_STATUS_CLEAR_DELAY = 6000; // 6 seconds
|
||||
addActionHandler('apiUpdate', (global, actions, update): ActionReturnType => {
|
||||
switch (update['@type']) {
|
||||
case 'updateChat': {
|
||||
const { isForum: prevIsForum, lastReadOutboxMessageId } = selectChat(global, update.id) || {};
|
||||
const localChat = selectChat(global, update.id);
|
||||
const { isForum: prevIsForum, lastReadOutboxMessageId } = localChat || {};
|
||||
|
||||
if (update.chat.lastReadOutboxMessageId && lastReadOutboxMessageId
|
||||
&& update.chat.lastReadOutboxMessageId < lastReadOutboxMessageId) {
|
||||
@ -55,8 +56,6 @@ addActionHandler('apiUpdate', (global, actions, update): ActionReturnType => {
|
||||
};
|
||||
}
|
||||
|
||||
const localChat = selectChat(global, update.id);
|
||||
|
||||
global = updateChat(global, update.id, update.chat);
|
||||
|
||||
if (localChat?.areStoriesHidden !== update.chat.areStoriesHidden) {
|
||||
@ -65,8 +64,10 @@ addActionHandler('apiUpdate', (global, actions, update): ActionReturnType => {
|
||||
|
||||
setGlobal(global);
|
||||
|
||||
if (!update.noTopChatsRequest && !selectIsChatListed(global, update.id)) {
|
||||
// Chat can appear in dialogs list.
|
||||
const updatedChat = selectChat(global, update.id);
|
||||
if (!update.noTopChatsRequest && updatedChat && !selectIsChatListed(global, update.id)
|
||||
&& !updatedChat.isNotJoined) {
|
||||
// Reload top chats to update chat listing
|
||||
actions.loadTopChats();
|
||||
}
|
||||
|
||||
|
||||
@ -423,33 +423,31 @@ addActionHandler('apiUpdate', (global, actions, update): ActionReturnType => {
|
||||
break;
|
||||
}
|
||||
|
||||
case 'updateThreadInfos': {
|
||||
case 'updateThreadInfo': {
|
||||
const {
|
||||
threadInfoUpdates,
|
||||
threadInfo,
|
||||
} = update;
|
||||
|
||||
global = updateThreadInfos(global, threadInfoUpdates);
|
||||
threadInfoUpdates.forEach((threadInfo) => {
|
||||
const { chatId, threadId } = threadInfo;
|
||||
if (!chatId || !threadId) return;
|
||||
global = updateThreadInfos(global, [threadInfo]);
|
||||
const { chatId, threadId } = threadInfo;
|
||||
if (!chatId || !threadId) return;
|
||||
|
||||
const chat = selectChat(global, chatId);
|
||||
const currentThreadInfo = selectThreadInfo(global, chatId, threadId);
|
||||
if (chat?.isForum && threadInfo.lastReadInboxMessageId !== currentThreadInfo?.lastReadInboxMessageId) {
|
||||
actions.loadTopicById({ chatId, topicId: Number(threadId) });
|
||||
}
|
||||
const chat = selectChat(global, chatId);
|
||||
const currentThreadInfo = selectThreadInfo(global, chatId, threadId);
|
||||
if (chat?.isForum && threadInfo.lastReadInboxMessageId !== currentThreadInfo?.lastReadInboxMessageId) {
|
||||
actions.loadTopicById({ chatId, topicId: Number(threadId) });
|
||||
}
|
||||
|
||||
// Update reply thread last read message id if already read in main thread
|
||||
if (!chat?.isForum) {
|
||||
const lastReadInboxMessageId = chat?.lastReadInboxMessageId;
|
||||
const lastReadInboxMessageIdInThread = threadInfo.lastReadInboxMessageId || lastReadInboxMessageId;
|
||||
if (lastReadInboxMessageId && lastReadInboxMessageIdInThread) {
|
||||
global = updateThreadInfo(global, chatId, threadId, {
|
||||
lastReadInboxMessageId: Math.max(lastReadInboxMessageIdInThread, lastReadInboxMessageId),
|
||||
});
|
||||
}
|
||||
// Update reply thread last read message id if already read in main thread
|
||||
if (!chat?.isForum) {
|
||||
const lastReadInboxMessageId = chat?.lastReadInboxMessageId;
|
||||
const lastReadInboxMessageIdInThread = threadInfo.lastReadInboxMessageId || lastReadInboxMessageId;
|
||||
if (lastReadInboxMessageId && lastReadInboxMessageIdInThread) {
|
||||
global = updateThreadInfo(global, chatId, threadId, {
|
||||
lastReadInboxMessageId: Math.max(lastReadInboxMessageIdInThread, lastReadInboxMessageId),
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
setGlobal(global);
|
||||
|
||||
break;
|
||||
|
||||
@ -4,7 +4,9 @@ import { PaymentStep } from '../../../types';
|
||||
import { addActionHandler, setGlobal } from '../../index';
|
||||
import {
|
||||
addBlockedUser,
|
||||
addChats,
|
||||
addStoriesForPeer,
|
||||
addUsers,
|
||||
removeBlockedUser,
|
||||
removePeerStory,
|
||||
setConfirmPaymentUrl,
|
||||
@ -13,11 +15,21 @@ import {
|
||||
updatePeerStory,
|
||||
updatePeersWithStories,
|
||||
updateStealthMode,
|
||||
updateThreadInfos,
|
||||
} from '../../reducers';
|
||||
import { selectPeerStories, selectPeerStory } from '../../selectors';
|
||||
|
||||
addActionHandler('apiUpdate', (global, actions, update): ActionReturnType => {
|
||||
switch (update['@type']) {
|
||||
case 'updateEntities': {
|
||||
const { users, chats, threadInfos } = update;
|
||||
if (users) global = addUsers(global, users);
|
||||
if (chats) global = addChats(global, chats);
|
||||
if (threadInfos) global = updateThreadInfos(global, threadInfos);
|
||||
setGlobal(global);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'updatePeerBlocked':
|
||||
if (update.isBlocked) {
|
||||
return addBlockedUser(global, update.id);
|
||||
|
||||
@ -7,7 +7,7 @@ import type {
|
||||
import { requestNextMutation } from '../../../lib/fasterdom/fasterdom';
|
||||
import { copyTextToClipboard } from '../../../util/clipboard';
|
||||
import { getCurrentTabId } from '../../../util/establishMultitabRole';
|
||||
import { buildCollectionByKey, omit } from '../../../util/iteratees';
|
||||
import { omit } from '../../../util/iteratees';
|
||||
import * as langProvider from '../../../util/oldLangProvider';
|
||||
import safePlay from '../../../util/safePlay';
|
||||
import { ARE_CALLS_SUPPORTED } from '../../../util/windowEnvironment';
|
||||
@ -17,7 +17,6 @@ import {
|
||||
addActionHandler, getGlobal,
|
||||
setGlobal,
|
||||
} from '../../index';
|
||||
import { addChats, addUsers } from '../../reducers';
|
||||
import { updateGroupCall } from '../../reducers/calls';
|
||||
import { updateTabState } from '../../reducers/tabs';
|
||||
import {
|
||||
@ -107,31 +106,19 @@ async function fetchGroupCall<T extends GlobalState>(global: T, groupCall: Parti
|
||||
undefined,
|
||||
existingGroupCall?.isLoaded ? undefined : result.groupCall.participantsCount,
|
||||
);
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
global = addChats(global, buildCollectionByKey(result.chats, 'id'));
|
||||
|
||||
setGlobal(global);
|
||||
|
||||
return result.groupCall;
|
||||
}
|
||||
|
||||
async function fetchGroupCallParticipants<T extends GlobalState>(
|
||||
global: T,
|
||||
function requestGroupCallParticipants(
|
||||
groupCall: Partial<ApiGroupCall>, nextOffset?: string,
|
||||
) {
|
||||
const result = await callApi('fetchGroupCallParticipants', {
|
||||
return callApi('fetchGroupCallParticipants', {
|
||||
call: groupCall as ApiGroupCall,
|
||||
offset: nextOffset,
|
||||
});
|
||||
|
||||
if (!result) return;
|
||||
|
||||
global = getGlobal();
|
||||
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
global = addChats(global, buildCollectionByKey(result.chats, 'id'));
|
||||
|
||||
setGlobal(global);
|
||||
}
|
||||
|
||||
addActionHandler('toggleGroupCallPanel', (global, actions, payload): ActionReturnType => {
|
||||
@ -150,7 +137,7 @@ addActionHandler('subscribeToGroupCallUpdates', async (global, actions, payload)
|
||||
if (subscribed) {
|
||||
await fetchGroupCall(global, groupCall);
|
||||
global = getGlobal();
|
||||
await fetchGroupCallParticipants(global, groupCall);
|
||||
await requestGroupCallParticipants(groupCall);
|
||||
}
|
||||
|
||||
await callApi('toggleGroupCallStartSubscription', {
|
||||
@ -373,7 +360,7 @@ addActionHandler('loadMoreGroupCallParticipants', (global): ActionReturnType =>
|
||||
return;
|
||||
}
|
||||
|
||||
void fetchGroupCallParticipants(global, groupCall, groupCall.nextOffset);
|
||||
void requestGroupCallParticipants(groupCall, groupCall.nextOffset);
|
||||
});
|
||||
|
||||
addActionHandler('requestMasterAndRequestCall', (global, actions, payload): ActionReturnType => {
|
||||
|
||||
@ -2,11 +2,11 @@ import type { ActionReturnType } from '../../types';
|
||||
|
||||
import { copyTextToClipboard } from '../../../util/clipboard';
|
||||
import { getCurrentTabId } from '../../../util/establishMultitabRole';
|
||||
import { buildCollectionByKey, omit } from '../../../util/iteratees';
|
||||
import { omit } from '../../../util/iteratees';
|
||||
import * as langProvider from '../../../util/oldLangProvider';
|
||||
import { callApi } from '../../../api/gramjs';
|
||||
import { addActionHandler, getGlobal, setGlobal } from '../../index';
|
||||
import { addChats, addStoriesForPeer, addUsers } from '../../reducers';
|
||||
import { addStoriesForPeer } from '../../reducers';
|
||||
import { updateTabState } from '../../reducers/tabs';
|
||||
import {
|
||||
selectCurrentViewedStory,
|
||||
@ -39,8 +39,6 @@ addActionHandler('openStoryViewer', async (global, actions, payload): Promise<vo
|
||||
return;
|
||||
}
|
||||
global = getGlobal();
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
global = addChats(global, buildCollectionByKey(result.chats, 'id'));
|
||||
global = addStoriesForPeer(global, peerId, result.stories);
|
||||
}
|
||||
|
||||
|
||||
@ -576,15 +576,9 @@ export function updateThreadInfo<T extends GlobalState>(
|
||||
...update,
|
||||
} as ApiThreadInfo;
|
||||
|
||||
if (!doNotUpdateLinked) {
|
||||
if (!doNotUpdateLinked && !newThreadInfo.isCommentsInfo) {
|
||||
const linkedUpdate = pick(newThreadInfo, ['messagesCount', 'lastMessageId', 'lastReadInboxMessageId']);
|
||||
if (newThreadInfo.isCommentsInfo) {
|
||||
if (newThreadInfo.threadId) {
|
||||
global = updateThreadInfo(
|
||||
global, newThreadInfo.chatId, newThreadInfo.threadId, linkedUpdate, true,
|
||||
);
|
||||
}
|
||||
} else if (newThreadInfo.fromChannelId && newThreadInfo.fromMessageId) {
|
||||
if (newThreadInfo.fromChannelId && newThreadInfo.fromMessageId) {
|
||||
global = updateThreadInfo(
|
||||
global, newThreadInfo.fromChannelId, newThreadInfo.fromMessageId, linkedUpdate, true,
|
||||
);
|
||||
|
||||
@ -5,7 +5,7 @@ import type { GlobalState, TabArgs, TabState } from '../types';
|
||||
|
||||
import { areDeepEqual } from '../../util/areDeepEqual';
|
||||
import { getCurrentTabId } from '../../util/establishMultitabRole';
|
||||
import { omit, pick } from '../../util/iteratees';
|
||||
import { omit, unique } from '../../util/iteratees';
|
||||
import { MEMO_EMPTY_ARRAY } from '../../util/memo';
|
||||
import { selectTabState } from '../selectors';
|
||||
import { updateChat } from './chats';
|
||||
@ -26,19 +26,19 @@ function updateContactList<T extends GlobalState>(global: T, updatedUsers: ApiUs
|
||||
|
||||
if (!contactUserIds) return global;
|
||||
|
||||
const newContactUserIds = updatedUsers
|
||||
.filter((user) => user?.isContact && !contactUserIds.includes(user.id))
|
||||
const contactUserIdsFromUpdate = updatedUsers
|
||||
.filter((user) => user?.isContact)
|
||||
.map((user) => user.id);
|
||||
|
||||
if (newContactUserIds.length === 0) return global;
|
||||
if (contactUserIdsFromUpdate.length === 0) return global;
|
||||
|
||||
return {
|
||||
...global,
|
||||
contactList: {
|
||||
userIds: [
|
||||
...newContactUserIds,
|
||||
userIds: unique([
|
||||
...contactUserIdsFromUpdate,
|
||||
...contactUserIds,
|
||||
],
|
||||
]),
|
||||
},
|
||||
};
|
||||
}
|
||||
@ -244,14 +244,9 @@ export function updateUserFullInfo<T extends GlobalState>(
|
||||
export function addUserStatuses<T extends GlobalState>(global: T, newById: Record<string, ApiUserStatus>): T {
|
||||
const { statusesById } = global.users;
|
||||
|
||||
const newKeys = Object.keys(newById).filter((id) => !statusesById[id]);
|
||||
if (!newKeys.length) {
|
||||
return global;
|
||||
}
|
||||
|
||||
global = replaceUserStatuses(global, {
|
||||
...statusesById,
|
||||
...pick(newById, newKeys),
|
||||
...newById,
|
||||
});
|
||||
|
||||
return global;
|
||||
|
||||
@ -1437,8 +1437,7 @@ export interface ActionPayloads {
|
||||
preloadTopChatMessages: undefined;
|
||||
loadAllChats: {
|
||||
listType: ChatListType;
|
||||
onReplace?: VoidFunction;
|
||||
shouldReplace?: boolean;
|
||||
onFirstBatchDone?: VoidFunction;
|
||||
};
|
||||
openChatWithInfo: ActionPayloads['openChat'] & {
|
||||
profileTab?: ProfileTabType;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user