mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
126 lines
5.9 KiB
Swift
126 lines
5.9 KiB
Swift
import Foundation
|
|
import Postbox
|
|
import TelegramApi
|
|
import SwiftSignalKit
|
|
|
|
public enum ResolvePeerByNameOptionCached {
|
|
case none
|
|
case cached
|
|
case cachedIfLaterThan(timestamp: Int32)
|
|
}
|
|
|
|
public enum ResolvePeerByNameOptionRemote {
|
|
case updateIfEarlierThan(timestamp: Int32)
|
|
case update
|
|
}
|
|
|
|
public enum ResolvePeerIdByNameResult {
|
|
case progress
|
|
case result(PeerId?)
|
|
}
|
|
|
|
public enum ResolvePeerResult {
|
|
case progress
|
|
case result(EnginePeer?)
|
|
}
|
|
|
|
func _internal_resolvePeerByName(account: Account, name: String, ageLimit: Int32 = 2 * 60 * 60 * 24) -> Signal<ResolvePeerIdByNameResult, NoError> {
|
|
var normalizedName = name
|
|
if normalizedName.hasPrefix("@") {
|
|
normalizedName = String(normalizedName[name.index(after: name.startIndex)...])
|
|
}
|
|
|
|
let accountPeerId = account.peerId
|
|
|
|
return account.postbox.transaction { transaction -> CachedResolvedByNamePeer? in
|
|
return transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.resolvedByNamePeers, key: CachedResolvedByNamePeer.key(name: normalizedName)))?.get(CachedResolvedByNamePeer.self)
|
|
}
|
|
|> mapToSignal { cachedEntry -> Signal<ResolvePeerIdByNameResult, NoError> in
|
|
let timestamp = Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970)
|
|
if let cachedEntry = cachedEntry, cachedEntry.timestamp <= timestamp && cachedEntry.timestamp >= timestamp - ageLimit {
|
|
return .single(.result(cachedEntry.peerId))
|
|
} else {
|
|
return .single(.progress)
|
|
|> then(account.network.request(Api.functions.contacts.resolveUsername(flags: 0, username: normalizedName, referer: nil))
|
|
|> mapError { _ -> Void in
|
|
return Void()
|
|
}
|
|
|> mapToSignal { result -> Signal<ResolvePeerIdByNameResult, Void> in
|
|
return account.postbox.transaction { transaction -> ResolvePeerIdByNameResult in
|
|
var peerId: PeerId? = nil
|
|
|
|
switch result {
|
|
case let .resolvedPeer(apiPeer, chats, users):
|
|
let parsedPeers = AccumulatedPeers(transaction: transaction, chats: chats, users: users)
|
|
|
|
if let peer = parsedPeers.get(apiPeer.peerId) {
|
|
peerId = peer.id
|
|
|
|
updatePeers(transaction: transaction, accountPeerId: accountPeerId, peers: parsedPeers)
|
|
}
|
|
}
|
|
|
|
let timestamp = Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970)
|
|
if let entry = CodableEntry(CachedResolvedByNamePeer(peerId: peerId, timestamp: timestamp)) {
|
|
transaction.putItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.resolvedByNamePeers, key: CachedResolvedByNamePeer.key(name: normalizedName)), entry: entry)
|
|
}
|
|
return .result(peerId)
|
|
}
|
|
|> castError(Void.self)
|
|
}
|
|
|> `catch` { _ -> Signal<ResolvePeerIdByNameResult, NoError> in
|
|
return .single(.result(nil))
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
func _internal_resolvePeerByPhone(account: Account, phone: String, ageLimit: Int32 = 2 * 60 * 60 * 24) -> Signal<PeerId?, NoError> {
|
|
var normalizedPhone = phone
|
|
if normalizedPhone.hasPrefix("+") {
|
|
normalizedPhone = String(normalizedPhone[normalizedPhone.index(after: normalizedPhone.startIndex)...])
|
|
}
|
|
|
|
let accountPeerId = account.peerId
|
|
|
|
return account.postbox.transaction { transaction -> CachedResolvedByPhonePeer? in
|
|
return transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.resolvedByPhonePeers, key: CachedResolvedByPhonePeer.key(name: normalizedPhone)))?.get(CachedResolvedByPhonePeer.self)
|
|
} |> mapToSignal { cachedEntry -> Signal<PeerId?, NoError> in
|
|
let timestamp = Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970)
|
|
if let cachedEntry = cachedEntry, cachedEntry.timestamp <= timestamp && cachedEntry.timestamp >= timestamp - ageLimit {
|
|
return .single(cachedEntry.peerId)
|
|
} else {
|
|
return account.network.request(Api.functions.contacts.resolvePhone(phone: normalizedPhone))
|
|
|> mapError { _ -> Void in
|
|
return Void()
|
|
}
|
|
|> mapToSignal { result -> Signal<PeerId?, Void> in
|
|
return account.postbox.transaction { transaction -> PeerId? in
|
|
var peerId: PeerId? = nil
|
|
|
|
switch result {
|
|
case let .resolvedPeer(apiPeer, chats, users):
|
|
let parsedPeers = AccumulatedPeers(transaction: transaction, chats: chats, users: users)
|
|
|
|
if let peer = parsedPeers.get(apiPeer.peerId) {
|
|
peerId = peer.id
|
|
|
|
updatePeers(transaction: transaction, accountPeerId: accountPeerId, peers: parsedPeers)
|
|
}
|
|
}
|
|
|
|
let timestamp = Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970)
|
|
if let entry = CodableEntry(CachedResolvedByPhonePeer(peerId: peerId, timestamp: timestamp)) {
|
|
transaction.putItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.resolvedByPhonePeers, key: CachedResolvedByPhonePeer.key(name: normalizedPhone)), entry: entry)
|
|
}
|
|
return peerId
|
|
}
|
|
|> castError(Void.self)
|
|
}
|
|
|> `catch` { _ -> Signal<PeerId?, NoError> in
|
|
return .single(nil)
|
|
}
|
|
}
|
|
}
|
|
}
|