Refactoring

This commit is contained in:
Ali 2021-07-22 00:18:19 +02:00
parent 1a04fb4408
commit c9f009eae7
59 changed files with 614 additions and 399 deletions

View File

@ -1,6 +1,5 @@
import Foundation import Foundation
import UIKit import UIKit
import Postbox
import TelegramCore import TelegramCore
import TextFormat import TextFormat
import AsyncDisplayKit import AsyncDisplayKit
@ -8,24 +7,25 @@ import Display
import SwiftSignalKit import SwiftSignalKit
import TelegramPresentationData import TelegramPresentationData
import TelegramUIPreferences import TelegramUIPreferences
import Postbox
public final class ChatMessageItemAssociatedData: Equatable { public final class ChatMessageItemAssociatedData: Equatable {
public enum ChannelDiscussionGroupStatus: Equatable { public enum ChannelDiscussionGroupStatus: Equatable {
case unknown case unknown
case known(PeerId?) case known(EnginePeer.Id?)
} }
public let automaticDownloadPeerType: MediaAutoDownloadPeerType public let automaticDownloadPeerType: MediaAutoDownloadPeerType
public let automaticDownloadNetworkType: MediaAutoDownloadNetworkType public let automaticDownloadNetworkType: MediaAutoDownloadNetworkType
public let isRecentActions: Bool public let isRecentActions: Bool
public let subject: ChatControllerSubject? public let subject: ChatControllerSubject?
public let contactsPeerIds: Set<PeerId> public let contactsPeerIds: Set<EnginePeer.Id>
public let channelDiscussionGroup: ChannelDiscussionGroupStatus public let channelDiscussionGroup: ChannelDiscussionGroupStatus
public let animatedEmojiStickers: [String: [StickerPackItem]] public let animatedEmojiStickers: [String: [StickerPackItem]]
public let forcedResourceStatus: FileMediaResourceStatus? public let forcedResourceStatus: FileMediaResourceStatus?
public let currentlyPlayingMessageId: MessageIndex? public let currentlyPlayingMessageId: EngineMessage.Index?
public init(automaticDownloadPeerType: MediaAutoDownloadPeerType, automaticDownloadNetworkType: MediaAutoDownloadNetworkType, isRecentActions: Bool = false, subject: ChatControllerSubject? = nil, contactsPeerIds: Set<PeerId> = Set(), channelDiscussionGroup: ChannelDiscussionGroupStatus = .unknown, animatedEmojiStickers: [String: [StickerPackItem]] = [:], forcedResourceStatus: FileMediaResourceStatus? = nil, currentlyPlayingMessageId: MessageIndex? = nil) { public init(automaticDownloadPeerType: MediaAutoDownloadPeerType, automaticDownloadNetworkType: MediaAutoDownloadNetworkType, isRecentActions: Bool = false, subject: ChatControllerSubject? = nil, contactsPeerIds: Set<EnginePeer.Id> = Set(), channelDiscussionGroup: ChannelDiscussionGroupStatus = .unknown, animatedEmojiStickers: [String: [StickerPackItem]] = [:], forcedResourceStatus: FileMediaResourceStatus? = nil, currentlyPlayingMessageId: EngineMessage.Index? = nil) {
self.automaticDownloadPeerType = automaticDownloadPeerType self.automaticDownloadPeerType = automaticDownloadPeerType
self.automaticDownloadNetworkType = automaticDownloadNetworkType self.automaticDownloadNetworkType = automaticDownloadNetworkType
self.isRecentActions = isRecentActions self.isRecentActions = isRecentActions
@ -79,7 +79,7 @@ public extension ChatMessageItemAssociatedData {
public enum ChatControllerInteractionLongTapAction { public enum ChatControllerInteractionLongTapAction {
case url(String) case url(String)
case mention(String) case mention(String)
case peerMention(PeerId, String) case peerMention(EnginePeer.Id, String)
case command(String) case command(String)
case hashtag(String) case hashtag(String)
case timecode(Double, String) case timecode(Double, String)
@ -110,7 +110,7 @@ public enum ChatHistoryMessageSelection: Equatable {
public enum ChatControllerInitialBotStartBehavior { public enum ChatControllerInitialBotStartBehavior {
case interactive case interactive
case automatic(returnToPeerId: PeerId, scheduled: Bool) case automatic(returnToPeerId: EnginePeer.Id, scheduled: Bool)
} }
public struct ChatControllerInitialBotStart { public struct ChatControllerInitialBotStart {
@ -171,7 +171,7 @@ public enum ChatTextInputStateTextAttributeType: PostboxCoding, Equatable {
case bold case bold
case italic case italic
case monospace case monospace
case textMention(PeerId) case textMention(EnginePeer.Id)
case textUrl(String) case textUrl(String)
public init(decoder: PostboxDecoder) { public init(decoder: PostboxDecoder) {
@ -183,7 +183,7 @@ public enum ChatTextInputStateTextAttributeType: PostboxCoding, Equatable {
case 2: case 2:
self = .monospace self = .monospace
case 3: case 3:
self = .textMention(PeerId(decoder.decodeInt64ForKey("peerId", orElse: 0))) self = .textMention(EnginePeer.Id(decoder.decodeInt64ForKey("peerId", orElse: 0)))
case 4: case 4:
self = .textUrl(decoder.decodeStringForKey("url", orElse: "")) self = .textUrl(decoder.decodeStringForKey("url", orElse: ""))
default: default:
@ -340,9 +340,9 @@ public struct ChatTextInputStateText: PostboxCoding, Equatable {
} }
public enum ChatControllerSubject: Equatable { public enum ChatControllerSubject: Equatable {
case message(id: MessageId, highlight: Bool, timecode: Double?) case message(id: EngineMessage.Id, highlight: Bool, timecode: Double?)
case scheduledMessages case scheduledMessages
case pinnedMessages(id: MessageId?) case pinnedMessages(id: EngineMessage.Id?)
} }
public enum ChatControllerPresentationMode: Equatable { public enum ChatControllerPresentationMode: Equatable {
@ -382,10 +382,10 @@ public final class ChatEmbeddedInterfaceState: PeerChatListEmbeddedInterfaceStat
public enum ChatPresentationInputQueryResult: Equatable { public enum ChatPresentationInputQueryResult: Equatable {
case stickers([FoundStickerItem]) case stickers([FoundStickerItem])
case hashtags([String]) case hashtags([String])
case mentions([Peer]) case mentions([EnginePeer])
case commands([PeerCommand]) case commands([PeerCommand])
case emojis([(String, String)], NSRange) case emojis([(String, String)], NSRange)
case contextRequestResult(Peer?, ChatContextResultCollection?) case contextRequestResult(EnginePeer?, ChatContextResultCollection?)
public static func ==(lhs: ChatPresentationInputQueryResult, rhs: ChatPresentationInputQueryResult) -> Bool { public static func ==(lhs: ChatPresentationInputQueryResult, rhs: ChatPresentationInputQueryResult) -> Bool {
switch lhs { switch lhs {
@ -403,16 +403,10 @@ public enum ChatPresentationInputQueryResult: Equatable {
} }
case let .mentions(lhsPeers): case let .mentions(lhsPeers):
if case let .mentions(rhsPeers) = rhs { if case let .mentions(rhsPeers) = rhs {
if lhsPeers.count != rhsPeers.count { if lhsPeers != rhsPeers {
return false return false
} else {
for i in 0 ..< lhsPeers.count {
if !lhsPeers[i].isEqual(rhsPeers[i]) {
return false
}
}
return true
} }
return true
} else { } else {
return false return false
} }
@ -444,14 +438,9 @@ public enum ChatPresentationInputQueryResult: Equatable {
} }
case let .contextRequestResult(lhsPeer, lhsCollection): case let .contextRequestResult(lhsPeer, lhsCollection):
if case let .contextRequestResult(rhsPeer, rhsCollection) = rhs { if case let .contextRequestResult(rhsPeer, rhsCollection) = rhs {
if let lhsPeer = lhsPeer, let rhsPeer = rhsPeer { if lhsPeer != rhsPeer {
if !lhsPeer.isEqual(rhsPeer) {
return false
}
} else if (lhsPeer != nil) != (rhsPeer != nil) {
return false return false
} }
if lhsCollection != rhsCollection { if lhsCollection != rhsCollection {
return false return false
} }
@ -483,7 +472,7 @@ public protocol ChatController: ViewController {
var isSendButtonVisible: Bool { get } var isSendButtonVisible: Bool { get }
} }
public protocol ChatMessagePreviewItemNode: class { public protocol ChatMessagePreviewItemNode: AnyObject {
var forwardInfoReferenceNode: ASDisplayNode? { get } var forwardInfoReferenceNode: ASDisplayNode? { get }
} }

View File

@ -829,11 +829,6 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
var items: [ActionSheetItem] = [] var items: [ActionSheetItem] = []
var personalPeerName: String? var personalPeerName: String?
var isChannel = false var isChannel = false
// if let user = peer as? TelegramUser {
// personalPeerName = user.compactDisplayTitle
// } else if let channel = peer as? TelegramChannel, case .broadcast = channel.info {
// isChannel = true
// }
if actions.options.contains(.deleteGlobally) { if actions.options.contains(.deleteGlobally) {
let globalTitle: String let globalTitle: String

View File

@ -72,8 +72,8 @@ final class InstantPageFeedbackNode: ASDisplayNode, InstantPageNode {
} }
@objc func buttonPressed() { @objc func buttonPressed() {
self.resolveDisposable.set((self.context.engine.peers.resolvePeerByName(name: "previews") |> deliverOnMainQueue).start(next: { [weak self] peerId in self.resolveDisposable.set((self.context.engine.peers.resolvePeerByName(name: "previews") |> deliverOnMainQueue).start(next: { [weak self] peer in
if let strongSelf = self, let _ = peerId, let webPageId = strongSelf.webPage.id?.id { if let strongSelf = self, let _ = peer, let webPageId = strongSelf.webPage.id?.id {
strongSelf.openUrl(InstantPageUrlItem(url: "https://t.me/previews?start=webpage\(webPageId)", webpageId: nil)) strongSelf.openUrl(InstantPageUrlItem(url: "https://t.me/previews?start=webpage\(webPageId)", webpageId: nil))
} }
})) }))

View File

@ -151,11 +151,9 @@ final class InstantPagePeerReferenceNode: ASDisplayNode, InstantPageNode {
|> mapToSignal({ peer -> Signal<Peer, NoError> in |> mapToSignal({ peer -> Signal<Peer, NoError> in
if let peer = peer as? TelegramChannel, let username = peer.username, peer.accessHash == nil { if let peer = peer as? TelegramChannel, let username = peer.username, peer.accessHash == nil {
return .single(peer) |> then(context.engine.peers.resolvePeerByName(name: username) return .single(peer) |> then(context.engine.peers.resolvePeerByName(name: username)
|> mapToSignal({ peerId -> Signal<Peer, NoError> in |> mapToSignal({ updatedPeer -> Signal<Peer, NoError> in
if let peerId = peerId { if let updatedPeer = updatedPeer {
return account.postbox.transaction({ transaction -> Peer in return .single(updatedPeer._asPeer())
return transaction.getPeer(peerId) ?? peer
})
} else { } else {
return .single(peer) return .single(peer)
} }

View File

@ -16,7 +16,7 @@ public func legacySuggestionContext(context: AccountContext, peerId: PeerId, cha
let disposable = searchPeerMembers(context: context, peerId: peerId, chatLocation: chatLocation, query: query, scope: .mention).start(next: { peers in let disposable = searchPeerMembers(context: context, peerId: peerId, chatLocation: chatLocation, query: query, scope: .mention).start(next: { peers in
let users = NSMutableArray() let users = NSMutableArray()
for peer in peers { for peer in peers {
if let peer = peer as? TelegramUser { if case let .user(peer) = peer {
let user = TGUser() let user = TGUser()
user.uid = peer.id.id._internalGetInt32Value() user.uid = peer.id.id._internalGetInt32Value()
user.firstName = peer.firstName user.firstName = peer.firstName

View File

@ -60,3 +60,13 @@ public extension Peer {
} }
} }
} }
public extension EnginePeer {
var compactDisplayTitle: String {
return self._asPeer().compactDisplayTitle
}
func displayTitle(strings: PresentationStrings, displayOrder: PresentationPersonNameOrder) -> String {
return self._asPeer().displayTitle(strings: strings, displayOrder: displayOrder)
}
}

View File

@ -38,11 +38,11 @@ public func nearbyVenues(context: AccountContext, latitude: Double, longitude: D
} |> mapToSignal { searchBotsConfiguration in } |> mapToSignal { searchBotsConfiguration in
return context.engine.peers.resolvePeerByName(name: searchBotsConfiguration.venueBotUsername ?? "foursquare") return context.engine.peers.resolvePeerByName(name: searchBotsConfiguration.venueBotUsername ?? "foursquare")
|> take(1) |> take(1)
|> mapToSignal { peerId -> Signal<ChatContextResultCollection?, NoError> in |> mapToSignal { peer -> Signal<ChatContextResultCollection?, NoError> in
guard let peerId = peerId else { guard let peer = peer else {
return .single(nil) return .single(nil)
} }
return context.engine.messages.requestChatContextResults(botId: peerId, peerId: context.account.peerId, query: query ?? "", location: .single((latitude, longitude)), offset: "") return context.engine.messages.requestChatContextResults(botId: peer.id, peerId: context.account.peerId, query: query ?? "", location: .single((latitude, longitude)), offset: "")
|> map { results -> ChatContextResultCollection? in |> map { results -> ChatContextResultCollection? in
return results?.results return results?.results
} }

View File

@ -761,9 +761,9 @@ public func channelPermissionsController(context: AccountContext, peerId origina
} }
pushControllerImpl?(controller) pushControllerImpl?(controller)
}, openChannelExample: { }, openChannelExample: {
resolveDisposable.set((context.engine.peers.resolvePeerByName(name: "durov") |> deliverOnMainQueue).start(next: { peerId in resolveDisposable.set((context.engine.peers.resolvePeerByName(name: "durov") |> deliverOnMainQueue).start(next: { peer in
if let peerId = peerId { if let peer = peer {
navigateToChatControllerImpl?(peerId) navigateToChatControllerImpl?(peer.id)
} }
})) }))
}, updateSlowmode: { value in }, updateSlowmode: { value in

View File

@ -401,10 +401,10 @@ public func groupStickerPackSetupController(context: AccountContext, peerId: Pee
}, updateSearchText: { text in }, updateSearchText: { text in
searchText.set(text) searchText.set(text)
}, openStickersBot: { }, openStickersBot: {
resolveDisposable.set((context.engine.peers.resolvePeerByName(name: "stickers") |> deliverOnMainQueue).start(next: { peerId in resolveDisposable.set((context.engine.peers.resolvePeerByName(name: "stickers") |> deliverOnMainQueue).start(next: { peer in
if let peerId = peerId { if let peer = peer {
dismissImpl?() dismissImpl?()
navigateToChatControllerImpl?(peerId) navigateToChatControllerImpl?(peer.id)
} }
})) }))
}) })

View File

@ -1,5 +1,4 @@
import Foundation import Foundation
import Postbox
import TelegramCore import TelegramCore
import SwiftSignalKit import SwiftSignalKit
import AccountContext import AccountContext
@ -9,32 +8,32 @@ public enum SearchPeerMembersScope {
case mention case mention
} }
public func searchPeerMembers(context: AccountContext, peerId: PeerId, chatLocation: ChatLocation, query: String, scope: SearchPeerMembersScope) -> Signal<[Peer], NoError> { public func searchPeerMembers(context: AccountContext, peerId: EnginePeer.Id, chatLocation: ChatLocation, query: String, scope: SearchPeerMembersScope) -> Signal<[EnginePeer], NoError> {
if peerId.namespace == Namespaces.Peer.CloudChannel { if peerId.namespace == Namespaces.Peer.CloudChannel {
return context.account.postbox.transaction { transaction -> CachedChannelData? in return context.engine.data.get(
return transaction.getPeerCachedData(peerId: peerId) as? CachedChannelData TelegramEngine.EngineData.Item.Peer.ParticipantCount(id: peerId)
} )
|> mapToSignal { cachedData -> Signal<([Peer], Bool), NoError> in |> mapToSignal { participantCount -> Signal<([EnginePeer], Bool), NoError> in
if case .peer = chatLocation, let cachedData = cachedData, let memberCount = cachedData.participantsSummary.memberCount, memberCount <= 64 { if case .peer = chatLocation, let memberCount = participantCount, memberCount <= 64 {
return Signal { subscriber in return Signal { subscriber in
let (disposable, _) = context.peerChannelMemberCategoriesContextsManager.recent(engine: context.engine, postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peerId, searchQuery: nil, requestUpdate: false, updated: { state in let (disposable, _) = context.peerChannelMemberCategoriesContextsManager.recent(engine: context.engine, postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peerId, searchQuery: nil, requestUpdate: false, updated: { state in
if case .ready = state.loadingState { if case .ready = state.loadingState {
let normalizedQuery = query.lowercased() let normalizedQuery = query.lowercased()
subscriber.putNext((state.list.compactMap { participant -> Peer? in subscriber.putNext((state.list.compactMap { participant -> EnginePeer? in
if participant.peer.isDeleted { if participant.peer.isDeleted {
return nil return nil
} }
if normalizedQuery.isEmpty { if normalizedQuery.isEmpty {
return participant.peer return EnginePeer(participant.peer)
} }
if normalizedQuery.isEmpty { if normalizedQuery.isEmpty {
return participant.peer return EnginePeer(participant.peer)
} else { } else {
if participant.peer.indexName.matchesByTokens(normalizedQuery) { if participant.peer.indexName.matchesByTokens(normalizedQuery) {
return participant.peer return EnginePeer(participant.peer)
} }
if let addressName = participant.peer.addressName, addressName.lowercased().hasPrefix(normalizedQuery) { if let addressName = participant.peer.addressName, addressName.lowercased().hasPrefix(normalizedQuery) {
return participant.peer return EnginePeer(participant.peer)
} }
return nil return nil
@ -59,7 +58,7 @@ public func searchPeerMembers(context: AccountContext, peerId: PeerId, chatLocat
if participant.peer.isDeleted { if participant.peer.isDeleted {
return nil return nil
} }
return participant.peer return EnginePeer(participant.peer)
}, true)) }, true))
} }
}) })
@ -74,7 +73,7 @@ public func searchPeerMembers(context: AccountContext, peerId: PeerId, chatLocat
if participant.peer.isDeleted { if participant.peer.isDeleted {
return nil return nil
} }
return participant.peer return EnginePeer(participant.peer)
}, true)) }, true))
} }
}) })
@ -85,16 +84,19 @@ public func searchPeerMembers(context: AccountContext, peerId: PeerId, chatLocat
} }
} |> runOn(Queue.mainQueue()) } |> runOn(Queue.mainQueue())
} }
|> mapToSignal { result, isReady -> Signal<[Peer], NoError> in |> mapToSignal { result, isReady -> Signal<[EnginePeer], NoError> in
switch scope { switch scope {
case .mention: case .mention:
return .single(result) return .single(result)
case .memberSuggestion: case .memberSuggestion:
return context.account.postbox.transaction { transaction -> [Peer] in return context.engine.data.get(
TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)
)
|> map { peer -> [EnginePeer] in
var result = result var result = result
let normalizedQuery = query.lowercased() let normalizedQuery = query.lowercased()
if isReady { if isReady {
if let channel = transaction.getPeer(peerId) as? TelegramChannel, case .group = channel.info { if case let .channel(channel) = peer, case .group = channel.info {
var matches = false var matches = false
if normalizedQuery.isEmpty { if normalizedQuery.isEmpty {
matches = true matches = true
@ -107,7 +109,7 @@ public func searchPeerMembers(context: AccountContext, peerId: PeerId, chatLocat
} }
} }
if matches { if matches {
result.insert(channel, at: 0) result.insert(.channel(channel), at: 0)
} }
} }
} }
@ -117,5 +119,8 @@ public func searchPeerMembers(context: AccountContext, peerId: PeerId, chatLocat
} }
} else { } else {
return context.engine.peers.searchGroupMembers(peerId: peerId, query: query) return context.engine.peers.searchGroupMembers(peerId: peerId, query: query)
|> map { peers -> [EnginePeer] in
return peers.map(EnginePeer.init)
}
} }
} }

View File

@ -580,9 +580,9 @@ public func installedStickerPacksController(context: AccountContext, mode: Insta
]) ])
presentControllerImpl?(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet)) presentControllerImpl?(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
}, openStickersBot: { }, openStickersBot: {
resolveDisposable.set((context.engine.peers.resolvePeerByName(name: "stickers") |> deliverOnMainQueue).start(next: { peerId in resolveDisposable.set((context.engine.peers.resolvePeerByName(name: "stickers") |> deliverOnMainQueue).start(next: { peer in
if let peerId = peerId { if let peer = peer {
navigateToChatControllerImpl?(peerId) navigateToChatControllerImpl?(peer.id)
} }
})) }))
}, openMasks: { }, openMasks: {

View File

@ -497,13 +497,9 @@ final class ThemeGridSearchContentNode: SearchDisplayControllerContentNode {
return .single(nil) return .single(nil)
} }
return context.engine.peers.resolvePeerByName(name: name) return context.engine.peers.resolvePeerByName(name: name)
|> mapToSignal { peerId -> Signal<Peer?, NoError> in |> mapToSignal { peer -> Signal<Peer?, NoError> in
if let peerId = peerId { if let peer = peer {
return context.account.postbox.loadedPeerWithId(peerId) return .single(peer._asPeer())
|> map { peer -> Peer? in
return peer
}
|> take(1)
} else { } else {
return .single(nil) return .single(nil)
} }

View File

@ -132,10 +132,9 @@ public final class StickerPackPreviewController: ViewController, StandalonePrese
let account = strongSelf.context.account let account = strongSelf.context.account
strongSelf.openMentionDisposable.set((strongSelf.context.engine.peers.resolvePeerByName(name: mention) strongSelf.openMentionDisposable.set((strongSelf.context.engine.peers.resolvePeerByName(name: mention)
|> mapToSignal { peerId -> Signal<Peer?, NoError> in |> mapToSignal { peer -> Signal<Peer?, NoError> in
if let peerId = peerId { if let peer = peer {
return account.postbox.loadedPeerWithId(peerId) return .single(peer._asPeer())
|> map(Optional.init)
} else { } else {
return .single(nil) return .single(nil)
} }

View File

@ -13,10 +13,8 @@ public enum InternalUpdaterError {
public func requestUpdatesXml(account: Account, source: String) -> Signal<Data, InternalUpdaterError> { public func requestUpdatesXml(account: Account, source: String) -> Signal<Data, InternalUpdaterError> {
return TelegramEngine(account: account).peers.resolvePeerByName(name: source) return TelegramEngine(account: account).peers.resolvePeerByName(name: source)
|> castError(InternalUpdaterError.self) |> castError(InternalUpdaterError.self)
|> mapToSignal { peerId -> Signal<Peer?, InternalUpdaterError> in |> mapToSignal { peer -> Signal<Peer?, InternalUpdaterError> in
return account.postbox.transaction { transaction in return .single(peer?._asPeer())
return peerId != nil ? transaction.getPeer(peerId!) : nil
} |> castError(InternalUpdaterError.self)
} }
|> mapToSignal { peer in |> mapToSignal { peer in
if let peer = peer, let inputPeer = apiInputPeer(peer) { if let peer = peer, let inputPeer = apiInputPeer(peer) {
@ -80,10 +78,8 @@ public enum AppUpdateDownloadResult {
public func downloadAppUpdate(account: Account, source: String, messageId: Int32) -> Signal<AppUpdateDownloadResult, InternalUpdaterError> { public func downloadAppUpdate(account: Account, source: String, messageId: Int32) -> Signal<AppUpdateDownloadResult, InternalUpdaterError> {
return TelegramEngine(account: account).peers.resolvePeerByName(name: source) return TelegramEngine(account: account).peers.resolvePeerByName(name: source)
|> castError(InternalUpdaterError.self) |> castError(InternalUpdaterError.self)
|> mapToSignal { peerId -> Signal<Peer?, InternalUpdaterError> in |> mapToSignal { peer -> Signal<Peer?, InternalUpdaterError> in
return account.postbox.transaction { transaction in return .single(peer?._asPeer())
return peerId != nil ? transaction.getPeer(peerId!) : nil
} |> castError(InternalUpdaterError.self)
} }
|> mapToSignal { peer in |> mapToSignal { peer in
if let peer = peer, let inputChannel = apiInputChannel(peer) { if let peer = peer, let inputChannel = apiInputChannel(peer) {

View File

@ -147,7 +147,7 @@ public struct TelegramChannelFlags: OptionSet {
public static let isGigagroup = TelegramChannelFlags(rawValue: 1 << 7) public static let isGigagroup = TelegramChannelFlags(rawValue: 1 << 7)
} }
public final class TelegramChannel: Peer { public final class TelegramChannel: Peer, Equatable {
public let id: PeerId public let id: PeerId
public let accessHash: TelegramPeerAccessHash? public let accessHash: TelegramPeerAccessHash?
public let title: String public let title: String
@ -267,30 +267,34 @@ public final class TelegramChannel: Peer {
return false return false
} }
if self.id != other.id || self.accessHash != other.accessHash || self.title != other.title || self.username != other.username || self.photo != other.photo { return self == other
}
public static func ==(lhs: TelegramChannel, rhs: TelegramChannel) -> Bool {
if lhs.id != rhs.id || lhs.accessHash != rhs.accessHash || lhs.title != rhs.title || lhs.username != rhs.username || lhs.photo != rhs.photo {
return false return false
} }
if self.creationDate != other.creationDate || self.version != other.version || self.participationStatus != other.participationStatus { if lhs.creationDate != rhs.creationDate || lhs.version != rhs.version || lhs.participationStatus != rhs.participationStatus {
return false return false
} }
if self.info != other.info || self.flags != other.flags || self.restrictionInfo != other.restrictionInfo { if lhs.info != rhs.info || lhs.flags != rhs.flags || lhs.restrictionInfo != rhs.restrictionInfo {
return false return false
} }
if self.adminRights != other.adminRights { if lhs.adminRights != rhs.adminRights {
return false return false
} }
if self.bannedRights != other.bannedRights { if lhs.bannedRights != rhs.bannedRights {
return false return false
} }
if self.defaultBannedRights != other.defaultBannedRights { if lhs.defaultBannedRights != rhs.defaultBannedRights {
return false return false
} }
return true return true
} }

View File

@ -74,7 +74,7 @@ public struct TelegramGroupToChannelMigrationReference: Equatable {
} }
} }
public final class TelegramGroup: Peer { public final class TelegramGroup: Peer, Equatable {
public let id: PeerId public let id: PeerId
public let title: String public let title: String
public let photo: [TelegramMediaImageRepresentation] public let photo: [TelegramMediaImageRepresentation]
@ -159,45 +159,49 @@ public final class TelegramGroup: Peer {
public func isEqual(_ other: Peer) -> Bool { public func isEqual(_ other: Peer) -> Bool {
if let other = other as? TelegramGroup { if let other = other as? TelegramGroup {
if self.id != other.id { return self == other
return false
}
if self.title != other.title {
return false
}
if self.photo != other.photo {
return false
}
if self.membership != other.membership {
return false
}
if self.version != other.version {
return false
}
if self.participantCount != other.participantCount {
return false
}
if self.role != other.role {
return false
}
if self.defaultBannedRights != other.defaultBannedRights {
return false
}
if self.migrationReference != other.migrationReference {
return false
}
if self.creationDate != other.creationDate {
return false
}
if self.flags != other.flags {
return false
}
return true
} else { } else {
return false return false
} }
} }
public static func ==(lhs: TelegramGroup, rhs: TelegramGroup) -> Bool {
if lhs.id != rhs.id {
return false
}
if lhs.title != rhs.title {
return false
}
if lhs.photo != rhs.photo {
return false
}
if lhs.membership != rhs.membership {
return false
}
if lhs.version != rhs.version {
return false
}
if lhs.participantCount != rhs.participantCount {
return false
}
if lhs.role != rhs.role {
return false
}
if lhs.defaultBannedRights != rhs.defaultBannedRights {
return false
}
if lhs.migrationReference != rhs.migrationReference {
return false
}
if lhs.creationDate != rhs.creationDate {
return false
}
if lhs.flags != rhs.flags {
return false
}
return true
}
public func updateFlags(flags: TelegramGroupFlags, version: Int) -> TelegramGroup { public func updateFlags(flags: TelegramGroupFlags, version: Int) -> TelegramGroup {
return TelegramGroup(id: self.id, title: self.title, photo: self.photo, participantCount: self.participantCount, role: self.role, membership: self.membership, flags: flags, defaultBannedRights: self.defaultBannedRights, migrationReference: self.migrationReference, creationDate: self.creationDate, version: version) return TelegramGroup(id: self.id, title: self.title, photo: self.photo, participantCount: self.participantCount, role: self.role, membership: self.membership, flags: flags, defaultBannedRights: self.defaultBannedRights, migrationReference: self.migrationReference, creationDate: self.creationDate, version: version)
} }

View File

@ -1,7 +1,7 @@
import Foundation import Foundation
import Postbox import Postbox
public final class TelegramSecretChat: Peer { public final class TelegramSecretChat: Peer, Equatable {
public let id: PeerId public let id: PeerId
public let regularPeerId: PeerId public let regularPeerId: PeerId
public let accessHash: Int64 public let accessHash: Int64
@ -57,11 +57,15 @@ public final class TelegramSecretChat: Peer {
public func isEqual(_ other: Peer) -> Bool { public func isEqual(_ other: Peer) -> Bool {
if let other = other as? TelegramSecretChat { if let other = other as? TelegramSecretChat {
return self.id == other.id && self.regularPeerId == other.regularPeerId && self.accessHash == other.accessHash && self.embeddedState == other.embeddedState && self.messageAutoremoveTimeout == other.messageAutoremoveTimeout && self.creationDate == other.creationDate && self.role == other.role return self == other
} else { } else {
return false return false
} }
} }
public static func ==(lhs: TelegramSecretChat, rhs: TelegramSecretChat) -> Bool {
return lhs.id == rhs.id && lhs.regularPeerId == rhs.regularPeerId && lhs.accessHash == rhs.accessHash && lhs.embeddedState == rhs.embeddedState && lhs.messageAutoremoveTimeout == rhs.messageAutoremoveTimeout && lhs.creationDate == rhs.creationDate && lhs.role == rhs.role
}
public func withUpdatedEmbeddedState(_ embeddedState: SecretChatEmbeddedPeerState) -> TelegramSecretChat { public func withUpdatedEmbeddedState(_ embeddedState: SecretChatEmbeddedPeerState) -> TelegramSecretChat {
return TelegramSecretChat(id: self.id, creationDate: self.creationDate, regularPeerId: self.regularPeerId, accessHash: self.accessHash, role: self.role, embeddedState: embeddedState, messageAutoremoveTimeout: self.messageAutoremoveTimeout) return TelegramSecretChat(id: self.id, creationDate: self.creationDate, regularPeerId: self.regularPeerId, accessHash: self.accessHash, role: self.role, embeddedState: embeddedState, messageAutoremoveTimeout: self.messageAutoremoveTimeout)

View File

@ -57,7 +57,7 @@ public struct BotUserInfo: PostboxCoding, Equatable {
} }
} }
public final class TelegramUser: Peer { public final class TelegramUser: Peer, Equatable {
public let id: PeerId public let id: PeerId
public let accessHash: TelegramPeerAccessHash? public let accessHash: TelegramPeerAccessHash?
public let firstName: String? public let firstName: String?
@ -198,45 +198,49 @@ public final class TelegramUser: Peer {
public func isEqual(_ other: Peer) -> Bool { public func isEqual(_ other: Peer) -> Bool {
if let other = other as? TelegramUser { if let other = other as? TelegramUser {
if self.id != other.id { return self == other
return false
}
if self.accessHash != other.accessHash {
return false
}
if self.firstName != other.firstName {
return false
}
if self.lastName != other.lastName {
return false
}
if self.phone != other.phone {
return false
}
if self.photo.count != other.photo.count {
return false
}
for i in 0 ..< self.photo.count {
if self.photo[i] != other.photo[i] {
return false
}
}
if self.botInfo != other.botInfo {
return false
}
if self.restrictionInfo != other.restrictionInfo {
return false
}
if self.flags != other.flags {
return false
}
return true
} else { } else {
return false return false
} }
} }
public static func ==(lhs: TelegramUser, rhs: TelegramUser) -> Bool {
if lhs.id != rhs.id {
return false
}
if lhs.accessHash != rhs.accessHash {
return false
}
if lhs.firstName != rhs.firstName {
return false
}
if lhs.lastName != rhs.lastName {
return false
}
if lhs.phone != rhs.phone {
return false
}
if lhs.photo.count != rhs.photo.count {
return false
}
for i in 0 ..< lhs.photo.count {
if lhs.photo[i] != rhs.photo[i] {
return false
}
}
if lhs.botInfo != rhs.botInfo {
return false
}
if lhs.restrictionInfo != rhs.restrictionInfo {
return false
}
if lhs.flags != rhs.flags {
return false
}
return true
}
public func withUpdatedUsername(_ username:String?) -> TelegramUser { public func withUpdatedUsername(_ username:String?) -> TelegramUser {
return TelegramUser(id: self.id, accessHash: self.accessHash, firstName: self.firstName, lastName: self.lastName, username: username, phone: self.phone, photo: self.photo, botInfo: self.botInfo, restrictionInfo: self.restrictionInfo, flags: self.flags) return TelegramUser(id: self.id, accessHash: self.accessHash, firstName: self.firstName, lastName: self.lastName, username: username, phone: self.phone, photo: self.photo, botInfo: self.botInfo, restrictionInfo: self.restrictionInfo, flags: self.flags)

View File

@ -0,0 +1,61 @@
import SwiftSignalKit
import Postbox
public extension TelegramEngine.EngineData.Item {
enum Peer {
public struct Peer: TelegramEngineDataItem, PostboxViewDataItem {
public typealias Result = Optional<EnginePeer>
fileprivate var id: EnginePeer.Id
public init(id: EnginePeer.Id) {
self.id = id
}
var key: PostboxViewKey {
return .basicPeer(self.id)
}
func extract(view: PostboxView) -> Result {
guard let view = view as? BasicPeerView else {
preconditionFailure()
}
guard let peer = view.peer else {
return nil
}
return EnginePeer(peer)
}
}
public struct ParticipantCount: TelegramEngineDataItem, PostboxViewDataItem {
public typealias Result = Optional<Int>
fileprivate var id: EnginePeer.Id
public init(id: EnginePeer.Id) {
self.id = id
}
var key: PostboxViewKey {
return .cachedPeerData(peerId: self.id)
}
func extract(view: PostboxView) -> Result {
guard let view = view as? CachedPeerDataView else {
preconditionFailure()
}
guard let cachedPeerData = view.cachedPeerData else {
return nil
}
switch cachedPeerData {
case let channel as CachedChannelData:
return channel.participantsSummary.memberCount.flatMap(Int.init)
case let group as CachedGroupData:
return group.participants?.participants.count
default:
return nil
}
}
}
}
}

View File

@ -0,0 +1,97 @@
import SwiftSignalKit
import Postbox
public protocol TelegramEngineDataItem {
associatedtype Result
}
protocol AnyPostboxViewDataItem {
var key: PostboxViewKey { get }
func _extract(view: PostboxView) -> Any
}
protocol PostboxViewDataItem: TelegramEngineDataItem, AnyPostboxViewDataItem {
func extract(view: PostboxView) -> Result
}
extension PostboxViewDataItem {
func _extract(view: PostboxView) -> Any {
return self.extract(view: view)
}
}
public extension TelegramEngine {
final class EngineData {
public struct Item {
}
private let account: Account
init(account: Account) {
self.account = account
}
private func _subscribe(items: [AnyPostboxViewDataItem]) -> Signal<[Any], NoError> {
return self.account.postbox.combinedView(keys: items.map(\.key))
|> map { views -> [Any] in
var results: [Any] = []
for item in items {
guard let view = views.views[item.key] else {
preconditionFailure()
}
results.append(item._extract(view: view))
}
return results
}
}
public func subscribe<T0: TelegramEngineDataItem>(_ t0: T0) -> Signal<T0.Result, NoError> {
return self._subscribe(items: [t0 as! AnyPostboxViewDataItem])
|> map { results -> T0.Result in
return results[0] as! T0.Result
}
}
public func get<T0: TelegramEngineDataItem>(_ t0: T0) -> Signal<T0.Result, NoError> {
return self.subscribe(t0)
|> take(1)
}
public func subscribe<
T0: TelegramEngineDataItem,
T1: TelegramEngineDataItem
>(
_ t0: T0,
_ t1: T1
) -> Signal<
(
T0.Result,
T1.Result
),
NoError> {
return self._subscribe(items: [t0 as! AnyPostboxViewDataItem])
|> map { results -> (T0.Result, T1.Result) in
return (
results[0] as! T0.Result,
results[1] as! T1.Result
)
}
}
public func get<
T0: TelegramEngineDataItem,
T1: TelegramEngineDataItem
>(
_ t0: T0,
_ t1: T1
) -> Signal<
(
T0.Result,
T1.Result
),
NoError> {
return self.subscribe(t0, t1) |> take(1)
}
}
}

View File

@ -0,0 +1,5 @@
import Postbox
public enum EngineMedia {
public typealias Id = MediaId
}

View File

@ -0,0 +1,83 @@
import Postbox
public final class EngineMessage {
public typealias Id = MessageId
public typealias Index = MessageIndex
private let impl: Message
public var stableId: UInt32 {
return self.impl.stableId
}
public var stableVersion: UInt32 {
return self.impl.stableVersion
}
public var id: Id {
return self.impl.id
}
public var globallyUniqueId: Int64? {
return self.impl.globallyUniqueId
}
public var groupingKey: Int64? {
return self.impl.groupingKey
}
public var groupInfo: MessageGroupInfo? {
return self.impl.groupInfo
}
public var threadId: Int64? {
return self.impl.threadId
}
public var timestamp: Int32 {
return self.impl.timestamp
}
public var flags: MessageFlags {
return self.impl.flags
}
public var tags: MessageTags {
return self.impl.tags
}
public var globalTags: GlobalMessageTags {
return self.impl.globalTags
}
public var localTags: LocalMessageTags {
return self.impl.localTags
}
public var forwardInfo: MessageForwardInfo? {
return self.impl.forwardInfo
}
public var author: EnginePeer? {
return self.impl.author.flatMap(EnginePeer.init)
}
public var text: String {
return self.impl.text
}
public var attributes: [MessageAttribute] {
return self.impl.attributes
}
public var media: [Media] {
return self.impl.media
}
public var peers: SimpleDictionary<PeerId, Peer> {
return self.impl.peers
}
public var associatedMessages: SimpleDictionary<MessageId, Message> {
return self.impl.associatedMessages
}
public var associatedMessageIds: [MessageId] {
return self.impl.associatedMessageIds
}
public var index: MessageIndex {
return self.impl.index
}
public init(_ impl: Message) {
self.impl = impl
}
public func _asMessage() -> Message {
return self.impl
}
}

View File

@ -0,0 +1,83 @@
import Postbox
public enum EnginePeer: Equatable {
public typealias Id = PeerId
case user(TelegramUser)
case legacyGroup(TelegramGroup)
case channel(TelegramChannel)
case secretChat(TelegramSecretChat)
public static func ==(lhs: EnginePeer, rhs: EnginePeer) -> Bool {
switch lhs {
case let .user(user):
if case .user(user) = rhs {
return true
} else {
return false
}
case let .legacyGroup(legacyGroup):
if case .legacyGroup(legacyGroup) = rhs {
return true
} else {
return false
}
case let .channel(channel):
if case .channel(channel) = rhs {
return true
} else {
return false
}
case let .secretChat(secretChat):
if case .secretChat(secretChat) = rhs {
return true
} else {
return false
}
}
}
}
public extension EnginePeer {
var id: Id {
return self._asPeer().id
}
var addressName: String? {
return self._asPeer().addressName
}
var indexName: PeerIndexNameRepresentation {
return self._asPeer().indexName
}
}
public extension EnginePeer {
init(_ peer: Peer) {
switch peer {
case let user as TelegramUser:
self = .user(user)
case let group as TelegramGroup:
self = .legacyGroup(group)
case let channel as TelegramChannel:
self = .channel(channel)
case let secretChat as TelegramSecretChat:
self = .secretChat(secretChat)
default:
preconditionFailure("Unknown peer type")
}
}
func _asPeer() -> Peer {
switch self {
case let .user(user):
return user
case let .legacyGroup(legacyGroup):
return legacyGroup
case let .channel(channel):
return channel
case let .secretChat(secretChat):
return secretChat
}
}
}

View File

@ -63,8 +63,16 @@ public extension TelegramEngine {
return _internal_inactiveChannelList(network: self.account.network) return _internal_inactiveChannelList(network: self.account.network)
} }
public func resolvePeerByName(name: String, ageLimit: Int32 = 2 * 60 * 60 * 24) -> Signal<PeerId?, NoError> { public func resolvePeerByName(name: String, ageLimit: Int32 = 2 * 60 * 60 * 24) -> Signal<EnginePeer?, NoError> {
return _internal_resolvePeerByName(account: self.account, name: name, ageLimit: ageLimit) return _internal_resolvePeerByName(account: self.account, name: name, ageLimit: ageLimit)
|> mapToSignal { peerId -> Signal<EnginePeer?, NoError> in
guard let peerId = peerId else {
return .single(nil)
}
return self.account.postbox.transaction { transaction -> EnginePeer? in
return transaction.getPeer(peerId).flatMap(EnginePeer.init)
}
}
} }
public func searchPeers(query: String) -> Signal<([FoundPeer], [FoundPeer]), NoError> { public func searchPeers(query: String) -> Signal<([FoundPeer], [FoundPeer]), NoError> {
@ -320,8 +328,13 @@ public extension TelegramEngine {
return _internal_addRecentlyUsedInlineBot(postbox: self.account.postbox, peerId: peerId) return _internal_addRecentlyUsedInlineBot(postbox: self.account.postbox, peerId: peerId)
} }
public func recentlyUsedInlineBots() -> Signal<[(Peer, Double)], NoError> { public func recentlyUsedInlineBots() -> Signal<[(EnginePeer, Double)], NoError> {
return _internal_recentlyUsedInlineBots(postbox: self.account.postbox) return _internal_recentlyUsedInlineBots(postbox: self.account.postbox)
|> map { list -> [(EnginePeer, Double)] in
return list.map { peer, rating in
return (EnginePeer(peer), rating)
}
}
} }
public func removeRecentlyUsedInlineBot(peerId: PeerId) -> Signal<Void, NoError> { public func removeRecentlyUsedInlineBot(peerId: PeerId) -> Signal<Void, NoError> {

View File

@ -67,6 +67,10 @@ public final class TelegramEngine {
public lazy var resolve: Resolve = { public lazy var resolve: Resolve = {
return Resolve(account: self.account) return Resolve(account: self.account)
}() }()
public lazy var data: EngineData = {
return EngineData(account: self.account)
}()
} }
public final class TelegramEngineUnauthorized { public final class TelegramEngineUnauthorized {

View File

@ -413,8 +413,7 @@ final class SharedApplicationContext {
}, appData: self.deviceToken.get() }, appData: self.deviceToken.get()
|> map { token in |> map { token in
let data = buildConfig.bundleData(withAppToken: token, signatureDict: signatureDict) let data = buildConfig.bundleData(withAppToken: token, signatureDict: signatureDict)
if let data = data, let jsonString = String(data: data, encoding: .utf8) { if let data = data, let _ = String(data: data, encoding: .utf8) {
//Logger.shared.log("data", "\(jsonString)")
} else { } else {
Logger.shared.log("data", "can't deserialize") Logger.shared.log("data", "can't deserialize")
} }
@ -632,6 +631,8 @@ final class SharedApplicationContext {
return .denied return .denied
case .notDetermined: case .notDetermined:
return .notDetermined return .notDetermined
@unknown default:
return .notDetermined
} }
} else { } else {
return .denied return .denied
@ -2155,7 +2156,6 @@ final class SharedApplicationContext {
let muteMediaMessageCategory = UIMutableUserNotificationCategory() let muteMediaMessageCategory = UIMutableUserNotificationCategory()
muteMediaMessageCategory.identifier = "withMuteMedia" muteMediaMessageCategory.identifier = "withMuteMedia"
let categories = [unknownMessageCategory, replyMessageCategory, replyLegacyMessageCategory, replyLegacyMediaMessageCategory, replyMediaMessageCategory, legacyChannelMessageCategory, muteMessageCategory, muteMediaMessageCategory]
let settings = UIUserNotificationSettings(types: [.badge, .sound, .alert], categories: []) let settings = UIUserNotificationSettings(types: [.badge, .sound, .alert], categories: [])
UIApplication.shared.registerUserNotificationSettings(settings) UIApplication.shared.registerUserNotificationSettings(settings)
UIApplication.shared.registerForRemoteNotifications() UIApplication.shared.registerForRemoteNotifications()
@ -2189,9 +2189,7 @@ final class SharedApplicationContext {
private func maybeCheckForUpdates() { private func maybeCheckForUpdates() {
#if targetEnvironment(simulator) #if targetEnvironment(simulator)
return; #else
#endif
guard let buildConfig = self.buildConfig, !buildConfig.isAppStoreBuild, let appCenterId = buildConfig.appCenterId, !appCenterId.isEmpty else { guard let buildConfig = self.buildConfig, !buildConfig.isAppStoreBuild, let appCenterId = buildConfig.appCenterId, !appCenterId.isEmpty else {
return return
} }
@ -2236,6 +2234,7 @@ final class SharedApplicationContext {
})) }))
} }
} }
#endif
} }
override var next: UIResponder? { override var next: UIResponder? {

View File

@ -406,7 +406,7 @@ final class AuthorizedApplicationContext {
var processed = false var processed = false
for media in firstMessage.media { for media in firstMessage.media {
if let action = media as? TelegramMediaAction, case let .geoProximityReached(fromId, toId, distance) = action.action { if let action = media as? TelegramMediaAction, case .geoProximityReached = action.action {
strongSelf.context.sharedContext.openLocationScreen(context: strongSelf.context, messageId: firstMessage.id, navigationController: strongSelf.rootController) strongSelf.context.sharedContext.openLocationScreen(context: strongSelf.context, messageId: firstMessage.id, navigationController: strongSelf.rootController)
processed = true processed = true
break break
@ -464,9 +464,9 @@ final class AuthorizedApplicationContext {
|> deliverOnMainQueue).start(completed: { |> deliverOnMainQueue).start(completed: {
controller?.dismiss() controller?.dismiss()
if let strongSelf = self, let botName = botName { if let strongSelf = self, let botName = botName {
strongSelf.termsOfServiceProceedToBotDisposable.set((strongSelf.context.engine.peers.resolvePeerByName(name: botName, ageLimit: 10) |> take(1) |> deliverOnMainQueue).start(next: { peerId in strongSelf.termsOfServiceProceedToBotDisposable.set((strongSelf.context.engine.peers.resolvePeerByName(name: botName, ageLimit: 10) |> take(1) |> deliverOnMainQueue).start(next: { peer in
if let strongSelf = self, let peerId = peerId { if let strongSelf = self, let peer = peer {
self?.rootController.pushViewController(ChatControllerImpl(context: strongSelf.context, chatLocation: .peer(peerId))) self?.rootController.pushViewController(ChatControllerImpl(context: strongSelf.context, chatLocation: .peer(peer.id)))
} }
})) }))
} }
@ -611,7 +611,7 @@ final class AuthorizedApplicationContext {
switch state { switch state {
case .contacts: case .contacts:
splitTest.addEvent(.ContactsRequest) splitTest.addEvent(.ContactsRequest)
DeviceAccess.authorizeAccess(to: .contacts, presentationData: context.sharedContext.currentPresentationData.with { $0 }) { result in DeviceAccess.authorizeAccess(to: .contacts, presentationData: context.sharedContext.currentPresentationData.with { $0 }, { result in
if result { if result {
splitTest.addEvent(.ContactsAllowed) splitTest.addEvent(.ContactsAllowed)
} else { } else {
@ -619,12 +619,12 @@ final class AuthorizedApplicationContext {
} }
permissionsPosition.set(position + 1) permissionsPosition.set(position + 1)
ApplicationSpecificNotice.setPermissionWarning(accountManager: context.sharedContext.accountManager, permission: .contacts, value: 0) ApplicationSpecificNotice.setPermissionWarning(accountManager: context.sharedContext.accountManager, permission: .contacts, value: 0)
} })
case .notifications: case .notifications:
splitTest.addEvent(.NotificationsRequest) splitTest.addEvent(.NotificationsRequest)
DeviceAccess.authorizeAccess(to: .notifications, registerForNotifications: { result in DeviceAccess.authorizeAccess(to: .notifications, registerForNotifications: { result in
context.sharedContext.applicationBindings.registerForNotifications(result) context.sharedContext.applicationBindings.registerForNotifications(result)
}) { result in }, { result in
if result { if result {
splitTest.addEvent(.NotificationsAllowed) splitTest.addEvent(.NotificationsAllowed)
} else { } else {
@ -632,7 +632,7 @@ final class AuthorizedApplicationContext {
} }
permissionsPosition.set(position + 1) permissionsPosition.set(position + 1)
ApplicationSpecificNotice.setPermissionWarning(accountManager: context.sharedContext.accountManager, permission: .notifications, value: 0) ApplicationSpecificNotice.setPermissionWarning(accountManager: context.sharedContext.accountManager, permission: .notifications, value: 0)
} })
case .cellularData: case .cellularData:
DeviceAccess.authorizeAccess(to: .cellularData, presentationData: context.sharedContext.currentPresentationData.with { $0 }, present: { [weak self] c, a in DeviceAccess.authorizeAccess(to: .cellularData, presentationData: context.sharedContext.currentPresentationData.with { $0 }, present: { [weak self] c, a in
if let strongSelf = self { if let strongSelf = self {
@ -647,9 +647,9 @@ final class AuthorizedApplicationContext {
case .siri: case .siri:
DeviceAccess.authorizeAccess(to: .siri, requestSiriAuthorization: { completion in DeviceAccess.authorizeAccess(to: .siri, requestSiriAuthorization: { completion in
return context.sharedContext.applicationBindings.requestSiriAuthorization(completion) return context.sharedContext.applicationBindings.requestSiriAuthorization(completion)
}) { result in }, { result in
permissionsPosition.set(position + 1) permissionsPosition.set(position + 1)
} })
default: default:
break break
} }

View File

@ -783,7 +783,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
} }
controllers.append(self.passwordEntryController(hint: hint, suggestReset: suggestReset, syncContacts: syncContacts)) controllers.append(self.passwordEntryController(hint: hint, suggestReset: suggestReset, syncContacts: syncContacts))
self.setViewControllers(controllers, animated: !self.viewControllers.isEmpty) self.setViewControllers(controllers, animated: !self.viewControllers.isEmpty)
case let .passwordRecovery(hint, _, _, emailPattern, syncContacts): case let .passwordRecovery(_, _, _, emailPattern, syncContacts):
var controllers: [ViewController] = [] var controllers: [ViewController] = []
if !self.otherAccountPhoneNumbers.1.isEmpty { if !self.otherAccountPhoneNumbers.1.isEmpty {
controllers.append(self.splashController()) controllers.append(self.splashController())

View File

@ -101,7 +101,6 @@ final class AuthorizationSequencePasswordRecoveryControllerNode: ASDisplayNode,
let noticeSize = self.noticeNode.measure(CGSize(width: layout.size.width - 28.0, height: CGFloat.greatestFiniteMagnitude)) let noticeSize = self.noticeNode.measure(CGSize(width: layout.size.width - 28.0, height: CGFloat.greatestFiniteMagnitude))
let noAccessSize = self.noAccessNode.measure(CGSize(width: layout.size.width, height: CGFloat.greatestFiniteMagnitude)) let noAccessSize = self.noAccessNode.measure(CGSize(width: layout.size.width, height: CGFloat.greatestFiniteMagnitude))
let resetSize = self.noAccessNode.measure(CGSize(width: layout.size.width, height: CGFloat.greatestFiniteMagnitude))
var items: [AuthorizationLayoutItem] = [] var items: [AuthorizationLayoutItem] = []
items.append(AuthorizationLayoutItem(node: self.titleNode, size: titleSize, spacingBefore: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0))) items.append(AuthorizationLayoutItem(node: self.titleNode, size: titleSize, spacingBefore: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0)))

View File

@ -7068,7 +7068,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
self.chatDisplayNode.loadInputPanels(theme: self.presentationInterfaceState.theme, strings: self.presentationInterfaceState.strings, fontSize: self.presentationInterfaceState.fontSize) self.chatDisplayNode.loadInputPanels(theme: self.presentationInterfaceState.theme, strings: self.presentationInterfaceState.strings, fontSize: self.presentationInterfaceState.fontSize)
self.recentlyUsedInlineBotsDisposable = (self.context.engine.peers.recentlyUsedInlineBots() |> deliverOnMainQueue).start(next: { [weak self] peers in self.recentlyUsedInlineBotsDisposable = (self.context.engine.peers.recentlyUsedInlineBots() |> deliverOnMainQueue).start(next: { [weak self] peers in
self?.recentlyUsedInlineBotsValue = peers.filter({ $0.1 >= 0.14 }).map({ $0.0 }) self?.recentlyUsedInlineBotsValue = peers.filter({ $0.1 >= 0.14 }).map({ $0.0._asPeer() })
}) })
if case .standard(false) = self.presentationInterfaceState.mode, self.raiseToListen == nil { if case .standard(false) = self.presentationInterfaceState.mode, self.raiseToListen == nil {
@ -11283,14 +11283,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
let account = self.context.account let account = self.context.account
disposable.set((resolveSignal disposable.set((resolveSignal
|> take(1) |> take(1)
|> mapToSignal { peerId -> Signal<Peer?, NoError> in |> mapToSignal { peer -> Signal<Peer?, NoError> in
return account.postbox.transaction { transaction -> Peer? in return .single(peer?._asPeer())
if let peerId = peerId {
return transaction.getPeer(peerId)
} else {
return nil
}
}
} }
|> deliverOnMainQueue).start(next: { [weak self] peer in |> deliverOnMainQueue).start(next: { [weak self] peer in
if let strongSelf = self { if let strongSelf = self {
@ -11319,10 +11313,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
var resolveSignal: Signal<Peer?, NoError> var resolveSignal: Signal<Peer?, NoError>
if let peerName = peerName { if let peerName = peerName {
resolveSignal = self.context.engine.peers.resolvePeerByName(name: peerName) resolveSignal = self.context.engine.peers.resolvePeerByName(name: peerName)
|> mapToSignal { peerId -> Signal<Peer?, NoError> in |> mapToSignal { peer -> Signal<Peer?, NoError> in
if let peerId = peerId { if let peer = peer {
return account.postbox.loadedPeerWithId(peerId) return .single(peer._asPeer())
|> map(Optional.init)
} else { } else {
return .single(nil) return .single(nil)
} }

View File

@ -203,7 +203,7 @@ func inputContextQueriesForChatPresentationIntefaceState(_ chatPresentationInter
func inputTextPanelStateForChatPresentationInterfaceState(_ chatPresentationInterfaceState: ChatPresentationInterfaceState, context: AccountContext) -> ChatTextInputPanelState { func inputTextPanelStateForChatPresentationInterfaceState(_ chatPresentationInterfaceState: ChatPresentationInterfaceState, context: AccountContext) -> ChatTextInputPanelState {
var contextPlaceholder: NSAttributedString? var contextPlaceholder: NSAttributedString?
loop: for (_, result) in chatPresentationInterfaceState.inputQueryResults { loop: for (_, result) in chatPresentationInterfaceState.inputQueryResults {
if case let .contextRequestResult(peer, _) = result, let botUser = peer as? TelegramUser, let botInfo = botUser.botInfo, let inlinePlaceholder = botInfo.inlinePlaceholder { if case let .contextRequestResult(peer, _) = result, case let .user(botUser) = peer, let botInfo = botUser.botInfo, let inlinePlaceholder = botInfo.inlinePlaceholder {
let inputQueries = inputContextQueriesForChatPresentationIntefaceState(chatPresentationInterfaceState) let inputQueries = inputContextQueriesForChatPresentationIntefaceState(chatPresentationInterfaceState)
for inputQuery in inputQueries { for inputQuery in inputQueries {
if case let .contextRequest(addressName, query) = inputQuery, query.isEmpty { if case let .contextRequest(addressName, query) = inputQuery, query.isEmpty {

View File

@ -49,5 +49,4 @@ func inputNodeForChatPresentationIntefaceState(_ chatPresentationInterfaceState:
case .none, .text: case .none, .text:
return nil return nil
} }
return nil
} }

View File

@ -177,7 +177,8 @@ private func updatedContextQueryResultStateForQuery(context: AccountContext, pee
signal = .single({ _ in return .mentions([]) }) signal = .single({ _ in return .mentions([]) })
} }
let inlineBots: Signal<[(Peer, Double)], NoError> = types.contains(.contextBots) ? context.engine.peers.recentlyUsedInlineBots() : .single([]) let inlineBots: Signal<[(EnginePeer, Double)], NoError> = types.contains(.contextBots) ? context.engine.peers.recentlyUsedInlineBots() : .single([])
let strings = context.sharedContext.currentPresentationData.with({ $0 }).strings
let participants = combineLatest(inlineBots, searchPeerMembers(context: context, peerId: peer.id, chatLocation: chatLocation, query: query, scope: .mention)) let participants = combineLatest(inlineBots, searchPeerMembers(context: context, peerId: peer.id, chatLocation: chatLocation, query: query, scope: .mention))
|> map { inlineBots, peers -> (ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult? in |> map { inlineBots, peers -> (ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult? in
let filteredInlineBots = inlineBots.sorted(by: { $0.1 > $1.1 }).filter { peer, rating in let filteredInlineBots = inlineBots.sorted(by: { $0.1 > $1.1 }).filter { peer, rating in
@ -210,7 +211,7 @@ private func updatedContextQueryResultStateForQuery(context: AccountContext, pee
return result == .orderedAscending return result == .orderedAscending
})) }))
sortedPeers = sortedPeers.filter { peer in sortedPeers = sortedPeers.filter { peer in
return !peer.debugDisplayTitle.isEmpty return !peer.displayTitle(strings: strings, displayOrder: .firstLast).isEmpty
} }
return { _ in return .mentions(sortedPeers) } return { _ in return .mentions(sortedPeers) }
} }
@ -264,20 +265,9 @@ private func updatedContextQueryResultStateForQuery(context: AccountContext, pee
let chatPeer = peer let chatPeer = peer
let contextBot = context.engine.peers.resolvePeerByName(name: addressName) let contextBot = context.engine.peers.resolvePeerByName(name: addressName)
|> mapToSignal { peerId -> Signal<Peer?, NoError> in
if let peerId = peerId {
return context.account.postbox.loadedPeerWithId(peerId)
|> map { peer -> Peer? in
return peer
}
|> take(1)
} else {
return .single(nil)
}
}
|> castError(ChatContextQueryError.self) |> castError(ChatContextQueryError.self)
|> mapToSignal { peer -> Signal<(ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?, ChatContextQueryError> in |> mapToSignal { peer -> Signal<(ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?, ChatContextQueryError> in
if let user = peer as? TelegramUser, let botInfo = user.botInfo, let _ = botInfo.inlinePlaceholder { if case let .user(user) = peer, let botInfo = user.botInfo, let _ = botInfo.inlinePlaceholder {
let contextResults = context.engine.messages.requestChatContextResults(botId: user.id, peerId: chatPeer.id, query: query, location: context.sharedContext.locationManager.flatMap { locationManager -> Signal<(Double, Double)?, NoError> in let contextResults = context.engine.messages.requestChatContextResults(botId: user.id, peerId: chatPeer.id, query: query, location: context.sharedContext.locationManager.flatMap { locationManager -> Signal<(Double, Double)?, NoError> in
return `deferred` { return `deferred` {
Queue.mainQueue().async { Queue.mainQueue().async {
@ -305,7 +295,7 @@ private func updatedContextQueryResultStateForQuery(context: AccountContext, pee
} }
|> map { results -> (ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult? in |> map { results -> (ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult? in
return { _ in return { _ in
return .contextRequestResult(user, results?.results) return .contextRequestResult(.user(user), results?.results)
} }
} }
@ -318,7 +308,7 @@ private func updatedContextQueryResultStateForQuery(context: AccountContext, pee
} }
} }
} }
return .contextRequestResult(user, passthroughPreviousResult) return .contextRequestResult(.user(user), passthroughPreviousResult)
}) })
let maybeDelayedContextResults: Signal<(ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?, ChatContextQueryError> let maybeDelayedContextResults: Signal<(ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?, ChatContextQueryError>
@ -399,7 +389,7 @@ func searchQuerySuggestionResultStateForChatInterfacePresentationState(_ chatPre
let participants = searchPeerMembers(context: context, peerId: peer.id, chatLocation: chatPresentationInterfaceState.chatLocation, query: query, scope: .memberSuggestion) let participants = searchPeerMembers(context: context, peerId: peer.id, chatLocation: chatPresentationInterfaceState.chatLocation, query: query, scope: .memberSuggestion)
|> map { peers -> (ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult? in |> map { peers -> (ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult? in
let filteredPeers = peers let filteredPeers = peers
var sortedPeers: [Peer] = [] var sortedPeers: [EnginePeer] = []
sortedPeers.append(contentsOf: filteredPeers.sorted(by: { lhs, rhs in sortedPeers.append(contentsOf: filteredPeers.sorted(by: { lhs, rhs in
let result = lhs.indexName.indexName(.lastNameFirst).compare(rhs.indexName.indexName(.lastNameFirst)) let result = lhs.indexName.indexName(.lastNameFirst).compare(rhs.indexName.indexName(.lastNameFirst))
return result == .orderedAscending return result == .orderedAscending

View File

@ -176,8 +176,6 @@ class ChatMessageActionBubbleContentNode: ChatMessageBubbleContentNode {
labelRects[i].size.height = 20.0 labelRects[i].size.height = 20.0
labelRects[i].origin.x = floor((labelLayout.size.width - labelRects[i].width) / 2.0) labelRects[i].origin.x = floor((labelLayout.size.width - labelRects[i].width) / 2.0)
} }
let serviceColor = serviceMessageColorComponents(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper)
let backgroundMaskImage: (CGPoint, UIImage)? let backgroundMaskImage: (CGPoint, UIImage)?
var backgroundMaskUpdated = false var backgroundMaskUpdated = false

View File

@ -854,7 +854,6 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
var replyMarkup: ReplyMarkupMessageAttribute? var replyMarkup: ReplyMarkupMessageAttribute?
var ignoreForward = self.telegramDice == nil var ignoreForward = self.telegramDice == nil
var ignoreSource = false
let availableContentWidth = max(60.0, params.width - params.leftInset - params.rightInset - max(imageSize.width, 160.0) - 20.0 - layoutConstants.bubble.edgeInset * 2.0 - avatarInset - layoutConstants.bubble.contentInsets.left) let availableContentWidth = max(60.0, params.width - params.leftInset - params.rightInset - max(imageSize.width, 160.0) - 20.0 - layoutConstants.bubble.edgeInset * 2.0 - avatarInset - layoutConstants.bubble.contentInsets.left)
@ -864,8 +863,6 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
if let attribute = attribute as? SourceReferenceMessageAttribute { if let attribute = attribute as? SourceReferenceMessageAttribute {
if attribute.messageId.peerId == forwardInfo.author?.id { if attribute.messageId.peerId == forwardInfo.author?.id {
ignoreForward = true ignoreForward = true
} else {
ignoreSource = true
} }
break break
} }
@ -1348,16 +1345,9 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
}) })
} else if let _ = self.emojiFile { } else if let _ = self.emojiFile {
if let animationNode = self.animationNode as? AnimatedStickerNode, let _ = recognizer { if let animationNode = self.animationNode as? AnimatedStickerNode, let _ = recognizer {
var startTime: Signal<Double, NoError>
var shouldPlay = false var shouldPlay = false
if !animationNode.isPlaying { if !animationNode.isPlaying {
shouldPlay = true shouldPlay = true
startTime = .single(0.0)
} else {
startTime = animationNode.status
|> map { $0.timestamp }
|> take(1)
|> deliverOnMainQueue
} }
let beatingHearts: [UInt32] = [0x2764, 0x1F90E, 0x1F9E1, 0x1F499, 0x1F49A, 0x1F49C, 0x1F49B, 0x1F5A4, 0x1F90D] let beatingHearts: [UInt32] = [0x2764, 0x1F90E, 0x1F9E1, 0x1F499, 0x1F49A, 0x1F49C, 0x1F49B, 0x1F5A4, 0x1F90D]

View File

@ -1560,8 +1560,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
} else { } else {
authorNameColor = item.presentationData.theme.theme.chat.message.outgoing.accentTextColor authorNameColor = item.presentationData.theme.theme.chat.message.outgoing.accentTextColor
} }
var isScam = effectiveAuthor.isScam
if case let .peer(peerId) = item.chatLocation, let authorPeerId = item.message.author?.id, authorPeerId == peerId { if case let .peer(peerId) = item.chatLocation, let authorPeerId = item.message.author?.id, authorPeerId == peerId {
} else if effectiveAuthor.isScam { } else if effectiveAuthor.isScam {
@ -1860,7 +1859,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
} }
for i in 0 ..< contentPropertiesAndLayouts.count { for i in 0 ..< contentPropertiesAndLayouts.count {
let (_, contentNodeProperties, preparePosition, attributes, contentNodeLayout, contentGroupId, itemSelection) = contentPropertiesAndLayouts[i] let (_, contentNodeProperties, preparePosition, _, contentNodeLayout, contentGroupId, itemSelection) = contentPropertiesAndLayouts[i]
if let mosaicRange = mosaicRange, mosaicRange.contains(i), let (framesAndPositions, size) = calculatedGroupFramesAndSize { if let mosaicRange = mosaicRange, mosaicRange.contains(i), let (framesAndPositions, size) = calculatedGroupFramesAndSize {
let mosaicIndex = i - mosaicRange.lowerBound let mosaicIndex = i - mosaicRange.lowerBound
@ -2516,19 +2515,19 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
} }
contextSourceNode.updateAbsoluteRect = { [weak strongSelf, weak container, weak contextSourceNode] rect, size in contextSourceNode.updateAbsoluteRect = { [weak strongSelf, weak container, weak contextSourceNode] rect, size in
guard let strongSelf = strongSelf, let strongContextSourceNode = contextSourceNode, strongContextSourceNode.isExtractedToContextPreview else { guard let _ = strongSelf, let strongContextSourceNode = contextSourceNode, strongContextSourceNode.isExtractedToContextPreview else {
return return
} }
container?.updateAbsoluteRect(relativeFrame.offsetBy(dx: rect.minX, dy: rect.minY), within: size) container?.updateAbsoluteRect(relativeFrame.offsetBy(dx: rect.minX, dy: rect.minY), within: size)
} }
contextSourceNode.applyAbsoluteOffset = { [weak strongSelf, weak container, weak contextSourceNode] value, animationCurve, duration in contextSourceNode.applyAbsoluteOffset = { [weak strongSelf, weak container, weak contextSourceNode] value, animationCurve, duration in
guard let strongSelf = strongSelf, let strongContextSourceNode = contextSourceNode, strongContextSourceNode.isExtractedToContextPreview else { guard let _ = strongSelf, let strongContextSourceNode = contextSourceNode, strongContextSourceNode.isExtractedToContextPreview else {
return return
} }
container?.applyAbsoluteOffset(value: value, animationCurve: animationCurve, duration: duration) container?.applyAbsoluteOffset(value: value, animationCurve: animationCurve, duration: duration)
} }
contextSourceNode.applyAbsoluteOffsetSpring = { [weak strongSelf, weak container, weak contextSourceNode] value, duration, damping in contextSourceNode.applyAbsoluteOffsetSpring = { [weak strongSelf, weak container, weak contextSourceNode] value, duration, damping in
guard let strongSelf = strongSelf, let strongContextSourceNode = contextSourceNode, strongContextSourceNode.isExtractedToContextPreview else { guard let _ = strongSelf, let strongContextSourceNode = contextSourceNode, strongContextSourceNode.isExtractedToContextPreview else {
return return
} }
container?.applyAbsoluteOffsetSpring(value: value, duration: duration, damping: damping) container?.applyAbsoluteOffsetSpring(value: value, duration: duration, damping: damping)

View File

@ -69,7 +69,6 @@ class ChatMessageCallBubbleContentNode: ChatMessageBubbleContentNode {
return { item, layoutConstants, _, _, _ in return { item, layoutConstants, _, _, _ in
let contentProperties = ChatMessageBubbleContentProperties(hidesSimpleAuthorHeader: false, headerSpacing: 0.0, hidesBackground: .never, forceFullCorners: false, forceAlignment: .none) let contentProperties = ChatMessageBubbleContentProperties(hidesSimpleAuthorHeader: false, headerSpacing: 0.0, hidesBackground: .never, forceFullCorners: false, forceAlignment: .none)
return (contentProperties, nil, CGFloat.greatestFiniteMagnitude, { constrainedSize, position in return (contentProperties, nil, CGFloat.greatestFiniteMagnitude, { constrainedSize, position in
let message = item.message
let incoming = item.message.effectivelyIncoming(item.context.account.peerId) let incoming = item.message.effectivelyIncoming(item.context.account.peerId)
let horizontalInset = layoutConstants.text.bubbleInsets.left + layoutConstants.text.bubbleInsets.right let horizontalInset = layoutConstants.text.bubbleInsets.left + layoutConstants.text.bubbleInsets.right

View File

@ -214,7 +214,6 @@ class ChatMessageDateAndStatusNode: ASDisplayNode {
var currentBackgroundNode = self.backgroundNode var currentBackgroundNode = self.backgroundNode
var currentImpressionIcon = self.impressionIcon var currentImpressionIcon = self.impressionIcon
var currentRepliesIcon = self.repliesIcon var currentRepliesIcon = self.repliesIcon
var currentSelfExpiringIcon = self.selfExpiringIcon
let currentType = self.type let currentType = self.type
let currentTheme = self.theme let currentTheme = self.theme

View File

@ -440,8 +440,6 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView, UIGestureRecognizerD
replyBackgroundImage = graphics.chatFreeformContentAdditionalInfoBackgroundImage replyBackgroundImage = graphics.chatFreeformContentAdditionalInfoBackgroundImage
} }
var updatedShareButtonBackground: UIImage?
var updatedShareButtonNode: ChatMessageShareButton? var updatedShareButtonNode: ChatMessageShareButton?
if needShareButton { if needShareButton {
if currentShareButtonNode != nil { if currentShareButtonNode != nil {
@ -874,7 +872,7 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView, UIGestureRecognizerD
private var wasPlaying = false private var wasPlaying = false
@objc func seekGesture(_ recognizer: UIPanGestureRecognizer) { @objc func seekGesture(_ recognizer: UIPanGestureRecognizer) {
var location = recognizer.location(in: self.interactiveVideoNode.view) let location = recognizer.location(in: self.interactiveVideoNode.view)
switch recognizer.state { switch recognizer.state {
case .began: case .began:
self.interactiveVideoNode.pause() self.interactiveVideoNode.pause()

View File

@ -1057,7 +1057,6 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
if visibility { if visibility {
return fetchSignal return fetchSignal
|> mapToSignal { _ -> Signal<Void, NoError> in |> mapToSignal { _ -> Signal<Void, NoError> in
return .complete()
} }
} else { } else {
return .complete() return .complete()

View File

@ -231,7 +231,7 @@ final class ChatMessageAccessibilityData {
var isSpecialFile = false var isSpecialFile = false
for attribute in file.attributes { for attribute in file.attributes {
switch attribute { switch attribute {
case let .Sticker(displayText, packReference, _): case let .Sticker(displayText, _, _):
isSpecialFile = true isSpecialFile = true
text = displayText text = displayText
if file.mimeType == "application/x-tgsticker" { if file.mimeType == "application/x-tgsticker" {

View File

@ -153,13 +153,11 @@ final class ChatMessageNotificationItemNode: NotificationItemNode {
self.avatarNode.setPeer(context: item.context, theme: presentationData.theme, peer: avatarPeer, overrideImage: peer.id == item.context.account.peerId ? .savedMessagesIcon : nil, emptyColor: presentationData.theme.list.mediaPlaceholderColor) self.avatarNode.setPeer(context: item.context, theme: presentationData.theme, peer: avatarPeer, overrideImage: peer.id == item.context.account.peerId ? .savedMessagesIcon : nil, emptyColor: presentationData.theme.list.mediaPlaceholderColor)
} }
var titleIcon: UIImage?
var updatedMedia: Media? var updatedMedia: Media?
var imageDimensions: CGSize? var imageDimensions: CGSize?
var isRound = false var isRound = false
var messageText: String var messageText: String
if item.messages.first?.id.peerId.namespace == Namespaces.Peer.SecretChat { if item.messages.first?.id.peerId.namespace == Namespaces.Peer.SecretChat {
titleIcon = PresentationResourcesRootController.inAppNotificationSecretChatIcon(presentationData.theme)
messageText = item.strings.PUSH_ENCRYPTED_MESSAGE("").string messageText = item.strings.PUSH_ENCRYPTED_MESSAGE("").string
} else if item.messages.count == 1 { } else if item.messages.count == 1 {
let message = item.messages[0] let message = item.messages[0]

View File

@ -137,11 +137,7 @@ class ChatMessageRestrictedBubbleContentNode: ChatMessageBubbleContentNode {
var statusFrame: CGRect? var statusFrame: CGRect?
if let statusSize = statusSize { if let statusSize = statusSize {
if forceStatusNewline { statusFrame = CGRect(origin: CGPoint(x: textFrameWithoutInsets.maxX - statusSize.width, y: textFrameWithoutInsets.maxY - statusSize.height), size: statusSize)
statusFrame = CGRect(origin: CGPoint(x: textFrameWithoutInsets.maxX - statusSize.width, y: textFrameWithoutInsets.maxY), size: statusSize)
} else {
statusFrame = CGRect(origin: CGPoint(x: textFrameWithoutInsets.maxX - statusSize.width, y: textFrameWithoutInsets.maxY - statusSize.height), size: statusSize)
}
} }
textFrame = textFrame.offsetBy(dx: layoutConstants.text.bubbleInsets.left, dy: layoutConstants.text.bubbleInsets.top) textFrame = textFrame.offsetBy(dx: layoutConstants.text.bubbleInsets.left, dy: layoutConstants.text.bubbleInsets.top)

View File

@ -296,11 +296,7 @@ class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode {
var statusFrame: CGRect? var statusFrame: CGRect?
if let statusSize = statusSize { if let statusSize = statusSize {
if forceStatusNewline { statusFrame = CGRect(origin: CGPoint(x: textFrameWithoutInsets.maxX - statusSize.width, y: textFrameWithoutInsets.maxY - statusSize.height), size: statusSize)
statusFrame = CGRect(origin: CGPoint(x: textFrameWithoutInsets.maxX - statusSize.width, y: textFrameWithoutInsets.maxY), size: statusSize)
} else {
statusFrame = CGRect(origin: CGPoint(x: textFrameWithoutInsets.maxX - statusSize.width, y: textFrameWithoutInsets.maxY - statusSize.height), size: statusSize)
}
} }
textFrame = textFrame.offsetBy(dx: layoutConstants.text.bubbleInsets.left, dy: layoutConstants.text.bubbleInsets.top) textFrame = textFrame.offsetBy(dx: layoutConstants.text.bubbleInsets.left, dy: layoutConstants.text.bubbleInsets.top)

View File

@ -208,7 +208,6 @@ final class ChatMessageWebpageBubbleContentNode: ChatMessageBubbleContentNode {
} else if let type = webpage.type { } else if let type = webpage.type {
if type == "telegram_background" { if type == "telegram_background" {
var colors: [UInt32] = [] var colors: [UInt32] = []
var bottomColor: UIColor?
var rotation: Int32? var rotation: Int32?
if let wallpaper = parseWallpaperUrl(webpage.url) { if let wallpaper = parseWallpaperUrl(webpage.url) {
if case let .color(color) = wallpaper { if case let .color(color) = wallpaper {

View File

@ -16,7 +16,7 @@ enum ChatPresentationInputQueryKind: Int32 {
case emojiSearch case emojiSearch
} }
struct ChatInputQueryMentionTypes: OptionSet { struct ChatInputQueryMentionTypes: OptionSet, Hashable {
var rawValue: Int32 var rawValue: Int32
init(rawValue: Int32) { init(rawValue: Int32) {
@ -52,26 +52,6 @@ enum ChatPresentationInputQuery: Hashable, Equatable {
return .emojiSearch return .emojiSearch
} }
} }
var hashValue: Int {
switch self {
case let .emoji(value):
return 1 &+ value.hashValue
case let .hashtag(value):
return 2 &+ value.hashValue
case let .mention(text, types):
return 3 &+ text.hashValue &* 31 &+ types.rawValue.hashValue
case let .command(value):
return 4 &+ value.hashValue
case let .contextRequest(addressName, query):
return 5 &+ addressName.hashValue &* 31 &+ query.hashValue
case let .emojiSearch(value, languageCode, range):
var hash = value.hashValue
hash = hash &* 31 &+ languageCode.hashValue
hash = hash &* 31 &+ range.hashValue
return 6 &+ hash
}
}
} }
enum ChatMediaInputMode { enum ChatMediaInputMode {

View File

@ -282,13 +282,8 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
let resolveSignal: Signal<Peer?, NoError> let resolveSignal: Signal<Peer?, NoError>
if let peerName = peerName { if let peerName = peerName {
resolveSignal = strongSelf.context.engine.peers.resolvePeerByName(name: peerName) resolveSignal = strongSelf.context.engine.peers.resolvePeerByName(name: peerName)
|> mapToSignal { peerId -> Signal<Peer?, NoError> in |> mapToSignal { peer -> Signal<Peer?, NoError> in
if let peerId = peerId { return .single(peer?._asPeer())
return context.account.postbox.loadedPeerWithId(peerId)
|> map(Optional.init)
} else {
return .single(nil)
}
} }
} else { } else {
resolveSignal = context.account.postbox.loadedPeerWithId(strongSelf.peer.id) resolveSignal = context.account.postbox.loadedPeerWithId(strongSelf.peer.id)
@ -789,17 +784,10 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
let postbox = self.context.account.postbox let postbox = self.context.account.postbox
self.navigationActionDisposable.set((self.context.engine.peers.resolvePeerByName(name: name, ageLimit: 10) self.navigationActionDisposable.set((self.context.engine.peers.resolvePeerByName(name: name, ageLimit: 10)
|> take(1) |> take(1)
|> mapToSignal { peerId -> Signal<Peer?, NoError> in
if let peerId = peerId {
return postbox.loadedPeerWithId(peerId) |> map(Optional.init)
} else {
return .single(nil)
}
}
|> deliverOnMainQueue).start(next: { [weak self] peer in |> deliverOnMainQueue).start(next: { [weak self] peer in
if let strongSelf = self { if let strongSelf = self {
if let peer = peer { if let peer = peer {
if let infoController = strongSelf.context.sharedContext.makePeerInfoController(context: strongSelf.context, peer: peer, mode: .generic, avatarInitiallyExpanded: false, fromChat: false) { if let infoController = strongSelf.context.sharedContext.makePeerInfoController(context: strongSelf.context, peer: peer._asPeer(), mode: .generic, avatarInitiallyExpanded: false, fromChat: false) {
strongSelf.pushController(infoController) strongSelf.pushController(infoController)
} }
} }

View File

@ -124,7 +124,7 @@ final class ChatTextInputAudioRecordingOverlay {
var containerNodeRef: ASDisplayNode? = self.containerNode var containerNodeRef: ASDisplayNode? = self.containerNode
var completion: () -> Void = { let completion: () -> Void = {
if let containerNode = containerNodeRef, innerCompleted, outerCompleted, iconCompleted { if let containerNode = containerNodeRef, innerCompleted, outerCompleted, iconCompleted {
containerNode.removeFromSupernode() containerNode.removeFromSupernode()
containerNodeRef = nil containerNodeRef = nil

View File

@ -2352,14 +2352,6 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
backgroundView.frame = self.textInputBackgroundNode.frame backgroundView.frame = self.textInputBackgroundNode.frame
func updateIsCaretHidden(view: UIView, isHidden: Bool) { func updateIsCaretHidden(view: UIView, isHidden: Bool) {
return;
if String(describing: type(of: view)).contains("TextSelectionView") {
view.isHidden = isHidden
} else {
for subview in view.subviews {
updateIsCaretHidden(view: subview, isHidden: isHidden)
}
}
} }
updateIsCaretHidden(view: textInputNode.view, isHidden: true) updateIsCaretHidden(view: textInputNode.view, isHidden: true)

View File

@ -38,7 +38,6 @@ final class ComposeControllerNode: ASDisplayNode {
self.presentationData = context.sharedContext.currentPresentationData.with { $0 } self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
var openCreateNewGroupImpl: (() -> Void)? var openCreateNewGroupImpl: (() -> Void)?
var openCreateNewSecretChatImpl: (() -> Void)?
var openCreateContactImpl: (() -> Void)? var openCreateContactImpl: (() -> Void)?
var openCreateNewChannelImpl: (() -> Void)? var openCreateNewChannelImpl: (() -> Void)?
@ -67,9 +66,6 @@ final class ComposeControllerNode: ASDisplayNode {
openCreateNewGroupImpl = { [weak self] in openCreateNewGroupImpl = { [weak self] in
self?.openCreateNewGroup?() self?.openCreateNewGroup?()
} }
openCreateNewSecretChatImpl = { [weak self] in
self?.openCreateNewSecretChat?()
}
openCreateContactImpl = { [weak self] in openCreateContactImpl = { [weak self] in
self?.contactListNode.listNode.clearHighlightAnimated(true) self?.contactListNode.listNode.clearHighlightAnimated(true)
self?.openCreateContact?() self?.openCreateContact?()

View File

@ -29,25 +29,14 @@ func paneGifSearchForQuery(context: AccountContext, query: String, offset: Strin
let configuration = currentSearchBotsConfiguration(transaction: transaction) let configuration = currentSearchBotsConfiguration(transaction: transaction)
return configuration.gifBotUsername ?? "gif" return configuration.gifBotUsername ?? "gif"
} }
|> mapToSignal { botName -> Signal<PeerId?, NoError> in |> mapToSignal { botName -> Signal<EnginePeer?, NoError> in
return context.engine.peers.resolvePeerByName(name: botName) return context.engine.peers.resolvePeerByName(name: botName)
} }
|> mapToSignal { peerId -> Signal<Peer?, NoError> in
if let peerId = peerId {
return context.account.postbox.loadedPeerWithId(peerId)
|> map { peer -> Peer? in
return peer
}
|> take(1)
} else {
return .single(nil)
}
}
|> mapToSignal { peer -> Signal<(ChatPresentationInputQueryResult?, Bool, Bool), NoError> in |> mapToSignal { peer -> Signal<(ChatPresentationInputQueryResult?, Bool, Bool), NoError> in
if let user = peer as? TelegramUser, let botInfo = user.botInfo, let _ = botInfo.inlinePlaceholder { if case let .user(user) = peer, let botInfo = user.botInfo, let _ = botInfo.inlinePlaceholder {
let results = requestContextResults(context: context, botId: user.id, query: query, peerId: context.account.peerId, offset: offset ?? "", incompleteResults: incompleteResults, staleCachedResults: staleCachedResults, limit: 1) let results = requestContextResults(context: context, botId: user.id, query: query, peerId: context.account.peerId, offset: offset ?? "", incompleteResults: incompleteResults, staleCachedResults: staleCachedResults, limit: 1)
|> map { results -> (ChatPresentationInputQueryResult?, Bool, Bool) in |> map { results -> (ChatPresentationInputQueryResult?, Bool, Bool) in
return (.contextRequestResult(user, results?.results), results != nil, results?.isStale ?? false) return (.contextRequestResult(.user(user), results?.results), results != nil, results?.isStale ?? false)
} }
let maybeDelayedContextResults: Signal<(ChatPresentationInputQueryResult?, Bool, Bool), NoError> let maybeDelayedContextResults: Signal<(ChatPresentationInputQueryResult?, Bool, Bool), NoError>

View File

@ -1,7 +1,6 @@
import Foundation import Foundation
import UIKit import UIKit
import AsyncDisplayKit import AsyncDisplayKit
import Postbox
import TelegramCore import TelegramCore
import Display import Display
import TelegramPresentationData import TelegramPresentationData
@ -14,7 +13,7 @@ import ItemListUI
private struct MentionChatInputContextPanelEntry: Comparable, Identifiable { private struct MentionChatInputContextPanelEntry: Comparable, Identifiable {
let index: Int let index: Int
let peer: Peer let peer: EnginePeer
let revealed: Bool let revealed: Bool
var stableId: Int64 { var stableId: Int64 {
@ -22,15 +21,15 @@ private struct MentionChatInputContextPanelEntry: Comparable, Identifiable {
} }
static func ==(lhs: MentionChatInputContextPanelEntry, rhs: MentionChatInputContextPanelEntry) -> Bool { static func ==(lhs: MentionChatInputContextPanelEntry, rhs: MentionChatInputContextPanelEntry) -> Bool {
return lhs.index == rhs.index && lhs.peer.isEqual(rhs.peer) && lhs.revealed == rhs.revealed return lhs.index == rhs.index && lhs.peer == rhs.peer && lhs.revealed == rhs.revealed
} }
static func <(lhs: MentionChatInputContextPanelEntry, rhs: MentionChatInputContextPanelEntry) -> Bool { static func <(lhs: MentionChatInputContextPanelEntry, rhs: MentionChatInputContextPanelEntry) -> Bool {
return lhs.index < rhs.index return lhs.index < rhs.index
} }
func item(context: AccountContext, presentationData: PresentationData, inverted: Bool, setPeerIdRevealed: @escaping (PeerId?) -> Void, peerSelected: @escaping (Peer) -> Void, removeRequested: @escaping (PeerId) -> Void) -> ListViewItem { func item(context: AccountContext, presentationData: PresentationData, inverted: Bool, setPeerIdRevealed: @escaping (EnginePeer.Id?) -> Void, peerSelected: @escaping (EnginePeer) -> Void, removeRequested: @escaping (EnginePeer.Id) -> Void) -> ListViewItem {
return MentionChatInputPanelItem(context: context, presentationData: ItemListPresentationData(presentationData), inverted: inverted, peer: self.peer, revealed: self.revealed, setPeerIdRevealed: setPeerIdRevealed, peerSelected: peerSelected, removeRequested: removeRequested) return MentionChatInputPanelItem(context: context, presentationData: ItemListPresentationData(presentationData), inverted: inverted, peer: self.peer._asPeer(), revealed: self.revealed, setPeerIdRevealed: setPeerIdRevealed, peerSelected: peerSelected, removeRequested: removeRequested)
} }
} }
@ -40,7 +39,7 @@ private struct CommandChatInputContextPanelTransition {
let updates: [ListViewUpdateItem] let updates: [ListViewUpdateItem]
} }
private func preparedTransition(from fromEntries: [MentionChatInputContextPanelEntry], to toEntries: [MentionChatInputContextPanelEntry], context: AccountContext, presentationData: PresentationData, inverted: Bool, forceUpdate: Bool, setPeerIdRevealed: @escaping (PeerId?) -> Void, peerSelected: @escaping (Peer) -> Void, removeRequested: @escaping (PeerId) -> Void) -> CommandChatInputContextPanelTransition { private func preparedTransition(from fromEntries: [MentionChatInputContextPanelEntry], to toEntries: [MentionChatInputContextPanelEntry], context: AccountContext, presentationData: PresentationData, inverted: Bool, forceUpdate: Bool, setPeerIdRevealed: @escaping (EnginePeer.Id?) -> Void, peerSelected: @escaping (EnginePeer) -> Void, removeRequested: @escaping (EnginePeer.Id) -> Void) -> CommandChatInputContextPanelTransition {
let (deleteIndices, indicesAndItems, updateIndices) = mergeListsStableWithUpdates(leftList: fromEntries, rightList: toEntries, allUpdated: forceUpdate) let (deleteIndices, indicesAndItems, updateIndices) = mergeListsStableWithUpdates(leftList: fromEntries, rightList: toEntries, allUpdated: forceUpdate)
let deletions = deleteIndices.map { ListViewDeleteItem(index: $0, directionHint: nil) } let deletions = deleteIndices.map { ListViewDeleteItem(index: $0, directionHint: nil) }
@ -61,8 +60,8 @@ final class MentionChatInputContextPanelNode: ChatInputContextPanelNode {
private let listView: ListView private let listView: ListView
private var currentEntries: [MentionChatInputContextPanelEntry]? private var currentEntries: [MentionChatInputContextPanelEntry]?
private var currentResults: [Peer] = [] private var currentResults: [EnginePeer] = []
private var revealedPeerId: PeerId? private var revealedPeerId: EnginePeer.Id?
private var enqueuedTransitions: [(CommandChatInputContextPanelTransition, Bool)] = [] private var enqueuedTransitions: [(CommandChatInputContextPanelTransition, Bool)] = []
private var validLayout: (CGSize, CGFloat, CGFloat, CGFloat)? private var validLayout: (CGSize, CGFloat, CGFloat, CGFloat)?
@ -92,7 +91,7 @@ final class MentionChatInputContextPanelNode: ChatInputContextPanelNode {
} }
} }
func updateResults(_ results: [Peer]) { func updateResults(_ results: [EnginePeer]) {
self.currentResults = results self.currentResults = results
var entries: [MentionChatInputContextPanelEntry] = [] var entries: [MentionChatInputContextPanelEntry] = []
@ -159,7 +158,7 @@ final class MentionChatInputContextPanelNode: ChatInputContextPanelNode {
return (textInputState, inputMode) return (textInputState, inputMode)
} }
case .search: case .search:
interfaceInteraction.beginMessageSearch(.member(peer), "") interfaceInteraction.beginMessageSearch(.member(peer._asPeer()), "")
} }
} }
}, removeRequested: { [weak self] peerId in }, removeRequested: { [weak self] peerId in
@ -227,7 +226,7 @@ final class MentionChatInputContextPanelNode: ChatInputContextPanelNode {
} }
private func topInsetForLayout(size: CGSize) -> CGFloat { private func topInsetForLayout(size: CGSize) -> CGFloat {
var minimumItemHeights: CGFloat = floor(MentionChatInputPanelItemNode.itemHeight * 3.5) let minimumItemHeights: CGFloat = floor(MentionChatInputPanelItemNode.itemHeight * 3.5)
return max(size.height - minimumItemHeights, 0.0) return max(size.height - minimumItemHeights, 0.0)
} }

View File

@ -17,13 +17,13 @@ final class MentionChatInputPanelItem: ListViewItem {
fileprivate let revealed: Bool fileprivate let revealed: Bool
fileprivate let inverted: Bool fileprivate let inverted: Bool
fileprivate let peer: Peer fileprivate let peer: Peer
private let peerSelected: (Peer) -> Void private let peerSelected: (EnginePeer) -> Void
fileprivate let setPeerIdRevealed: (PeerId?) -> Void fileprivate let setPeerIdRevealed: (EnginePeer.Id?) -> Void
fileprivate let removeRequested: (PeerId) -> Void fileprivate let removeRequested: (EnginePeer.Id) -> Void
let selectable: Bool = true let selectable: Bool = true
public init(context: AccountContext, presentationData: ItemListPresentationData, inverted: Bool, peer: Peer, revealed: Bool, setPeerIdRevealed: @escaping (PeerId?) -> Void, peerSelected: @escaping (Peer) -> Void, removeRequested: @escaping (PeerId) -> Void) { public init(context: AccountContext, presentationData: ItemListPresentationData, inverted: Bool, peer: Peer, revealed: Bool, setPeerIdRevealed: @escaping (PeerId?) -> Void, peerSelected: @escaping (EnginePeer) -> Void, removeRequested: @escaping (PeerId) -> Void) {
self.context = context self.context = context
self.presentationData = presentationData self.presentationData = presentationData
self.inverted = inverted self.inverted = inverted
@ -85,7 +85,7 @@ final class MentionChatInputPanelItem: ListViewItem {
if self.revealed { if self.revealed {
self.setPeerIdRevealed(nil) self.setPeerIdRevealed(nil)
} else { } else {
self.peerSelected(self.peer) self.peerSelected(EnginePeer(self.peer))
} }
} }
} }
@ -187,8 +187,6 @@ final class MentionChatInputPanelItemNode: ListViewItemNode {
strongSelf.validLayout = (nodeLayout.contentSize, params.leftInset, params.rightInset) strongSelf.validLayout = (nodeLayout.contentSize, params.leftInset, params.rightInset)
let revealOffset = strongSelf.revealOffset
if let updatedInverted = updatedInverted { if let updatedInverted = updatedInverted {
if updatedInverted { if updatedInverted {
strongSelf.transform = CATransform3DMakeRotation(CGFloat(Double.pi), 0.0, 0.0, 1.0) strongSelf.transform = CATransform3DMakeRotation(CGFloat(Double.pi), 0.0, 0.0, 1.0)
@ -230,7 +228,7 @@ final class MentionChatInputPanelItemNode: ListViewItemNode {
} }
func updateRevealOffset(offset: CGFloat, transition: ContainedViewLayoutTransition) { func updateRevealOffset(offset: CGFloat, transition: ContainedViewLayoutTransition) {
if let (size, leftInset, rightInset) = self.validLayout { if let (size, leftInset, _) = self.validLayout {
transition.updateFrameAdditive(node: self.avatarNode, frame: CGRect(origin: CGPoint(x: min(offset, 0.0) + 12.0 + leftInset, y: self.avatarNode.frame.minY), size: self.avatarNode.frame.size)) transition.updateFrameAdditive(node: self.avatarNode, frame: CGRect(origin: CGPoint(x: min(offset, 0.0) + 12.0 + leftInset, y: self.avatarNode.frame.minY), size: self.avatarNode.frame.size))
transition.updateFrameAdditive(node: self.textNode, frame: CGRect(origin: CGPoint(x: min(offset, 0.0) + 55.0 + leftInset, y: self.textNode.frame.minY), size: self.textNode.frame.size)) transition.updateFrameAdditive(node: self.textNode, frame: CGRect(origin: CGPoint(x: min(offset, 0.0) + 55.0 + leftInset, y: self.textNode.frame.minY), size: self.textNode.frame.size))
} }
@ -239,7 +237,7 @@ final class MentionChatInputPanelItemNode: ListViewItemNode {
override func setHighlighted(_ highlighted: Bool, at point: CGPoint, animated: Bool) { override func setHighlighted(_ highlighted: Bool, at point: CGPoint, animated: Bool) {
super.setHighlighted(highlighted, at: point, animated: animated) super.setHighlighted(highlighted, at: point, animated: animated)
if let revealNode = self.revealNode, self.revealOffset != 0 { if let _ = self.revealNode, self.revealOffset != 0 {
return return
} }
@ -418,7 +416,7 @@ final class MentionChatInputPanelItemNode: ListViewItemNode {
private func updateRevealOffsetInternal(offset: CGFloat, transition: ContainedViewLayoutTransition) { private func updateRevealOffsetInternal(offset: CGFloat, transition: ContainedViewLayoutTransition) {
self.revealOffset = offset self.revealOffset = offset
guard let (size, leftInset, rightInset) = self.validLayout else { guard let (size, _, rightInset) = self.validLayout else {
return return
} }

View File

@ -242,13 +242,10 @@ func openResolvedUrlImpl(_ resolvedUrl: ResolvedUrl, context: AccountContext, ur
if let to = to { if let to = to {
if to.hasPrefix("@") { if to.hasPrefix("@") {
let _ = (context.engine.peers.resolvePeerByName(name: String(to[to.index(to.startIndex, offsetBy: 1)...])) let _ = (context.engine.peers.resolvePeerByName(name: String(to[to.index(to.startIndex, offsetBy: 1)...]))
|> deliverOnMainQueue).start(next: { peerId in |> deliverOnMainQueue).start(next: { peer in
if let peerId = peerId { if let peer = peer {
let _ = (context.account.postbox.loadedPeerWithId(peerId) context.sharedContext.applicationBindings.dismissNativeController()
|> deliverOnMainQueue).start(next: { peer in continueWithPeer(peer.id)
context.sharedContext.applicationBindings.dismissNativeController()
continueWithPeer(peer.id)
})
} }
}) })
} else { } else {

View File

@ -3273,14 +3273,8 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD
let account = self.context.account let account = self.context.account
disposable.set((resolveSignal disposable.set((resolveSignal
|> take(1) |> take(1)
|> mapToSignal { peerId -> Signal<Peer?, NoError> in |> mapToSignal { peer -> Signal<Peer?, NoError> in
return account.postbox.transaction { transaction -> Peer? in return .single(peer?._asPeer())
if let peerId = peerId {
return transaction.getPeer(peerId)
} else {
return nil
}
}
} }
|> deliverOnMainQueue).start(next: { [weak self] peer in |> deliverOnMainQueue).start(next: { [weak self] peer in
if let strongSelf = self { if let strongSelf = self {
@ -3307,13 +3301,8 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD
var resolveSignal: Signal<Peer?, NoError> var resolveSignal: Signal<Peer?, NoError>
if let peerName = peerName { if let peerName = peerName {
resolveSignal = self.context.engine.peers.resolvePeerByName(name: peerName) resolveSignal = self.context.engine.peers.resolvePeerByName(name: peerName)
|> mapToSignal { peerId -> Signal<Peer?, NoError> in |> mapToSignal { peer -> Signal<Peer?, NoError> in
if let peerId = peerId { return .single(peer?._asPeer())
return account.postbox.loadedPeerWithId(peerId)
|> map(Optional.init)
} else {
return .single(nil)
}
} }
} else { } else {
resolveSignal = self.context.account.postbox.loadedPeerWithId(self.peerId) resolveSignal = self.context.account.postbox.loadedPeerWithId(self.peerId)
@ -5505,10 +5494,10 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD
let context = self.context let context = self.context
let navigationController = self.controller?.navigationController as? NavigationController let navigationController = self.controller?.navigationController as? NavigationController
self.tipsPeerDisposable.set((self.context.engine.peers.resolvePeerByName(name: self.presentationData.strings.Settings_TipsUsername) |> deliverOnMainQueue).start(next: { [weak controller] peerId in self.tipsPeerDisposable.set((self.context.engine.peers.resolvePeerByName(name: self.presentationData.strings.Settings_TipsUsername) |> deliverOnMainQueue).start(next: { [weak controller] peer in
controller?.dismiss() controller?.dismiss()
if let peerId = peerId, let navigationController = navigationController { if let peer = peer, let navigationController = navigationController {
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peerId))) context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer.id)))
} }
})) }))
} }

View File

@ -90,8 +90,8 @@ func handleTextLinkActionImpl(context: AccountContext, peerId: PeerId?, navigate
} }
let openPeerMentionImpl: (String) -> Void = { mention in let openPeerMentionImpl: (String) -> Void = { mention in
navigateDisposable.set((context.engine.peers.resolvePeerByName(name: mention, ageLimit: 10) |> take(1) |> deliverOnMainQueue).start(next: { peerId in navigateDisposable.set((context.engine.peers.resolvePeerByName(name: mention, ageLimit: 10) |> take(1) |> deliverOnMainQueue).start(next: { peer in
openResolvedPeerImpl(peerId, .default) openResolvedPeerImpl(peer?.id, .default)
})) }))
} }

View File

@ -346,14 +346,8 @@ private func resolveInternalUrl(context: AccountContext, url: ParsedInternalUrl)
case let .peerName(name, parameter): case let .peerName(name, parameter):
return context.engine.peers.resolvePeerByName(name: name) return context.engine.peers.resolvePeerByName(name: name)
|> take(1) |> take(1)
|> mapToSignal { peerId -> Signal<Peer?, NoError> in |> mapToSignal { peer -> Signal<Peer?, NoError> in
return context.account.postbox.transaction { transaction -> Peer? in return .single(peer?._asPeer())
if let peerId = peerId {
return transaction.getPeer(peerId)
} else {
return nil
}
}
} }
|> mapToSignal { peer -> Signal<ResolvedUrl?, NoError> in |> mapToSignal { peer -> Signal<ResolvedUrl?, NoError> in
if let peer = peer { if let peer = peer {

View File

@ -750,11 +750,11 @@ final class WatchLocationHandler: WatchRequestHandler {
if let context = context { if let context = context {
return context.engine.peers.resolvePeerByName(name: "foursquare") return context.engine.peers.resolvePeerByName(name: "foursquare")
|> take(1) |> take(1)
|> mapToSignal { peerId -> Signal<ChatContextResultCollection?, NoError> in |> mapToSignal { peer -> Signal<ChatContextResultCollection?, NoError> in
guard let peerId = peerId else { guard let peer = peer else {
return .single(nil) return .single(nil)
} }
return context.engine.messages.requestChatContextResults(botId: peerId, peerId: context.account.peerId, query: "", location: .single((args.coordinate.latitude, args.coordinate.longitude)), offset: "") return context.engine.messages.requestChatContextResults(botId: peer.id, peerId: context.account.peerId, query: "", location: .single((args.coordinate.latitude, args.coordinate.longitude)), offset: "")
|> map { results -> ChatContextResultCollection? in |> map { results -> ChatContextResultCollection? in
return results?.results return results?.results
} }

View File

@ -446,23 +446,15 @@ public final class WebSearchController: ViewController {
let account = self.context.account let account = self.context.account
let context = self.context let context = self.context
let contextBot = self.context.engine.peers.resolvePeerByName(name: name) let contextBot = self.context.engine.peers.resolvePeerByName(name: name)
|> mapToSignal { peerId -> Signal<Peer?, NoError> in |> mapToSignal { peer -> Signal<Peer?, NoError> in
if let peerId = peerId { return .single(peer?._asPeer())
return account.postbox.loadedPeerWithId(peerId)
|> map { peer -> Peer? in
return peer
}
|> take(1)
} else {
return .single(nil)
}
} }
|> mapToSignal { peer -> Signal<(ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?, NoError> in |> mapToSignal { peer -> Signal<(ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?, NoError> in
if let user = peer as? TelegramUser, let botInfo = user.botInfo, let _ = botInfo.inlinePlaceholder { if let user = peer as? TelegramUser, let botInfo = user.botInfo, let _ = botInfo.inlinePlaceholder {
let results = requestContextResults(context: context, botId: user.id, query: query, peerId: peerId, limit: 64) let results = requestContextResults(context: context, botId: user.id, query: query, peerId: peerId, limit: 64)
|> map { results -> (ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult? in |> map { results -> (ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult? in
return { _ in return { _ in
return .contextRequestResult(user, results?.results) return .contextRequestResult(.user(user), results?.results)
} }
} }