mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-15 21:45:19 +00:00
Refactoring
This commit is contained in:
parent
1a04fb4408
commit
c9f009eae7
@ -1,6 +1,5 @@
|
||||
import Foundation
|
||||
import UIKit
|
||||
import Postbox
|
||||
import TelegramCore
|
||||
import TextFormat
|
||||
import AsyncDisplayKit
|
||||
@ -8,24 +7,25 @@ import Display
|
||||
import SwiftSignalKit
|
||||
import TelegramPresentationData
|
||||
import TelegramUIPreferences
|
||||
import Postbox
|
||||
|
||||
public final class ChatMessageItemAssociatedData: Equatable {
|
||||
public enum ChannelDiscussionGroupStatus: Equatable {
|
||||
case unknown
|
||||
case known(PeerId?)
|
||||
case known(EnginePeer.Id?)
|
||||
}
|
||||
|
||||
public let automaticDownloadPeerType: MediaAutoDownloadPeerType
|
||||
public let automaticDownloadNetworkType: MediaAutoDownloadNetworkType
|
||||
public let isRecentActions: Bool
|
||||
public let subject: ChatControllerSubject?
|
||||
public let contactsPeerIds: Set<PeerId>
|
||||
public let contactsPeerIds: Set<EnginePeer.Id>
|
||||
public let channelDiscussionGroup: ChannelDiscussionGroupStatus
|
||||
public let animatedEmojiStickers: [String: [StickerPackItem]]
|
||||
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.automaticDownloadNetworkType = automaticDownloadNetworkType
|
||||
self.isRecentActions = isRecentActions
|
||||
@ -79,7 +79,7 @@ public extension ChatMessageItemAssociatedData {
|
||||
public enum ChatControllerInteractionLongTapAction {
|
||||
case url(String)
|
||||
case mention(String)
|
||||
case peerMention(PeerId, String)
|
||||
case peerMention(EnginePeer.Id, String)
|
||||
case command(String)
|
||||
case hashtag(String)
|
||||
case timecode(Double, String)
|
||||
@ -110,7 +110,7 @@ public enum ChatHistoryMessageSelection: Equatable {
|
||||
|
||||
public enum ChatControllerInitialBotStartBehavior {
|
||||
case interactive
|
||||
case automatic(returnToPeerId: PeerId, scheduled: Bool)
|
||||
case automatic(returnToPeerId: EnginePeer.Id, scheduled: Bool)
|
||||
}
|
||||
|
||||
public struct ChatControllerInitialBotStart {
|
||||
@ -171,7 +171,7 @@ public enum ChatTextInputStateTextAttributeType: PostboxCoding, Equatable {
|
||||
case bold
|
||||
case italic
|
||||
case monospace
|
||||
case textMention(PeerId)
|
||||
case textMention(EnginePeer.Id)
|
||||
case textUrl(String)
|
||||
|
||||
public init(decoder: PostboxDecoder) {
|
||||
@ -183,7 +183,7 @@ public enum ChatTextInputStateTextAttributeType: PostboxCoding, Equatable {
|
||||
case 2:
|
||||
self = .monospace
|
||||
case 3:
|
||||
self = .textMention(PeerId(decoder.decodeInt64ForKey("peerId", orElse: 0)))
|
||||
self = .textMention(EnginePeer.Id(decoder.decodeInt64ForKey("peerId", orElse: 0)))
|
||||
case 4:
|
||||
self = .textUrl(decoder.decodeStringForKey("url", orElse: ""))
|
||||
default:
|
||||
@ -340,9 +340,9 @@ public struct ChatTextInputStateText: PostboxCoding, 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 pinnedMessages(id: MessageId?)
|
||||
case pinnedMessages(id: EngineMessage.Id?)
|
||||
}
|
||||
|
||||
public enum ChatControllerPresentationMode: Equatable {
|
||||
@ -382,10 +382,10 @@ public final class ChatEmbeddedInterfaceState: PeerChatListEmbeddedInterfaceStat
|
||||
public enum ChatPresentationInputQueryResult: Equatable {
|
||||
case stickers([FoundStickerItem])
|
||||
case hashtags([String])
|
||||
case mentions([Peer])
|
||||
case mentions([EnginePeer])
|
||||
case commands([PeerCommand])
|
||||
case emojis([(String, String)], NSRange)
|
||||
case contextRequestResult(Peer?, ChatContextResultCollection?)
|
||||
case contextRequestResult(EnginePeer?, ChatContextResultCollection?)
|
||||
|
||||
public static func ==(lhs: ChatPresentationInputQueryResult, rhs: ChatPresentationInputQueryResult) -> Bool {
|
||||
switch lhs {
|
||||
@ -403,16 +403,10 @@ public enum ChatPresentationInputQueryResult: Equatable {
|
||||
}
|
||||
case let .mentions(lhsPeers):
|
||||
if case let .mentions(rhsPeers) = rhs {
|
||||
if lhsPeers.count != rhsPeers.count {
|
||||
if lhsPeers != rhsPeers {
|
||||
return false
|
||||
} else {
|
||||
for i in 0 ..< lhsPeers.count {
|
||||
if !lhsPeers[i].isEqual(rhsPeers[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
@ -444,14 +438,9 @@ public enum ChatPresentationInputQueryResult: Equatable {
|
||||
}
|
||||
case let .contextRequestResult(lhsPeer, lhsCollection):
|
||||
if case let .contextRequestResult(rhsPeer, rhsCollection) = rhs {
|
||||
if let lhsPeer = lhsPeer, let rhsPeer = rhsPeer {
|
||||
if !lhsPeer.isEqual(rhsPeer) {
|
||||
return false
|
||||
}
|
||||
} else if (lhsPeer != nil) != (rhsPeer != nil) {
|
||||
if lhsPeer != rhsPeer {
|
||||
return false
|
||||
}
|
||||
|
||||
if lhsCollection != rhsCollection {
|
||||
return false
|
||||
}
|
||||
@ -483,7 +472,7 @@ public protocol ChatController: ViewController {
|
||||
var isSendButtonVisible: Bool { get }
|
||||
}
|
||||
|
||||
public protocol ChatMessagePreviewItemNode: class {
|
||||
public protocol ChatMessagePreviewItemNode: AnyObject {
|
||||
var forwardInfoReferenceNode: ASDisplayNode? { get }
|
||||
}
|
||||
|
||||
|
@ -829,11 +829,6 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
|
||||
var items: [ActionSheetItem] = []
|
||||
var personalPeerName: String?
|
||||
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) {
|
||||
let globalTitle: String
|
||||
|
@ -72,8 +72,8 @@ final class InstantPageFeedbackNode: ASDisplayNode, InstantPageNode {
|
||||
}
|
||||
|
||||
@objc func buttonPressed() {
|
||||
self.resolveDisposable.set((self.context.engine.peers.resolvePeerByName(name: "previews") |> deliverOnMainQueue).start(next: { [weak self] peerId in
|
||||
if let strongSelf = self, let _ = peerId, let webPageId = strongSelf.webPage.id?.id {
|
||||
self.resolveDisposable.set((self.context.engine.peers.resolvePeerByName(name: "previews") |> deliverOnMainQueue).start(next: { [weak self] peer in
|
||||
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))
|
||||
}
|
||||
}))
|
||||
|
@ -151,11 +151,9 @@ final class InstantPagePeerReferenceNode: ASDisplayNode, InstantPageNode {
|
||||
|> mapToSignal({ peer -> Signal<Peer, NoError> in
|
||||
if let peer = peer as? TelegramChannel, let username = peer.username, peer.accessHash == nil {
|
||||
return .single(peer) |> then(context.engine.peers.resolvePeerByName(name: username)
|
||||
|> mapToSignal({ peerId -> Signal<Peer, NoError> in
|
||||
if let peerId = peerId {
|
||||
return account.postbox.transaction({ transaction -> Peer in
|
||||
return transaction.getPeer(peerId) ?? peer
|
||||
})
|
||||
|> mapToSignal({ updatedPeer -> Signal<Peer, NoError> in
|
||||
if let updatedPeer = updatedPeer {
|
||||
return .single(updatedPeer._asPeer())
|
||||
} else {
|
||||
return .single(peer)
|
||||
}
|
||||
|
@ -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 users = NSMutableArray()
|
||||
for peer in peers {
|
||||
if let peer = peer as? TelegramUser {
|
||||
if case let .user(peer) = peer {
|
||||
let user = TGUser()
|
||||
user.uid = peer.id.id._internalGetInt32Value()
|
||||
user.firstName = peer.firstName
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -38,11 +38,11 @@ public func nearbyVenues(context: AccountContext, latitude: Double, longitude: D
|
||||
} |> mapToSignal { searchBotsConfiguration in
|
||||
return context.engine.peers.resolvePeerByName(name: searchBotsConfiguration.venueBotUsername ?? "foursquare")
|
||||
|> take(1)
|
||||
|> mapToSignal { peerId -> Signal<ChatContextResultCollection?, NoError> in
|
||||
guard let peerId = peerId else {
|
||||
|> mapToSignal { peer -> Signal<ChatContextResultCollection?, NoError> in
|
||||
guard let peer = peer else {
|
||||
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
|
||||
return results?.results
|
||||
}
|
||||
|
@ -761,9 +761,9 @@ public func channelPermissionsController(context: AccountContext, peerId origina
|
||||
}
|
||||
pushControllerImpl?(controller)
|
||||
}, openChannelExample: {
|
||||
resolveDisposable.set((context.engine.peers.resolvePeerByName(name: "durov") |> deliverOnMainQueue).start(next: { peerId in
|
||||
if let peerId = peerId {
|
||||
navigateToChatControllerImpl?(peerId)
|
||||
resolveDisposable.set((context.engine.peers.resolvePeerByName(name: "durov") |> deliverOnMainQueue).start(next: { peer in
|
||||
if let peer = peer {
|
||||
navigateToChatControllerImpl?(peer.id)
|
||||
}
|
||||
}))
|
||||
}, updateSlowmode: { value in
|
||||
|
@ -401,10 +401,10 @@ public func groupStickerPackSetupController(context: AccountContext, peerId: Pee
|
||||
}, updateSearchText: { text in
|
||||
searchText.set(text)
|
||||
}, openStickersBot: {
|
||||
resolveDisposable.set((context.engine.peers.resolvePeerByName(name: "stickers") |> deliverOnMainQueue).start(next: { peerId in
|
||||
if let peerId = peerId {
|
||||
resolveDisposable.set((context.engine.peers.resolvePeerByName(name: "stickers") |> deliverOnMainQueue).start(next: { peer in
|
||||
if let peer = peer {
|
||||
dismissImpl?()
|
||||
navigateToChatControllerImpl?(peerId)
|
||||
navigateToChatControllerImpl?(peer.id)
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
@ -1,5 +1,4 @@
|
||||
import Foundation
|
||||
import Postbox
|
||||
import TelegramCore
|
||||
import SwiftSignalKit
|
||||
import AccountContext
|
||||
@ -9,32 +8,32 @@ public enum SearchPeerMembersScope {
|
||||
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 {
|
||||
return context.account.postbox.transaction { transaction -> CachedChannelData? in
|
||||
return transaction.getPeerCachedData(peerId: peerId) as? CachedChannelData
|
||||
}
|
||||
|> mapToSignal { cachedData -> Signal<([Peer], Bool), NoError> in
|
||||
if case .peer = chatLocation, let cachedData = cachedData, let memberCount = cachedData.participantsSummary.memberCount, memberCount <= 64 {
|
||||
return context.engine.data.get(
|
||||
TelegramEngine.EngineData.Item.Peer.ParticipantCount(id: peerId)
|
||||
)
|
||||
|> mapToSignal { participantCount -> Signal<([EnginePeer], Bool), NoError> in
|
||||
if case .peer = chatLocation, let memberCount = participantCount, memberCount <= 64 {
|
||||
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
|
||||
if case .ready = state.loadingState {
|
||||
let normalizedQuery = query.lowercased()
|
||||
subscriber.putNext((state.list.compactMap { participant -> Peer? in
|
||||
subscriber.putNext((state.list.compactMap { participant -> EnginePeer? in
|
||||
if participant.peer.isDeleted {
|
||||
return nil
|
||||
}
|
||||
if normalizedQuery.isEmpty {
|
||||
return participant.peer
|
||||
return EnginePeer(participant.peer)
|
||||
}
|
||||
if normalizedQuery.isEmpty {
|
||||
return participant.peer
|
||||
return EnginePeer(participant.peer)
|
||||
} else {
|
||||
if participant.peer.indexName.matchesByTokens(normalizedQuery) {
|
||||
return participant.peer
|
||||
return EnginePeer(participant.peer)
|
||||
}
|
||||
if let addressName = participant.peer.addressName, addressName.lowercased().hasPrefix(normalizedQuery) {
|
||||
return participant.peer
|
||||
return EnginePeer(participant.peer)
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -59,7 +58,7 @@ public func searchPeerMembers(context: AccountContext, peerId: PeerId, chatLocat
|
||||
if participant.peer.isDeleted {
|
||||
return nil
|
||||
}
|
||||
return participant.peer
|
||||
return EnginePeer(participant.peer)
|
||||
}, true))
|
||||
}
|
||||
})
|
||||
@ -74,7 +73,7 @@ public func searchPeerMembers(context: AccountContext, peerId: PeerId, chatLocat
|
||||
if participant.peer.isDeleted {
|
||||
return nil
|
||||
}
|
||||
return participant.peer
|
||||
return EnginePeer(participant.peer)
|
||||
}, true))
|
||||
}
|
||||
})
|
||||
@ -85,16 +84,19 @@ public func searchPeerMembers(context: AccountContext, peerId: PeerId, chatLocat
|
||||
}
|
||||
} |> runOn(Queue.mainQueue())
|
||||
}
|
||||
|> mapToSignal { result, isReady -> Signal<[Peer], NoError> in
|
||||
|> mapToSignal { result, isReady -> Signal<[EnginePeer], NoError> in
|
||||
switch scope {
|
||||
case .mention:
|
||||
return .single(result)
|
||||
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
|
||||
let normalizedQuery = query.lowercased()
|
||||
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
|
||||
if normalizedQuery.isEmpty {
|
||||
matches = true
|
||||
@ -107,7 +109,7 @@ public func searchPeerMembers(context: AccountContext, peerId: PeerId, chatLocat
|
||||
}
|
||||
}
|
||||
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 {
|
||||
return context.engine.peers.searchGroupMembers(peerId: peerId, query: query)
|
||||
|> map { peers -> [EnginePeer] in
|
||||
return peers.map(EnginePeer.init)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -580,9 +580,9 @@ public func installedStickerPacksController(context: AccountContext, mode: Insta
|
||||
])
|
||||
presentControllerImpl?(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
||||
}, openStickersBot: {
|
||||
resolveDisposable.set((context.engine.peers.resolvePeerByName(name: "stickers") |> deliverOnMainQueue).start(next: { peerId in
|
||||
if let peerId = peerId {
|
||||
navigateToChatControllerImpl?(peerId)
|
||||
resolveDisposable.set((context.engine.peers.resolvePeerByName(name: "stickers") |> deliverOnMainQueue).start(next: { peer in
|
||||
if let peer = peer {
|
||||
navigateToChatControllerImpl?(peer.id)
|
||||
}
|
||||
}))
|
||||
}, openMasks: {
|
||||
|
@ -497,13 +497,9 @@ final class ThemeGridSearchContentNode: SearchDisplayControllerContentNode {
|
||||
return .single(nil)
|
||||
}
|
||||
return context.engine.peers.resolvePeerByName(name: name)
|
||||
|> mapToSignal { peerId -> Signal<Peer?, NoError> in
|
||||
if let peerId = peerId {
|
||||
return context.account.postbox.loadedPeerWithId(peerId)
|
||||
|> map { peer -> Peer? in
|
||||
return peer
|
||||
}
|
||||
|> take(1)
|
||||
|> mapToSignal { peer -> Signal<Peer?, NoError> in
|
||||
if let peer = peer {
|
||||
return .single(peer._asPeer())
|
||||
} else {
|
||||
return .single(nil)
|
||||
}
|
||||
|
@ -132,10 +132,9 @@ public final class StickerPackPreviewController: ViewController, StandalonePrese
|
||||
|
||||
let account = strongSelf.context.account
|
||||
strongSelf.openMentionDisposable.set((strongSelf.context.engine.peers.resolvePeerByName(name: mention)
|
||||
|> mapToSignal { peerId -> Signal<Peer?, NoError> in
|
||||
if let peerId = peerId {
|
||||
return account.postbox.loadedPeerWithId(peerId)
|
||||
|> map(Optional.init)
|
||||
|> mapToSignal { peer -> Signal<Peer?, NoError> in
|
||||
if let peer = peer {
|
||||
return .single(peer._asPeer())
|
||||
} else {
|
||||
return .single(nil)
|
||||
}
|
||||
|
@ -13,10 +13,8 @@ public enum InternalUpdaterError {
|
||||
public func requestUpdatesXml(account: Account, source: String) -> Signal<Data, InternalUpdaterError> {
|
||||
return TelegramEngine(account: account).peers.resolvePeerByName(name: source)
|
||||
|> castError(InternalUpdaterError.self)
|
||||
|> mapToSignal { peerId -> Signal<Peer?, InternalUpdaterError> in
|
||||
return account.postbox.transaction { transaction in
|
||||
return peerId != nil ? transaction.getPeer(peerId!) : nil
|
||||
} |> castError(InternalUpdaterError.self)
|
||||
|> mapToSignal { peer -> Signal<Peer?, InternalUpdaterError> in
|
||||
return .single(peer?._asPeer())
|
||||
}
|
||||
|> mapToSignal { peer in
|
||||
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> {
|
||||
return TelegramEngine(account: account).peers.resolvePeerByName(name: source)
|
||||
|> castError(InternalUpdaterError.self)
|
||||
|> mapToSignal { peerId -> Signal<Peer?, InternalUpdaterError> in
|
||||
return account.postbox.transaction { transaction in
|
||||
return peerId != nil ? transaction.getPeer(peerId!) : nil
|
||||
} |> castError(InternalUpdaterError.self)
|
||||
|> mapToSignal { peer -> Signal<Peer?, InternalUpdaterError> in
|
||||
return .single(peer?._asPeer())
|
||||
}
|
||||
|> mapToSignal { peer in
|
||||
if let peer = peer, let inputChannel = apiInputChannel(peer) {
|
||||
|
@ -147,7 +147,7 @@ public struct TelegramChannelFlags: OptionSet {
|
||||
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 accessHash: TelegramPeerAccessHash?
|
||||
public let title: String
|
||||
@ -267,30 +267,34 @@ public final class TelegramChannel: Peer {
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
if self.adminRights != other.adminRights {
|
||||
|
||||
if lhs.adminRights != rhs.adminRights {
|
||||
return false
|
||||
}
|
||||
|
||||
if self.bannedRights != other.bannedRights {
|
||||
|
||||
if lhs.bannedRights != rhs.bannedRights {
|
||||
return false
|
||||
}
|
||||
|
||||
if self.defaultBannedRights != other.defaultBannedRights {
|
||||
|
||||
if lhs.defaultBannedRights != rhs.defaultBannedRights {
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -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 title: String
|
||||
public let photo: [TelegramMediaImageRepresentation]
|
||||
@ -159,45 +159,49 @@ public final class TelegramGroup: Peer {
|
||||
|
||||
public func isEqual(_ other: Peer) -> Bool {
|
||||
if let other = other as? TelegramGroup {
|
||||
if self.id != other.id {
|
||||
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
|
||||
return self == other
|
||||
} else {
|
||||
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 {
|
||||
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)
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import Foundation
|
||||
import Postbox
|
||||
|
||||
public final class TelegramSecretChat: Peer {
|
||||
public final class TelegramSecretChat: Peer, Equatable {
|
||||
public let id: PeerId
|
||||
public let regularPeerId: PeerId
|
||||
public let accessHash: Int64
|
||||
@ -57,11 +57,15 @@ public final class TelegramSecretChat: Peer {
|
||||
|
||||
public func isEqual(_ other: Peer) -> Bool {
|
||||
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 {
|
||||
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 {
|
||||
return TelegramSecretChat(id: self.id, creationDate: self.creationDate, regularPeerId: self.regularPeerId, accessHash: self.accessHash, role: self.role, embeddedState: embeddedState, messageAutoremoveTimeout: self.messageAutoremoveTimeout)
|
||||
|
@ -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 accessHash: TelegramPeerAccessHash?
|
||||
public let firstName: String?
|
||||
@ -198,45 +198,49 @@ public final class TelegramUser: Peer {
|
||||
|
||||
public func isEqual(_ other: Peer) -> Bool {
|
||||
if let other = other as? TelegramUser {
|
||||
if self.id != other.id {
|
||||
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
|
||||
return self == other
|
||||
} else {
|
||||
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 {
|
||||
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)
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
import Postbox
|
||||
|
||||
public enum EngineMedia {
|
||||
public typealias Id = MediaId
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
@ -63,8 +63,16 @@ public extension TelegramEngine {
|
||||
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)
|
||||
|> 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> {
|
||||
@ -320,8 +328,13 @@ public extension TelegramEngine {
|
||||
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)
|
||||
|> map { list -> [(EnginePeer, Double)] in
|
||||
return list.map { peer, rating in
|
||||
return (EnginePeer(peer), rating)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func removeRecentlyUsedInlineBot(peerId: PeerId) -> Signal<Void, NoError> {
|
||||
|
@ -67,6 +67,10 @@ public final class TelegramEngine {
|
||||
public lazy var resolve: Resolve = {
|
||||
return Resolve(account: self.account)
|
||||
}()
|
||||
|
||||
public lazy var data: EngineData = {
|
||||
return EngineData(account: self.account)
|
||||
}()
|
||||
}
|
||||
|
||||
public final class TelegramEngineUnauthorized {
|
||||
|
@ -413,8 +413,7 @@ final class SharedApplicationContext {
|
||||
}, appData: self.deviceToken.get()
|
||||
|> map { token in
|
||||
let data = buildConfig.bundleData(withAppToken: token, signatureDict: signatureDict)
|
||||
if let data = data, let jsonString = String(data: data, encoding: .utf8) {
|
||||
//Logger.shared.log("data", "\(jsonString)")
|
||||
if let data = data, let _ = String(data: data, encoding: .utf8) {
|
||||
} else {
|
||||
Logger.shared.log("data", "can't deserialize")
|
||||
}
|
||||
@ -632,6 +631,8 @@ final class SharedApplicationContext {
|
||||
return .denied
|
||||
case .notDetermined:
|
||||
return .notDetermined
|
||||
@unknown default:
|
||||
return .notDetermined
|
||||
}
|
||||
} else {
|
||||
return .denied
|
||||
@ -2155,7 +2156,6 @@ final class SharedApplicationContext {
|
||||
let muteMediaMessageCategory = UIMutableUserNotificationCategory()
|
||||
muteMediaMessageCategory.identifier = "withMuteMedia"
|
||||
|
||||
let categories = [unknownMessageCategory, replyMessageCategory, replyLegacyMessageCategory, replyLegacyMediaMessageCategory, replyMediaMessageCategory, legacyChannelMessageCategory, muteMessageCategory, muteMediaMessageCategory]
|
||||
let settings = UIUserNotificationSettings(types: [.badge, .sound, .alert], categories: [])
|
||||
UIApplication.shared.registerUserNotificationSettings(settings)
|
||||
UIApplication.shared.registerForRemoteNotifications()
|
||||
@ -2189,9 +2189,7 @@ final class SharedApplicationContext {
|
||||
|
||||
private func maybeCheckForUpdates() {
|
||||
#if targetEnvironment(simulator)
|
||||
return;
|
||||
#endif
|
||||
|
||||
#else
|
||||
guard let buildConfig = self.buildConfig, !buildConfig.isAppStoreBuild, let appCenterId = buildConfig.appCenterId, !appCenterId.isEmpty else {
|
||||
return
|
||||
}
|
||||
@ -2236,6 +2234,7 @@ final class SharedApplicationContext {
|
||||
}))
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
override var next: UIResponder? {
|
||||
|
@ -406,7 +406,7 @@ final class AuthorizedApplicationContext {
|
||||
|
||||
var processed = false
|
||||
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)
|
||||
processed = true
|
||||
break
|
||||
@ -464,9 +464,9 @@ final class AuthorizedApplicationContext {
|
||||
|> deliverOnMainQueue).start(completed: {
|
||||
controller?.dismiss()
|
||||
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
|
||||
if let strongSelf = self, let peerId = peerId {
|
||||
self?.rootController.pushViewController(ChatControllerImpl(context: strongSelf.context, chatLocation: .peer(peerId)))
|
||||
strongSelf.termsOfServiceProceedToBotDisposable.set((strongSelf.context.engine.peers.resolvePeerByName(name: botName, ageLimit: 10) |> take(1) |> deliverOnMainQueue).start(next: { peer in
|
||||
if let strongSelf = self, let peer = peer {
|
||||
self?.rootController.pushViewController(ChatControllerImpl(context: strongSelf.context, chatLocation: .peer(peer.id)))
|
||||
}
|
||||
}))
|
||||
}
|
||||
@ -611,7 +611,7 @@ final class AuthorizedApplicationContext {
|
||||
switch state {
|
||||
case .contacts:
|
||||
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 {
|
||||
splitTest.addEvent(.ContactsAllowed)
|
||||
} else {
|
||||
@ -619,12 +619,12 @@ final class AuthorizedApplicationContext {
|
||||
}
|
||||
permissionsPosition.set(position + 1)
|
||||
ApplicationSpecificNotice.setPermissionWarning(accountManager: context.sharedContext.accountManager, permission: .contacts, value: 0)
|
||||
}
|
||||
})
|
||||
case .notifications:
|
||||
splitTest.addEvent(.NotificationsRequest)
|
||||
DeviceAccess.authorizeAccess(to: .notifications, registerForNotifications: { result in
|
||||
context.sharedContext.applicationBindings.registerForNotifications(result)
|
||||
}) { result in
|
||||
}, { result in
|
||||
if result {
|
||||
splitTest.addEvent(.NotificationsAllowed)
|
||||
} else {
|
||||
@ -632,7 +632,7 @@ final class AuthorizedApplicationContext {
|
||||
}
|
||||
permissionsPosition.set(position + 1)
|
||||
ApplicationSpecificNotice.setPermissionWarning(accountManager: context.sharedContext.accountManager, permission: .notifications, value: 0)
|
||||
}
|
||||
})
|
||||
case .cellularData:
|
||||
DeviceAccess.authorizeAccess(to: .cellularData, presentationData: context.sharedContext.currentPresentationData.with { $0 }, present: { [weak self] c, a in
|
||||
if let strongSelf = self {
|
||||
@ -647,9 +647,9 @@ final class AuthorizedApplicationContext {
|
||||
case .siri:
|
||||
DeviceAccess.authorizeAccess(to: .siri, requestSiriAuthorization: { completion in
|
||||
return context.sharedContext.applicationBindings.requestSiriAuthorization(completion)
|
||||
}) { result in
|
||||
}, { result in
|
||||
permissionsPosition.set(position + 1)
|
||||
}
|
||||
})
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
@ -783,7 +783,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
||||
}
|
||||
controllers.append(self.passwordEntryController(hint: hint, suggestReset: suggestReset, syncContacts: syncContacts))
|
||||
self.setViewControllers(controllers, animated: !self.viewControllers.isEmpty)
|
||||
case let .passwordRecovery(hint, _, _, emailPattern, syncContacts):
|
||||
case let .passwordRecovery(_, _, _, emailPattern, syncContacts):
|
||||
var controllers: [ViewController] = []
|
||||
if !self.otherAccountPhoneNumbers.1.isEmpty {
|
||||
controllers.append(self.splashController())
|
||||
|
@ -101,7 +101,6 @@ final class AuthorizationSequencePasswordRecoveryControllerNode: ASDisplayNode,
|
||||
|
||||
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 resetSize = self.noAccessNode.measure(CGSize(width: layout.size.width, height: CGFloat.greatestFiniteMagnitude))
|
||||
|
||||
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)))
|
||||
|
@ -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.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 {
|
||||
@ -11283,14 +11283,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
let account = self.context.account
|
||||
disposable.set((resolveSignal
|
||||
|> take(1)
|
||||
|> mapToSignal { peerId -> Signal<Peer?, NoError> in
|
||||
return account.postbox.transaction { transaction -> Peer? in
|
||||
if let peerId = peerId {
|
||||
return transaction.getPeer(peerId)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|> mapToSignal { peer -> Signal<Peer?, NoError> in
|
||||
return .single(peer?._asPeer())
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peer in
|
||||
if let strongSelf = self {
|
||||
@ -11319,10 +11313,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
var resolveSignal: Signal<Peer?, NoError>
|
||||
if let peerName = peerName {
|
||||
resolveSignal = self.context.engine.peers.resolvePeerByName(name: peerName)
|
||||
|> mapToSignal { peerId -> Signal<Peer?, NoError> in
|
||||
if let peerId = peerId {
|
||||
return account.postbox.loadedPeerWithId(peerId)
|
||||
|> map(Optional.init)
|
||||
|> mapToSignal { peer -> Signal<Peer?, NoError> in
|
||||
if let peer = peer {
|
||||
return .single(peer._asPeer())
|
||||
} else {
|
||||
return .single(nil)
|
||||
}
|
||||
|
@ -203,7 +203,7 @@ func inputContextQueriesForChatPresentationIntefaceState(_ chatPresentationInter
|
||||
func inputTextPanelStateForChatPresentationInterfaceState(_ chatPresentationInterfaceState: ChatPresentationInterfaceState, context: AccountContext) -> ChatTextInputPanelState {
|
||||
var contextPlaceholder: NSAttributedString?
|
||||
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)
|
||||
for inputQuery in inputQueries {
|
||||
if case let .contextRequest(addressName, query) = inputQuery, query.isEmpty {
|
||||
|
@ -49,5 +49,4 @@ func inputNodeForChatPresentationIntefaceState(_ chatPresentationInterfaceState:
|
||||
case .none, .text:
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -177,7 +177,8 @@ private func updatedContextQueryResultStateForQuery(context: AccountContext, pee
|
||||
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))
|
||||
|> map { inlineBots, peers -> (ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult? 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
|
||||
}))
|
||||
sortedPeers = sortedPeers.filter { peer in
|
||||
return !peer.debugDisplayTitle.isEmpty
|
||||
return !peer.displayTitle(strings: strings, displayOrder: .firstLast).isEmpty
|
||||
}
|
||||
return { _ in return .mentions(sortedPeers) }
|
||||
}
|
||||
@ -264,20 +265,9 @@ private func updatedContextQueryResultStateForQuery(context: AccountContext, pee
|
||||
|
||||
let chatPeer = peer
|
||||
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)
|
||||
|> 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
|
||||
return `deferred` {
|
||||
Queue.mainQueue().async {
|
||||
@ -305,7 +295,7 @@ private func updatedContextQueryResultStateForQuery(context: AccountContext, pee
|
||||
}
|
||||
|> map { results -> (ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult? 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>
|
||||
@ -399,7 +389,7 @@ func searchQuerySuggestionResultStateForChatInterfacePresentationState(_ chatPre
|
||||
let participants = searchPeerMembers(context: context, peerId: peer.id, chatLocation: chatPresentationInterfaceState.chatLocation, query: query, scope: .memberSuggestion)
|
||||
|> map { peers -> (ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult? in
|
||||
let filteredPeers = peers
|
||||
var sortedPeers: [Peer] = []
|
||||
var sortedPeers: [EnginePeer] = []
|
||||
sortedPeers.append(contentsOf: filteredPeers.sorted(by: { lhs, rhs in
|
||||
let result = lhs.indexName.indexName(.lastNameFirst).compare(rhs.indexName.indexName(.lastNameFirst))
|
||||
return result == .orderedAscending
|
||||
|
@ -176,8 +176,6 @@ class ChatMessageActionBubbleContentNode: ChatMessageBubbleContentNode {
|
||||
labelRects[i].size.height = 20.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)?
|
||||
var backgroundMaskUpdated = false
|
||||
|
@ -854,7 +854,6 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
var replyMarkup: ReplyMarkupMessageAttribute?
|
||||
|
||||
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)
|
||||
|
||||
@ -864,8 +863,6 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
if let attribute = attribute as? SourceReferenceMessageAttribute {
|
||||
if attribute.messageId.peerId == forwardInfo.author?.id {
|
||||
ignoreForward = true
|
||||
} else {
|
||||
ignoreSource = true
|
||||
}
|
||||
break
|
||||
}
|
||||
@ -1348,16 +1345,9 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
})
|
||||
} else if let _ = self.emojiFile {
|
||||
if let animationNode = self.animationNode as? AnimatedStickerNode, let _ = recognizer {
|
||||
var startTime: Signal<Double, NoError>
|
||||
var shouldPlay = false
|
||||
if !animationNode.isPlaying {
|
||||
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]
|
||||
|
@ -1560,8 +1560,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
||||
} else {
|
||||
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 {
|
||||
|
||||
} else if effectiveAuthor.isScam {
|
||||
@ -1860,7 +1859,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
||||
}
|
||||
|
||||
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 {
|
||||
let mosaicIndex = i - mosaicRange.lowerBound
|
||||
@ -2516,19 +2515,19 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
container?.updateAbsoluteRect(relativeFrame.offsetBy(dx: rect.minX, dy: rect.minY), within: size)
|
||||
}
|
||||
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
|
||||
}
|
||||
container?.applyAbsoluteOffset(value: value, animationCurve: animationCurve, duration: duration)
|
||||
}
|
||||
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
|
||||
}
|
||||
container?.applyAbsoluteOffsetSpring(value: value, duration: duration, damping: damping)
|
||||
|
@ -69,7 +69,6 @@ class ChatMessageCallBubbleContentNode: ChatMessageBubbleContentNode {
|
||||
return { item, layoutConstants, _, _, _ in
|
||||
let contentProperties = ChatMessageBubbleContentProperties(hidesSimpleAuthorHeader: false, headerSpacing: 0.0, hidesBackground: .never, forceFullCorners: false, forceAlignment: .none)
|
||||
return (contentProperties, nil, CGFloat.greatestFiniteMagnitude, { constrainedSize, position in
|
||||
let message = item.message
|
||||
let incoming = item.message.effectivelyIncoming(item.context.account.peerId)
|
||||
|
||||
let horizontalInset = layoutConstants.text.bubbleInsets.left + layoutConstants.text.bubbleInsets.right
|
||||
|
@ -214,7 +214,6 @@ class ChatMessageDateAndStatusNode: ASDisplayNode {
|
||||
var currentBackgroundNode = self.backgroundNode
|
||||
var currentImpressionIcon = self.impressionIcon
|
||||
var currentRepliesIcon = self.repliesIcon
|
||||
var currentSelfExpiringIcon = self.selfExpiringIcon
|
||||
|
||||
let currentType = self.type
|
||||
let currentTheme = self.theme
|
||||
|
@ -440,8 +440,6 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView, UIGestureRecognizerD
|
||||
replyBackgroundImage = graphics.chatFreeformContentAdditionalInfoBackgroundImage
|
||||
}
|
||||
|
||||
var updatedShareButtonBackground: UIImage?
|
||||
|
||||
var updatedShareButtonNode: ChatMessageShareButton?
|
||||
if needShareButton {
|
||||
if currentShareButtonNode != nil {
|
||||
@ -874,7 +872,7 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView, UIGestureRecognizerD
|
||||
|
||||
private var wasPlaying = false
|
||||
@objc func seekGesture(_ recognizer: UIPanGestureRecognizer) {
|
||||
var location = recognizer.location(in: self.interactiveVideoNode.view)
|
||||
let location = recognizer.location(in: self.interactiveVideoNode.view)
|
||||
switch recognizer.state {
|
||||
case .began:
|
||||
self.interactiveVideoNode.pause()
|
||||
|
@ -1057,7 +1057,6 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
||||
if visibility {
|
||||
return fetchSignal
|
||||
|> mapToSignal { _ -> Signal<Void, NoError> in
|
||||
return .complete()
|
||||
}
|
||||
} else {
|
||||
return .complete()
|
||||
|
@ -231,7 +231,7 @@ final class ChatMessageAccessibilityData {
|
||||
var isSpecialFile = false
|
||||
for attribute in file.attributes {
|
||||
switch attribute {
|
||||
case let .Sticker(displayText, packReference, _):
|
||||
case let .Sticker(displayText, _, _):
|
||||
isSpecialFile = true
|
||||
text = displayText
|
||||
if file.mimeType == "application/x-tgsticker" {
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
var titleIcon: UIImage?
|
||||
var updatedMedia: Media?
|
||||
var imageDimensions: CGSize?
|
||||
var isRound = false
|
||||
var messageText: String
|
||||
if item.messages.first?.id.peerId.namespace == Namespaces.Peer.SecretChat {
|
||||
titleIcon = PresentationResourcesRootController.inAppNotificationSecretChatIcon(presentationData.theme)
|
||||
messageText = item.strings.PUSH_ENCRYPTED_MESSAGE("").string
|
||||
} else if item.messages.count == 1 {
|
||||
let message = item.messages[0]
|
||||
|
@ -137,11 +137,7 @@ class ChatMessageRestrictedBubbleContentNode: ChatMessageBubbleContentNode {
|
||||
|
||||
var statusFrame: CGRect?
|
||||
if let statusSize = statusSize {
|
||||
if forceStatusNewline {
|
||||
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)
|
||||
}
|
||||
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)
|
||||
|
@ -296,11 +296,7 @@ class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode {
|
||||
|
||||
var statusFrame: CGRect?
|
||||
if let statusSize = statusSize {
|
||||
if forceStatusNewline {
|
||||
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)
|
||||
}
|
||||
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)
|
||||
|
@ -208,7 +208,6 @@ final class ChatMessageWebpageBubbleContentNode: ChatMessageBubbleContentNode {
|
||||
} else if let type = webpage.type {
|
||||
if type == "telegram_background" {
|
||||
var colors: [UInt32] = []
|
||||
var bottomColor: UIColor?
|
||||
var rotation: Int32?
|
||||
if let wallpaper = parseWallpaperUrl(webpage.url) {
|
||||
if case let .color(color) = wallpaper {
|
||||
|
@ -16,7 +16,7 @@ enum ChatPresentationInputQueryKind: Int32 {
|
||||
case emojiSearch
|
||||
}
|
||||
|
||||
struct ChatInputQueryMentionTypes: OptionSet {
|
||||
struct ChatInputQueryMentionTypes: OptionSet, Hashable {
|
||||
var rawValue: Int32
|
||||
|
||||
init(rawValue: Int32) {
|
||||
@ -52,26 +52,6 @@ enum ChatPresentationInputQuery: Hashable, Equatable {
|
||||
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 {
|
||||
|
@ -282,13 +282,8 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
|
||||
let resolveSignal: Signal<Peer?, NoError>
|
||||
if let peerName = peerName {
|
||||
resolveSignal = strongSelf.context.engine.peers.resolvePeerByName(name: peerName)
|
||||
|> mapToSignal { peerId -> Signal<Peer?, NoError> in
|
||||
if let peerId = peerId {
|
||||
return context.account.postbox.loadedPeerWithId(peerId)
|
||||
|> map(Optional.init)
|
||||
} else {
|
||||
return .single(nil)
|
||||
}
|
||||
|> mapToSignal { peer -> Signal<Peer?, NoError> in
|
||||
return .single(peer?._asPeer())
|
||||
}
|
||||
} else {
|
||||
resolveSignal = context.account.postbox.loadedPeerWithId(strongSelf.peer.id)
|
||||
@ -789,17 +784,10 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
|
||||
let postbox = self.context.account.postbox
|
||||
self.navigationActionDisposable.set((self.context.engine.peers.resolvePeerByName(name: name, ageLimit: 10)
|
||||
|> 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
|
||||
if let strongSelf = self {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ final class ChatTextInputAudioRecordingOverlay {
|
||||
|
||||
var containerNodeRef: ASDisplayNode? = self.containerNode
|
||||
|
||||
var completion: () -> Void = {
|
||||
let completion: () -> Void = {
|
||||
if let containerNode = containerNodeRef, innerCompleted, outerCompleted, iconCompleted {
|
||||
containerNode.removeFromSupernode()
|
||||
containerNodeRef = nil
|
||||
|
@ -2352,14 +2352,6 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
backgroundView.frame = self.textInputBackgroundNode.frame
|
||||
|
||||
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)
|
||||
|
@ -38,7 +38,6 @@ final class ComposeControllerNode: ASDisplayNode {
|
||||
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
|
||||
var openCreateNewGroupImpl: (() -> Void)?
|
||||
var openCreateNewSecretChatImpl: (() -> Void)?
|
||||
var openCreateContactImpl: (() -> Void)?
|
||||
var openCreateNewChannelImpl: (() -> Void)?
|
||||
|
||||
@ -67,9 +66,6 @@ final class ComposeControllerNode: ASDisplayNode {
|
||||
openCreateNewGroupImpl = { [weak self] in
|
||||
self?.openCreateNewGroup?()
|
||||
}
|
||||
openCreateNewSecretChatImpl = { [weak self] in
|
||||
self?.openCreateNewSecretChat?()
|
||||
}
|
||||
openCreateContactImpl = { [weak self] in
|
||||
self?.contactListNode.listNode.clearHighlightAnimated(true)
|
||||
self?.openCreateContact?()
|
||||
|
@ -29,25 +29,14 @@ func paneGifSearchForQuery(context: AccountContext, query: String, offset: Strin
|
||||
let configuration = currentSearchBotsConfiguration(transaction: transaction)
|
||||
return configuration.gifBotUsername ?? "gif"
|
||||
}
|
||||
|> mapToSignal { botName -> Signal<PeerId?, NoError> in
|
||||
|> mapToSignal { botName -> Signal<EnginePeer?, NoError> in
|
||||
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
|
||||
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)
|
||||
|> 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>
|
||||
|
@ -1,7 +1,6 @@
|
||||
import Foundation
|
||||
import UIKit
|
||||
import AsyncDisplayKit
|
||||
import Postbox
|
||||
import TelegramCore
|
||||
import Display
|
||||
import TelegramPresentationData
|
||||
@ -14,7 +13,7 @@ import ItemListUI
|
||||
|
||||
private struct MentionChatInputContextPanelEntry: Comparable, Identifiable {
|
||||
let index: Int
|
||||
let peer: Peer
|
||||
let peer: EnginePeer
|
||||
let revealed: Bool
|
||||
|
||||
var stableId: Int64 {
|
||||
@ -22,15 +21,15 @@ private struct MentionChatInputContextPanelEntry: Comparable, Identifiable {
|
||||
}
|
||||
|
||||
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 {
|
||||
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 {
|
||||
return MentionChatInputPanelItem(context: context, presentationData: ItemListPresentationData(presentationData), inverted: inverted, peer: self.peer, revealed: self.revealed, setPeerIdRevealed: setPeerIdRevealed, peerSelected: peerSelected, removeRequested: removeRequested)
|
||||
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._asPeer(), revealed: self.revealed, setPeerIdRevealed: setPeerIdRevealed, peerSelected: peerSelected, removeRequested: removeRequested)
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,7 +39,7 @@ private struct CommandChatInputContextPanelTransition {
|
||||
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 deletions = deleteIndices.map { ListViewDeleteItem(index: $0, directionHint: nil) }
|
||||
@ -61,8 +60,8 @@ final class MentionChatInputContextPanelNode: ChatInputContextPanelNode {
|
||||
private let listView: ListView
|
||||
private var currentEntries: [MentionChatInputContextPanelEntry]?
|
||||
|
||||
private var currentResults: [Peer] = []
|
||||
private var revealedPeerId: PeerId?
|
||||
private var currentResults: [EnginePeer] = []
|
||||
private var revealedPeerId: EnginePeer.Id?
|
||||
|
||||
private var enqueuedTransitions: [(CommandChatInputContextPanelTransition, Bool)] = []
|
||||
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
|
||||
|
||||
var entries: [MentionChatInputContextPanelEntry] = []
|
||||
@ -159,7 +158,7 @@ final class MentionChatInputContextPanelNode: ChatInputContextPanelNode {
|
||||
return (textInputState, inputMode)
|
||||
}
|
||||
case .search:
|
||||
interfaceInteraction.beginMessageSearch(.member(peer), "")
|
||||
interfaceInteraction.beginMessageSearch(.member(peer._asPeer()), "")
|
||||
}
|
||||
}
|
||||
}, removeRequested: { [weak self] peerId in
|
||||
@ -227,7 +226,7 @@ final class MentionChatInputContextPanelNode: ChatInputContextPanelNode {
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
@ -17,13 +17,13 @@ final class MentionChatInputPanelItem: ListViewItem {
|
||||
fileprivate let revealed: Bool
|
||||
fileprivate let inverted: Bool
|
||||
fileprivate let peer: Peer
|
||||
private let peerSelected: (Peer) -> Void
|
||||
fileprivate let setPeerIdRevealed: (PeerId?) -> Void
|
||||
fileprivate let removeRequested: (PeerId) -> Void
|
||||
private let peerSelected: (EnginePeer) -> Void
|
||||
fileprivate let setPeerIdRevealed: (EnginePeer.Id?) -> Void
|
||||
fileprivate let removeRequested: (EnginePeer.Id) -> Void
|
||||
|
||||
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.presentationData = presentationData
|
||||
self.inverted = inverted
|
||||
@ -85,7 +85,7 @@ final class MentionChatInputPanelItem: ListViewItem {
|
||||
if self.revealed {
|
||||
self.setPeerIdRevealed(nil)
|
||||
} 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)
|
||||
|
||||
let revealOffset = strongSelf.revealOffset
|
||||
|
||||
if let updatedInverted = updatedInverted {
|
||||
if updatedInverted {
|
||||
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) {
|
||||
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.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) {
|
||||
super.setHighlighted(highlighted, at: point, animated: animated)
|
||||
|
||||
if let revealNode = self.revealNode, self.revealOffset != 0 {
|
||||
if let _ = self.revealNode, self.revealOffset != 0 {
|
||||
return
|
||||
}
|
||||
|
||||
@ -418,7 +416,7 @@ final class MentionChatInputPanelItemNode: ListViewItemNode {
|
||||
|
||||
private func updateRevealOffsetInternal(offset: CGFloat, transition: ContainedViewLayoutTransition) {
|
||||
self.revealOffset = offset
|
||||
guard let (size, leftInset, rightInset) = self.validLayout else {
|
||||
guard let (size, _, rightInset) = self.validLayout else {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -242,13 +242,10 @@ func openResolvedUrlImpl(_ resolvedUrl: ResolvedUrl, context: AccountContext, ur
|
||||
if let to = to {
|
||||
if to.hasPrefix("@") {
|
||||
let _ = (context.engine.peers.resolvePeerByName(name: String(to[to.index(to.startIndex, offsetBy: 1)...]))
|
||||
|> deliverOnMainQueue).start(next: { peerId in
|
||||
if let peerId = peerId {
|
||||
let _ = (context.account.postbox.loadedPeerWithId(peerId)
|
||||
|> deliverOnMainQueue).start(next: { peer in
|
||||
context.sharedContext.applicationBindings.dismissNativeController()
|
||||
continueWithPeer(peer.id)
|
||||
})
|
||||
|> deliverOnMainQueue).start(next: { peer in
|
||||
if let peer = peer {
|
||||
context.sharedContext.applicationBindings.dismissNativeController()
|
||||
continueWithPeer(peer.id)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
|
@ -3273,14 +3273,8 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD
|
||||
let account = self.context.account
|
||||
disposable.set((resolveSignal
|
||||
|> take(1)
|
||||
|> mapToSignal { peerId -> Signal<Peer?, NoError> in
|
||||
return account.postbox.transaction { transaction -> Peer? in
|
||||
if let peerId = peerId {
|
||||
return transaction.getPeer(peerId)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|> mapToSignal { peer -> Signal<Peer?, NoError> in
|
||||
return .single(peer?._asPeer())
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peer in
|
||||
if let strongSelf = self {
|
||||
@ -3307,13 +3301,8 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD
|
||||
var resolveSignal: Signal<Peer?, NoError>
|
||||
if let peerName = peerName {
|
||||
resolveSignal = self.context.engine.peers.resolvePeerByName(name: peerName)
|
||||
|> mapToSignal { peerId -> Signal<Peer?, NoError> in
|
||||
if let peerId = peerId {
|
||||
return account.postbox.loadedPeerWithId(peerId)
|
||||
|> map(Optional.init)
|
||||
} else {
|
||||
return .single(nil)
|
||||
}
|
||||
|> mapToSignal { peer -> Signal<Peer?, NoError> in
|
||||
return .single(peer?._asPeer())
|
||||
}
|
||||
} else {
|
||||
resolveSignal = self.context.account.postbox.loadedPeerWithId(self.peerId)
|
||||
@ -5505,10 +5494,10 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD
|
||||
|
||||
let context = self.context
|
||||
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()
|
||||
if let peerId = peerId, let navigationController = navigationController {
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peerId)))
|
||||
if let peer = peer, let navigationController = navigationController {
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer.id)))
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
@ -90,8 +90,8 @@ func handleTextLinkActionImpl(context: AccountContext, peerId: PeerId?, navigate
|
||||
}
|
||||
|
||||
let openPeerMentionImpl: (String) -> Void = { mention in
|
||||
navigateDisposable.set((context.engine.peers.resolvePeerByName(name: mention, ageLimit: 10) |> take(1) |> deliverOnMainQueue).start(next: { peerId in
|
||||
openResolvedPeerImpl(peerId, .default)
|
||||
navigateDisposable.set((context.engine.peers.resolvePeerByName(name: mention, ageLimit: 10) |> take(1) |> deliverOnMainQueue).start(next: { peer in
|
||||
openResolvedPeerImpl(peer?.id, .default)
|
||||
}))
|
||||
}
|
||||
|
||||
|
@ -346,14 +346,8 @@ private func resolveInternalUrl(context: AccountContext, url: ParsedInternalUrl)
|
||||
case let .peerName(name, parameter):
|
||||
return context.engine.peers.resolvePeerByName(name: name)
|
||||
|> take(1)
|
||||
|> mapToSignal { peerId -> Signal<Peer?, NoError> in
|
||||
return context.account.postbox.transaction { transaction -> Peer? in
|
||||
if let peerId = peerId {
|
||||
return transaction.getPeer(peerId)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|> mapToSignal { peer -> Signal<Peer?, NoError> in
|
||||
return .single(peer?._asPeer())
|
||||
}
|
||||
|> mapToSignal { peer -> Signal<ResolvedUrl?, NoError> in
|
||||
if let peer = peer {
|
||||
|
@ -750,11 +750,11 @@ final class WatchLocationHandler: WatchRequestHandler {
|
||||
if let context = context {
|
||||
return context.engine.peers.resolvePeerByName(name: "foursquare")
|
||||
|> take(1)
|
||||
|> mapToSignal { peerId -> Signal<ChatContextResultCollection?, NoError> in
|
||||
guard let peerId = peerId else {
|
||||
|> mapToSignal { peer -> Signal<ChatContextResultCollection?, NoError> in
|
||||
guard let peer = peer else {
|
||||
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
|
||||
return results?.results
|
||||
}
|
||||
|
@ -446,23 +446,15 @@ public final class WebSearchController: ViewController {
|
||||
let account = self.context.account
|
||||
let context = self.context
|
||||
let contextBot = self.context.engine.peers.resolvePeerByName(name: name)
|
||||
|> mapToSignal { peerId -> Signal<Peer?, NoError> in
|
||||
if let peerId = peerId {
|
||||
return account.postbox.loadedPeerWithId(peerId)
|
||||
|> map { peer -> Peer? in
|
||||
return peer
|
||||
}
|
||||
|> take(1)
|
||||
} else {
|
||||
return .single(nil)
|
||||
}
|
||||
|> mapToSignal { peer -> Signal<Peer?, NoError> in
|
||||
return .single(peer?._asPeer())
|
||||
}
|
||||
|> mapToSignal { peer -> Signal<(ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?, NoError> in
|
||||
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)
|
||||
|> map { results -> (ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult? in
|
||||
return { _ in
|
||||
return .contextRequestResult(user, results?.results)
|
||||
return .contextRequestResult(.user(user), results?.results)
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user