Update to layer 133 (#1525)
This commit is contained in:
parent
d4d11b7d4b
commit
1e60003f5a
@ -11,7 +11,7 @@
|
||||
"deploy:production": "npm run build:production && git add -A && git commit -a -m '[Build]' --no-verify && git push",
|
||||
"inc_version": "echo $((`cat .patch-version` + 1)) > .patch-version && echo \"$(node -p -e \"require('./package.json').version.match(/^\\d+\\.\\d+/)[0]\").$(cat .patch-version)\"",
|
||||
"perf:serve": "cross-env APP_ENV=perf parcel src/index-perf.html",
|
||||
"lint": "eslint . --ext .ts,.tsx --ignore-pattern src/lib/gramjs",
|
||||
"lint": "tsc && eslint . --ext .ts,.tsx --ignore-pattern src/lib/gramjs",
|
||||
"lint:fix": "npm run lint -- --fix",
|
||||
"gramjs:tl": "node ./src/lib/gramjs/tl/generateModules.js",
|
||||
"gramjs:lint:fix": "eslint ./src/lib/gramjs --ignore-path=src/lib/gramjs/.eslintignore --fix",
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import BigInt from 'big-integer';
|
||||
import { Api as GramJs } from '../../../lib/gramjs';
|
||||
import {
|
||||
ApiChat,
|
||||
@ -10,7 +11,7 @@ import {
|
||||
} from '../../types';
|
||||
import { pick, pickTruthy } from '../../../util/iteratees';
|
||||
import {
|
||||
isInputPeerChannel, isInputPeerChat, isInputPeerUser, isPeerChat, isPeerUser,
|
||||
buildApiPeerId, getApiChatIdFromMtpPeer, isPeerChat, isPeerUser,
|
||||
} from './peers';
|
||||
import { omitVirtualClassFields } from './helpers';
|
||||
import { getServerTime } from '../../../util/serverTime';
|
||||
@ -93,11 +94,13 @@ function buildApiChatPermissions(peerEntity: GramJs.TypeUser | GramJs.TypeChat):
|
||||
}
|
||||
|
||||
return {
|
||||
adminRights: omitVirtualClassFields(peerEntity.adminRights),
|
||||
currentUserBannedRights: peerEntity instanceof GramJs.Channel
|
||||
adminRights: peerEntity.adminRights ? omitVirtualClassFields(peerEntity.adminRights) : undefined,
|
||||
currentUserBannedRights: peerEntity instanceof GramJs.Channel && peerEntity.bannedRights
|
||||
? omitVirtualClassFields(peerEntity.bannedRights)
|
||||
: undefined,
|
||||
defaultBannedRights: omitVirtualClassFields(peerEntity.defaultBannedRights),
|
||||
defaultBannedRights: peerEntity.defaultBannedRights
|
||||
? omitVirtualClassFields(peerEntity.defaultBannedRights)
|
||||
: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
@ -146,7 +149,7 @@ function buildApiChatRestrictions(peerEntity: GramJs.TypeUser | GramJs.TypeChat)
|
||||
|
||||
function buildApiChatMigrationInfo(peerEntity: GramJs.TypeChat): {
|
||||
migratedTo?: {
|
||||
chatId: number;
|
||||
chatId: string;
|
||||
accessHash?: string;
|
||||
};
|
||||
} {
|
||||
@ -159,7 +162,7 @@ function buildApiChatMigrationInfo(peerEntity: GramJs.TypeChat): {
|
||||
migratedTo: {
|
||||
chatId: getApiChatIdFromMtpPeer(peerEntity.migratedTo),
|
||||
...(peerEntity.migratedTo instanceof GramJs.InputChannel && {
|
||||
accessHash: peerEntity.migratedTo.accessHash.toString(),
|
||||
accessHash: String(peerEntity.migratedTo.accessHash),
|
||||
}),
|
||||
},
|
||||
};
|
||||
@ -200,34 +203,13 @@ export function buildApiChatFromPreview(
|
||||
}
|
||||
|
||||
return {
|
||||
id: preview instanceof GramJs.User ? preview.id : -preview.id,
|
||||
id: buildApiPeerId(preview.id, preview instanceof GramJs.User ? 'user' : 'chat'),
|
||||
type: getApiChatTypeFromPeerEntity(preview),
|
||||
title: preview instanceof GramJs.User ? getUserName(preview) : preview.title,
|
||||
...buildApiChatFieldsFromPeerEntity(preview, isSupport),
|
||||
};
|
||||
}
|
||||
|
||||
export function getApiChatIdFromMtpPeer(peer: GramJs.TypePeer): number {
|
||||
if (isPeerUser(peer)) {
|
||||
return peer.userId;
|
||||
} else if (isPeerChat(peer)) {
|
||||
return -peer.chatId;
|
||||
} else {
|
||||
return -peer.channelId;
|
||||
}
|
||||
}
|
||||
|
||||
export function getApiChatIdFromInputMtpPeer(peer: GramJs.TypeInputPeer): number | undefined {
|
||||
if (isInputPeerUser(peer)) {
|
||||
return peer.userId;
|
||||
} else if (isInputPeerChat(peer)) {
|
||||
return -peer.chatId;
|
||||
} else if (isInputPeerChannel(peer)) {
|
||||
return -peer.channelId;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function getApiChatTypeFromPeerEntity(peerEntity: GramJs.TypeChat | GramJs.TypeUser) {
|
||||
if (peerEntity instanceof GramJs.User || peerEntity instanceof GramJs.UserEmpty) {
|
||||
return 'chatTypePrivate';
|
||||
@ -268,7 +250,7 @@ function getUserName(user: GramJs.User) {
|
||||
|
||||
export function buildAvatarHash(photo: GramJs.TypeUserProfilePhoto | GramJs.TypeChatPhoto) {
|
||||
if ('photoId' in photo) {
|
||||
return photo.photoId.toString();
|
||||
return String(photo.photoId);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
@ -279,14 +261,14 @@ export function buildChatMember(
|
||||
): ApiChatMember | undefined {
|
||||
const userId = (member instanceof GramJs.ChannelParticipantBanned || member instanceof GramJs.ChannelParticipantLeft)
|
||||
? getApiChatIdFromMtpPeer(member.peer)
|
||||
: member.userId;
|
||||
: buildApiPeerId(member.userId, 'user');
|
||||
|
||||
return {
|
||||
userId,
|
||||
inviterId: 'inviterId' in member ? member.inviterId : undefined,
|
||||
inviterId: 'inviterId' in member ? buildApiPeerId(member.inviterId as BigInt.BigInteger, 'user') : undefined,
|
||||
joinedDate: 'date' in member ? member.date : undefined,
|
||||
kickedByUserId: 'kickedBy' in member ? member.kickedBy : undefined,
|
||||
promotedByUserId: 'promotedBy' in member ? member.promotedBy : undefined,
|
||||
kickedByUserId: 'kickedBy' in member ? buildApiPeerId(member.kickedBy, 'user') : undefined,
|
||||
promotedByUserId: 'promotedBy' in member ? buildApiPeerId(member.promotedBy, 'user') : undefined,
|
||||
bannedRights: 'bannedRights' in member ? omitVirtualClassFields(member.bannedRights) : undefined,
|
||||
adminRights: 'adminRights' in member ? omitVirtualClassFields(member.adminRights) : undefined,
|
||||
customTitle: 'rank' in member ? member.rank : undefined,
|
||||
@ -362,9 +344,9 @@ export function buildApiChatFolder(filter: GramJs.DialogFilter): ApiChatFolder {
|
||||
'excludeMuted', 'excludeRead', 'excludeArchived',
|
||||
]),
|
||||
channels: filter.broadcasts,
|
||||
pinnedChatIds: filter.pinnedPeers.map(getApiChatIdFromInputMtpPeer).filter<number>(Boolean as any),
|
||||
includedChatIds: filter.includePeers.map(getApiChatIdFromInputMtpPeer).filter<number>(Boolean as any),
|
||||
excludedChatIds: filter.excludePeers.map(getApiChatIdFromInputMtpPeer).filter<number>(Boolean as any),
|
||||
pinnedChatIds: filter.pinnedPeers.map(getApiChatIdFromMtpPeer).filter<string>(Boolean as any),
|
||||
includedChatIds: filter.includePeers.map(getApiChatIdFromMtpPeer).filter<string>(Boolean as any),
|
||||
excludedChatIds: filter.excludePeers.map(getApiChatIdFromMtpPeer).filter<string>(Boolean as any),
|
||||
};
|
||||
}
|
||||
|
||||
@ -382,8 +364,10 @@ export function buildApiChatFolderFromSuggested({
|
||||
|
||||
export function buildApiChatBotCommands(botInfos: GramJs.BotInfo[]) {
|
||||
return botInfos.reduce((botCommands, botInfo) => {
|
||||
const botId = buildApiPeerId(botInfo.userId, 'user');
|
||||
|
||||
botCommands = botCommands.concat(botInfo.commands.map((mtpCommand) => ({
|
||||
botId: botInfo.userId,
|
||||
botId,
|
||||
...omitVirtualClassFields(mtpCommand),
|
||||
})));
|
||||
|
||||
|
||||
@ -1,20 +1,29 @@
|
||||
import { Api as GramJs } from '../../../lib/gramjs';
|
||||
|
||||
type VirtualFields =
|
||||
'flags'
|
||||
| 'CONSTRUCTOR_ID'
|
||||
| 'SUBCLASS_OF_ID'
|
||||
| 'className'
|
||||
| 'classType'
|
||||
| 'getBytes';
|
||||
|
||||
export function bytesToDataUri(bytes: Buffer, shouldOmitPrefix = false, mimeType: string = 'image/jpeg') {
|
||||
const prefix = shouldOmitPrefix ? '' : `data:${mimeType};base64,`;
|
||||
|
||||
return `${prefix}${btoa(String.fromCharCode(...bytes))}`;
|
||||
}
|
||||
|
||||
export function omitVirtualClassFields(instance: any) {
|
||||
if (!instance) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function omitVirtualClassFields<T extends GramJs.VirtualClass<T> & { flags?: any }>(
|
||||
instance: T,
|
||||
): Omit<T, VirtualFields> {
|
||||
const {
|
||||
flags,
|
||||
CONSTRUCTOR_ID,
|
||||
SUBCLASS_OF_ID,
|
||||
className,
|
||||
classType,
|
||||
getBytes,
|
||||
...rest
|
||||
} = instance;
|
||||
|
||||
|
||||
@ -32,21 +32,20 @@ import {
|
||||
VIDEO_MOV_TYPE,
|
||||
} from '../../../config';
|
||||
import { pick } from '../../../util/iteratees';
|
||||
import { getApiChatIdFromMtpPeer } from './chats';
|
||||
import { buildStickerFromDocument } from './symbols';
|
||||
import { buildApiPhoto, buildApiPhotoSize, buildApiThumbnailFromStripped } from './common';
|
||||
import { interpolateArray } from '../../../util/waveform';
|
||||
import { buildPeer } from '../gramjsBuilders';
|
||||
import { addPhotoToLocalDb, resolveMessageApiChatId } from '../helpers';
|
||||
import { buildApiPeerId, getApiChatIdFromMtpPeer } from './peers';
|
||||
|
||||
const LOCAL_IMAGE_UPLOADING_TEMP_ID = 'temp';
|
||||
const LOCAL_VIDEO_UPLOADING_TEMP_ID = 'temp';
|
||||
const LOCAL_MEDIA_UPLOADING_TEMP_ID = 'temp';
|
||||
const INPUT_WAVEFORM_LENGTH = 63;
|
||||
|
||||
let localMessageCounter = LOCAL_MESSAGE_ID_BASE;
|
||||
let currentUserId!: number;
|
||||
let currentUserId!: string;
|
||||
|
||||
export function setMessageBuilderCurrentUserId(_currentUserId: number) {
|
||||
export function setMessageBuilderCurrentUserId(_currentUserId: string) {
|
||||
currentUserId = _currentUserId;
|
||||
}
|
||||
|
||||
@ -62,20 +61,20 @@ export function buildApiMessage(mtpMessage: GramJs.TypeMessage): ApiMessage | un
|
||||
}
|
||||
|
||||
export function buildApiMessageFromShort(mtpMessage: GramJs.UpdateShortMessage): ApiMessage {
|
||||
const chatId = getApiChatIdFromMtpPeer({ userId: mtpMessage.userId } as GramJs.TypePeer);
|
||||
const chatId = buildApiPeerId(mtpMessage.userId, 'user');
|
||||
|
||||
return buildApiMessageWithChatId(chatId, {
|
||||
...mtpMessage,
|
||||
fromId: buildPeer(mtpMessage.out ? currentUserId : mtpMessage.userId),
|
||||
fromId: buildPeer(mtpMessage.out ? currentUserId : buildApiPeerId(mtpMessage.userId, 'user')),
|
||||
});
|
||||
}
|
||||
|
||||
export function buildApiMessageFromShortChat(mtpMessage: GramJs.UpdateShortChatMessage): ApiMessage {
|
||||
const chatId = getApiChatIdFromMtpPeer({ chatId: mtpMessage.chatId } as GramJs.TypePeer);
|
||||
const chatId = buildApiPeerId(mtpMessage.chatId, 'chat');
|
||||
|
||||
return buildApiMessageWithChatId(chatId, {
|
||||
...mtpMessage,
|
||||
fromId: buildPeer(mtpMessage.fromId),
|
||||
fromId: buildPeer(buildApiPeerId(mtpMessage.fromId, 'user')),
|
||||
});
|
||||
}
|
||||
|
||||
@ -117,7 +116,7 @@ type UniversalMessage = (
|
||||
)>
|
||||
);
|
||||
|
||||
export function buildApiMessageWithChatId(chatId: number, mtpMessage: UniversalMessage): ApiMessage {
|
||||
export function buildApiMessageWithChatId(chatId: string, mtpMessage: UniversalMessage): ApiMessage {
|
||||
const fromId = mtpMessage.fromId ? getApiChatIdFromMtpPeer(mtpMessage.fromId) : undefined;
|
||||
const peerId = mtpMessage.peerId ? getApiChatIdFromMtpPeer(mtpMessage.peerId) : undefined;
|
||||
const isChatWithSelf = !fromId && chatId === currentUserId;
|
||||
@ -151,7 +150,7 @@ export function buildApiMessageWithChatId(chatId: number, mtpMessage: UniversalM
|
||||
} = buildReplyButtons(mtpMessage) || {};
|
||||
const forwardInfo = mtpMessage.fwdFrom && buildApiMessageForwardInfo(mtpMessage.fwdFrom, isChatWithSelf);
|
||||
const { replies, mediaUnread: isMediaUnread, postAuthor } = mtpMessage;
|
||||
const groupedId = mtpMessage.groupedId && mtpMessage.groupedId.toString();
|
||||
const groupedId = mtpMessage.groupedId && String(mtpMessage.groupedId);
|
||||
const isInAlbum = Boolean(groupedId) && !(content.document || content.audio);
|
||||
const shouldHideKeyboardButtons = mtpMessage.replyMarkup instanceof GramJs.ReplyKeyboardHide;
|
||||
|
||||
@ -179,7 +178,7 @@ export function buildApiMessageWithChatId(chatId: number, mtpMessage: UniversalM
|
||||
inlineButtons,
|
||||
...(keyboardButtons && { keyboardButtons, keyboardPlaceholder, isKeyboardSingleUse }),
|
||||
...(shouldHideKeyboardButtons && { shouldHideKeyboardButtons }),
|
||||
...(mtpMessage.viaBotId && { viaBotId: mtpMessage.viaBotId }),
|
||||
...(mtpMessage.viaBotId && { viaBotId: buildApiPeerId(mtpMessage.viaBotId, 'user') }),
|
||||
...(replies?.comments && { threadInfo: buildThreadInfo(replies, mtpMessage.id, chatId) }),
|
||||
...(postAuthor && { adminTitle: postAuthor }),
|
||||
};
|
||||
@ -463,12 +462,13 @@ function buildContact(media: GramJs.TypeMessageMedia): ApiContact | undefined {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return pick(media, [
|
||||
'firstName',
|
||||
'lastName',
|
||||
'phoneNumber',
|
||||
'userId',
|
||||
]);
|
||||
const {
|
||||
firstName, lastName, phoneNumber, userId,
|
||||
} = media;
|
||||
|
||||
return {
|
||||
firstName, lastName, phoneNumber, userId: buildApiPeerId(userId, 'user'),
|
||||
};
|
||||
}
|
||||
|
||||
function buildPollFromMedia(media: GramJs.TypeMessageMedia): ApiPoll | undefined {
|
||||
@ -495,7 +495,7 @@ export function buildPoll(poll: GramJs.Poll, pollResults: GramJs.PollResults): A
|
||||
}));
|
||||
|
||||
return {
|
||||
id: id.toString(),
|
||||
id: String(id),
|
||||
summary: {
|
||||
isPublic: poll.publicVoters,
|
||||
...pick(poll, [
|
||||
@ -543,7 +543,7 @@ export function buildPollResults(pollResults: GramJs.PollResults): ApiPoll['resu
|
||||
|
||||
return {
|
||||
totalVoters,
|
||||
recentVoterIds: recentVoters,
|
||||
recentVoterIds: recentVoters?.map((id) => buildApiPeerId(id, 'user')),
|
||||
results,
|
||||
solution,
|
||||
...(entities && { solutionEntities: entities.map(buildApiMessageEntity) }),
|
||||
@ -584,8 +584,8 @@ export function buildWebPage(media: GramJs.TypeMessageMedia): ApiWebPage | undef
|
||||
|
||||
function buildAction(
|
||||
action: GramJs.TypeMessageAction,
|
||||
senderId: number | undefined,
|
||||
targetPeerId: number | undefined,
|
||||
senderId: string | undefined,
|
||||
targetPeerId: string | undefined,
|
||||
isChannelPost: boolean,
|
||||
isOutgoing: boolean,
|
||||
): ApiAction | undefined {
|
||||
@ -601,9 +601,9 @@ function buildAction(
|
||||
let photo: ApiPhoto | undefined;
|
||||
|
||||
const targetUserIds = 'users' in action
|
||||
? action.users && action.users
|
||||
: ('userId' in action && [action.userId]) || [];
|
||||
let targetChatId: number | undefined;
|
||||
? action.users && action.users.map((id) => buildApiPeerId(id, 'user'))
|
||||
: ('userId' in action && [buildApiPeerId(action.userId, 'user')]) || [];
|
||||
let targetChatId: string | undefined;
|
||||
|
||||
if (action instanceof GramJs.MessageActionChatCreate) {
|
||||
text = 'Notification.CreatedChatWithTitle';
|
||||
@ -908,7 +908,7 @@ function buildUploadingMedia(
|
||||
if (mimeType.startsWith('image/')) {
|
||||
return {
|
||||
photo: {
|
||||
id: LOCAL_IMAGE_UPLOADING_TEMP_ID,
|
||||
id: LOCAL_MEDIA_UPLOADING_TEMP_ID,
|
||||
sizes: [],
|
||||
thumbnail: { width, height, dataUri: '' }, // Used only for dimensions
|
||||
blobUrl,
|
||||
@ -917,7 +917,7 @@ function buildUploadingMedia(
|
||||
} else {
|
||||
return {
|
||||
video: {
|
||||
id: LOCAL_VIDEO_UPLOADING_TEMP_ID,
|
||||
id: LOCAL_MEDIA_UPLOADING_TEMP_ID,
|
||||
mimeType,
|
||||
duration: duration || 0,
|
||||
fileName,
|
||||
@ -962,7 +962,7 @@ function buildUploadingMedia(
|
||||
function buildNewPoll(poll: ApiNewPoll, localId: number) {
|
||||
return {
|
||||
poll: {
|
||||
id: localId.toString(),
|
||||
id: String(localId),
|
||||
summary: pick(poll.summary, ['question', 'answers']),
|
||||
results: {},
|
||||
},
|
||||
@ -981,22 +981,26 @@ function buildApiMessageEntity(entity: GramJs.TypeMessageEntity): ApiMessageEnti
|
||||
}
|
||||
|
||||
function buildThreadInfo(
|
||||
messageReplies: GramJs.TypeMessageReplies, messageId: number, chatId: number,
|
||||
messageReplies: GramJs.TypeMessageReplies, messageId: number, chatId: string,
|
||||
): ApiThreadInfo | undefined {
|
||||
const {
|
||||
channelId, replies, maxId, readMaxId, recentRepliers,
|
||||
} = messageReplies;
|
||||
|
||||
if (channelId === DELETED_COMMENTS_CHANNEL_ID) {
|
||||
if (!channelId) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const isPostThread = chatId !== channelId;
|
||||
const apiChannelId = buildApiPeerId(channelId, 'channel');
|
||||
if (apiChannelId === DELETED_COMMENTS_CHANNEL_ID) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const isPostThread = chatId !== apiChannelId;
|
||||
|
||||
return {
|
||||
threadId: messageId,
|
||||
...(isPostThread ? {
|
||||
chatId: getApiChatIdFromMtpPeer({ channelId } as GramJs.TypePeer),
|
||||
chatId: apiChannelId,
|
||||
originChannelId: chatId,
|
||||
} : {
|
||||
chatId,
|
||||
|
||||
@ -4,7 +4,7 @@ import { ApiCountry, ApiSession, ApiWallpaper } from '../../types';
|
||||
import { ApiPrivacySettings, ApiPrivacyKey, PrivacyVisibility } from '../../../types';
|
||||
|
||||
import { buildApiDocument } from './messages';
|
||||
import { getApiChatIdFromMtpPeer } from './chats';
|
||||
import { buildApiPeerId, getApiChatIdFromMtpPeer } from './peers';
|
||||
import { flatten, pick } from '../../../util/iteratees';
|
||||
import { getServerTime } from '../../../util/serverTime';
|
||||
|
||||
@ -60,10 +60,10 @@ export function buildPrivacyKey(key: GramJs.TypePrivacyKey): ApiPrivacyKey | und
|
||||
|
||||
export function buildPrivacyRules(rules: GramJs.TypePrivacyRule[]): ApiPrivacySettings {
|
||||
let visibility: PrivacyVisibility | undefined;
|
||||
let allowUserIds: number[] | undefined;
|
||||
let allowChatIds: number[] | undefined;
|
||||
let blockUserIds: number[] | undefined;
|
||||
let blockChatIds: number[] | undefined;
|
||||
let allowUserIds: string[] | undefined;
|
||||
let allowChatIds: string[] | undefined;
|
||||
let blockUserIds: string[] | undefined;
|
||||
let blockChatIds: string[] | undefined;
|
||||
|
||||
rules.forEach((rule) => {
|
||||
if (rule instanceof GramJs.PrivacyValueAllowAll) {
|
||||
@ -75,13 +75,13 @@ export function buildPrivacyRules(rules: GramJs.TypePrivacyRule[]): ApiPrivacySe
|
||||
} else if (rule instanceof GramJs.PrivacyValueDisallowAll) {
|
||||
visibility = visibility || 'nobody';
|
||||
} else if (rule instanceof GramJs.PrivacyValueAllowUsers) {
|
||||
allowUserIds = rule.users;
|
||||
allowUserIds = rule.users.map((chatId) => buildApiPeerId(chatId, 'user'));
|
||||
} else if (rule instanceof GramJs.PrivacyValueDisallowUsers) {
|
||||
blockUserIds = rule.users;
|
||||
blockUserIds = rule.users.map((chatId) => buildApiPeerId(chatId, 'user'));
|
||||
} else if (rule instanceof GramJs.PrivacyValueAllowChatParticipants) {
|
||||
allowChatIds = rule.chats.map((id) => -id);
|
||||
allowChatIds = rule.chats.map((chatId) => buildApiPeerId(chatId, 'chat'));
|
||||
} else if (rule instanceof GramJs.PrivacyValueDisallowChatParticipants) {
|
||||
blockChatIds = rule.chats.map((id) => -id);
|
||||
blockChatIds = rule.chats.map((chatId) => buildApiPeerId(chatId, 'chat'));
|
||||
}
|
||||
});
|
||||
|
||||
@ -113,6 +113,7 @@ export function buildApiNotifyException(
|
||||
...(showPreviews !== undefined && { shouldShowPreviews: Boolean(showPreviews) }),
|
||||
};
|
||||
}
|
||||
|
||||
function buildApiCountry(country: GramJs.help.Country, code?: GramJs.help.CountryCode) {
|
||||
const {
|
||||
hidden, iso2, defaultName, name,
|
||||
|
||||
@ -96,7 +96,7 @@ export function buildPaymentForm(form: GramJs.payments.PaymentForm) {
|
||||
canSaveCredentials,
|
||||
passwordMissing,
|
||||
formId: String(formId),
|
||||
providerId,
|
||||
providerId: String(providerId),
|
||||
nativeProvider,
|
||||
savedInfo,
|
||||
invoice: {
|
||||
|
||||
@ -1,25 +1,29 @@
|
||||
import BigInt from 'big-integer';
|
||||
|
||||
import { Api as GramJs } from '../../../lib/gramjs';
|
||||
|
||||
export function isPeerUser(peer: GramJs.TypePeer): peer is GramJs.PeerUser {
|
||||
export function isPeerUser(peer: GramJs.TypePeer | GramJs.TypeInputPeer): peer is GramJs.PeerUser {
|
||||
return peer.hasOwnProperty('userId');
|
||||
}
|
||||
|
||||
export function isPeerChat(peer: GramJs.TypePeer): peer is GramJs.PeerChat {
|
||||
export function isPeerChat(peer: GramJs.TypePeer | GramJs.TypeInputPeer): peer is GramJs.PeerChat {
|
||||
return peer.hasOwnProperty('chatId');
|
||||
}
|
||||
|
||||
export function isPeerChannel(peer: GramJs.TypePeer): peer is GramJs.PeerChannel {
|
||||
export function isPeerChannel(peer: GramJs.TypePeer | GramJs.TypeInputPeer): peer is GramJs.PeerChannel {
|
||||
return peer.hasOwnProperty('channelId');
|
||||
}
|
||||
|
||||
export function isInputPeerUser(peer: GramJs.TypeInputPeer): peer is GramJs.InputPeerUser {
|
||||
return peer.hasOwnProperty('userId');
|
||||
export function buildApiPeerId(id: BigInt.BigInteger, type: 'user' | 'chat' | 'channel') {
|
||||
return type === 'user' ? String(id) : `-${id}`;
|
||||
}
|
||||
|
||||
export function isInputPeerChat(peer: GramJs.TypeInputPeer): peer is GramJs.InputPeerChat {
|
||||
return peer.hasOwnProperty('chatId');
|
||||
}
|
||||
|
||||
export function isInputPeerChannel(peer: GramJs.TypeInputPeer): peer is GramJs.InputPeerChannel {
|
||||
return peer.hasOwnProperty('channelId');
|
||||
export function getApiChatIdFromMtpPeer(peer: GramJs.TypePeer | GramJs.TypeInputPeer) {
|
||||
if (isPeerUser(peer)) {
|
||||
return buildApiPeerId(peer.userId, 'user');
|
||||
} else if (isPeerChat(peer)) {
|
||||
return buildApiPeerId(peer.chatId, 'chat');
|
||||
} else {
|
||||
return buildApiPeerId((peer as GramJs.InputPeerChannel).channelId, 'channel');
|
||||
}
|
||||
}
|
||||
|
||||
@ -72,7 +72,6 @@ export function buildStickerSet(set: GramJs.StickerSet): ApiStickerSet {
|
||||
title,
|
||||
thumbs,
|
||||
count,
|
||||
hash,
|
||||
shortName,
|
||||
} = set;
|
||||
|
||||
@ -85,7 +84,6 @@ export function buildStickerSet(set: GramJs.StickerSet): ApiStickerSet {
|
||||
title,
|
||||
hasThumbnail: Boolean(thumbs?.length),
|
||||
count,
|
||||
hash,
|
||||
shortName,
|
||||
};
|
||||
}
|
||||
|
||||
@ -2,21 +2,24 @@ import { Api as GramJs } from '../../../lib/gramjs';
|
||||
import {
|
||||
ApiBotCommand, ApiUser, ApiUserStatus, ApiUserType,
|
||||
} from '../../types';
|
||||
import { buildApiPeerId } from './peers';
|
||||
|
||||
export function buildApiUserFromFull(mtpUserFull: GramJs.UserFull): ApiUser {
|
||||
const {
|
||||
about, commonChatsCount, pinnedMsgId, botInfo, blocked,
|
||||
} = mtpUserFull;
|
||||
|
||||
const user = buildApiUser(mtpUserFull.user)!;
|
||||
|
||||
return {
|
||||
...(buildApiUser(mtpUserFull.user) as ApiUser),
|
||||
...user,
|
||||
fullInfo: {
|
||||
bio: about,
|
||||
commonChatsCount,
|
||||
pinnedMessageId: pinnedMsgId,
|
||||
isBlocked: Boolean(blocked),
|
||||
...(botInfo && { botDescription: botInfo.description }),
|
||||
...(botInfo && botInfo.commands.length && { botCommands: buildApiBotCommands(mtpUserFull.user.id, botInfo) }),
|
||||
...(botInfo && botInfo.commands.length && { botCommands: buildApiBotCommands(user.id, botInfo) }),
|
||||
},
|
||||
};
|
||||
}
|
||||
@ -33,7 +36,7 @@ export function buildApiUser(mtpUser: GramJs.TypeUser): ApiUser | undefined {
|
||||
const userType = buildApiUserType(mtpUser);
|
||||
|
||||
return {
|
||||
id,
|
||||
id: buildApiPeerId(id, 'user'),
|
||||
isMin: Boolean(mtpUser.min),
|
||||
...(mtpUser.self && { isSelf: true }),
|
||||
...(mtpUser.verified && { isVerified: true }),
|
||||
@ -78,7 +81,7 @@ export function buildApiUserStatus(mtpStatus?: GramJs.TypeUserStatus): ApiUserSt
|
||||
}
|
||||
}
|
||||
|
||||
function buildApiBotCommands(botId: number, botInfo: GramJs.BotInfo) {
|
||||
function buildApiBotCommands(botId: string, botInfo: GramJs.BotInfo) {
|
||||
return botInfo.commands.map(({ command, description }) => ({
|
||||
botId,
|
||||
command,
|
||||
|
||||
@ -18,7 +18,24 @@ import {
|
||||
import localDb from '../localDb';
|
||||
import { pick } from '../../../util/iteratees';
|
||||
|
||||
export function getEntityTypeById(chatOrUserId: number) {
|
||||
const CHANNEL_ID_MIN_LENGTH = 11; // Example: -1000000000
|
||||
|
||||
export function getEntityTypeById(chatOrUserId: string) {
|
||||
if (typeof chatOrUserId === 'number') {
|
||||
return getEntityTypeByDeprecatedId(chatOrUserId);
|
||||
}
|
||||
|
||||
if (!chatOrUserId.startsWith('-')) {
|
||||
return 'user';
|
||||
} else if (chatOrUserId.length >= CHANNEL_ID_MIN_LENGTH) {
|
||||
return 'channel';
|
||||
} else {
|
||||
return 'chat';
|
||||
}
|
||||
}
|
||||
|
||||
// Workaround for old-fashioned IDs stored locally
|
||||
export function getEntityTypeByDeprecatedId(chatOrUserId: number) {
|
||||
if (chatOrUserId > 0) {
|
||||
return 'user';
|
||||
} else if (chatOrUserId <= -1000000000) {
|
||||
@ -28,81 +45,78 @@ export function getEntityTypeById(chatOrUserId: number) {
|
||||
}
|
||||
}
|
||||
|
||||
export function buildPeer(chatOrUserId: number): GramJs.TypePeer {
|
||||
if (chatOrUserId > 0) {
|
||||
export function buildPeer(chatOrUserId: string): GramJs.TypePeer {
|
||||
const type = getEntityTypeById(chatOrUserId);
|
||||
|
||||
if (type === 'user') {
|
||||
return new GramJs.PeerUser({
|
||||
userId: chatOrUserId,
|
||||
userId: buildMtpPeerId(chatOrUserId, 'user'),
|
||||
});
|
||||
} else if (chatOrUserId <= -1000000000) {
|
||||
} else if (type === 'channel') {
|
||||
return new GramJs.PeerChannel({
|
||||
channelId: -chatOrUserId,
|
||||
channelId: buildMtpPeerId(chatOrUserId, 'channel'),
|
||||
});
|
||||
} else {
|
||||
return new GramJs.PeerChat({
|
||||
chatId: -chatOrUserId,
|
||||
chatId: buildMtpPeerId(chatOrUserId, 'chat'),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function buildInputPeer(chatOrUserId: number, accessHash?: string): GramJs.TypeInputPeer {
|
||||
if (chatOrUserId > 0 || chatOrUserId <= -1000000000) {
|
||||
return chatOrUserId > 0
|
||||
? new GramJs.InputPeerUser({
|
||||
userId: chatOrUserId,
|
||||
accessHash: BigInt(accessHash!),
|
||||
})
|
||||
: new GramJs.InputPeerChannel({
|
||||
channelId: -chatOrUserId,
|
||||
accessHash: BigInt(accessHash!),
|
||||
});
|
||||
export function buildInputPeer(chatOrUserId: string, accessHash?: string): GramJs.TypeInputPeer {
|
||||
const type = getEntityTypeById(chatOrUserId);
|
||||
|
||||
if (type === 'user') {
|
||||
return new GramJs.InputPeerUser({
|
||||
userId: buildMtpPeerId(chatOrUserId, 'user'),
|
||||
accessHash: BigInt(accessHash!),
|
||||
});
|
||||
} else if (type === 'channel') {
|
||||
return new GramJs.InputPeerChannel({
|
||||
channelId: buildMtpPeerId(chatOrUserId, 'channel'),
|
||||
accessHash: BigInt(accessHash!),
|
||||
});
|
||||
} else {
|
||||
return new GramJs.InputPeerChat({
|
||||
chatId: -chatOrUserId,
|
||||
chatId: buildMtpPeerId(chatOrUserId, 'chat'),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function buildInputPeerFromLocalDb(chatOrUserId: number): GramJs.TypeInputPeer | undefined {
|
||||
if (chatOrUserId > 0) {
|
||||
const { accessHash } = localDb.users[chatOrUserId] || {};
|
||||
export function buildInputPeerFromLocalDb(chatOrUserId: string): GramJs.TypeInputPeer | undefined {
|
||||
const type = getEntityTypeById(chatOrUserId);
|
||||
let accessHash: BigInt.BigInteger | undefined;
|
||||
|
||||
return accessHash
|
||||
? new GramJs.InputPeerUser({
|
||||
userId: chatOrUserId,
|
||||
accessHash,
|
||||
})
|
||||
: undefined;
|
||||
if (type === 'user') {
|
||||
accessHash = localDb.users[chatOrUserId]?.accessHash;
|
||||
if (!accessHash) {
|
||||
return undefined;
|
||||
}
|
||||
} else if (type === 'channel') {
|
||||
accessHash = (localDb.chats[chatOrUserId] as GramJs.Channel)?.accessHash;
|
||||
if (!accessHash) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
if (chatOrUserId <= -1000000000) {
|
||||
const { accessHash } = (localDb.chats[-chatOrUserId] as GramJs.Channel) || {};
|
||||
|
||||
return accessHash
|
||||
? new GramJs.InputPeerChannel({
|
||||
channelId: -chatOrUserId,
|
||||
accessHash,
|
||||
})
|
||||
: undefined;
|
||||
}
|
||||
|
||||
return new GramJs.InputPeerChat({
|
||||
chatId: -chatOrUserId,
|
||||
});
|
||||
return buildInputPeer(chatOrUserId, String(accessHash));
|
||||
}
|
||||
|
||||
export function buildInputEntity(chatOrUserId: number, accessHash?: string) {
|
||||
if (chatOrUserId > 0) {
|
||||
export function buildInputEntity(chatOrUserId: string, accessHash?: string) {
|
||||
const type = getEntityTypeById(chatOrUserId);
|
||||
|
||||
if (type === 'user') {
|
||||
return new GramJs.InputUser({
|
||||
userId: chatOrUserId,
|
||||
userId: buildMtpPeerId(chatOrUserId, 'user'),
|
||||
accessHash: BigInt(accessHash!),
|
||||
});
|
||||
} else if (chatOrUserId <= -1000000000) {
|
||||
} else if (type === 'channel') {
|
||||
return new GramJs.InputChannel({
|
||||
channelId: -chatOrUserId,
|
||||
channelId: buildMtpPeerId(chatOrUserId, 'channel'),
|
||||
accessHash: BigInt(accessHash!),
|
||||
});
|
||||
} else {
|
||||
return -chatOrUserId;
|
||||
return buildMtpPeerId(chatOrUserId, 'chat');
|
||||
}
|
||||
}
|
||||
|
||||
@ -225,7 +239,7 @@ export function generateRandomBigInt() {
|
||||
|
||||
export function buildMessageFromUpdate(
|
||||
id: number,
|
||||
chatId: number,
|
||||
chatId: string,
|
||||
update: GramJs.UpdateShortSentMessage | GramJs.UpdateServiceNotification,
|
||||
) {
|
||||
// This is not a proper message, but we only need these fields for downloading media through `localDb`.
|
||||
@ -269,24 +283,13 @@ export function buildMtpMessageEntity(entity: ApiMessageEntity): GramJs.TypeMess
|
||||
return new GramJs.InputMessageEntityMentionName({
|
||||
offset,
|
||||
length,
|
||||
userId: new GramJs.InputUser({ userId: userId!, accessHash: user!.accessHash! }),
|
||||
userId: new GramJs.InputUser({ userId: BigInt(userId!), accessHash: user!.accessHash! }),
|
||||
});
|
||||
default:
|
||||
return new GramJs.MessageEntityUnknown({ offset, length });
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: This formula is taken from API docs, but doesn't seem to calculate hash correctly
|
||||
export function calculateResultHash(ids: number[]) {
|
||||
let hash = 0;
|
||||
ids.forEach((id) => {
|
||||
// eslint-disable-next-line no-bitwise
|
||||
hash = (((hash * 0x4F25) & 0x7FFFFFFF) + id) & 0x7FFFFFFF;
|
||||
});
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
export function isMessageWithMedia(message: GramJs.Message | GramJs.UpdateServiceNotification) {
|
||||
const { media } = message;
|
||||
if (!media) {
|
||||
@ -412,3 +415,12 @@ export function buildInputReportReason(reason: ApiReportReason) {
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function buildMtpPeerId(id: string, type: 'user' | 'chat' | 'channel') {
|
||||
// Workaround for old-fashioned IDs stored locally
|
||||
if (typeof id === 'number') {
|
||||
return BigInt(Math.abs(id));
|
||||
}
|
||||
|
||||
return type === 'user' ? BigInt(id) : BigInt(id.slice(1));
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { Api as GramJs } from '../../lib/gramjs';
|
||||
import localDb from './localDb';
|
||||
import { getApiChatIdFromMtpPeer } from './apiBuilders/chats';
|
||||
import { getApiChatIdFromMtpPeer } from './apiBuilders/peers';
|
||||
|
||||
export function resolveMessageApiChatId(mtpMessage: GramJs.TypeMessage) {
|
||||
if (!(mtpMessage instanceof GramJs.Message || mtpMessage instanceof GramJs.MessageService)) {
|
||||
|
||||
@ -4,8 +4,8 @@ import { ApiMessage } from '../types';
|
||||
interface LocalDb {
|
||||
localMessages: Record<string, ApiMessage>;
|
||||
// Used for loading avatars and media through in-memory Gram JS instances.
|
||||
chats: Record<number, GramJs.Chat | GramJs.Channel>;
|
||||
users: Record<number, GramJs.User>;
|
||||
chats: Record<string, GramJs.Chat | GramJs.Channel>;
|
||||
users: Record<string, GramJs.User>;
|
||||
messages: Record<string, GramJs.Message | GramJs.MessageService>;
|
||||
documents: Record<string, GramJs.Document>;
|
||||
stickerSets: Record<string, GramJs.StickerSet>;
|
||||
|
||||
@ -5,10 +5,11 @@ import { ApiChat, ApiUser } from '../../types';
|
||||
|
||||
import localDb from '../localDb';
|
||||
import { invokeRequest } from './client';
|
||||
import { buildInputPeer, calculateResultHash, generateRandomBigInt } from '../gramjsBuilders';
|
||||
import { buildInputPeer, generateRandomBigInt } from '../gramjsBuilders';
|
||||
import { buildApiUser } from '../apiBuilders/users';
|
||||
import { buildApiBotInlineMediaResult, buildApiBotInlineResult, buildBotSwitchPm } from '../apiBuilders/bots';
|
||||
import { buildApiChatFromPreview } from '../apiBuilders/chats';
|
||||
import { buildApiPeerId } from '../apiBuilders/peers';
|
||||
|
||||
export function init() {
|
||||
}
|
||||
@ -17,7 +18,7 @@ export function answerCallbackButton(
|
||||
{
|
||||
chatId, accessHash, messageId, data,
|
||||
}: {
|
||||
chatId: number; accessHash?: string; messageId: number; data: string;
|
||||
chatId: string; accessHash?: string; messageId: number; data: string;
|
||||
},
|
||||
) {
|
||||
return invokeRequest(new GramJs.messages.GetBotCallbackAnswer({
|
||||
@ -27,9 +28,8 @@ export function answerCallbackButton(
|
||||
}));
|
||||
}
|
||||
|
||||
export async function fetchTopInlineBots({ hash = 0 }: { hash?: number }) {
|
||||
export async function fetchTopInlineBots() {
|
||||
const topPeers = await invokeRequest(new GramJs.contacts.GetTopPeers({
|
||||
hash,
|
||||
botsInline: true,
|
||||
}));
|
||||
|
||||
@ -41,7 +41,6 @@ export async function fetchTopInlineBots({ hash = 0 }: { hash?: number }) {
|
||||
const ids = users.map(({ id }) => id);
|
||||
|
||||
return {
|
||||
hash: calculateResultHash(ids),
|
||||
ids,
|
||||
users,
|
||||
};
|
||||
@ -160,7 +159,7 @@ function getInlineBotResultsNextOffset(username: string, nextOffset?: string) {
|
||||
}
|
||||
|
||||
function addUserToLocalDb(user: GramJs.User) {
|
||||
localDb.users[user.id] = user;
|
||||
localDb.users[buildApiPeerId(user.id, 'user')] = user;
|
||||
}
|
||||
|
||||
function addDocumentToLocalDb(document: GramJs.Document) {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import BigInt from 'big-integer';
|
||||
import { Api as GramJs } from '../../../lib/gramjs';
|
||||
import {
|
||||
OnApiUpdate,
|
||||
@ -21,7 +22,6 @@ import {
|
||||
getPeerKey,
|
||||
buildChatMembers,
|
||||
buildApiChatFromPreview,
|
||||
getApiChatIdFromMtpPeer,
|
||||
buildApiChatFolder,
|
||||
buildApiChatFolderFromSuggested,
|
||||
buildApiChatBotCommands,
|
||||
@ -40,6 +40,7 @@ import {
|
||||
buildChatAdminRights,
|
||||
} from '../gramjsBuilders';
|
||||
import { addMessageToLocalDb } from '../helpers';
|
||||
import { buildApiPeerId, getApiChatIdFromMtpPeer } from '../apiBuilders/peers';
|
||||
|
||||
const MAX_INT_32 = 2 ** 31 - 1;
|
||||
let onUpdate: OnApiUpdate;
|
||||
@ -96,12 +97,12 @@ export async function fetchChats({
|
||||
...preparePeers(result),
|
||||
};
|
||||
const chats: ApiChat[] = [];
|
||||
const draftsById: Record<number, ApiFormattedText> = {};
|
||||
const replyingToById: Record<number, number> = {};
|
||||
const draftsById: Record<string, ApiFormattedText> = {};
|
||||
const replyingToById: Record<string, number> = {};
|
||||
|
||||
const dialogs = (resultPinned ? resultPinned.dialogs : []).concat(result.dialogs);
|
||||
|
||||
const orderedPinnedIds: number[] = [];
|
||||
const orderedPinnedIds: string[] = [];
|
||||
|
||||
dialogs.forEach((dialog) => {
|
||||
if (
|
||||
@ -325,12 +326,12 @@ export function clearDraft(chat: ApiChat) {
|
||||
}));
|
||||
}
|
||||
|
||||
async function getFullChatInfo(chatId: number): Promise<{
|
||||
async function getFullChatInfo(chatId: string): Promise<{
|
||||
fullInfo: ApiChatFullInfo;
|
||||
users?: ApiUser[];
|
||||
} | undefined> {
|
||||
const result = await invokeRequest(new GramJs.messages.GetFullChat({
|
||||
chatId: buildInputEntity(chatId) as number,
|
||||
chatId: buildInputEntity(chatId) as BigInt.BigInteger,
|
||||
}));
|
||||
|
||||
if (!result || !(result.fullChat instanceof GramJs.ChatFull)) {
|
||||
@ -366,7 +367,7 @@ async function getFullChatInfo(chatId: number): Promise<{
|
||||
}
|
||||
|
||||
async function getFullChannelInfo(
|
||||
id: number,
|
||||
id: string,
|
||||
accessHash: string,
|
||||
adminRights?: ApiChatAdminRights,
|
||||
) {
|
||||
@ -430,7 +431,7 @@ async function getFullChannelInfo(
|
||||
nextSendDate: slowmodeNextSendDate,
|
||||
} : undefined,
|
||||
migratedFrom: migratedFromChatId ? {
|
||||
chatId: getApiChatIdFromMtpPeer({ chatId: migratedFromChatId } as GramJs.TypePeer),
|
||||
chatId: buildApiPeerId(migratedFromChatId, 'chat'),
|
||||
maxMessageId: migratedFromMaxId,
|
||||
} : undefined,
|
||||
canViewMembers: canViewParticipants,
|
||||
@ -438,8 +439,8 @@ async function getFullChannelInfo(
|
||||
members,
|
||||
kickedMembers,
|
||||
adminMembers,
|
||||
groupCallId: call ? call.id.toString() : undefined,
|
||||
linkedChatId: linkedChatId ? getApiChatIdFromMtpPeer({ chatId: linkedChatId } as GramJs.TypePeer) : undefined,
|
||||
groupCallId: call ? String(call.id) : undefined,
|
||||
linkedChatId: linkedChatId ? buildApiPeerId(linkedChatId, 'chat') : undefined,
|
||||
botCommands,
|
||||
},
|
||||
users: [...(users || []), ...(bannedUsers || []), ...(adminUsers || [])],
|
||||
@ -515,7 +516,7 @@ export async function createChannel({
|
||||
export function joinChannel({
|
||||
channelId, accessHash,
|
||||
}: {
|
||||
channelId: number; accessHash: string;
|
||||
channelId: string; accessHash: string;
|
||||
}) {
|
||||
return invokeRequest(new GramJs.channels.JoinChannel({
|
||||
channel: buildInputEntity(channelId, accessHash) as GramJs.InputChannel,
|
||||
@ -529,7 +530,7 @@ export function deleteChatUser({
|
||||
}) {
|
||||
if (chat.type !== 'chatTypeBasicGroup') return undefined;
|
||||
return invokeRequest(new GramJs.messages.DeleteChatUser({
|
||||
chatId: buildInputEntity(chat.id, chat.accessHash) as number,
|
||||
chatId: buildInputEntity(chat.id, chat.accessHash) as BigInt.BigInteger,
|
||||
userId: buildInputEntity(user.id, user.accessHash) as GramJs.InputUser,
|
||||
}), true);
|
||||
}
|
||||
@ -537,17 +538,17 @@ export function deleteChatUser({
|
||||
export function deleteChat({
|
||||
chatId,
|
||||
}: {
|
||||
chatId: number;
|
||||
chatId: string;
|
||||
}) {
|
||||
return invokeRequest(new GramJs.messages.DeleteChat({
|
||||
chatId: buildInputEntity(chatId) as number,
|
||||
chatId: buildInputEntity(chatId) as BigInt.BigInteger,
|
||||
}), true);
|
||||
}
|
||||
|
||||
export function leaveChannel({
|
||||
channelId, accessHash,
|
||||
}: {
|
||||
channelId: number; accessHash: string;
|
||||
channelId: string; accessHash: string;
|
||||
}) {
|
||||
return invokeRequest(new GramJs.channels.LeaveChannel({
|
||||
channel: buildInputEntity(channelId, accessHash) as GramJs.InputChannel,
|
||||
@ -557,7 +558,7 @@ export function leaveChannel({
|
||||
export function deleteChannel({
|
||||
channelId, accessHash,
|
||||
}: {
|
||||
channelId: number; accessHash: string;
|
||||
channelId: string; accessHash: string;
|
||||
}) {
|
||||
return invokeRequest(new GramJs.channels.DeleteChannel({
|
||||
channel: buildInputEntity(channelId, accessHash) as GramJs.InputChannel,
|
||||
@ -600,7 +601,7 @@ export async function createGroupChat({
|
||||
export async function editChatPhoto({
|
||||
chatId, accessHash, photo,
|
||||
}: {
|
||||
chatId: number; accessHash?: string; photo: File;
|
||||
chatId: string; accessHash?: string; photo: File;
|
||||
}) {
|
||||
const uploadedPhoto = await uploadFile(photo);
|
||||
const inputEntity = buildInputEntity(chatId, accessHash);
|
||||
@ -614,7 +615,7 @@ export async function editChatPhoto({
|
||||
}),
|
||||
})
|
||||
: new GramJs.messages.EditChatPhoto({
|
||||
chatId: inputEntity as number,
|
||||
chatId: inputEntity as BigInt.BigInteger,
|
||||
photo: new GramJs.InputChatUploadedPhoto({
|
||||
file: uploadedPhoto,
|
||||
}),
|
||||
@ -837,7 +838,7 @@ export async function updateChatTitle(chat: ApiChat, title: string) {
|
||||
channel: inputEntity as GramJs.InputChannel,
|
||||
title,
|
||||
}) : new GramJs.messages.EditChatTitle({
|
||||
chatId: inputEntity as number,
|
||||
chatId: inputEntity as BigInt.BigInteger,
|
||||
title,
|
||||
}),
|
||||
true,
|
||||
@ -881,7 +882,7 @@ type ChannelMembersFilter =
|
||||
| 'recent';
|
||||
|
||||
export async function fetchMembers(
|
||||
chatId: number,
|
||||
chatId: string,
|
||||
accessHash: string,
|
||||
memberFilter: ChannelMembersFilter = 'recent',
|
||||
offset?: number,
|
||||
@ -946,7 +947,7 @@ export function setDiscussionGroup({
|
||||
|
||||
export async function migrateChat(chat: ApiChat) {
|
||||
const result = await invokeRequest(
|
||||
new GramJs.messages.MigrateChat({ chatId: buildInputEntity(chat.id) as number }), true,
|
||||
new GramJs.messages.MigrateChat({ chatId: buildInputEntity(chat.id) as BigInt.BigInteger }), true,
|
||||
);
|
||||
|
||||
// `migrateChat` can return a lot of different update types according to docs,
|
||||
@ -1014,7 +1015,7 @@ export function addChatMembers(chat: ApiChat, users: ApiUser[]) {
|
||||
|
||||
return Promise.all(users.map((user) => {
|
||||
return invokeRequest(new GramJs.messages.AddChatUser({
|
||||
chatId: buildInputEntity(chat.id) as number,
|
||||
chatId: buildInputEntity(chat.id) as BigInt.BigInteger,
|
||||
userId: buildInputEntity(user.id, user.accessHash) as GramJs.InputUser,
|
||||
}), true);
|
||||
}));
|
||||
@ -1043,7 +1044,7 @@ export function deleteChatMember(chat: ApiChat, user: ApiUser) {
|
||||
});
|
||||
} else {
|
||||
return invokeRequest(new GramJs.messages.DeleteChatUser({
|
||||
chatId: buildInputEntity(chat.id) as number,
|
||||
chatId: buildInputEntity(chat.id) as BigInt.BigInteger,
|
||||
userId: buildInputEntity(user.id, user.accessHash) as GramJs.InputUser,
|
||||
}), true);
|
||||
}
|
||||
@ -1074,7 +1075,7 @@ function updateLocalDb(result: (
|
||||
if ('users' in result) {
|
||||
result.users.forEach((user) => {
|
||||
if (user instanceof GramJs.User) {
|
||||
localDb.users[user.id] = user;
|
||||
localDb.users[buildApiPeerId(user.id, 'user')] = user;
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -1082,7 +1083,7 @@ function updateLocalDb(result: (
|
||||
if ('chats' in result) {
|
||||
result.chats.forEach((chat) => {
|
||||
if (chat instanceof GramJs.Chat || chat instanceof GramJs.Channel) {
|
||||
localDb.chats[chat.id] = chat;
|
||||
localDb.chats[buildApiPeerId(chat.id, chat instanceof GramJs.Chat ? 'chat' : 'channel')] = chat;
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -1102,7 +1103,5 @@ export async function importChatInvite({ hash }: { hash: string }) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const chat = buildApiChatFromPreview(updates.chats[0]);
|
||||
|
||||
return chat;
|
||||
return buildApiChatFromPreview(updates.chats[0]);
|
||||
}
|
||||
|
||||
@ -24,6 +24,7 @@ import { setMessageBuilderCurrentUserId } from '../apiBuilders/messages';
|
||||
import downloadMediaWithClient from './media';
|
||||
import { buildApiUserFromFull } from '../apiBuilders/users';
|
||||
import localDb from '../localDb';
|
||||
import { buildApiPeerId } from '../apiBuilders/peers';
|
||||
|
||||
const DEFAULT_USER_AGENT = 'Unknown UserAgent';
|
||||
const APP_CODE_NAME = 'Z';
|
||||
@ -254,7 +255,7 @@ export async function fetchCurrentUser() {
|
||||
return;
|
||||
}
|
||||
|
||||
localDb.users[userFull.user.id] = userFull.user;
|
||||
localDb.users[buildApiPeerId(userFull.user.id, 'user')] = userFull.user;
|
||||
const currentUser = buildApiUserFromFull(userFull);
|
||||
|
||||
setMessageBuilderCurrentUserId(currentUser.id);
|
||||
|
||||
@ -91,16 +91,16 @@ async function download(
|
||||
}
|
||||
|
||||
let entityType: EntityType;
|
||||
let entityId: string | number = mediaMatch[2];
|
||||
const entityId: string | number = mediaMatch[2];
|
||||
const sizeType = mediaMatch[3] ? mediaMatch[3].replace('?size=', '') : undefined;
|
||||
let entity: (
|
||||
GramJs.User | GramJs.Chat | GramJs.Channel | GramJs.Photo |
|
||||
GramJs.Message | GramJs.Document | GramJs.StickerSet | GramJs.TypeWebDocument | undefined
|
||||
GramJs.Message | GramJs.MessageService |
|
||||
GramJs.Document | GramJs.StickerSet | GramJs.TypeWebDocument | undefined
|
||||
);
|
||||
|
||||
if (mediaMatch[1] === 'avatar' || mediaMatch[1] === 'profile') {
|
||||
entityType = getEntityTypeById(Number(entityId));
|
||||
entityId = Math.abs(Number(entityId));
|
||||
entityType = getEntityTypeById(entityId);
|
||||
} else {
|
||||
entityType = mediaMatch[1] as 'msg' | 'sticker' | 'wallpaper' | 'gif' | 'stickerSet' | 'photo' | 'webDocument';
|
||||
}
|
||||
@ -108,27 +108,27 @@ async function download(
|
||||
switch (entityType) {
|
||||
case 'channel':
|
||||
case 'chat':
|
||||
entity = localDb.chats[entityId as number];
|
||||
entity = localDb.chats[entityId];
|
||||
break;
|
||||
case 'user':
|
||||
entity = localDb.users[entityId as number];
|
||||
entity = localDb.users[entityId];
|
||||
break;
|
||||
case 'msg':
|
||||
entity = localDb.messages[entityId as string];
|
||||
entity = localDb.messages[entityId];
|
||||
break;
|
||||
case 'sticker':
|
||||
case 'gif':
|
||||
case 'wallpaper':
|
||||
entity = localDb.documents[entityId as string];
|
||||
entity = localDb.documents[entityId];
|
||||
break;
|
||||
case 'photo':
|
||||
entity = localDb.photos[entityId as string];
|
||||
entity = localDb.photos[entityId];
|
||||
break;
|
||||
case 'stickerSet':
|
||||
entity = localDb.stickerSets[entityId as string];
|
||||
entity = localDb.stickerSets[entityId];
|
||||
break;
|
||||
case 'webDocument':
|
||||
entity = localDb.webDocuments[entityId as string];
|
||||
entity = localDb.webDocuments[entityId];
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@ -43,7 +43,6 @@ import {
|
||||
buildMtpMessageEntity,
|
||||
isMessageWithMedia,
|
||||
isServiceMessageWithMedia,
|
||||
calculateResultHash,
|
||||
buildInputReportReason,
|
||||
} from '../gramjsBuilders';
|
||||
import localDb from '../localDb';
|
||||
@ -52,6 +51,7 @@ import { fetchFile } from '../../../util/files';
|
||||
import { addMessageToLocalDb, resolveMessageApiChatId } from '../helpers';
|
||||
import { interpolateArray } from '../../../util/waveform';
|
||||
import { requestChatUpdate } from './chats';
|
||||
import { buildApiPeerId } from '../apiBuilders/peers';
|
||||
|
||||
const FAST_SEND_TIMEOUT = 1000;
|
||||
const INPUT_WAVEFORM_LENGTH = 63;
|
||||
@ -238,7 +238,7 @@ export function sendMessage(
|
||||
}, FAST_SEND_TIMEOUT);
|
||||
|
||||
const randomId = generateRandomBigInt();
|
||||
localDb.localMessages[randomId.toString()] = localMessage;
|
||||
localDb.localMessages[String(randomId)] = localMessage;
|
||||
|
||||
if (groupedId) {
|
||||
return sendGroupedMedia({
|
||||
@ -1078,12 +1078,11 @@ export async function findFirstMessageIdAfterDate({
|
||||
return result.messages[0].id;
|
||||
}
|
||||
|
||||
export async function fetchScheduledHistory({ chat, hash = 0 }: { chat: ApiChat; hash?: number }) {
|
||||
export async function fetchScheduledHistory({ chat }: { chat: ApiChat }) {
|
||||
const { id, accessHash } = chat;
|
||||
|
||||
const result = await invokeRequest(new GramJs.messages.GetScheduledHistory({
|
||||
peer: buildInputPeer(id, accessHash),
|
||||
hash,
|
||||
}));
|
||||
|
||||
if (
|
||||
@ -1100,7 +1099,6 @@ export async function fetchScheduledHistory({ chat, hash = 0 }: { chat: ApiChat;
|
||||
|
||||
return {
|
||||
messages,
|
||||
hash: calculateResultHash(messages.map((message) => message.id)),
|
||||
};
|
||||
}
|
||||
|
||||
@ -1119,13 +1117,13 @@ function updateLocalDb(result: (
|
||||
)) {
|
||||
result.users.forEach((user) => {
|
||||
if (user instanceof GramJs.User) {
|
||||
localDb.users[user.id] = user;
|
||||
localDb.users[buildApiPeerId(user.id, 'user')] = user;
|
||||
}
|
||||
});
|
||||
|
||||
result.chats.forEach((chat) => {
|
||||
if (chat instanceof GramJs.Chat || chat instanceof GramJs.Channel) {
|
||||
localDb.chats[chat.id] = chat;
|
||||
localDb.chats[buildApiPeerId(chat.id, chat instanceof GramJs.Chat ? 'chat' : 'channel')] = chat;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@ import { Api as GramJs } from '../../../lib/gramjs';
|
||||
import {
|
||||
ApiChat, ApiLangString, ApiLanguage, ApiNotifyException, ApiUser, ApiWallpaper,
|
||||
} from '../../types';
|
||||
import { ApiPrivacyKey, IInputPrivacyRules } from '../../../types';
|
||||
import { ApiPrivacyKey, InputPrivacyRules } from '../../../types';
|
||||
|
||||
import { BLOCKED_LIST_LIMIT, DEFAULT_LANG_PACK, LANG_PACKS } from '../../../config';
|
||||
import {
|
||||
@ -12,13 +12,14 @@ import {
|
||||
} from '../apiBuilders/misc';
|
||||
|
||||
import { buildApiUser } from '../apiBuilders/users';
|
||||
import { buildApiChatFromPreview, getApiChatIdFromMtpPeer } from '../apiBuilders/chats';
|
||||
import { buildInputPrivacyKey, buildInputPeer } from '../gramjsBuilders';
|
||||
import { buildApiChatFromPreview } from '../apiBuilders/chats';
|
||||
import { buildInputPrivacyKey, buildInputPeer, buildInputEntity } from '../gramjsBuilders';
|
||||
import { invokeRequest, uploadFile, getClient } from './client';
|
||||
import { omitVirtualClassFields } from '../apiBuilders/helpers';
|
||||
import { buildCollectionByKey } from '../../../util/iteratees';
|
||||
import localDb from '../localDb';
|
||||
import { getServerTime } from '../../../util/serverTime';
|
||||
import { buildApiPeerId, getApiChatIdFromMtpPeer } from '../apiBuilders/peers';
|
||||
|
||||
const MAX_INT_32 = 2 ** 31 - 1;
|
||||
const BETA_LANG_CODES = ['ar', 'fa', 'id', 'ko', 'uz'];
|
||||
@ -61,8 +62,8 @@ export async function uploadProfilePhoto(file: File) {
|
||||
}));
|
||||
}
|
||||
|
||||
export async function fetchWallpapers(hash: number) {
|
||||
const result = await invokeRequest(new GramJs.account.GetWallPapers({ hash }));
|
||||
export async function fetchWallpapers() {
|
||||
const result = await invokeRequest(new GramJs.account.GetWallPapers({ hash: BigInt('0') }));
|
||||
|
||||
if (!result || result instanceof GramJs.account.WallPapersNotModified) {
|
||||
return undefined;
|
||||
@ -84,7 +85,6 @@ export async function fetchWallpapers(hash: number) {
|
||||
});
|
||||
|
||||
return {
|
||||
hash: result.hash,
|
||||
wallpapers: filteredWallpapers.map(buildApiWallpaper).filter<ApiWallpaper>(Boolean as any),
|
||||
};
|
||||
}
|
||||
@ -130,13 +130,13 @@ export async function fetchBlockedContacts() {
|
||||
};
|
||||
}
|
||||
|
||||
export function blockContact(chatOrUserId: number, accessHash?: string) {
|
||||
export function blockContact(chatOrUserId: string, accessHash?: string) {
|
||||
return invokeRequest(new GramJs.contacts.Block({
|
||||
id: buildInputPeer(chatOrUserId, accessHash),
|
||||
}));
|
||||
}
|
||||
|
||||
export function unblockContact(chatOrUserId: number, accessHash?: string) {
|
||||
export function unblockContact(chatOrUserId: string, accessHash?: string) {
|
||||
return invokeRequest(new GramJs.contacts.Unblock({
|
||||
id: buildInputPeer(chatOrUserId, accessHash),
|
||||
}));
|
||||
@ -353,29 +353,29 @@ export function unregisterDevice(token: string) {
|
||||
}
|
||||
|
||||
export async function setPrivacySettings(
|
||||
privacyKey: ApiPrivacyKey, rules: IInputPrivacyRules,
|
||||
privacyKey: ApiPrivacyKey, rules: InputPrivacyRules,
|
||||
) {
|
||||
const key = buildInputPrivacyKey(privacyKey);
|
||||
const privacyRules: GramJs.TypeInputPrivacyRule[] = [];
|
||||
|
||||
if (rules.allowedUsers) {
|
||||
privacyRules.push(new GramJs.InputPrivacyValueAllowUsers({
|
||||
users: rules.allowedUsers.map(({ id, accessHash }) => buildInputPeer(id, accessHash)),
|
||||
users: rules.allowedUsers.map(({ id, accessHash }) => buildInputEntity(id, accessHash) as GramJs.InputUser),
|
||||
}));
|
||||
}
|
||||
if (rules.allowedChats) {
|
||||
privacyRules.push(new GramJs.InputPrivacyValueAllowChatParticipants({
|
||||
chats: rules.allowedChats.map(({ id }) => -id),
|
||||
chats: rules.allowedChats.map(({ id }) => buildInputEntity(id) as BigInt.BigInteger),
|
||||
}));
|
||||
}
|
||||
if (rules.blockedUsers) {
|
||||
privacyRules.push(new GramJs.InputPrivacyValueDisallowUsers({
|
||||
users: rules.blockedUsers.map(({ id, accessHash }) => buildInputPeer(id, accessHash)),
|
||||
users: rules.blockedUsers.map(({ id, accessHash }) => buildInputEntity(id, accessHash) as GramJs.InputUser),
|
||||
}));
|
||||
}
|
||||
if (rules.blockedChats) {
|
||||
privacyRules.push(new GramJs.InputPrivacyValueDisallowChatParticipants({
|
||||
chats: rules.blockedChats.map(({ id }) => -id),
|
||||
chats: rules.blockedChats.map(({ id }) => buildInputEntity(id) as BigInt.BigInteger),
|
||||
}));
|
||||
}
|
||||
switch (rules.visibility) {
|
||||
@ -437,13 +437,13 @@ function updateLocalDb(
|
||||
) {
|
||||
result.users.forEach((user) => {
|
||||
if (user instanceof GramJs.User) {
|
||||
localDb.users[user.id] = user;
|
||||
localDb.users[buildApiPeerId(user.id, 'user')] = user;
|
||||
}
|
||||
});
|
||||
|
||||
result.chats.forEach((chat) => {
|
||||
if (chat instanceof GramJs.Chat || chat instanceof GramJs.Channel) {
|
||||
localDb.chats[chat.id] = chat;
|
||||
localDb.chats[buildApiPeerId(chat.id, chat instanceof GramJs.Chat ? 'chat' : 'channel')] = chat;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import BigInt from 'big-integer';
|
||||
import { Api as GramJs } from '../../../lib/gramjs';
|
||||
import { ApiSticker, ApiVideo, OnApiUpdate } from '../../types';
|
||||
|
||||
@ -15,8 +16,8 @@ export function init(_onUpdate: OnApiUpdate) {
|
||||
onUpdate = _onUpdate;
|
||||
}
|
||||
|
||||
export async function fetchStickerSets({ hash }: { hash: number }) {
|
||||
const allStickers = await invokeRequest(new GramJs.messages.GetAllStickers({ hash }));
|
||||
export async function fetchStickerSets({ hash = '0' }: { hash?: string }) {
|
||||
const allStickers = await invokeRequest(new GramJs.messages.GetAllStickers({ hash: BigInt(hash) }));
|
||||
|
||||
if (!allStickers || allStickers instanceof GramJs.messages.AllStickersNotModified) {
|
||||
return undefined;
|
||||
@ -29,46 +30,46 @@ export async function fetchStickerSets({ hash }: { hash: number }) {
|
||||
});
|
||||
|
||||
return {
|
||||
hash: allStickers.hash,
|
||||
hash: String(allStickers.hash),
|
||||
sets: allStickers.sets.map(buildStickerSet),
|
||||
};
|
||||
}
|
||||
|
||||
export async function fetchRecentStickers({ hash }: { hash: number }) {
|
||||
const result = await invokeRequest(new GramJs.messages.GetRecentStickers({ hash }));
|
||||
export async function fetchRecentStickers({ hash = '0' }: { hash?: string }) {
|
||||
const result = await invokeRequest(new GramJs.messages.GetRecentStickers({ hash: BigInt(hash) }));
|
||||
|
||||
if (!result || result instanceof GramJs.messages.RecentStickersNotModified) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return {
|
||||
hash: result.hash,
|
||||
hash: String(result.hash),
|
||||
stickers: processStickerResult(result.stickers.slice(0, RECENT_STICKERS_LIMIT)),
|
||||
};
|
||||
}
|
||||
|
||||
export async function fetchFavoriteStickers({ hash }: { hash: number }) {
|
||||
const result = await invokeRequest(new GramJs.messages.GetFavedStickers({ hash }));
|
||||
export async function fetchFavoriteStickers({ hash = '0' }: { hash?: string }) {
|
||||
const result = await invokeRequest(new GramJs.messages.GetFavedStickers({ hash: BigInt(hash) }));
|
||||
|
||||
if (!result || result instanceof GramJs.messages.FavedStickersNotModified) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return {
|
||||
hash: result.hash,
|
||||
hash: String(result.hash),
|
||||
stickers: processStickerResult(result.stickers),
|
||||
};
|
||||
}
|
||||
|
||||
export async function fetchFeaturedStickers({ hash }: { hash: number }) {
|
||||
const result = await invokeRequest(new GramJs.messages.GetFeaturedStickers({ hash }));
|
||||
export async function fetchFeaturedStickers({ hash = '0' }: { hash?: string }) {
|
||||
const result = await invokeRequest(new GramJs.messages.GetFeaturedStickers({ hash: BigInt(hash) }));
|
||||
|
||||
if (!result || result instanceof GramJs.messages.FeaturedStickersNotModified) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return {
|
||||
hash: result.hash,
|
||||
hash: String(result.hash),
|
||||
sets: result.sets.map(buildStickerSetCovered),
|
||||
};
|
||||
}
|
||||
@ -93,8 +94,10 @@ export async function faveSticker({
|
||||
}
|
||||
}
|
||||
|
||||
export async function fetchStickers({ stickerSetShortName, stickerSetId, accessHash }:
|
||||
{ stickerSetShortName?: string; stickerSetId?: string; accessHash: string }) {
|
||||
export async function fetchStickers(
|
||||
{ stickerSetShortName, stickerSetId, accessHash }:
|
||||
{ stickerSetShortName?: string; stickerSetId?: string; accessHash: string },
|
||||
) {
|
||||
const result = await invokeRequest(new GramJs.messages.GetStickerSet({
|
||||
stickerset: stickerSetId
|
||||
? buildInputStickerSet(stickerSetId, accessHash)
|
||||
@ -127,10 +130,10 @@ export async function fetchAnimatedEmojis() {
|
||||
};
|
||||
}
|
||||
|
||||
export async function searchStickers({ query, hash }: { query: string; hash: number }) {
|
||||
export async function searchStickers({ query, hash = '0' }: { query: string; hash?: string }) {
|
||||
const result = await invokeRequest(new GramJs.messages.SearchStickerSets({
|
||||
q: query,
|
||||
hash,
|
||||
hash: BigInt(hash),
|
||||
}));
|
||||
|
||||
if (!result || result instanceof GramJs.messages.FoundStickerSetsNotModified) {
|
||||
@ -138,20 +141,20 @@ export async function searchStickers({ query, hash }: { query: string; hash: num
|
||||
}
|
||||
|
||||
return {
|
||||
hash: result.hash,
|
||||
hash: String(result.hash),
|
||||
sets: result.sets.map(buildStickerSetCovered),
|
||||
};
|
||||
}
|
||||
|
||||
export async function fetchSavedGifs({ hash }: { hash: number }) {
|
||||
const result = await invokeRequest(new GramJs.messages.GetSavedGifs({ hash }));
|
||||
export async function fetchSavedGifs({ hash = '0' }: { hash?: string }) {
|
||||
const result = await invokeRequest(new GramJs.messages.GetSavedGifs({ hash: BigInt(hash) }));
|
||||
|
||||
if (!result || result instanceof GramJs.messages.SavedGifsNotModified) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return {
|
||||
hash: result.hash,
|
||||
hash: String(result.hash),
|
||||
gifs: processGifResult(result.gifs),
|
||||
};
|
||||
}
|
||||
@ -233,11 +236,11 @@ export async function searchGifs({ query, offset = '' }: { query: string; offset
|
||||
}
|
||||
|
||||
export async function fetchStickersForEmoji({
|
||||
emoji, hash = 0,
|
||||
}: { emoji: string; hash?: number }) {
|
||||
emoji, hash = '0',
|
||||
}: { emoji: string; hash?: string }) {
|
||||
const result = await invokeRequest(new GramJs.messages.GetStickers({
|
||||
emoticon: emoji,
|
||||
hash,
|
||||
hash: BigInt(hash),
|
||||
}));
|
||||
|
||||
if (!result || result instanceof GramJs.messages.StickersNotModified) {
|
||||
@ -246,7 +249,7 @@ export async function fetchStickersForEmoji({
|
||||
|
||||
return {
|
||||
stickers: processStickerResult(result.stickers),
|
||||
hash: result.hash,
|
||||
hash: String(result.hash),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -10,7 +10,6 @@ import { invokeRequest } from './client';
|
||||
import { searchMessagesLocal } from './messages';
|
||||
import {
|
||||
buildInputEntity,
|
||||
calculateResultHash,
|
||||
buildInputPeer,
|
||||
buildInputContact,
|
||||
} from '../gramjsBuilders';
|
||||
@ -20,6 +19,7 @@ import { buildApiPhoto } from '../apiBuilders/common';
|
||||
import localDb from '../localDb';
|
||||
import { addPhotoToLocalDb } from '../helpers';
|
||||
import { buildApiCountryList } from '../apiBuilders/misc';
|
||||
import { buildApiPeerId } from '../apiBuilders/peers';
|
||||
|
||||
let onUpdate: OnApiUpdate;
|
||||
|
||||
@ -31,7 +31,7 @@ export async function fetchFullUser({
|
||||
id,
|
||||
accessHash,
|
||||
}: {
|
||||
id: number;
|
||||
id: string;
|
||||
accessHash?: string;
|
||||
}) {
|
||||
const input = buildInputEntity(id, accessHash);
|
||||
@ -73,9 +73,8 @@ export async function fetchCountryList({ langCode = 'en' }: { langCode?: LangCod
|
||||
return buildApiCountryList(countryList.countries);
|
||||
}
|
||||
|
||||
export async function fetchTopUsers({ hash = 0 }: { hash?: number }) {
|
||||
export async function fetchTopUsers() {
|
||||
const topPeers = await invokeRequest(new GramJs.contacts.GetTopPeers({
|
||||
hash,
|
||||
correspondents: true,
|
||||
}));
|
||||
if (!(topPeers instanceof GramJs.contacts.TopPeers)) {
|
||||
@ -86,29 +85,24 @@ export async function fetchTopUsers({ hash = 0 }: { hash?: number }) {
|
||||
const ids = users.map(({ id }) => id);
|
||||
|
||||
return {
|
||||
hash: calculateResultHash(ids),
|
||||
ids,
|
||||
users,
|
||||
};
|
||||
}
|
||||
|
||||
export async function fetchContactList({ hash = 0 }: { hash?: number }) {
|
||||
const result = await invokeRequest(new GramJs.contacts.GetContacts({ hash }));
|
||||
export async function fetchContactList() {
|
||||
const result = await invokeRequest(new GramJs.contacts.GetContacts({ hash: BigInt('0') }));
|
||||
if (!result || result instanceof GramJs.contacts.ContactsNotModified) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
result.users.forEach((user) => {
|
||||
if (user instanceof GramJs.User) {
|
||||
localDb.users[user.id] = user;
|
||||
localDb.users[buildApiPeerId(user.id, 'user')] = user;
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
hash: calculateResultHash([
|
||||
result.savedCount,
|
||||
...result.contacts.map(({ userId }) => userId),
|
||||
]),
|
||||
users: result.users.map(buildApiUser).filter<ApiUser>(Boolean as any),
|
||||
chats: result.users.map((user) => buildApiChatFromPreview(user)).filter<ApiChat>(Boolean as any),
|
||||
};
|
||||
@ -124,7 +118,7 @@ export async function fetchUsers({ users }: { users: ApiUser[] }) {
|
||||
|
||||
result.forEach((user) => {
|
||||
if (user instanceof GramJs.User) {
|
||||
localDb.users[user.id] = user;
|
||||
localDb.users[buildApiPeerId(user.id, 'user')] = user;
|
||||
}
|
||||
});
|
||||
|
||||
@ -156,7 +150,7 @@ export function addContact({
|
||||
firstName = '',
|
||||
lastName = '',
|
||||
}: {
|
||||
id: number;
|
||||
id: string;
|
||||
accessHash?: string;
|
||||
phoneNumber?: string;
|
||||
firstName?: string;
|
||||
@ -174,7 +168,7 @@ export async function deleteUser({
|
||||
id,
|
||||
accessHash,
|
||||
}: {
|
||||
id: number;
|
||||
id: string;
|
||||
accessHash?: string;
|
||||
}) {
|
||||
const input = buildInputEntity(id, accessHash);
|
||||
|
||||
@ -14,14 +14,12 @@ import {
|
||||
buildMessageDraft,
|
||||
} from './apiBuilders/messages';
|
||||
import {
|
||||
getApiChatIdFromMtpPeer,
|
||||
buildChatMember,
|
||||
buildChatMembers,
|
||||
buildChatTypingStatus,
|
||||
buildAvatarHash,
|
||||
buildApiChatFromPreview,
|
||||
buildApiChatFolder,
|
||||
getApiChatIdFromInputMtpPeer,
|
||||
} from './apiBuilders/chats';
|
||||
import { buildApiUser, buildApiUserStatus } from './apiBuilders/users';
|
||||
import {
|
||||
@ -35,6 +33,7 @@ import { DEBUG } from '../../config';
|
||||
import { addMessageToLocalDb, addPhotoToLocalDb, resolveMessageApiChatId } from './helpers';
|
||||
import { buildApiNotifyException, buildPrivacyKey, buildPrivacyRules } from './apiBuilders/misc';
|
||||
import { buildApiPhoto } from './apiBuilders/common';
|
||||
import { buildApiPeerId, getApiChatIdFromMtpPeer } from './apiBuilders/peers';
|
||||
|
||||
type Update = (
|
||||
(GramJs.TypeUpdate | GramJs.TypeUpdates) & { _entities?: (GramJs.TypeUser | GramJs.TypeChat)[] }
|
||||
@ -178,7 +177,7 @@ export function updater(update: Update, originRequest?: GramJs.AnyRequest) {
|
||||
const photo = buildChatPhotoForLocalDb(action.photo);
|
||||
const avatarHash = buildAvatarHash(photo);
|
||||
|
||||
const localDbChatId = Math.abs(resolveMessageApiChatId(update.message)!);
|
||||
const localDbChatId = resolveMessageApiChatId(update.message)!;
|
||||
if (localDb.chats[localDbChatId]) {
|
||||
localDb.chats[localDbChatId].photo = photo;
|
||||
}
|
||||
@ -195,7 +194,7 @@ export function updater(update: Update, originRequest?: GramJs.AnyRequest) {
|
||||
});
|
||||
}
|
||||
} else if (action instanceof GramJs.MessageActionChatDeletePhoto) {
|
||||
const localDbChatId = Math.abs(resolveMessageApiChatId(update.message)!);
|
||||
const localDbChatId = resolveMessageApiChatId(update.message)!;
|
||||
if (localDb.chats[localDbChatId]) {
|
||||
localDb.chats[localDbChatId].photo = new GramJs.ChatPhotoEmpty();
|
||||
}
|
||||
@ -270,10 +269,10 @@ export function updater(update: Update, originRequest?: GramJs.AnyRequest) {
|
||||
onUpdate({
|
||||
'@type': 'deleteScheduledMessages',
|
||||
ids: update.messages,
|
||||
chatId: getApiChatIdFromInputMtpPeer(update.peer),
|
||||
chatId: getApiChatIdFromMtpPeer(update.peer),
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdateDeleteChannelMessages) {
|
||||
const chatId = getApiChatIdFromMtpPeer({ channelId: update.channelId } as GramJs.PeerChannel);
|
||||
const chatId = buildApiPeerId(update.channelId, 'channel');
|
||||
const ids = update.messages;
|
||||
const existingIds = ids.filter((id) => localDb.messages[`${chatId}-${id}`]);
|
||||
const missingIds = ids.filter((id) => !localDb.messages[`${chatId}-${id}`]);
|
||||
@ -339,7 +338,7 @@ export function updater(update: Update, originRequest?: GramJs.AnyRequest) {
|
||||
randomId = originRequest.randomId;
|
||||
}
|
||||
|
||||
const localMessage = randomId && localDb.localMessages[randomId.toString()];
|
||||
const localMessage = randomId && localDb.localMessages[String(randomId)];
|
||||
if (!localMessage) {
|
||||
throw new Error('Local message not found');
|
||||
}
|
||||
@ -400,7 +399,7 @@ export function updater(update: Update, originRequest?: GramJs.AnyRequest) {
|
||||
} else if (update instanceof GramJs.UpdateChannelReadMessagesContents) {
|
||||
onUpdate({
|
||||
'@type': 'updateChannelMessages',
|
||||
channelId: update.channelId,
|
||||
channelId: buildApiPeerId(update.channelId, 'channel'),
|
||||
ids: update.messages,
|
||||
messageUpdate: {
|
||||
hasUnreadMention: false,
|
||||
@ -414,28 +413,28 @@ export function updater(update: Update, originRequest?: GramJs.AnyRequest) {
|
||||
|
||||
onUpdate({
|
||||
'@type': 'updateMessagePoll',
|
||||
pollId: pollId.toString(),
|
||||
pollId: String(pollId),
|
||||
pollUpdate: apiPoll,
|
||||
});
|
||||
} else {
|
||||
const pollResults = buildPollResults(results);
|
||||
onUpdate({
|
||||
'@type': 'updateMessagePoll',
|
||||
pollId: pollId.toString(),
|
||||
pollId: String(pollId),
|
||||
pollUpdate: { results: pollResults },
|
||||
});
|
||||
}
|
||||
} else if (update instanceof GramJs.UpdateMessagePollVote) {
|
||||
onUpdate({
|
||||
'@type': 'updateMessagePollVote',
|
||||
pollId: update.pollId.toString(),
|
||||
userId: update.userId,
|
||||
pollId: String(update.pollId),
|
||||
userId: buildApiPeerId(update.userId, 'user'),
|
||||
options: update.options.map((option) => String.fromCharCode(...option)),
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdateChannelMessageViews) {
|
||||
onUpdate({
|
||||
'@type': 'updateMessage',
|
||||
chatId: getApiChatIdFromMtpPeer({ channelId: update.channelId } as GramJs.PeerChannel),
|
||||
chatId: buildApiPeerId(update.channelId, 'channel'),
|
||||
id: update.id,
|
||||
message: { views: update.views },
|
||||
});
|
||||
@ -461,7 +460,7 @@ export function updater(update: Update, originRequest?: GramJs.AnyRequest) {
|
||||
} else if (update instanceof GramJs.UpdateReadChannelInbox) {
|
||||
onUpdate({
|
||||
'@type': 'updateChat',
|
||||
id: getApiChatIdFromMtpPeer({ channelId: update.channelId } as GramJs.PeerChannel),
|
||||
id: buildApiPeerId(update.channelId, 'channel'),
|
||||
chat: {
|
||||
lastReadInboxMessageId: update.maxId,
|
||||
unreadCount: update.stillUnreadCount,
|
||||
@ -470,7 +469,7 @@ export function updater(update: Update, originRequest?: GramJs.AnyRequest) {
|
||||
} else if (update instanceof GramJs.UpdateReadChannelOutbox) {
|
||||
onUpdate({
|
||||
'@type': 'updateChat',
|
||||
id: getApiChatIdFromMtpPeer({ channelId: update.channelId } as GramJs.PeerChannel),
|
||||
id: buildApiPeerId(update.channelId, 'channel'),
|
||||
chat: {
|
||||
lastReadOutboxMessageId: update.maxId,
|
||||
},
|
||||
@ -525,7 +524,7 @@ export function updater(update: Update, originRequest?: GramJs.AnyRequest) {
|
||||
|
||||
onUpdate({
|
||||
'@type': 'updateChatMembers',
|
||||
id: getApiChatIdFromMtpPeer({ chatId: update.participants.chatId } as GramJs.TypePeer),
|
||||
id: buildApiPeerId(update.participants.chatId, 'chat'),
|
||||
replacedMembers,
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdateChatParticipantAdd) {
|
||||
@ -535,25 +534,22 @@ export function updater(update: Update, originRequest?: GramJs.AnyRequest) {
|
||||
|
||||
onUpdate({
|
||||
'@type': 'updateChatMembers',
|
||||
id: getApiChatIdFromMtpPeer({ chatId: update.chatId } as GramJs.PeerChat),
|
||||
id: buildApiPeerId(update.chatId, 'chat'),
|
||||
addedMember,
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdateChatParticipantDelete) {
|
||||
const { userId: deletedMemberId } = update;
|
||||
|
||||
onUpdate({
|
||||
'@type': 'updateChatMembers',
|
||||
id: getApiChatIdFromMtpPeer({ chatId: update.chatId } as GramJs.PeerChat),
|
||||
deletedMemberId,
|
||||
id: buildApiPeerId(update.chatId, 'chat'),
|
||||
deletedMemberId: buildApiPeerId(update.userId, 'user'),
|
||||
});
|
||||
} else if (
|
||||
update instanceof GramJs.UpdatePinnedMessages
|
||||
|| update instanceof GramJs.UpdatePinnedChannelMessages
|
||||
) {
|
||||
const peer = update instanceof GramJs.UpdatePinnedMessages
|
||||
? update.peer
|
||||
: { channelId: update.channelId } as GramJs.PeerChannel;
|
||||
const chatId = getApiChatIdFromMtpPeer(peer);
|
||||
const chatId = update instanceof GramJs.UpdatePinnedMessages
|
||||
? getApiChatIdFromMtpPeer(update.peer)
|
||||
: buildApiPeerId(update.channelId, 'channel');
|
||||
|
||||
onUpdate({
|
||||
'@type': 'updatePinnedIds',
|
||||
@ -574,8 +570,8 @@ export function updater(update: Update, originRequest?: GramJs.AnyRequest) {
|
||||
|| update instanceof GramJs.UpdateChatUserTyping
|
||||
) {
|
||||
const id = update instanceof GramJs.UpdateUserTyping
|
||||
? update.userId
|
||||
: getApiChatIdFromMtpPeer({ chatId: update.chatId } as GramJs.PeerChat);
|
||||
? buildApiPeerId(update.userId, 'user')
|
||||
: buildApiPeerId(update.chatId, 'chat');
|
||||
|
||||
onUpdate({
|
||||
'@type': 'updateChatTypingStatus',
|
||||
@ -583,7 +579,7 @@ export function updater(update: Update, originRequest?: GramJs.AnyRequest) {
|
||||
typingStatus: buildChatTypingStatus(update, serverTimeOffset),
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdateChannelUserTyping) {
|
||||
const id = getApiChatIdFromMtpPeer({ channelId: update.channelId } as GramJs.PeerChannel);
|
||||
const id = buildApiPeerId(update.channelId, 'channel');
|
||||
|
||||
onUpdate({
|
||||
'@type': 'updateChatTypingStatus',
|
||||
@ -612,11 +608,11 @@ export function updater(update: Update, originRequest?: GramJs.AnyRequest) {
|
||||
|
||||
onUpdate({
|
||||
'@type': chat.isNotJoined ? 'updateChatLeave' : 'updateChatJoin',
|
||||
id: getApiChatIdFromMtpPeer({ channelId: update.channelId } as GramJs.PeerChannel),
|
||||
id: buildApiPeerId(update.channelId, 'channel'),
|
||||
});
|
||||
}
|
||||
} else if (channel instanceof GramJs.ChannelForbidden) {
|
||||
const chatId = getApiChatIdFromMtpPeer({ channelId: update.channelId } as GramJs.PeerChannel);
|
||||
const chatId = buildApiPeerId(update.channelId, 'channel');
|
||||
|
||||
onUpdate({
|
||||
'@type': 'updateChat',
|
||||
@ -635,7 +631,7 @@ export function updater(update: Update, originRequest?: GramJs.AnyRequest) {
|
||||
// No corresponding update available at this moment https://core.telegram.org/type/Updates
|
||||
onUpdate({
|
||||
'@type': 'resetMessages',
|
||||
id: getApiChatIdFromMtpPeer({ chatId: update.channelId } as GramJs.PeerChat),
|
||||
id: buildApiPeerId(update.channelId, 'channel'),
|
||||
});
|
||||
}
|
||||
} else if (
|
||||
@ -660,35 +656,35 @@ export function updater(update: Update, originRequest?: GramJs.AnyRequest) {
|
||||
|
||||
// Users
|
||||
} else if (update instanceof GramJs.UpdateUserStatus) {
|
||||
const { userId, status } = update;
|
||||
|
||||
onUpdate({
|
||||
'@type': 'updateUserStatus',
|
||||
userId,
|
||||
status: buildApiUserStatus(status),
|
||||
userId: buildApiPeerId(update.userId, 'user'),
|
||||
status: buildApiUserStatus(update.status),
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdateUserName) {
|
||||
const updatedUser = localDb.users[update.userId];
|
||||
const apiUserId = buildApiPeerId(update.userId, 'user');
|
||||
const updatedUser = localDb.users[apiUserId];
|
||||
const user = updatedUser?.mutualContact && !updatedUser.self
|
||||
? pick(update, ['username'])
|
||||
: pick(update, ['firstName', 'lastName', 'username']);
|
||||
|
||||
onUpdate({
|
||||
'@type': 'updateUser',
|
||||
id: update.userId,
|
||||
id: apiUserId,
|
||||
user,
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdateUserPhoto) {
|
||||
const { userId, photo } = update;
|
||||
const apiUserId = buildApiPeerId(userId, 'user');
|
||||
const avatarHash = buildAvatarHash(photo);
|
||||
|
||||
if (localDb.users[userId]) {
|
||||
localDb.users[userId].photo = photo;
|
||||
if (localDb.users[apiUserId]) {
|
||||
localDb.users[apiUserId].photo = photo;
|
||||
}
|
||||
|
||||
onUpdate({
|
||||
'@type': 'updateUser',
|
||||
id: userId,
|
||||
id: apiUserId,
|
||||
user: { avatarHash },
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdateUserPhone) {
|
||||
@ -696,7 +692,7 @@ export function updater(update: Update, originRequest?: GramJs.AnyRequest) {
|
||||
|
||||
onUpdate({
|
||||
'@type': 'updateUser',
|
||||
id: userId,
|
||||
id: buildApiPeerId(userId, 'user'),
|
||||
user: { phoneNumber: phone },
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdatePeerSettings) {
|
||||
@ -712,7 +708,7 @@ export function updater(update: Update, originRequest?: GramJs.AnyRequest) {
|
||||
.forEach((user) => {
|
||||
onUpdate({
|
||||
'@type': 'deleteUser',
|
||||
id: user.id,
|
||||
id: buildApiPeerId(user.id, 'user'),
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@ -40,7 +40,7 @@ export interface ApiBotInlineSwitchPm {
|
||||
}
|
||||
|
||||
export interface ApiBotCommand {
|
||||
botId: number;
|
||||
botId: string;
|
||||
command: string;
|
||||
description: string;
|
||||
}
|
||||
|
||||
@ -8,7 +8,7 @@ type ApiChatType = (
|
||||
);
|
||||
|
||||
export interface ApiChat {
|
||||
id: number;
|
||||
id: string;
|
||||
folderId?: number;
|
||||
type: ApiChatType;
|
||||
title?: string;
|
||||
@ -47,7 +47,7 @@ export interface ApiChat {
|
||||
defaultBannedRights?: ApiChatBannedRights;
|
||||
|
||||
migratedTo?: {
|
||||
chatId: number;
|
||||
chatId: string;
|
||||
accessHash?: string;
|
||||
};
|
||||
|
||||
@ -58,26 +58,11 @@ export interface ApiChat {
|
||||
}
|
||||
|
||||
export interface ApiTypingStatus {
|
||||
userId?: number;
|
||||
userId?: string;
|
||||
action: string;
|
||||
timestamp: number;
|
||||
}
|
||||
|
||||
export interface ApiTypeGroupCall {
|
||||
joinMuted?: true;
|
||||
canChangeJoinMuted?: true;
|
||||
joinDateAsc?: true;
|
||||
scheduleStartSubscribed?: true;
|
||||
id: number;
|
||||
participantsCount: number;
|
||||
params?: any;
|
||||
title?: string;
|
||||
streamDcId?: number;
|
||||
recordStartDate?: number;
|
||||
scheduleDate?: number;
|
||||
version: number;
|
||||
}
|
||||
|
||||
export interface ApiChatFullInfo {
|
||||
about?: string;
|
||||
onlineCount?: number;
|
||||
@ -93,19 +78,19 @@ export interface ApiChatFullInfo {
|
||||
nextSendDate?: number;
|
||||
};
|
||||
migratedFrom?: {
|
||||
chatId: number;
|
||||
chatId: string;
|
||||
maxMessageId?: number;
|
||||
};
|
||||
linkedChatId?: number;
|
||||
linkedChatId?: string;
|
||||
botCommands?: ApiBotCommand[];
|
||||
}
|
||||
|
||||
export interface ApiChatMember {
|
||||
userId: number;
|
||||
inviterId?: number;
|
||||
userId: string;
|
||||
inviterId?: string;
|
||||
joinedDate?: number;
|
||||
kickedByUserId?: number;
|
||||
promotedByUserId?: number;
|
||||
kickedByUserId?: string;
|
||||
promotedByUserId?: string;
|
||||
bannedRights?: ApiChatBannedRights;
|
||||
adminRights?: ApiChatAdminRights;
|
||||
customTitle?: string;
|
||||
@ -159,7 +144,7 @@ export interface ApiChatFolder {
|
||||
excludeMuted?: true;
|
||||
excludeRead?: true;
|
||||
excludeArchived?: true;
|
||||
pinnedChatIds?: number[];
|
||||
includedChatIds: number[];
|
||||
excludedChatIds: number[];
|
||||
pinnedChatIds?: string[];
|
||||
includedChatIds: string[];
|
||||
excludedChatIds: string[];
|
||||
}
|
||||
|
||||
@ -39,7 +39,6 @@ export interface ApiStickerSet {
|
||||
title: string;
|
||||
hasThumbnail?: boolean;
|
||||
count: number;
|
||||
hash: number;
|
||||
stickers?: ApiSticker[];
|
||||
packs?: Record<string, ApiSticker[]>;
|
||||
covers?: ApiSticker[];
|
||||
@ -92,7 +91,7 @@ export interface ApiContact {
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
phoneNumber: string;
|
||||
userId: number;
|
||||
userId: string;
|
||||
}
|
||||
|
||||
export interface ApiPollAnswer {
|
||||
@ -122,7 +121,7 @@ export interface ApiPoll {
|
||||
results: {
|
||||
results?: ApiPollResult[];
|
||||
totalVoters?: number;
|
||||
recentVoterIds?: number[];
|
||||
recentVoterIds?: string[];
|
||||
solution?: string;
|
||||
solutionEntities?: ApiMessageEntity[];
|
||||
};
|
||||
@ -149,8 +148,8 @@ export type ApiNewPoll = {
|
||||
|
||||
export interface ApiAction {
|
||||
text: string;
|
||||
targetUserIds?: number[];
|
||||
targetChatId?: number;
|
||||
targetUserIds?: string[];
|
||||
targetChatId?: string;
|
||||
type: 'historyClear' | 'contactSignUp' | 'chatCreate' | 'other';
|
||||
photo?: ApiPhoto;
|
||||
amount?: number;
|
||||
@ -176,8 +175,8 @@ export interface ApiMessageForwardInfo {
|
||||
isChannelPost: boolean;
|
||||
channelPostId?: number;
|
||||
isLinkedChannelPost?: boolean;
|
||||
fromChatId?: number;
|
||||
senderUserId?: number;
|
||||
fromChatId?: string;
|
||||
senderUserId?: string;
|
||||
fromMessageId?: number;
|
||||
hiddenUserName?: string;
|
||||
adminTitle?: string;
|
||||
@ -187,7 +186,7 @@ export interface ApiMessageEntity {
|
||||
type: string;
|
||||
offset: number;
|
||||
length: number;
|
||||
userId?: number;
|
||||
userId?: string;
|
||||
url?: string;
|
||||
}
|
||||
|
||||
@ -218,7 +217,7 @@ export interface ApiFormattedText {
|
||||
|
||||
export interface ApiMessage {
|
||||
id: number;
|
||||
chatId: number;
|
||||
chatId: string;
|
||||
content: {
|
||||
text?: ApiFormattedText;
|
||||
photo?: ApiPhoto;
|
||||
@ -235,8 +234,8 @@ export interface ApiMessage {
|
||||
};
|
||||
date: number;
|
||||
isOutgoing: boolean;
|
||||
senderId?: number;
|
||||
replyToChatId?: number;
|
||||
senderId?: string;
|
||||
replyToChatId?: string;
|
||||
replyToMessageId?: number;
|
||||
replyToTopMessageId?: number;
|
||||
sendingState?: 'messageSendingStatePending' | 'messageSendingStateFailed';
|
||||
@ -254,7 +253,7 @@ export interface ApiMessage {
|
||||
keyboardButtons?: ApiKeyboardButtons;
|
||||
keyboardPlaceholder?: string;
|
||||
isKeyboardSingleUse?: boolean;
|
||||
viaBotId?: number;
|
||||
viaBotId?: string;
|
||||
threadInfo?: ApiThreadInfo;
|
||||
adminTitle?: string;
|
||||
isScheduled?: boolean;
|
||||
@ -264,13 +263,13 @@ export interface ApiMessage {
|
||||
|
||||
export interface ApiThreadInfo {
|
||||
threadId: number;
|
||||
chatId: number;
|
||||
chatId: string;
|
||||
topMessageId?: number;
|
||||
originChannelId?: number;
|
||||
originChannelId?: string;
|
||||
messagesCount: number;
|
||||
lastMessageId?: number;
|
||||
lastReadInboxMessageId?: number;
|
||||
recentReplierIds?: number[];
|
||||
recentReplierIds?: string[];
|
||||
}
|
||||
|
||||
export type ApiMessageOutgoingStatus = 'read' | 'succeeded' | 'pending' | 'failed';
|
||||
|
||||
@ -64,7 +64,7 @@ export interface ApiSessionData {
|
||||
}
|
||||
|
||||
export type ApiNotifyException = {
|
||||
chatId: number;
|
||||
chatId: string;
|
||||
isMuted: boolean;
|
||||
isSilent?: boolean;
|
||||
shouldShowPreviews?: boolean;
|
||||
|
||||
@ -17,7 +17,7 @@ export interface ApiPaymentSavedInfo {
|
||||
export interface ApiPaymentForm {
|
||||
canSaveCredentials?: boolean;
|
||||
passwordMissing?: boolean;
|
||||
providerId: number;
|
||||
providerId: string;
|
||||
nativeProvider?: string;
|
||||
savedInfo: any;
|
||||
invoice: {
|
||||
|
||||
@ -65,7 +65,7 @@ export type ApiUpdateCurrentUser = {
|
||||
|
||||
export type ApiUpdateChat = {
|
||||
'@type': 'updateChat';
|
||||
id: number;
|
||||
id: string;
|
||||
chat: Partial<ApiChat>;
|
||||
newProfilePhoto?: ApiPhoto;
|
||||
noTopChatsRequest?: boolean;
|
||||
@ -73,7 +73,7 @@ export type ApiUpdateChat = {
|
||||
|
||||
export type ApiUpdateChatJoin = {
|
||||
'@type': 'updateChatJoin';
|
||||
id: number;
|
||||
id: string;
|
||||
};
|
||||
|
||||
export type ApiUpdateShowInvite = {
|
||||
@ -83,50 +83,50 @@ export type ApiUpdateShowInvite = {
|
||||
|
||||
export type ApiUpdateChatLeave = {
|
||||
'@type': 'updateChatLeave';
|
||||
id: number;
|
||||
id: string;
|
||||
};
|
||||
|
||||
export type ApiUpdateChatInbox = {
|
||||
'@type': 'updateChatInbox';
|
||||
id: number;
|
||||
id: string;
|
||||
chat: Partial<ApiChat>;
|
||||
};
|
||||
|
||||
export type ApiUpdateChatTypingStatus = {
|
||||
'@type': 'updateChatTypingStatus';
|
||||
id: number;
|
||||
id: string;
|
||||
typingStatus: ApiTypingStatus | undefined;
|
||||
};
|
||||
|
||||
export type ApiUpdateChatFullInfo = {
|
||||
'@type': 'updateChatFullInfo';
|
||||
id: number;
|
||||
id: string;
|
||||
fullInfo: Partial<ApiChatFullInfo>;
|
||||
};
|
||||
|
||||
export type ApiUpdateChatMembers = {
|
||||
'@type': 'updateChatMembers';
|
||||
id: number;
|
||||
id: string;
|
||||
replacedMembers?: ApiChatMember[];
|
||||
addedMember?: ApiChatMember;
|
||||
deletedMemberId?: number;
|
||||
deletedMemberId?: string;
|
||||
};
|
||||
|
||||
export type ApiUpdatePinnedChatIds = {
|
||||
'@type': 'updatePinnedChatIds';
|
||||
ids: number[];
|
||||
ids: string[];
|
||||
folderId?: number;
|
||||
};
|
||||
|
||||
export type ApiUpdateChatListType = {
|
||||
'@type': 'updateChatListType';
|
||||
id: number;
|
||||
id: string;
|
||||
folderId: number;
|
||||
};
|
||||
|
||||
export type ApiUpdateChatPinned = {
|
||||
'@type': 'updateChatPinned';
|
||||
id: number;
|
||||
id: string;
|
||||
isPinned: boolean;
|
||||
};
|
||||
|
||||
@ -148,14 +148,14 @@ export type ApiUpdateRecommendedChatFolders = {
|
||||
|
||||
export type ApiUpdateNewScheduledMessage = {
|
||||
'@type': 'newScheduledMessage';
|
||||
chatId: number;
|
||||
chatId: string;
|
||||
id: number;
|
||||
message: Partial<ApiMessage>;
|
||||
};
|
||||
|
||||
export type ApiUpdateNewMessage = {
|
||||
'@type': 'newMessage';
|
||||
chatId: number;
|
||||
chatId: string;
|
||||
id: number;
|
||||
message: Partial<ApiMessage>;
|
||||
shouldForceReply?: boolean;
|
||||
@ -163,28 +163,28 @@ export type ApiUpdateNewMessage = {
|
||||
|
||||
export type ApiUpdateMessage = {
|
||||
'@type': 'updateMessage';
|
||||
chatId: number;
|
||||
chatId: string;
|
||||
id: number;
|
||||
message: Partial<ApiMessage>;
|
||||
};
|
||||
|
||||
export type ApiUpdateScheduledMessage = {
|
||||
'@type': 'updateScheduledMessage';
|
||||
chatId: number;
|
||||
chatId: string;
|
||||
id: number;
|
||||
message: Partial<ApiMessage>;
|
||||
};
|
||||
|
||||
export type ApiUpdatePinnedMessageIds = {
|
||||
'@type': 'updatePinnedIds';
|
||||
chatId: number;
|
||||
chatId: string;
|
||||
isPinned?: boolean;
|
||||
messageIds: number[];
|
||||
};
|
||||
|
||||
export type ApiUpdateThreadInfo = {
|
||||
'@type': 'updateThreadInfo';
|
||||
chatId: number;
|
||||
chatId: string;
|
||||
threadId: number;
|
||||
threadInfo: Partial<ApiThreadInfo>;
|
||||
firstMessageId?: number;
|
||||
@ -192,21 +192,21 @@ export type ApiUpdateThreadInfo = {
|
||||
|
||||
export type ApiUpdateScheduledMessageSendSucceeded = {
|
||||
'@type': 'updateScheduledMessageSendSucceeded';
|
||||
chatId: number;
|
||||
chatId: string;
|
||||
localId: number;
|
||||
message: ApiMessage;
|
||||
};
|
||||
|
||||
export type ApiUpdateMessageSendSucceeded = {
|
||||
'@type': 'updateMessageSendSucceeded';
|
||||
chatId: number;
|
||||
chatId: string;
|
||||
localId: number;
|
||||
message: ApiMessage;
|
||||
};
|
||||
|
||||
export type ApiUpdateMessageSendFailed = {
|
||||
'@type': 'updateMessageSendFailed';
|
||||
chatId: number;
|
||||
chatId: string;
|
||||
localId: number;
|
||||
sendingState: {
|
||||
'@type': 'messageSendingStateFailed';
|
||||
@ -221,7 +221,7 @@ export type ApiUpdateCommonBoxMessages = {
|
||||
|
||||
export type ApiUpdateChannelMessages = {
|
||||
'@type': 'updateChannelMessages';
|
||||
channelId: number;
|
||||
channelId: string;
|
||||
ids: number[];
|
||||
messageUpdate: Partial<ApiMessage>;
|
||||
};
|
||||
@ -235,7 +235,7 @@ export type ApiUpdateMessagePoll = {
|
||||
export type ApiUpdateMessagePollVote = {
|
||||
'@type': 'updateMessagePollVote';
|
||||
pollId: string;
|
||||
userId: number;
|
||||
userId: string;
|
||||
options: string[];
|
||||
};
|
||||
|
||||
@ -247,34 +247,34 @@ export type ApiUpdateServiceNotification = {
|
||||
export type ApiUpdateDeleteMessages = {
|
||||
'@type': 'deleteMessages';
|
||||
ids: number[];
|
||||
chatId?: number;
|
||||
chatId?: string;
|
||||
};
|
||||
|
||||
export type ApiUpdateDeleteScheduledMessages = {
|
||||
'@type': 'deleteScheduledMessages';
|
||||
ids: number[];
|
||||
chatId?: number;
|
||||
chatId?: string;
|
||||
};
|
||||
|
||||
export type ApiUpdateDeleteHistory = {
|
||||
'@type': 'deleteHistory';
|
||||
chatId: number;
|
||||
chatId: string;
|
||||
};
|
||||
|
||||
export type ApiUpdateDeleteProfilePhotos = {
|
||||
'@type': 'deleteProfilePhotos';
|
||||
ids: string[];
|
||||
chatId: number;
|
||||
chatId: string;
|
||||
};
|
||||
|
||||
export type ApiUpdateResetMessages = {
|
||||
'@type': 'resetMessages';
|
||||
id: number;
|
||||
id: string;
|
||||
};
|
||||
|
||||
export type ApiUpdateDraftMessage = {
|
||||
'@type': 'draftMessage';
|
||||
chatId: number;
|
||||
chatId: string;
|
||||
formattedText?: ApiFormattedText;
|
||||
date?: number;
|
||||
replyingToId?: number;
|
||||
@ -282,30 +282,30 @@ export type ApiUpdateDraftMessage = {
|
||||
|
||||
export type ApiDeleteUser = {
|
||||
'@type': 'deleteUser';
|
||||
id: number;
|
||||
id: string;
|
||||
};
|
||||
|
||||
export type ApiUpdateUser = {
|
||||
'@type': 'updateUser';
|
||||
id: number;
|
||||
id: string;
|
||||
user: Partial<ApiUser>;
|
||||
};
|
||||
|
||||
export type ApiUpdateUserStatus = {
|
||||
'@type': 'updateUserStatus';
|
||||
userId: number;
|
||||
userId: string;
|
||||
status: ApiUserStatus;
|
||||
};
|
||||
|
||||
export type ApiUpdateUserFullInfo = {
|
||||
'@type': 'updateUserFullInfo';
|
||||
id: number;
|
||||
id: string;
|
||||
fullInfo: Partial<ApiUserFullInfo>;
|
||||
};
|
||||
|
||||
export type ApiUpdateAvatar = {
|
||||
'@type': 'updateAvatar';
|
||||
chatId: number;
|
||||
chatId: string;
|
||||
dataUri: string;
|
||||
};
|
||||
|
||||
@ -357,7 +357,7 @@ export type ApiUpdateTwoFaStateWaitCode = {
|
||||
|
||||
export type ApiUpdatePeerBlocked = {
|
||||
'@type': 'updatePeerBlocked';
|
||||
id: number;
|
||||
id: string;
|
||||
isBlocked: boolean;
|
||||
};
|
||||
|
||||
@ -366,10 +366,10 @@ export type ApiUpdatePrivacy = {
|
||||
key: 'phoneNumber' | 'lastSeen' | 'profilePhoto' | 'forwards' | 'chatInvite';
|
||||
rules: {
|
||||
visibility: 'everybody' | 'contacts' | 'nonContacts' | 'nobody';
|
||||
allowUserIds: number[];
|
||||
allowChatIds: number[];
|
||||
blockUserIds: number[];
|
||||
blockChatIds: number[];
|
||||
allowUserIds: string[];
|
||||
allowChatIds: string[];
|
||||
blockUserIds: string[];
|
||||
blockChatIds: string[];
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@ import { ApiPhoto } from './messages';
|
||||
import { ApiBotCommand } from './bots';
|
||||
|
||||
export interface ApiUser {
|
||||
id: number;
|
||||
id: string;
|
||||
isMin: boolean;
|
||||
isSelf?: true;
|
||||
isVerified?: true;
|
||||
|
||||
@ -51,10 +51,10 @@ type OwnProps = {
|
||||
isSelectable?: boolean;
|
||||
isSelected?: boolean;
|
||||
isDownloading: boolean;
|
||||
onPlay: (messageId: number, chatId: number) => void;
|
||||
onPlay: (messageId: number, chatId: string) => void;
|
||||
onReadMedia?: () => void;
|
||||
onCancelUpload?: () => void;
|
||||
onDateClick?: (messageId: number, chatId: number) => void;
|
||||
onDateClick?: (messageId: number, chatId: string) => void;
|
||||
};
|
||||
|
||||
const AVG_VOICE_DURATION = 10;
|
||||
|
||||
@ -9,7 +9,7 @@ import {
|
||||
getChatTitle,
|
||||
getUserColorKey,
|
||||
getUserFullName,
|
||||
isChatPrivate,
|
||||
isUserId,
|
||||
isChatWithRepliesBot,
|
||||
isDeletedUser,
|
||||
isUserOnline,
|
||||
@ -78,7 +78,7 @@ const Avatar: FC<OwnProps> = ({
|
||||
content = userFullName ? getFirstLetters(userFullName, 2) : undefined;
|
||||
} else if (chat) {
|
||||
const title = getChatTitle(lang, chat);
|
||||
content = title && getFirstLetters(title, isChatPrivate(chat.id) ? 2 : 1);
|
||||
content = title && getFirstLetters(title, isUserId(chat.id) ? 2 : 1);
|
||||
} else if (text) {
|
||||
content = getFirstLetters(text, 2);
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ import {
|
||||
selectChat, selectNotifyExceptions, selectNotifySettings, selectUser,
|
||||
} from '../../modules/selectors';
|
||||
import {
|
||||
getChatDescription, getChatLink, getHasAdminRight, isChatChannel, isChatPrivate, isUserRightBanned, selectIsChatMuted,
|
||||
getChatDescription, getChatLink, getHasAdminRight, isChatChannel, isUserId, isUserRightBanned, selectIsChatMuted,
|
||||
} from '../../modules/helpers';
|
||||
import renderText from './helpers/renderText';
|
||||
import { pick } from '../../util/iteratees';
|
||||
@ -22,7 +22,7 @@ import ListItem from '../ui/ListItem';
|
||||
import Switcher from '../ui/Switcher';
|
||||
|
||||
type OwnProps = {
|
||||
chatOrUserId: number;
|
||||
chatOrUserId: string;
|
||||
forceShowSelf?: boolean;
|
||||
};
|
||||
|
||||
@ -140,7 +140,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
const { lastSyncTime, countryList: { phoneCodes: phoneCodeList } } = global;
|
||||
|
||||
const chat = chatOrUserId ? selectChat(global, chatOrUserId) : undefined;
|
||||
const user = isChatPrivate(chatOrUserId) ? selectUser(global, chatOrUserId) : undefined;
|
||||
const user = isUserId(chatOrUserId) ? selectUser(global, chatOrUserId) : undefined;
|
||||
const isMuted = chat && selectIsChatMuted(chat, selectNotifySettings(global), selectNotifyExceptions(global));
|
||||
|
||||
const canInviteUsers = chat && !user && (
|
||||
|
||||
@ -10,7 +10,7 @@ import Link from '../ui/Link';
|
||||
|
||||
type OwnProps = {
|
||||
className?: string;
|
||||
chatId?: number;
|
||||
chatId?: string;
|
||||
children: any;
|
||||
};
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@ import useInfiniteScroll from '../../hooks/useInfiniteScroll';
|
||||
import useLang from '../../hooks/useLang';
|
||||
import useKeyboardListNavigation from '../../hooks/useKeyboardListNavigation';
|
||||
import useInputFocusOnOpen from '../../hooks/useInputFocusOnOpen';
|
||||
import { isChatPrivate } from '../../modules/helpers';
|
||||
import { isUserId } from '../../modules/helpers';
|
||||
|
||||
import Loading from '../ui/Loading';
|
||||
import Modal from '../ui/Modal';
|
||||
@ -21,15 +21,15 @@ import PrivateChatInfo from './PrivateChatInfo';
|
||||
import './ChatOrUserPicker.scss';
|
||||
|
||||
export type OwnProps = {
|
||||
currentUserId?: number;
|
||||
chatOrUserIds: number[];
|
||||
currentUserId?: string;
|
||||
chatOrUserIds: string[];
|
||||
isOpen: boolean;
|
||||
filterRef: RefObject<HTMLInputElement>;
|
||||
filterPlaceholder: string;
|
||||
filter: string;
|
||||
onFilterChange: (filter: string) => void;
|
||||
loadMore: NoneToVoidFunction;
|
||||
onSelectChatOrUser: (chatOrUserId: number) => void;
|
||||
onSelectChatOrUser: (chatOrUserId: string) => void;
|
||||
onClose: NoneToVoidFunction;
|
||||
};
|
||||
|
||||
@ -104,7 +104,7 @@ const ChatOrUserPicker: FC<OwnProps> = ({
|
||||
className="chat-item-clickable force-rounded-corners"
|
||||
onClick={() => onSelectChatOrUser(id)}
|
||||
>
|
||||
{isChatPrivate(id) ? (
|
||||
{isUserId(id) ? (
|
||||
<PrivateChatInfo status={id === currentUserId ? lang('SavedMessagesInfo') : undefined} userId={id} />
|
||||
) : (
|
||||
<GroupChatInfo chatId={id} />
|
||||
|
||||
@ -6,7 +6,7 @@ import { GlobalActions } from '../../global/types';
|
||||
|
||||
import { selectIsChatWithSelf, selectUser } from '../../modules/selectors';
|
||||
import {
|
||||
isChatPrivate,
|
||||
isUserId,
|
||||
isUserBot,
|
||||
getUserFirstOrLastName,
|
||||
getPrivateChatUserId,
|
||||
@ -39,7 +39,7 @@ type StateProps = {
|
||||
isPrivateChat: boolean;
|
||||
isBasicGroup: boolean;
|
||||
isSuperGroup: boolean;
|
||||
currentUserId: number | undefined;
|
||||
currentUserId: string | undefined;
|
||||
canDeleteForAll?: boolean;
|
||||
contactName?: string;
|
||||
};
|
||||
@ -196,7 +196,7 @@ const DeleteChatModal: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
|
||||
export default memo(withGlobal<OwnProps>(
|
||||
(global, { chat }): StateProps => {
|
||||
const isPrivateChat = isChatPrivate(chat.id);
|
||||
const isPrivateChat = isUserId(chat.id);
|
||||
const isChatWithSelf = selectIsChatWithSelf(global, chat.id);
|
||||
const user = isPrivateChat && selectUser(global, getPrivateChatUserId(chat)!);
|
||||
const isBot = user && isUserBot(user) && !chat.isSupport;
|
||||
|
||||
@ -13,7 +13,7 @@ import {
|
||||
selectUser,
|
||||
} from '../../modules/selectors';
|
||||
import {
|
||||
isChatPrivate,
|
||||
isUserId,
|
||||
getUserFirstOrLastName,
|
||||
getPrivateChatUserId,
|
||||
isChatBasicGroup,
|
||||
@ -115,7 +115,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
const { threadId } = selectCurrentMessageList(global) || {};
|
||||
const { canDeleteForAll } = (threadId && selectAllowedMessageActions(global, message, threadId)) || {};
|
||||
const chat = selectChat(global, message.chatId);
|
||||
const contactName = chat && isChatPrivate(chat.id)
|
||||
const contactName = chat && isUserId(chat.id)
|
||||
? getUserFirstOrLastName(selectUser(global, getPrivateChatUserId(chat)!))
|
||||
: undefined;
|
||||
|
||||
|
||||
@ -32,7 +32,7 @@ type OwnProps = {
|
||||
isDownloading: boolean;
|
||||
onCancelUpload?: () => void;
|
||||
onMediaClick?: () => void;
|
||||
onDateClick?: (messageId: number, chatId: number) => void;
|
||||
onDateClick?: (messageId: number, chatId: string) => void;
|
||||
};
|
||||
|
||||
const Document: FC<OwnProps> = ({
|
||||
|
||||
@ -23,7 +23,7 @@ import VerifiedIcon from './VerifiedIcon';
|
||||
import TypingStatus from './TypingStatus';
|
||||
|
||||
type OwnProps = {
|
||||
chatId: number;
|
||||
chatId: string;
|
||||
typingStatus?: ApiTypingStatus;
|
||||
avatarSize?: 'small' | 'medium' | 'large' | 'jumbo';
|
||||
withMediaViewer?: boolean;
|
||||
|
||||
@ -16,7 +16,7 @@ import './Media.scss';
|
||||
type OwnProps = {
|
||||
message: ApiMessage;
|
||||
idPrefix?: string;
|
||||
onClick?: (messageId: number, chatId: number) => void;
|
||||
onClick?: (messageId: number, chatId: string) => void;
|
||||
};
|
||||
|
||||
const Media: FC<OwnProps> = ({ message, idPrefix = 'shared-media', onClick }) => {
|
||||
|
||||
@ -2,7 +2,7 @@ import React, {
|
||||
FC, useCallback, useRef, useEffect, memo,
|
||||
} from '../../lib/teact/teact';
|
||||
|
||||
import { isChatPrivate } from '../../modules/helpers';
|
||||
import { isUserId } from '../../modules/helpers';
|
||||
|
||||
import InfiniteScroll from '../ui/InfiniteScroll';
|
||||
import Checkbox from '../ui/Checkbox';
|
||||
@ -19,15 +19,15 @@ import Loading from '../ui/Loading';
|
||||
import './Picker.scss';
|
||||
|
||||
type OwnProps = {
|
||||
itemIds: number[];
|
||||
selectedIds: number[];
|
||||
itemIds: string[];
|
||||
selectedIds: string[];
|
||||
filterValue?: string;
|
||||
filterPlaceholder?: string;
|
||||
notFoundText?: string;
|
||||
searchInputId?: string;
|
||||
isLoading?: boolean;
|
||||
noScrollRestore?: boolean;
|
||||
onSelectedIdsChange: (ids: number[]) => void;
|
||||
onSelectedIdsChange: (ids: string[]) => void;
|
||||
onFilterChange: (value: string) => void;
|
||||
onLoadMore?: () => void;
|
||||
};
|
||||
@ -63,7 +63,7 @@ const Picker: FC<OwnProps> = ({
|
||||
}, FOCUS_DELAY_MS);
|
||||
}, []);
|
||||
|
||||
const handleItemClick = useCallback((id: number) => {
|
||||
const handleItemClick = useCallback((id: string) => {
|
||||
const newSelectedIds = [...selectedIds];
|
||||
if (newSelectedIds.includes(id)) {
|
||||
newSelectedIds.splice(newSelectedIds.indexOf(id), 1);
|
||||
@ -119,7 +119,7 @@ const Picker: FC<OwnProps> = ({
|
||||
ripple
|
||||
>
|
||||
<Checkbox label="" checked={selectedIds.includes(id)} />
|
||||
{isChatPrivate(id) ? (
|
||||
{isUserId(id) ? (
|
||||
<PrivateChatInfo userId={id} />
|
||||
) : (
|
||||
<GroupChatInfo chatId={id} />
|
||||
|
||||
@ -4,7 +4,7 @@ import { withGlobal } from '../../lib/teact/teactn';
|
||||
import { ApiChat, ApiUser } from '../../api/types';
|
||||
|
||||
import { selectChat, selectUser } from '../../modules/selectors';
|
||||
import { getChatTitle, getUserFirstOrLastName, isChatPrivate } from '../../modules/helpers';
|
||||
import { getChatTitle, getUserFirstOrLastName, isUserId } from '../../modules/helpers';
|
||||
import renderText from './helpers/renderText';
|
||||
import buildClassName from '../../util/buildClassName';
|
||||
import useLang from '../../hooks/useLang';
|
||||
@ -14,7 +14,7 @@ import Avatar from './Avatar';
|
||||
import './PickerSelectedItem.scss';
|
||||
|
||||
type OwnProps = {
|
||||
chatOrUserId?: number;
|
||||
chatOrUserId?: string;
|
||||
icon?: string;
|
||||
title?: string;
|
||||
isMinimized?: boolean;
|
||||
@ -106,7 +106,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
}
|
||||
|
||||
const chat = chatOrUserId ? selectChat(global, chatOrUserId) : undefined;
|
||||
const user = isChatPrivate(chatOrUserId) ? selectUser(global, chatOrUserId) : undefined;
|
||||
const user = isUserId(chatOrUserId) ? selectUser(global, chatOrUserId) : undefined;
|
||||
|
||||
return {
|
||||
chat,
|
||||
|
||||
@ -5,7 +5,7 @@ import { GlobalActions } from '../../global/types';
|
||||
|
||||
import { selectChat, selectIsChatWithSelf, selectUser } from '../../modules/selectors';
|
||||
import {
|
||||
isChatPrivate,
|
||||
isUserId,
|
||||
getUserFirstOrLastName,
|
||||
getPrivateChatUserId,
|
||||
isChatBasicGroup,
|
||||
@ -21,7 +21,7 @@ import Button from '../ui/Button';
|
||||
|
||||
export type OwnProps = {
|
||||
isOpen: boolean;
|
||||
chatId: number;
|
||||
chatId: string;
|
||||
messageId: number;
|
||||
onClose: () => void;
|
||||
};
|
||||
@ -103,14 +103,14 @@ const PinMessageModal: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
|
||||
export default memo(withGlobal<OwnProps>(
|
||||
(global, { chatId }): StateProps => {
|
||||
const isPrivateChat = isChatPrivate(chatId);
|
||||
const isPrivateChat = isUserId(chatId);
|
||||
const isChatWithSelf = selectIsChatWithSelf(global, chatId);
|
||||
const chat = selectChat(global, chatId);
|
||||
const isChannel = !!chat && isChatChannel(chat);
|
||||
const isGroup = !!chat && isChatBasicGroup(chat);
|
||||
const isSuperGroup = !!chat && isChatSuperGroup(chat);
|
||||
const canPinForAll = (isPrivateChat && !isChatWithSelf) || isSuperGroup || isGroup;
|
||||
const contactName = chat && isChatPrivate(chat.id)
|
||||
const contactName = chat && isUserId(chat.id)
|
||||
? getUserFirstOrLastName(selectUser(global, getPrivateChatUserId(chat)!))
|
||||
: undefined;
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ import VerifiedIcon from './VerifiedIcon';
|
||||
import TypingStatus from './TypingStatus';
|
||||
|
||||
type OwnProps = {
|
||||
userId: number;
|
||||
userId: string;
|
||||
typingStatus?: ApiTypingStatus;
|
||||
avatarSize?: 'tiny' | 'small' | 'medium' | 'large' | 'jumbo';
|
||||
forceShowSelf?: boolean;
|
||||
|
||||
@ -26,7 +26,7 @@ import Transition from '../ui/Transition';
|
||||
import './ProfileInfo.scss';
|
||||
|
||||
type OwnProps = {
|
||||
userId: number;
|
||||
userId: string;
|
||||
forceShowSelf?: boolean;
|
||||
};
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@ import {
|
||||
getChatTitle,
|
||||
getUserColorKey,
|
||||
getUserFullName,
|
||||
isChatPrivate,
|
||||
isUserId,
|
||||
isChatWithRepliesBot,
|
||||
isDeletedUser,
|
||||
} from '../../modules/helpers';
|
||||
@ -87,7 +87,7 @@ const ProfilePhoto: FC<OwnProps> = ({
|
||||
content = userFullName ? getFirstLetters(userFullName, 2) : undefined;
|
||||
} else if (!imageSrc && chat) {
|
||||
const title = getChatTitle(lang, chat);
|
||||
content = title && getFirstLetters(title, isChatPrivate(chat.id) ? 2 : 1);
|
||||
content = title && getFirstLetters(title, isUserId(chat.id) ? 2 : 1);
|
||||
} else {
|
||||
content = (
|
||||
<div className="spinner-wrapper">
|
||||
|
||||
@ -7,7 +7,7 @@ import Button from '../ui/Button';
|
||||
|
||||
export type OwnProps = {
|
||||
isOpen: boolean;
|
||||
chatId?: number;
|
||||
chatId?: string;
|
||||
pinnedMessagesCount?: number;
|
||||
onClose: () => void;
|
||||
onUnpin: () => void;
|
||||
|
||||
@ -20,7 +20,7 @@ const MAX_TEXT_LENGTH = 170; // symbols
|
||||
type OwnProps = {
|
||||
message: ApiMessage;
|
||||
senderTitle?: string;
|
||||
onMessageClick: (messageId: number, chatId: number) => void;
|
||||
onMessageClick: (messageId: number, chatId: string) => void;
|
||||
};
|
||||
|
||||
const WebLink: FC<OwnProps> = ({
|
||||
|
||||
@ -7,7 +7,7 @@ import {
|
||||
getMessageContent,
|
||||
getMessageSummaryText,
|
||||
getUserFullName,
|
||||
isChatPrivate,
|
||||
isUserId,
|
||||
} from '../../../modules/helpers';
|
||||
import trimText from '../../../util/trimText';
|
||||
import { formatCurrency } from '../../../util/formatCurrency';
|
||||
@ -32,7 +32,7 @@ export function renderActionMessageText(
|
||||
actionOrigin?: ApiUser | ApiChat,
|
||||
targetUsers?: ApiUser[],
|
||||
targetMessage?: ApiMessage,
|
||||
targetChatId?: number,
|
||||
targetChatId?: string,
|
||||
options: ActionMessageTextOptions = {},
|
||||
) {
|
||||
if (!message.content.action) {
|
||||
@ -167,7 +167,7 @@ function renderMessageContent(lang: LangFn, message: ApiMessage, options: Action
|
||||
}
|
||||
|
||||
function renderOriginContent(lang: LangFn, origin: ApiUser | ApiChat, asPlain?: boolean) {
|
||||
return isChatPrivate(origin.id)
|
||||
return isUserId(origin.id)
|
||||
? renderUserContent(origin as ApiUser, asPlain)
|
||||
: renderChatContent(lang, origin as ApiChat, asPlain);
|
||||
}
|
||||
@ -192,7 +192,7 @@ function renderChatContent(lang: LangFn, chat: ApiChat, asPlain?: boolean): stri
|
||||
return <ChatLink className="action-link" chatId={chat.id}>{chat && renderText(text!)}</ChatLink>;
|
||||
}
|
||||
|
||||
function renderMigratedContent(chatId: number, asPlain?: boolean): string | TextPart | undefined {
|
||||
function renderMigratedContent(chatId: string, asPlain?: boolean): string | TextPart | undefined {
|
||||
const text = 'another chat';
|
||||
|
||||
if (asPlain) {
|
||||
|
||||
@ -15,7 +15,7 @@ import CheckboxGroup from '../ui/CheckboxGroup';
|
||||
|
||||
export type OwnProps = {
|
||||
isOpen: boolean;
|
||||
chatId: number;
|
||||
chatId: string;
|
||||
onClose: () => void;
|
||||
onCloseAnimationEnd?: () => void;
|
||||
};
|
||||
@ -63,8 +63,8 @@ const ChatFolderModal: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
}, [folderOrderedIds, foldersById]);
|
||||
|
||||
const handleSubmit = useCallback(() => {
|
||||
const idsToRemove = initialSelectedFolderIds.filter((id) => !selectedFolderIds.includes(id)).map(Number);
|
||||
const idsToAdd = selectedFolderIds.filter((id) => !initialSelectedFolderIds.includes(id)).map(Number);
|
||||
const idsToRemove = initialSelectedFolderIds.filter((id) => !selectedFolderIds.includes(id));
|
||||
const idsToAdd = selectedFolderIds.filter((id) => !initialSelectedFolderIds.includes(id));
|
||||
|
||||
editChatFolders({ chatId, idsToRemove, idsToAdd });
|
||||
onClose();
|
||||
|
||||
@ -14,7 +14,7 @@ import { ANIMATION_END_DELAY } from '../../../config';
|
||||
import { IS_SINGLE_COLUMN_LAYOUT } from '../../../util/environment';
|
||||
import {
|
||||
getChatTitle,
|
||||
isChatPrivate,
|
||||
isUserId,
|
||||
isActionMessage,
|
||||
getPrivateChatUserId,
|
||||
getMessageAction,
|
||||
@ -56,7 +56,7 @@ import './Chat.scss';
|
||||
|
||||
type OwnProps = {
|
||||
style?: string;
|
||||
chatId: number;
|
||||
chatId: string;
|
||||
folderId?: number;
|
||||
orderDiff: number;
|
||||
animationType: ChatAnimationTypes;
|
||||
@ -67,10 +67,10 @@ type StateProps = {
|
||||
chat?: ApiChat;
|
||||
isMuted?: boolean;
|
||||
privateChatUser?: ApiUser;
|
||||
actionTargetUserIds?: number[];
|
||||
usersById?: Record<number, ApiUser>;
|
||||
actionTargetUserIds?: string[];
|
||||
usersById?: Record<string, ApiUser>;
|
||||
actionTargetMessage?: ApiMessage;
|
||||
actionTargetChatId?: number;
|
||||
actionTargetChatId?: string;
|
||||
lastMessageSender?: ApiUser;
|
||||
lastMessageOutgoingStatus?: ApiMessageOutgoingStatus;
|
||||
draft?: ApiFormattedText;
|
||||
@ -264,7 +264,7 @@ const Chat: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
|
||||
const className = buildClassName(
|
||||
'Chat chat-item-clickable',
|
||||
isChatPrivate(chatId) ? 'private' : 'group',
|
||||
isUserId(chatId) ? 'private' : 'group',
|
||||
isSelected && 'selected',
|
||||
);
|
||||
|
||||
|
||||
@ -30,14 +30,14 @@ type OwnProps = {
|
||||
};
|
||||
|
||||
type StateProps = {
|
||||
chatsById: Record<number, ApiChat>;
|
||||
usersById: Record<number, ApiUser>;
|
||||
chatsById: Record<string, ApiChat>;
|
||||
usersById: Record<string, ApiUser>;
|
||||
chatFoldersById: Record<number, ApiChatFolder>;
|
||||
notifySettings: NotifySettings;
|
||||
notifyExceptions?: Record<number, NotifyException>;
|
||||
orderedFolderIds?: number[];
|
||||
activeChatFolder: number;
|
||||
currentUserId?: number;
|
||||
currentUserId?: string;
|
||||
lastSyncTime?: number;
|
||||
shouldSkipHistoryAnimations?: boolean;
|
||||
};
|
||||
@ -86,7 +86,7 @@ const ChatFolders: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const chatIds = Object.keys(chatsById).map(Number);
|
||||
const chatIds = Object.keys(chatsById);
|
||||
const counters = displayedFolders.map((folder) => {
|
||||
const {
|
||||
unreadDialogsCount, hasActiveDialogs,
|
||||
|
||||
@ -35,11 +35,11 @@ type OwnProps = {
|
||||
};
|
||||
|
||||
type StateProps = {
|
||||
chatsById: Record<number, ApiChat>;
|
||||
usersById: Record<number, ApiUser>;
|
||||
chatsById: Record<string, ApiChat>;
|
||||
usersById: Record<string, ApiUser>;
|
||||
chatFolder?: ApiChatFolder;
|
||||
listIds?: number[];
|
||||
orderedPinnedIds?: number[];
|
||||
listIds?: string[];
|
||||
orderedPinnedIds?: string[];
|
||||
lastSyncTime?: number;
|
||||
notifySettings: NotifySettings;
|
||||
notifyExceptions?: Record<number, NotifyException>;
|
||||
|
||||
@ -26,8 +26,8 @@ export type OwnProps = {
|
||||
};
|
||||
|
||||
type StateProps = {
|
||||
usersById: Record<number, ApiUser>;
|
||||
contactIds?: number[];
|
||||
usersById: Record<string, ApiUser>;
|
||||
contactIds?: string[];
|
||||
serverTimeOffset: number;
|
||||
};
|
||||
|
||||
@ -49,12 +49,9 @@ const ContactList: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
|
||||
useHistoryBack(isActive, onReset);
|
||||
|
||||
const handleClick = useCallback(
|
||||
(id: number) => {
|
||||
openChat({ id, shouldReplaceHistory: true });
|
||||
},
|
||||
[openChat],
|
||||
);
|
||||
const handleClick = useCallback((id: string) => {
|
||||
openChat({ id, shouldReplaceHistory: true });
|
||||
}, [openChat]);
|
||||
|
||||
const listIds = useMemo(() => {
|
||||
if (!contactIds) {
|
||||
|
||||
@ -43,12 +43,12 @@ type OwnProps = {
|
||||
type StateProps = {
|
||||
searchQuery?: string;
|
||||
isLoading: boolean;
|
||||
currentUserId?: number;
|
||||
globalSearchChatId?: number;
|
||||
currentUserId?: string;
|
||||
globalSearchChatId?: string;
|
||||
searchDate?: number;
|
||||
theme: ISettings['theme'];
|
||||
animationLevel: 0 | 1 | 2;
|
||||
chatsById?: Record<number, ApiChat>;
|
||||
chatsById?: Record<string, ApiChat>;
|
||||
};
|
||||
|
||||
type DispatchProps = Pick<GlobalActions, (
|
||||
|
||||
@ -6,15 +6,15 @@ export enum ChatAnimationTypes {
|
||||
None,
|
||||
}
|
||||
|
||||
export function useChatAnimationType(orderDiffById: Record<number, number>) {
|
||||
const movesUp = useCallback((id: number) => orderDiffById[id] < 0, [orderDiffById]);
|
||||
const movesDown = useCallback((id: number) => orderDiffById[id] > 0, [orderDiffById]);
|
||||
export function useChatAnimationType(orderDiffById: Record<string, number>) {
|
||||
const movesUp = useCallback((id: string) => orderDiffById[id] < 0, [orderDiffById]);
|
||||
const movesDown = useCallback((id: string) => orderDiffById[id] > 0, [orderDiffById]);
|
||||
|
||||
const orderDiffIds = Object.keys(orderDiffById).map(Number);
|
||||
const orderDiffIds = Object.keys(orderDiffById);
|
||||
const numberOfUp = orderDiffIds.filter(movesUp).length;
|
||||
const numberOfDown = orderDiffIds.filter(movesDown).length;
|
||||
|
||||
return useCallback((chatId: number): ChatAnimationTypes => {
|
||||
return useCallback((chatId: string): ChatAnimationTypes => {
|
||||
const orderDiff = orderDiffById[chatId];
|
||||
|
||||
if (orderDiff === 0) {
|
||||
|
||||
@ -29,7 +29,7 @@ const NewChat: FC<OwnProps> = ({
|
||||
onContentChange,
|
||||
onReset,
|
||||
}) => {
|
||||
const [newChatMemberIds, setNewChatMemberIds] = useState<number[]>([]);
|
||||
const [newChatMemberIds, setNewChatMemberIds] = useState<string[]>([]);
|
||||
|
||||
const handleNextStep = useCallback(() => {
|
||||
onContentChange(isChannel ? LeftColumnContent.NewChannelStep2 : LeftColumnContent.NewGroupStep2);
|
||||
|
||||
@ -20,21 +20,21 @@ import Button from '../../ui/Button';
|
||||
export type OwnProps = {
|
||||
isChannel?: boolean;
|
||||
isActive: boolean;
|
||||
selectedMemberIds: number[];
|
||||
onSelectedMemberIdsChange: (ids: number[]) => void;
|
||||
selectedMemberIds: string[];
|
||||
onSelectedMemberIdsChange: (ids: string[]) => void;
|
||||
onNextStep: () => void;
|
||||
onReset: () => void;
|
||||
};
|
||||
|
||||
type StateProps = {
|
||||
currentUserId?: number;
|
||||
usersById: Record<number, ApiUser>;
|
||||
chatsById: Record<number, ApiChat>;
|
||||
localContactIds?: number[];
|
||||
currentUserId?: string;
|
||||
usersById: Record<string, ApiUser>;
|
||||
chatsById: Record<string, ApiChat>;
|
||||
localContactIds?: string[];
|
||||
searchQuery?: string;
|
||||
isSearching?: boolean;
|
||||
localUserIds?: number[];
|
||||
globalUserIds?: number[];
|
||||
localUserIds?: string[];
|
||||
globalUserIds?: string[];
|
||||
};
|
||||
|
||||
type DispatchProps = Pick<GlobalActions, 'loadContactList' | 'setGlobalSearchQuery'>;
|
||||
|
||||
@ -21,7 +21,7 @@ import PrivateChatInfo from '../../common/PrivateChatInfo';
|
||||
export type OwnProps = {
|
||||
isChannel?: boolean;
|
||||
isActive: boolean;
|
||||
memberIds: number[];
|
||||
memberIds: string[];
|
||||
onReset: (forceReturnToChatList?: boolean) => void;
|
||||
};
|
||||
|
||||
|
||||
@ -66,17 +66,17 @@ const AudioResults: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
}
|
||||
|
||||
return foundIds.map((id) => {
|
||||
const [chatId, messageId] = id.split('_').map(Number);
|
||||
const [chatId, messageId] = id.split('_');
|
||||
|
||||
return globalMessagesByChatId[chatId]?.byId[messageId];
|
||||
return globalMessagesByChatId[chatId]?.byId[Number(messageId)];
|
||||
}).filter(Boolean);
|
||||
}, [globalMessagesByChatId, foundIds]);
|
||||
|
||||
const handleMessageFocus = useCallback((messageId: number, chatId: number) => {
|
||||
const handleMessageFocus = useCallback((messageId: number, chatId: string) => {
|
||||
focusMessage({ chatId, messageId });
|
||||
}, [focusMessage]);
|
||||
|
||||
const handlePlayAudio = useCallback((messageId: number, chatId: number) => {
|
||||
const handlePlayAudio = useCallback((messageId: number, chatId: string) => {
|
||||
openAudioPlayer({ chatId, messageId, origin: AudioOrigin.Search });
|
||||
}, [openAudioPlayer]);
|
||||
|
||||
|
||||
@ -36,7 +36,7 @@ import './ChatMessage.scss';
|
||||
type OwnProps = {
|
||||
searchQuery?: string;
|
||||
message: ApiMessage;
|
||||
chatId: number;
|
||||
chatId: string;
|
||||
};
|
||||
|
||||
type StateProps = {
|
||||
|
||||
@ -26,10 +26,10 @@ export type OwnProps = {
|
||||
};
|
||||
|
||||
type StateProps = {
|
||||
currentUserId?: number;
|
||||
currentUserId?: string;
|
||||
foundIds?: string[];
|
||||
globalMessagesByChatId?: Record<number, { byId: Record<number, ApiMessage> }>;
|
||||
chatsById: Record<number, ApiChat>;
|
||||
globalMessagesByChatId?: Record<string, { byId: Record<number, ApiMessage> }>;
|
||||
chatsById: Record<string, ApiChat>;
|
||||
fetchingStatus?: { chats?: boolean; messages?: boolean };
|
||||
lastSyncTime?: number;
|
||||
};
|
||||
@ -70,9 +70,9 @@ const ChatMessageResults: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
|
||||
return foundIds
|
||||
.map((id) => {
|
||||
const [chatId, messageId] = id.split('_').map(Number);
|
||||
const [chatId, messageId] = id.split('_');
|
||||
|
||||
return globalMessagesByChatId?.[chatId]?.byId[messageId];
|
||||
return globalMessagesByChatId?.[chatId]?.byId[Number(messageId)];
|
||||
})
|
||||
.filter<ApiMessage>(Boolean as any)
|
||||
.sort((a, b) => b.date - a.date);
|
||||
|
||||
@ -33,16 +33,16 @@ export type OwnProps = {
|
||||
};
|
||||
|
||||
type StateProps = {
|
||||
currentUserId?: number;
|
||||
localContactIds?: number[];
|
||||
localChatIds?: number[];
|
||||
localUserIds?: number[];
|
||||
globalChatIds?: number[];
|
||||
globalUserIds?: number[];
|
||||
currentUserId?: string;
|
||||
localContactIds?: string[];
|
||||
localChatIds?: string[];
|
||||
localUserIds?: string[];
|
||||
globalChatIds?: string[];
|
||||
globalUserIds?: string[];
|
||||
foundIds?: string[];
|
||||
globalMessagesByChatId?: Record<number, { byId: Record<number, ApiMessage> }>;
|
||||
chatsById: Record<number, ApiChat>;
|
||||
usersById: Record<number, ApiUser>;
|
||||
globalMessagesByChatId?: Record<string, { byId: Record<number, ApiMessage> }>;
|
||||
chatsById: Record<string, ApiChat>;
|
||||
usersById: Record<string, ApiUser>;
|
||||
fetchingStatus?: { chats?: boolean; messages?: boolean };
|
||||
lastSyncTime?: number;
|
||||
};
|
||||
@ -79,7 +79,7 @@ const ChatResults: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
}, [lastSyncTime, searchMessagesGlobal, searchQuery]);
|
||||
|
||||
const handleChatClick = useCallback(
|
||||
(id: number) => {
|
||||
(id: string) => {
|
||||
openChat({ id, shouldReplaceHistory: true });
|
||||
|
||||
if (id !== currentUserId) {
|
||||
@ -93,7 +93,7 @@ const ChatResults: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
[currentUserId, openChat, addRecentlyFoundChatId, onReset],
|
||||
);
|
||||
|
||||
const handlePickerItemClick = useCallback((id: number) => {
|
||||
const handlePickerItemClick = useCallback((id: string) => {
|
||||
setGlobalSearchChatId({ id });
|
||||
}, [setGlobalSearchChatId]);
|
||||
|
||||
@ -142,9 +142,9 @@ const ChatResults: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
|
||||
return foundIds
|
||||
.map((id) => {
|
||||
const [chatId, messageId] = id.split('_').map(Number);
|
||||
const [chatId, messageId] = id.split('_');
|
||||
|
||||
return globalMessagesByChatId?.[chatId]?.byId[messageId];
|
||||
return globalMessagesByChatId?.[chatId]?.byId[Number(messageId)];
|
||||
})
|
||||
.filter<ApiMessage>(Boolean as any)
|
||||
.sort((a, b) => b.date - a.date);
|
||||
|
||||
@ -64,14 +64,14 @@ const FileResults: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
}
|
||||
|
||||
return foundIds.map((id) => {
|
||||
const [chatId, messageId] = id.split('_').map(Number);
|
||||
const message = globalMessagesByChatId[chatId]?.byId[messageId];
|
||||
const [chatId, messageId] = id.split('_');
|
||||
const message = globalMessagesByChatId[chatId]?.byId[Number(messageId)];
|
||||
|
||||
return message && getMessageDocument(message) ? message : undefined;
|
||||
}).filter(Boolean) as ApiMessage[];
|
||||
}, [globalMessagesByChatId, foundIds]);
|
||||
|
||||
const handleMessageFocus = useCallback((messageId: number, chatId: number) => {
|
||||
const handleMessageFocus = useCallback((messageId: number, chatId: string) => {
|
||||
focusMessage({ chatId, messageId });
|
||||
}, [focusMessage]);
|
||||
|
||||
|
||||
@ -32,7 +32,7 @@ export type OwnProps = {
|
||||
|
||||
type StateProps = {
|
||||
currentContent?: GlobalSearchContent;
|
||||
chatId?: number;
|
||||
chatId?: string;
|
||||
};
|
||||
|
||||
type DispatchProps = Pick<GlobalActions, ('setGlobalSearchContent' | 'setGlobalSearchDate')>;
|
||||
|
||||
@ -7,7 +7,7 @@ import { ApiChat, ApiUser } from '../../../api/types';
|
||||
|
||||
import useChatContextActions from '../../../hooks/useChatContextActions';
|
||||
import useFlag from '../../../hooks/useFlag';
|
||||
import { isChatPrivate, getPrivateChatUserId, selectIsChatMuted } from '../../../modules/helpers';
|
||||
import { isUserId, getPrivateChatUserId, selectIsChatMuted } from '../../../modules/helpers';
|
||||
import {
|
||||
selectChat, selectUser, selectIsChatPinned, selectNotifySettings, selectNotifyExceptions,
|
||||
} from '../../../modules/selectors';
|
||||
@ -20,9 +20,9 @@ import ListItem from '../../ui/ListItem';
|
||||
import ChatFolderModal from '../ChatFolderModal.async';
|
||||
|
||||
type OwnProps = {
|
||||
chatId: number;
|
||||
chatId: string;
|
||||
withUsername?: boolean;
|
||||
onClick: (id: number) => void;
|
||||
onClick: (id: string) => void;
|
||||
};
|
||||
|
||||
type StateProps = {
|
||||
@ -70,7 +70,7 @@ const LeftSearchResultChat: FC<OwnProps & StateProps> = ({
|
||||
contextActions={contextActions}
|
||||
buttonRef={buttonRef}
|
||||
>
|
||||
{isChatPrivate(chatId) ? (
|
||||
{isUserId(chatId) ? (
|
||||
<PrivateChatInfo userId={chatId} withUsername={withUsername} avatarSize="large" />
|
||||
) : (
|
||||
<GroupChatInfo chatId={chatId} withUsername={withUsername} avatarSize="large" />
|
||||
|
||||
@ -61,13 +61,13 @@ const LinkResults: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
}
|
||||
|
||||
return foundIds.map((id) => {
|
||||
const [chatId, messageId] = id.split('_').map(Number);
|
||||
const [chatId, messageId] = id.split('_');
|
||||
|
||||
return globalMessagesByChatId[chatId]?.byId[messageId];
|
||||
return globalMessagesByChatId[chatId]?.byId[Number(messageId)];
|
||||
}).filter(Boolean);
|
||||
}, [globalMessagesByChatId, foundIds]);
|
||||
|
||||
const handleMessageFocus = useCallback((messageId: number, chatId: number) => {
|
||||
const handleMessageFocus = useCallback((messageId: number, chatId: string) => {
|
||||
focusMessage({ chatId, messageId });
|
||||
}, [focusMessage]);
|
||||
|
||||
|
||||
@ -60,13 +60,13 @@ const MediaResults: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
}
|
||||
|
||||
return foundIds.map((id) => {
|
||||
const [chatId, messageId] = id.split('_').map(Number);
|
||||
const [chatId, messageId] = id.split('_');
|
||||
|
||||
return globalMessagesByChatId[chatId]?.byId[messageId];
|
||||
return globalMessagesByChatId[chatId]?.byId[Number(messageId)];
|
||||
}).filter(Boolean);
|
||||
}, [globalMessagesByChatId, foundIds]);
|
||||
|
||||
const handleSelectMedia = useCallback((messageId: number, chatId: number) => {
|
||||
const handleSelectMedia = useCallback((messageId: number, chatId: string) => {
|
||||
openMediaViewer({
|
||||
chatId,
|
||||
messageId,
|
||||
|
||||
@ -24,9 +24,9 @@ type OwnProps = {
|
||||
};
|
||||
|
||||
type StateProps = {
|
||||
topUserIds?: number[];
|
||||
usersById: Record<number, ApiUser>;
|
||||
recentlyFoundChatIds?: number[];
|
||||
topUserIds?: string[];
|
||||
usersById: Record<string, ApiUser>;
|
||||
recentlyFoundChatIds?: string[];
|
||||
};
|
||||
|
||||
type DispatchProps = Pick<GlobalActions, (
|
||||
@ -58,16 +58,13 @@ const RecentContacts: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
|
||||
useHorizontalScroll(topUsersRef.current, !topUserIds);
|
||||
|
||||
const handleClick = useCallback(
|
||||
(id: number) => {
|
||||
openChat({ id, shouldReplaceHistory: true });
|
||||
onReset();
|
||||
setTimeout(() => {
|
||||
addRecentlyFoundChatId({ id });
|
||||
}, SEARCH_CLOSE_TIMEOUT_MS);
|
||||
},
|
||||
[openChat, addRecentlyFoundChatId, onReset],
|
||||
);
|
||||
const handleClick = useCallback((id: string) => {
|
||||
openChat({ id, shouldReplaceHistory: true });
|
||||
onReset();
|
||||
setTimeout(() => {
|
||||
addRecentlyFoundChatId({ id });
|
||||
}, SEARCH_CLOSE_TIMEOUT_MS);
|
||||
}, [openChat, addRecentlyFoundChatId, onReset]);
|
||||
|
||||
const lang = useLang();
|
||||
|
||||
|
||||
@ -9,13 +9,13 @@ import { selectTheme } from '../../../../modules/selectors';
|
||||
export type StateProps = {
|
||||
theme: ISettings['theme'];
|
||||
isLoading?: boolean;
|
||||
chatsById: Record<number, ApiChat>;
|
||||
usersById: Record<number, ApiUser>;
|
||||
globalMessagesByChatId?: Record<number, { byId: Record<number, ApiMessage> }>;
|
||||
chatsById: Record<string, ApiChat>;
|
||||
usersById: Record<string, ApiUser>;
|
||||
globalMessagesByChatId?: Record<string, { byId: Record<number, ApiMessage> }>;
|
||||
foundIds?: string[];
|
||||
lastSyncTime?: number;
|
||||
searchChatId?: number;
|
||||
activeDownloads: Record<number, number[]>;
|
||||
searchChatId?: string;
|
||||
activeDownloads: Record<string, number[]>;
|
||||
};
|
||||
|
||||
export function createMapStateToProps(type: ApiGlobalMessageSearchType) {
|
||||
|
||||
@ -2,26 +2,26 @@ import { ApiChat, ApiMessage, ApiUser } from '../../../../api/types';
|
||||
import {
|
||||
getChatTitle,
|
||||
getSenderTitle,
|
||||
isChatPrivate,
|
||||
isUserId,
|
||||
isChatGroup,
|
||||
} from '../../../../modules/helpers';
|
||||
import { LangFn } from '../../../../hooks/useLang';
|
||||
|
||||
export function getSenderName(
|
||||
lang: LangFn, message: ApiMessage, chatsById: Record<number, ApiChat>, usersById: Record<number, ApiUser>,
|
||||
lang: LangFn, message: ApiMessage, chatsById: Record<string, ApiChat>, usersById: Record<string, ApiUser>,
|
||||
) {
|
||||
const { senderId } = message;
|
||||
if (!senderId) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const sender = isChatPrivate(senderId) ? usersById[senderId] : chatsById[senderId];
|
||||
const sender = isUserId(senderId) ? usersById[senderId] : chatsById[senderId];
|
||||
|
||||
let senderName = getSenderTitle(lang, sender);
|
||||
|
||||
const chat = chatsById[message.chatId];
|
||||
if (chat) {
|
||||
if (isChatPrivate(senderId) && (sender as ApiUser).isSelf) {
|
||||
if (isUserId(senderId) && (sender as ApiUser).isSelf) {
|
||||
senderName = `${lang('FromYou')} → ${getChatTitle(lang, chat)}`;
|
||||
} else if (isChatGroup(chat)) {
|
||||
senderName += ` → ${getChatTitle(lang, chat)}`;
|
||||
|
||||
@ -19,11 +19,11 @@ export type OwnProps = {
|
||||
};
|
||||
|
||||
type StateProps = {
|
||||
usersById: Record<number, ApiUser>;
|
||||
blockedIds: number[];
|
||||
contactIds?: number[];
|
||||
localContactIds?: number[];
|
||||
currentUserId?: number;
|
||||
usersById: Record<string, ApiUser>;
|
||||
blockedIds: string[];
|
||||
contactIds?: string[];
|
||||
localContactIds?: string[];
|
||||
currentUserId?: string;
|
||||
};
|
||||
|
||||
type DispatchProps = Pick<GlobalActions, 'loadContactList' | 'setUserSearchQuery' | 'blockContact'>;
|
||||
@ -54,7 +54,7 @@ const BlockUserModal: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
return !blockedIds.includes(contactId) && contactId !== currentUserId;
|
||||
});
|
||||
|
||||
return unique(availableContactsId).reduce((acc, contactId) => {
|
||||
return unique(availableContactsId).reduce<string[]>((acc, contactId) => {
|
||||
if (
|
||||
!filter
|
||||
|| !usersById[contactId]
|
||||
@ -65,7 +65,7 @@ const BlockUserModal: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
}
|
||||
|
||||
return acc;
|
||||
}, [] as number[])
|
||||
}, [])
|
||||
.sort((firstId, secondId) => {
|
||||
const firstName = getUserFullName(usersById[firstId]) || '';
|
||||
const secondName = getUserFullName(usersById[secondId]) || '';
|
||||
@ -74,7 +74,7 @@ const BlockUserModal: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
});
|
||||
}, [blockedIds, contactIds, currentUserId, filter, localContactIds, usersById]);
|
||||
|
||||
const handleRemoveUser = useCallback((userId: number) => {
|
||||
const handleRemoveUser = useCallback((userId: string) => {
|
||||
const { id: contactId, accessHash } = usersById[userId] || {};
|
||||
if (!contactId || !accessHash) {
|
||||
return;
|
||||
|
||||
@ -11,7 +11,7 @@ import { CHAT_HEIGHT_PX } from '../../../config';
|
||||
import { formatPhoneNumberWithCode } from '../../../util/phoneNumber';
|
||||
import { pick } from '../../../util/iteratees';
|
||||
import {
|
||||
getChatTitle, getUserFullName, isChatPrivate,
|
||||
getChatTitle, getUserFullName, isUserId,
|
||||
} from '../../../modules/helpers';
|
||||
import renderText from '../../common/helpers/renderText';
|
||||
import buildClassName from '../../../util/buildClassName';
|
||||
@ -32,9 +32,9 @@ type OwnProps = {
|
||||
};
|
||||
|
||||
type StateProps = {
|
||||
chatsByIds: Record<number, ApiChat>;
|
||||
usersByIds: Record<number, ApiUser>;
|
||||
blockedIds: number[];
|
||||
chatsByIds: Record<string, ApiChat>;
|
||||
usersByIds: Record<string, ApiUser>;
|
||||
blockedIds: string[];
|
||||
phoneCodeList: ApiCountryCode[];
|
||||
};
|
||||
|
||||
@ -52,14 +52,14 @@ const SettingsPrivacyBlockedUsers: FC<OwnProps & StateProps & DispatchProps> = (
|
||||
}) => {
|
||||
const lang = useLang();
|
||||
const [isBlockUserModalOpen, openBlockUserModal, closeBlockUserModal] = useFlag();
|
||||
const handleUnblockClick = useCallback((contactId: number) => {
|
||||
const handleUnblockClick = useCallback((contactId: string) => {
|
||||
unblockContact({ contactId });
|
||||
}, [unblockContact]);
|
||||
|
||||
useHistoryBack(isActive, onReset, onScreenSelect, SettingsScreens.PrivacyBlockedUsers);
|
||||
|
||||
function renderContact(contactId: number, i: number, viewportOffset: number) {
|
||||
const isPrivate = isChatPrivate(contactId);
|
||||
function renderContact(contactId: string, i: number, viewportOffset: number) {
|
||||
const isPrivate = isUserId(contactId);
|
||||
const user = isPrivate ? usersByIds[contactId] : undefined;
|
||||
const chat = !isPrivate ? chatsByIds[contactId] : undefined;
|
||||
|
||||
|
||||
@ -23,8 +23,8 @@ type OwnProps = {
|
||||
};
|
||||
|
||||
type StateProps = Partial<ApiPrivacySettings> & {
|
||||
chatsById?: Record<number, ApiChat>;
|
||||
usersById?: Record<number, ApiUser>;
|
||||
chatsById?: Record<string, ApiChat>;
|
||||
usersById?: Record<string, ApiUser>;
|
||||
};
|
||||
|
||||
type DispatchProps = Pick<GlobalActions, 'setPrivacyVisibility'>;
|
||||
|
||||
@ -12,7 +12,7 @@ import { pick } from '../../../util/iteratees';
|
||||
import searchWords from '../../../util/searchWords';
|
||||
import { getPrivacyKey } from './helper/privacy';
|
||||
import {
|
||||
getChatTitle, isChatGroup, isChatPrivate, prepareChatList,
|
||||
getChatTitle, isChatGroup, isUserId, prepareChatList,
|
||||
} from '../../../modules/helpers';
|
||||
import useHistoryBack from '../../../hooks/useHistoryBack';
|
||||
|
||||
@ -28,12 +28,12 @@ export type OwnProps = {
|
||||
};
|
||||
|
||||
type StateProps = {
|
||||
currentUserId?: number;
|
||||
chatsById: Record<number, ApiChat>;
|
||||
listIds?: number[];
|
||||
orderedPinnedIds?: number[];
|
||||
archivedListIds?: number[];
|
||||
archivedPinnedIds?: number[];
|
||||
currentUserId?: string;
|
||||
chatsById: Record<string, ApiChat>;
|
||||
listIds?: string[];
|
||||
orderedPinnedIds?: string[];
|
||||
archivedListIds?: string[];
|
||||
archivedPinnedIds?: string[];
|
||||
settings?: ApiPrivacySettings;
|
||||
};
|
||||
|
||||
@ -69,7 +69,7 @@ const SettingsPrivacyVisibilityExceptionList: FC<OwnProps & StateProps & Dispatc
|
||||
}, [isAllowList, settings]);
|
||||
const [searchQuery, setSearchQuery] = useState<string>('');
|
||||
const [isSubmitShown, setIsSubmitShown] = useState<boolean>(false);
|
||||
const [newSelectedContactIds, setNewSelectedContactIds] = useState<number[]>(selectedContactIds);
|
||||
const [newSelectedContactIds, setNewSelectedContactIds] = useState<string[]>(selectedContactIds);
|
||||
|
||||
const chats = useMemo(() => {
|
||||
const activeChatArrays = listIds
|
||||
@ -102,7 +102,7 @@ const SettingsPrivacyVisibilityExceptionList: FC<OwnProps & StateProps & Dispatc
|
||||
|
||||
return chats
|
||||
.filter((chat) => (
|
||||
((isChatPrivate(chat.id) && chat.id !== currentUserId) || isChatGroup(chat))
|
||||
((isUserId(chat.id) && chat.id !== currentUserId) || isChatGroup(chat))
|
||||
&& (
|
||||
!searchQuery
|
||||
|| searchWords(getChatTitle(lang, chat), searchQuery)
|
||||
@ -112,7 +112,7 @@ const SettingsPrivacyVisibilityExceptionList: FC<OwnProps & StateProps & Dispatc
|
||||
.map(({ id }) => id);
|
||||
}, [chats, currentUserId, lang, searchQuery, selectedContactIds]);
|
||||
|
||||
const handleSelectedContactIdsChange = useCallback((value: number[]) => {
|
||||
const handleSelectedContactIdsChange = useCallback((value: string[]) => {
|
||||
setNewSelectedContactIds(value);
|
||||
setIsSubmitShown(true);
|
||||
}, []);
|
||||
|
||||
@ -32,11 +32,11 @@ type OwnProps = {
|
||||
};
|
||||
|
||||
type StateProps = {
|
||||
chatsById: Record<number, ApiChat>;
|
||||
listIds?: number[];
|
||||
orderedPinnedIds?: number[];
|
||||
archivedListIds?: number[];
|
||||
archivedPinnedIds?: number[];
|
||||
chatsById: Record<string, ApiChat>;
|
||||
listIds?: string[];
|
||||
orderedPinnedIds?: string[];
|
||||
archivedListIds?: string[];
|
||||
archivedPinnedIds?: string[];
|
||||
};
|
||||
|
||||
type DispatchProps = Pick<GlobalActions, 'loadMoreChats'>;
|
||||
@ -101,7 +101,7 @@ const SettingsFoldersChatFilters: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
});
|
||||
}, [dispatch]);
|
||||
|
||||
const handleSelectedIdsChange = useCallback((ids: number[]) => {
|
||||
const handleSelectedIdsChange = useCallback((ids: string[]) => {
|
||||
if (mode === 'included') {
|
||||
dispatch({
|
||||
type: 'setIncludeFilters',
|
||||
|
||||
@ -2,7 +2,7 @@ import React, {
|
||||
FC, useCallback, useRef, useEffect, memo,
|
||||
} from '../../../../lib/teact/teact';
|
||||
|
||||
import { isChatPrivate } from '../../../../modules/helpers';
|
||||
import { isUserId } from '../../../../modules/helpers';
|
||||
import {
|
||||
INCLUDED_CHAT_TYPES,
|
||||
EXCLUDED_CHAT_TYPES,
|
||||
@ -25,11 +25,11 @@ import './SettingsFoldersChatsPicker.scss';
|
||||
|
||||
type OwnProps = {
|
||||
mode: 'included' | 'excluded';
|
||||
chatIds: number[];
|
||||
selectedIds: number[];
|
||||
chatIds: string[];
|
||||
selectedIds: string[];
|
||||
selectedChatTypes: string[];
|
||||
filterValue?: string;
|
||||
onSelectedIdsChange: (ids: number[]) => void;
|
||||
onSelectedIdsChange: (ids: string[]) => void;
|
||||
onSelectedChatTypesChange: (types: string[]) => void;
|
||||
onFilterChange: (value: string) => void;
|
||||
onLoadMore: () => void;
|
||||
@ -67,7 +67,7 @@ const SettingsFoldersChatsPicker: FC<OwnProps> = ({
|
||||
}, FOCUS_DELAY_MS);
|
||||
}, []);
|
||||
|
||||
const handleItemClick = useCallback((id: number) => {
|
||||
const handleItemClick = useCallback((id: string) => {
|
||||
const newSelectedIds = [...selectedIds];
|
||||
if (newSelectedIds.includes(id)) {
|
||||
newSelectedIds.splice(newSelectedIds.indexOf(id), 1);
|
||||
@ -131,7 +131,7 @@ const SettingsFoldersChatsPicker: FC<OwnProps> = ({
|
||||
);
|
||||
}
|
||||
|
||||
function renderItem(id: number) {
|
||||
function renderItem(id: string) {
|
||||
const isSelected = selectedIds.includes(id);
|
||||
|
||||
return (
|
||||
@ -142,7 +142,7 @@ const SettingsFoldersChatsPicker: FC<OwnProps> = ({
|
||||
ripple
|
||||
disabled={!isSelected && hasMaxChats}
|
||||
>
|
||||
{isChatPrivate(id) ? (
|
||||
{isUserId(id) ? (
|
||||
<PrivateChatInfo userId={id} />
|
||||
) : (
|
||||
<GroupChatInfo chatId={id} withChatType />
|
||||
|
||||
@ -8,7 +8,7 @@ import { SettingsScreens } from '../../../../types';
|
||||
|
||||
import { STICKER_SIZE_FOLDER_SETTINGS } from '../../../../config';
|
||||
import { findIntersectionWithSet, pick } from '../../../../util/iteratees';
|
||||
import { isChatPrivate } from '../../../../modules/helpers';
|
||||
import { isUserId } from '../../../../modules/helpers';
|
||||
import getAnimationData from '../../../common/helpers/animatedAssets';
|
||||
import {
|
||||
EXCLUDED_CHAT_TYPES,
|
||||
@ -41,8 +41,8 @@ type OwnProps = {
|
||||
};
|
||||
|
||||
type StateProps = {
|
||||
loadedActiveChatIds?: number[];
|
||||
loadedArchivedChatIds?: number[];
|
||||
loadedActiveChatIds?: string[];
|
||||
loadedArchivedChatIds?: string[];
|
||||
};
|
||||
|
||||
type DispatchProps = Pick<GlobalActions, 'editChatFolder' | 'addChatFolder' | 'loadMoreChats'>;
|
||||
@ -212,7 +212,7 @@ const SettingsFoldersEdit: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
narrow
|
||||
inactive
|
||||
>
|
||||
{isChatPrivate(id) ? (
|
||||
{isUserId(id) ? (
|
||||
<PrivateChatInfo avatarSize="small" userId={id} />
|
||||
) : (
|
||||
<GroupChatInfo avatarSize="small" chatId={id} />
|
||||
|
||||
@ -30,8 +30,8 @@ type OwnProps = {
|
||||
};
|
||||
|
||||
type StateProps = {
|
||||
chatsById: Record<number, ApiChat>;
|
||||
usersById: Record<number, ApiUser>;
|
||||
chatsById: Record<string, ApiChat>;
|
||||
usersById: Record<string, ApiUser>;
|
||||
orderedFolderIds?: number[];
|
||||
foldersById: Record<number, ApiChatFolder>;
|
||||
recommendedChatFolders?: ApiChatFolder[];
|
||||
@ -104,7 +104,7 @@ const SettingsFoldersMain: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const chatIds = Object.keys(chatsById).map(Number);
|
||||
const chatIds = Object.keys(chatsById);
|
||||
|
||||
return orderedFolderIds.map((id) => {
|
||||
const folder = foldersById[id];
|
||||
|
||||
@ -18,12 +18,12 @@ export type OwnProps = {
|
||||
};
|
||||
|
||||
type StateProps = {
|
||||
chatsById: Record<number, ApiChat>;
|
||||
pinnedIds?: number[];
|
||||
activeListIds?: number[];
|
||||
archivedListIds?: number[];
|
||||
orderedPinnedIds?: number[];
|
||||
currentUserId?: number;
|
||||
chatsById: Record<string, ApiChat>;
|
||||
pinnedIds?: string[];
|
||||
activeListIds?: string[];
|
||||
archivedListIds?: string[];
|
||||
orderedPinnedIds?: string[];
|
||||
currentUserId?: string;
|
||||
};
|
||||
|
||||
type DispatchProps = Pick<GlobalActions, 'setForwardChatId' | 'exitForwardMode' | 'loadMoreChats'>;
|
||||
@ -75,7 +75,7 @@ const ForwardPicker: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
], chatsById, undefined, priorityIds);
|
||||
}, [activeListIds, archivedListIds, chatsById, currentUserId, filter, lang, pinnedIds]);
|
||||
|
||||
const handleSelectUser = useCallback((userId: number) => {
|
||||
const handleSelectUser = useCallback((userId: string) => {
|
||||
setForwardChatId({ id: userId });
|
||||
}, [setForwardChatId]);
|
||||
|
||||
|
||||
@ -74,10 +74,10 @@ import PanZoom from './PanZoom';
|
||||
import './MediaViewer.scss';
|
||||
|
||||
type StateProps = {
|
||||
chatId?: number;
|
||||
chatId?: string;
|
||||
threadId?: number;
|
||||
messageId?: number;
|
||||
senderId?: number;
|
||||
senderId?: string;
|
||||
origin?: MediaViewerOrigin;
|
||||
avatarOwner?: ApiChat | ApiUser;
|
||||
profilePhotoIndex?: number;
|
||||
@ -139,7 +139,7 @@ const MediaViewer: FC<StateProps & DispatchProps> = ({
|
||||
|
||||
/* Animation */
|
||||
const animationKey = useRef<number>();
|
||||
const prevSenderId = usePrevious<number | undefined>(senderId);
|
||||
const prevSenderId = usePrevious<string | undefined>(senderId);
|
||||
if (isOpen && (!prevSenderId || prevSenderId !== senderId || !animationKey.current)) {
|
||||
animationKey.current = selectedMediaMessageIndex;
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@ import { withGlobal } from '../../lib/teact/teactn';
|
||||
import { GlobalActions } from '../../global/types';
|
||||
import { ApiChat, ApiMessage, ApiUser } from '../../api/types';
|
||||
|
||||
import { getSenderTitle, isChatPrivate } from '../../modules/helpers';
|
||||
import { getSenderTitle, isUserId } from '../../modules/helpers';
|
||||
import { formatMediaDateTime } from '../../util/dateFormat';
|
||||
import renderText from '../common/helpers/renderText';
|
||||
import {
|
||||
@ -21,7 +21,7 @@ import Avatar from '../common/Avatar';
|
||||
import './SenderInfo.scss';
|
||||
|
||||
type OwnProps = {
|
||||
chatId?: number;
|
||||
chatId?: string;
|
||||
messageId?: number;
|
||||
isAvatar?: boolean;
|
||||
};
|
||||
@ -53,15 +53,14 @@ const SenderInfo: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const isFromChat = sender.id < 0;
|
||||
const senderTitle = getSenderTitle(lang, sender);
|
||||
|
||||
return (
|
||||
<div className="SenderInfo" onClick={handleFocusMessage}>
|
||||
{isFromChat ? (
|
||||
<Avatar key={sender.id} size="medium" chat={sender as ApiChat} />
|
||||
) : (
|
||||
{isUserId(sender.id) ? (
|
||||
<Avatar key={sender.id} size="medium" user={sender as ApiUser} />
|
||||
) : (
|
||||
<Avatar key={sender.id} size="medium" chat={sender as ApiChat} />
|
||||
)}
|
||||
<div className="meta">
|
||||
<div className="title" dir="auto">
|
||||
@ -81,7 +80,7 @@ export default withGlobal<OwnProps>(
|
||||
(global, { chatId, messageId, isAvatar }): StateProps => {
|
||||
if (isAvatar && chatId) {
|
||||
return {
|
||||
sender: isChatPrivate(chatId) ? selectUser(global, chatId) : selectChat(global, chatId),
|
||||
sender: isUserId(chatId) ? selectUser(global, chatId) : selectChat(global, chatId),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -36,11 +36,11 @@ type OwnProps = {
|
||||
};
|
||||
|
||||
type StateProps = {
|
||||
usersById: Record<number, ApiUser>;
|
||||
usersById: Record<string, ApiUser>;
|
||||
sender?: ApiUser | ApiChat;
|
||||
targetUserIds?: number[];
|
||||
targetUserIds?: string[];
|
||||
targetMessage?: ApiMessage;
|
||||
targetChatId?: number;
|
||||
targetChatId?: string;
|
||||
isFocused: boolean;
|
||||
focusDirection?: FocusDirection;
|
||||
noFocusHighlight?: boolean;
|
||||
|
||||
@ -10,13 +10,14 @@ import { pick } from '../../util/iteratees';
|
||||
import { selectChat } from '../../modules/selectors';
|
||||
import { useIntersectionObserver } from '../../hooks/useIntersectionObserver';
|
||||
import useLang from '../../hooks/useLang';
|
||||
import { getUserIdDividend } from '../../modules/helpers';
|
||||
|
||||
import StickerButton from '../common/StickerButton';
|
||||
|
||||
import './ContactGreeting.scss';
|
||||
|
||||
type OwnProps = {
|
||||
userId: number;
|
||||
userId: string;
|
||||
};
|
||||
|
||||
type StateProps = {
|
||||
@ -94,7 +95,8 @@ const ContactGreeting: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
export default memo(withGlobal<OwnProps>(
|
||||
(global, { userId }): StateProps => {
|
||||
const { stickers } = global.stickers.greeting;
|
||||
const sticker = stickers?.length ? stickers[userId % stickers.length] : undefined;
|
||||
const dividend = getUserIdDividend(userId) + getUserIdDividend(global.currentUserId!);
|
||||
const sticker = stickers?.length ? stickers[dividend % stickers.length] : undefined;
|
||||
const chat = selectChat(global, userId);
|
||||
if (!chat) {
|
||||
return {};
|
||||
@ -111,5 +113,4 @@ export default memo(withGlobal<OwnProps>(
|
||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
||||
'loadGreetingStickers', 'sendMessage', 'markMessageListRead',
|
||||
]),
|
||||
|
||||
)(ContactGreeting));
|
||||
|
||||
@ -7,7 +7,7 @@ import { GlobalActions } from '../../global/types';
|
||||
|
||||
import { selectCanDeleteSelectedMessages, selectCurrentChat, selectUser } from '../../modules/selectors';
|
||||
import {
|
||||
isChatPrivate,
|
||||
isUserId,
|
||||
getUserFirstOrLastName,
|
||||
getPrivateChatUserId,
|
||||
isChatBasicGroup,
|
||||
@ -115,7 +115,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
const { messageIds: selectedMessageIds } = global.selectedMessages || {};
|
||||
const { canDeleteForAll } = selectCanDeleteSelectedMessages(global);
|
||||
const chat = selectCurrentChat(global);
|
||||
const contactName = chat && isChatPrivate(chat.id)
|
||||
const contactName = chat && isUserId(chat.id)
|
||||
? getUserFirstOrLastName(selectUser(global, getPrivateChatUserId(chat)!))
|
||||
: undefined;
|
||||
|
||||
|
||||
@ -29,7 +29,7 @@ import Button from '../ui/Button';
|
||||
import HeaderMenuContainer from './HeaderMenuContainer.async';
|
||||
|
||||
interface OwnProps {
|
||||
chatId: number;
|
||||
chatId: string;
|
||||
threadId: number;
|
||||
messageListType: MessageListType;
|
||||
}
|
||||
|
||||
@ -14,7 +14,7 @@ import {
|
||||
} from '../../modules/selectors';
|
||||
import { pick } from '../../util/iteratees';
|
||||
import {
|
||||
isChatPrivate, getCanDeleteChat, selectIsChatMuted, getCanAddContact,
|
||||
isUserId, getCanDeleteChat, selectIsChatMuted, getCanAddContact,
|
||||
} from '../../modules/helpers';
|
||||
import useShowTransition from '../../hooks/useShowTransition';
|
||||
import useLang from '../../hooks/useLang';
|
||||
@ -31,7 +31,7 @@ type DispatchProps = Pick<GlobalActions, (
|
||||
)>;
|
||||
|
||||
export type OwnProps = {
|
||||
chatId: number;
|
||||
chatId: string;
|
||||
threadId: number;
|
||||
isOpen: boolean;
|
||||
anchor: IAnchorPosition;
|
||||
@ -253,7 +253,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
if (!chat || chat.isRestricted) {
|
||||
return {};
|
||||
}
|
||||
const isPrivate = isChatPrivate(chat.id);
|
||||
const isPrivate = isUserId(chat.id);
|
||||
const user = isPrivate ? selectUser(global, chatId) : undefined;
|
||||
const canAddContact = user && getCanAddContact(user);
|
||||
|
||||
|
||||
@ -28,7 +28,7 @@ import {
|
||||
} from '../../modules/selectors';
|
||||
import {
|
||||
isChatChannel,
|
||||
isChatPrivate,
|
||||
isUserId,
|
||||
isChatWithRepliesBot,
|
||||
isChatGroup,
|
||||
} from '../../modules/helpers';
|
||||
@ -56,7 +56,7 @@ import NoMessages from './NoMessages';
|
||||
import './MessageList.scss';
|
||||
|
||||
type OwnProps = {
|
||||
chatId: number;
|
||||
chatId: string;
|
||||
threadId: number;
|
||||
type: MessageListType;
|
||||
canPost: boolean;
|
||||
@ -447,10 +447,10 @@ const MessageList: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
|
||||
const lang = useLang();
|
||||
|
||||
const isPrivate = Boolean(chatId && isChatPrivate(chatId));
|
||||
const isPrivate = Boolean(chatId && isUserId(chatId));
|
||||
const withUsers = Boolean((!isPrivate && !isChannelChat) || isChatWithSelf || isRepliesChat);
|
||||
const noAvatars = Boolean(!withUsers || isChannelChat);
|
||||
const shouldRenderGreeting = isChatPrivate(chatId) && !isChatWithSelf && !isBot
|
||||
const shouldRenderGreeting = isUserId(chatId) && !isChatWithSelf && !isBot
|
||||
&& (
|
||||
(
|
||||
!messageGroups && !lastMessage && messageIds
|
||||
|
||||
@ -37,7 +37,7 @@ import {
|
||||
selectPinnedIds,
|
||||
selectTheme,
|
||||
} from '../../modules/selectors';
|
||||
import { getCanPostInChat, getMessageSendingRestrictionReason, isChatPrivate } from '../../modules/helpers';
|
||||
import { getCanPostInChat, getMessageSendingRestrictionReason, isUserId } from '../../modules/helpers';
|
||||
import captureEscKeyListener from '../../util/captureEscKeyListener';
|
||||
import { pick } from '../../util/iteratees';
|
||||
import buildClassName from '../../util/buildClassName';
|
||||
@ -64,7 +64,7 @@ import ReceiptModal from '../payment/ReceiptModal.async';
|
||||
import './MiddleColumn.scss';
|
||||
|
||||
type StateProps = {
|
||||
chatId?: number;
|
||||
chatId?: string;
|
||||
threadId?: number;
|
||||
messageListType?: MessageListType;
|
||||
isPrivate?: boolean;
|
||||
@ -477,7 +477,7 @@ export default memo(withGlobal(
|
||||
chatId,
|
||||
threadId,
|
||||
messageListType,
|
||||
isPrivate: isChatPrivate(chatId),
|
||||
isPrivate: isUserId(chatId),
|
||||
canPost: !isPinnedMessageList && (!chat || canPost) && !isBotNotStarted,
|
||||
isPinnedMessageList,
|
||||
isScheduledMessageList,
|
||||
|
||||
@ -23,7 +23,7 @@ import {
|
||||
} from '../../config';
|
||||
import { IS_SINGLE_COLUMN_LAYOUT, IS_TABLET_COLUMN_LAYOUT } from '../../util/environment';
|
||||
import {
|
||||
isChatPrivate,
|
||||
isUserId,
|
||||
getMessageKey,
|
||||
getChatTitle,
|
||||
getSenderTitle,
|
||||
@ -68,7 +68,7 @@ const ANIMATION_DURATION = 350;
|
||||
const BACK_BUTTON_INACTIVE_TIME = 450;
|
||||
|
||||
type OwnProps = {
|
||||
chatId: number;
|
||||
chatId: string;
|
||||
threadId: number;
|
||||
messageListType: MessageListType;
|
||||
isReady?: boolean;
|
||||
@ -85,7 +85,7 @@ type StateProps = {
|
||||
isLeftColumnShown?: boolean;
|
||||
isRightColumnShown?: boolean;
|
||||
audioMessage?: ApiMessage;
|
||||
chatsById?: Record<number, ApiChat>;
|
||||
chatsById?: Record<string, ApiChat>;
|
||||
messagesCount?: number;
|
||||
isChatWithSelf?: boolean;
|
||||
isChatWithBot?: boolean;
|
||||
@ -348,7 +348,7 @@ const MiddleHeader: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
<>
|
||||
{(isLeftColumnHideable || currentTransitionKey > 0) && renderBackButton(shouldShowCloseButton, true)}
|
||||
<div className="chat-info-wrapper" onClick={handleHeaderClick}>
|
||||
{isChatPrivate(chatId) ? (
|
||||
{isUserId(chatId) ? (
|
||||
<PrivateChatInfo
|
||||
userId={chatId}
|
||||
typingStatus={typingStatus}
|
||||
|
||||
@ -7,7 +7,7 @@ import useLang, { LangFn } from '../../hooks/useLang';
|
||||
import './NoMessages.scss';
|
||||
|
||||
type OwnProps = {
|
||||
chatId: number;
|
||||
chatId: string;
|
||||
isChatWithSelf?: boolean;
|
||||
type: MessageListType;
|
||||
isGroupChatJustCreated?: boolean;
|
||||
|
||||
@ -31,9 +31,9 @@ export type OwnProps = {
|
||||
attachments: ApiAttachment[];
|
||||
caption: string;
|
||||
isReady?: boolean;
|
||||
currentUserId?: number;
|
||||
currentUserId?: string;
|
||||
groupChatMembers?: ApiChatMember[];
|
||||
usersById?: Record<number, ApiUser>;
|
||||
usersById?: Record<string, ApiUser>;
|
||||
recentEmojis: string[];
|
||||
baseEmojiKeywords?: Record<string, string[]>;
|
||||
emojiKeywords?: Record<string, string[]>;
|
||||
|
||||
@ -26,7 +26,7 @@ export type OwnProps = {
|
||||
};
|
||||
|
||||
type StateProps = {
|
||||
usersById: Record<number, ApiUser>;
|
||||
usersById: Record<string, ApiUser>;
|
||||
};
|
||||
|
||||
type DispatchProps = Pick<GlobalActions, 'sendBotCommand'>;
|
||||
|
||||
@ -41,7 +41,7 @@ import {
|
||||
import {
|
||||
getAllowedAttachmentOptions,
|
||||
getChatSlowModeOptions,
|
||||
isChatPrivate,
|
||||
isUserId,
|
||||
isChatAdmin,
|
||||
} from '../../../modules/helpers';
|
||||
import { formatMediaDuration, formatVoiceRecordDuration, getDayStartAt } from '../../../util/dateFormat';
|
||||
@ -98,7 +98,7 @@ import CalendarModal from '../../common/CalendarModal.async';
|
||||
import './Composer.scss';
|
||||
|
||||
type OwnProps = {
|
||||
chatId: number;
|
||||
chatId: string;
|
||||
threadId: number;
|
||||
messageListType: MessageListType;
|
||||
dropAreaState: string;
|
||||
@ -123,8 +123,8 @@ type StateProps = {
|
||||
canScheduleUntilOnline?: boolean;
|
||||
stickersForEmoji?: ApiSticker[];
|
||||
groupChatMembers?: ApiChatMember[];
|
||||
currentUserId?: number;
|
||||
usersById?: Record<number, ApiUser>;
|
||||
currentUserId?: string;
|
||||
usersById?: Record<string, ApiUser>;
|
||||
recentEmojis: string[];
|
||||
lastSyncTime?: number;
|
||||
contentToBeScheduled?: GlobalState['messages']['contentToBeScheduled'];
|
||||
@ -132,7 +132,7 @@ type StateProps = {
|
||||
baseEmojiKeywords?: Record<string, string[]>;
|
||||
emojiKeywords?: Record<string, string[]>;
|
||||
serverTimeOffset: number;
|
||||
topInlineBotIds?: number[];
|
||||
topInlineBotIds?: string[];
|
||||
isInlineBotLoading: boolean;
|
||||
inlineBots?: Record<string, false | InlineBotSettings>;
|
||||
botCommands?: ApiBotCommand[] | false;
|
||||
@ -1069,7 +1069,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
isChatWithSelf,
|
||||
canScheduleUntilOnline: (
|
||||
!isChatWithSelf && !isChatWithBot
|
||||
&& (chat && chatUser && isChatPrivate(chatId) && chatUser.status && Boolean(chatUser.status.wasOnline))
|
||||
&& (chat && chatUser && isUserId(chatId) && chatUser.status && Boolean(chatUser.status.wasOnline))
|
||||
),
|
||||
isRightColumnShown: selectIsRightColumnShown(global),
|
||||
isSelectModeActive: selectIsInSelectMode(global),
|
||||
|
||||
@ -23,7 +23,7 @@ import { pick } from '../../../util/iteratees';
|
||||
import useAsyncRendering from '../../right/hooks/useAsyncRendering';
|
||||
import useShowTransition from '../../../hooks/useShowTransition';
|
||||
import buildClassName from '../../../util/buildClassName';
|
||||
import { isChatPrivate } from '../../../modules/helpers';
|
||||
import { isUserId } from '../../../modules/helpers';
|
||||
|
||||
import Button from '../../ui/Button';
|
||||
import EmbeddedMessage from '../../common/EmbeddedMessage';
|
||||
@ -154,7 +154,7 @@ export default memo(withGlobal(
|
||||
sender = selectSender(global, message);
|
||||
}
|
||||
} else if (isForwarding) {
|
||||
sender = isChatPrivate(fromChatId!) ? selectUser(global, fromChatId!) : selectChat(global, fromChatId!);
|
||||
sender = isUserId(fromChatId!) ? selectUser(global, fromChatId!) : selectChat(global, fromChatId!);
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@ -32,7 +32,7 @@ const runThrottled = throttle((cb) => cb(), 500, true);
|
||||
|
||||
export type OwnProps = {
|
||||
isOpen: boolean;
|
||||
botId?: number;
|
||||
botId?: string;
|
||||
isGallery?: boolean;
|
||||
allowedAttachmentOptions: IAllowedAttachmentOptions;
|
||||
inlineBotResults?: (ApiBotInlineResult | ApiBotInlineMediaResult)[];
|
||||
|
||||
@ -20,7 +20,7 @@ export type OwnProps = {
|
||||
onClose: () => void;
|
||||
onInsertUserName: (user: ApiUser, forceFocus?: boolean) => void;
|
||||
filteredUsers?: ApiUser[];
|
||||
usersById?: Record<number, ApiUser>;
|
||||
usersById?: Record<string, ApiUser>;
|
||||
};
|
||||
|
||||
const MentionTooltip: FC<OwnProps> = ({
|
||||
@ -34,7 +34,7 @@ const MentionTooltip: FC<OwnProps> = ({
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const { shouldRender, transitionClassNames } = useShowTransition(isOpen, undefined, undefined, false);
|
||||
|
||||
const handleUserSelect = useCallback((userId: number, forceFocus = false) => {
|
||||
const handleUserSelect = useCallback((userId: string, forceFocus = false) => {
|
||||
const user = usersById?.[userId];
|
||||
if (!user) {
|
||||
return;
|
||||
|
||||
@ -47,7 +47,7 @@ type OwnProps = {
|
||||
};
|
||||
|
||||
type StateProps = {
|
||||
currentChatId?: number;
|
||||
currentChatId?: string;
|
||||
replyingToId?: number;
|
||||
noTabCapture?: boolean;
|
||||
messageSendKeyCombo?: ISettings['messageSendKeyCombo'];
|
||||
|
||||
@ -22,7 +22,7 @@ import Button from '../../ui/Button';
|
||||
import './WebPagePreview.scss';
|
||||
|
||||
type OwnProps = {
|
||||
chatId: number;
|
||||
chatId: string;
|
||||
threadId: number;
|
||||
messageText: string;
|
||||
disabled?: boolean;
|
||||
|
||||
@ -14,12 +14,12 @@ import useBeforeUnload from '../../../../hooks/useBeforeUnload';
|
||||
import { IS_TOUCH_ENV } from '../../../../util/environment';
|
||||
|
||||
// Used to avoid running debounced callbacks when chat changes.
|
||||
let currentChatId: number | undefined;
|
||||
let currentChatId: string | undefined;
|
||||
let currentThreadId: number | undefined;
|
||||
|
||||
export default (
|
||||
draft: ApiFormattedText | undefined,
|
||||
chatId: number,
|
||||
chatId: string,
|
||||
threadId: number,
|
||||
html: string,
|
||||
htmlRef: { current: string },
|
||||
@ -28,7 +28,7 @@ export default (
|
||||
saveDraft: GlobalActions['saveDraft'],
|
||||
clearDraft: GlobalActions['clearDraft'],
|
||||
) => {
|
||||
const updateDraft = useCallback((draftChatId: number, draftThreadId: number) => {
|
||||
const updateDraft = useCallback((draftChatId: string, draftThreadId: number) => {
|
||||
if (htmlRef.current.length && !editedMessage) {
|
||||
saveDraft({ chatId: draftChatId, threadId: draftThreadId, draft: parseMessageInput(htmlRef.current!) });
|
||||
} else {
|
||||
|
||||
@ -10,7 +10,7 @@ const HAS_NEW_LINE = /^@([a-z0-9_]{1,32})[\u00A0\u0020]+\n{2,}/i;
|
||||
|
||||
export default function useInlineBotTooltip(
|
||||
isAllowed: boolean,
|
||||
chatId: number,
|
||||
chatId: string,
|
||||
html: string,
|
||||
inlineBots?: Record<string, false | InlineBotSettings>,
|
||||
) {
|
||||
|
||||
@ -28,9 +28,9 @@ export default function useMentionTooltip(
|
||||
onUpdateHtml: (html: string) => void,
|
||||
inputId: string = EDITABLE_INPUT_ID,
|
||||
groupChatMembers?: ApiChatMember[],
|
||||
topInlineBotIds?: number[],
|
||||
currentUserId?: number,
|
||||
usersById?: Record<number, ApiUser>,
|
||||
topInlineBotIds?: string[],
|
||||
currentUserId?: string,
|
||||
usersById?: Record<string, ApiUser>,
|
||||
) {
|
||||
const [isOpen, markIsOpen, unmarkIsOpen] = useFlag();
|
||||
const [usersToMention, setUsersToMention] = useState<ApiUser[] | undefined>();
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user