fix(client): avoid secondary db calls in resolvePeer

This commit is contained in:
teidesu 2021-05-22 18:58:17 +03:00
parent 126ed3016d
commit 649f86f3ed

View file

@ -4,6 +4,7 @@ import { InputPeerLike, MtCuteNotFoundError } from '../../types'
import { getBasicPeerType, MAX_CHANNEL_ID } from '@mtcute/core'
import bigInt from 'big-integer'
import { normalizeToInputPeer } from '../../utils/peer-utils'
import { assertTypeIs } from '../../utils/type-assertion'
/**
* Get the `InputPeer` of a known peer id.
@ -27,27 +28,73 @@ export async function resolvePeer(
if (typeof peerId === 'string') {
if (peerId === 'self' || peerId === 'me') return { _: 'inputPeerSelf' }
peerId = peerId.replace(/[@+\s]/g, '')
peerId = peerId.replace(/[@+\s()]/g, '')
if (peerId.match(/^\d+$/)) {
// phone number
const fromStorage = await this.storage.getPeerByPhone(peerId)
if (fromStorage) return fromStorage
const res = await this.call({
_: 'contacts.getContacts',
hash: 0,
})
assertTypeIs('contacts.getContacts', res, 'contacts.contacts')
const found = res.users.find(
(it) => (it as tl.RawUser).phone === peerId
)
if (found && found._ === 'user')
return {
_: 'inputPeerUser',
userId: found.id,
accessHash: found.accessHash!,
}
throw new MtCuteNotFoundError(
`Could not find a peer by phone ${peerId}`
)
} else {
// username
let fromStorage = await this.storage.getPeerByUsername(peerId)
const fromStorage = await this.storage.getPeerByUsername(peerId)
if (fromStorage) return fromStorage
await this.call({
const res = await this.call({
_: 'contacts.resolveUsername',
username: peerId,
})
fromStorage = await this.storage.getPeerByUsername(peerId)
if (fromStorage) return fromStorage
if (res.peer._ === 'peerUser') {
const id = res.peer.userId
const found = res.users.find((it) => it.id === id)
if (found && found._ === 'user')
return {
_: 'inputPeerUser',
userId: found.id,
accessHash: found.accessHash!,
}
} else {
const id = res.peer._ === 'peerChannel' ? res.peer.channelId : res.peer.chatId
const found = res.chats.find((it) => it.id === id)
if (found)
switch (found._) {
case 'channel':
case 'channelForbidden':
return {
_: 'inputPeerChannel',
channelId: found.id,
accessHash: found.accessHash!
}
case 'chat':
case 'chatForbidden':
return {
_: 'inputPeerChat',
chatId: found.id
}
}
}
throw new MtCuteNotFoundError(
`Could not find a peer by username ${peerId}`
@ -57,9 +104,10 @@ export async function resolvePeer(
const peerType = getBasicPeerType(peerId)
// try fetching by id, with access_hash set to 0
switch (peerType) {
case 'user':
await this.call({
case 'user': {
const res = await this.call({
_: 'users.getUsers',
id: [
{
@ -69,15 +117,41 @@ export async function resolvePeer(
},
],
})
const found = res.find((it) => it.id === peerId)
if (found && found._ === 'user')
return {
_: 'inputPeerUser',
userId: found.id,
accessHash: found.accessHash!,
}
break
case 'chat':
await this.call({
_: 'messages.getChats',
id: [-peerId],
})
break
case 'channel':
await this.call({
}
case 'chat': {
// do we really need to make a call?
// const id = -peerId
// const res = await this.call({
// _: 'messages.getChats',
// id: [id],
// })
//
// const found = res.chats.find((it) => it.id === id)
// if (found && (found._ === 'chat' || found._ === 'chatForbidden'))
// return {
// _: 'inputPeerChat',
// chatId: found.id
// }
return {
_: 'inputPeerChat',
chatId: -peerId
}
// break
}
case 'channel': {
const id = MAX_CHANNEL_ID - peerId
const res = await this.call({
_: 'channels.getChannels',
id: [
{
@ -87,11 +161,18 @@ export async function resolvePeer(
},
],
})
break
}
const fromStorage = await this.storage.getPeerById(peerId)
if (fromStorage) return fromStorage
const found = res.chats.find((it) => it.id === id)
if (found && (found._ === 'channel' || found._ === 'channelForbidden'))
return {
_: 'inputPeerChannel',
channelId: found.id,
accessHash: found.accessHash!,
}
break
}
}
throw new MtCuteNotFoundError(`Could not find a peer by ID ${peerId}`)
}