Initial support for geo inline bot requests

This commit is contained in:
Ilya Laktyushin 2019-07-10 06:15:09 +02:00
parent f7d85f46b3
commit bcaf3f6569
11 changed files with 107 additions and 33 deletions

View File

@ -15,7 +15,12 @@ import Foundation
#endif #endif
#endif #endif
public func requestChatContextResults(account: Account, botId: PeerId, peerId: PeerId, query: String, location: Signal<(Double, Double)?, NoError> = .single(nil), offset: String) -> Signal<ChatContextResultCollection?, NoError> { public enum RequestChatContextResultsError {
case generic
case locationRequired
}
public func requestChatContextResults(account: Account, botId: PeerId, peerId: PeerId, query: String, location: Signal<(Double, Double)?, NoError> = .single(nil), offset: String) -> Signal<ChatContextResultCollection?, RequestChatContextResultsError> {
return combineLatest(account.postbox.transaction { transaction -> (bot: Peer, peer: Peer)? in return combineLatest(account.postbox.transaction { transaction -> (bot: Peer, peer: Peer)? in
if let bot = transaction.getPeer(botId), let peer = transaction.getPeer(peerId) { if let bot = transaction.getPeer(botId), let peer = transaction.getPeer(peerId) {
return (bot, peer) return (bot, peer)
@ -23,7 +28,8 @@ public func requestChatContextResults(account: Account, botId: PeerId, peerId: P
return nil return nil
} }
}, location) }, location)
|> mapToSignal { botAndPeer, location -> Signal<ChatContextResultCollection?, NoError> in |> introduceError(RequestChatContextResultsError.self)
|> mapToSignal { botAndPeer, location -> Signal<ChatContextResultCollection?, RequestChatContextResultsError> in
if let (bot, peer) = botAndPeer, let inputBot = apiInputUser(bot) { if let (bot, peer) = botAndPeer, let inputBot = apiInputUser(bot) {
var flags: Int32 = 0 var flags: Int32 = 0
var inputPeer: Api.InputPeer = .inputPeerEmpty var inputPeer: Api.InputPeer = .inputPeerEmpty
@ -39,8 +45,12 @@ public func requestChatContextResults(account: Account, botId: PeerId, peerId: P
|> map { result -> ChatContextResultCollection? in |> map { result -> ChatContextResultCollection? in
return ChatContextResultCollection(apiResults: result, botId: bot.id, peerId: peerId, query: query, geoPoint: location) return ChatContextResultCollection(apiResults: result, botId: bot.id, peerId: peerId, query: query, geoPoint: location)
} }
|> `catch` { _ -> Signal<ChatContextResultCollection?, NoError> in |> mapError { error -> RequestChatContextResultsError in
return .single(nil) if error.errorDescription == "BOT_INLINE_GEO_REQUIRED" {
return .locationRequired
} else {
return .generic
}
} }
} else { } else {
return .single(nil) return .single(nil)

View File

@ -332,6 +332,9 @@ public func searchGifs(account: Account, query: String) -> Signal<ChatContextRes
} }
|> mapToSignal { peer -> Signal<ChatContextResultCollection?, NoError> in |> mapToSignal { peer -> Signal<ChatContextResultCollection?, NoError> in
return requestChatContextResults(account: account, botId: peer.id, peerId: account.peerId, query: query, offset: "") return requestChatContextResults(account: account, botId: peer.id, peerId: account.peerId, query: query, offset: "")
|> `catch` { error -> Signal<ChatContextResultCollection?, NoError> in
return .single(nil)
}
} }
} }

View File

@ -4024,6 +4024,17 @@ public final class ChatController: TelegramController, GalleryHiddenMediaTarget,
}) })
} }
} }
}, error: { [weak self] error in
if let strongSelf = self {
switch error {
case let .inlineBotLocationRequest(peerId):
strongSelf.present(textAlertController(context: strongSelf.context, title: nil, text: strongSelf.presentationData.strings.Conversation_ShareInlineBotLocationConfirmation, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_Cancel, action: {
let _ = ApplicationSpecificNotice.setInlineBotLocationRequest(accountManager: strongSelf.context.sharedContext.accountManager, peerId: peerId, value: Int32(Date().timeIntervalSince1970 + 10 * 60)).start()
}), TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {
let _ = ApplicationSpecificNotice.setInlineBotLocationRequest(accountManager: strongSelf.context.sharedContext.accountManager, peerId: peerId, value: 0).start()
})]), in: .window(.root))
}
}
})) }))
inScope = false inScope = false
if let inScopeResult = inScopeResult { if let inScopeResult = inScopeResult {

View File

@ -7,9 +7,13 @@ import TelegramUIPreferences
import TelegramUIPrivateModule import TelegramUIPrivateModule
import LegacyComponents import LegacyComponents
enum ChatContextQueryError {
case inlineBotLocationRequest(PeerId)
}
enum ChatContextQueryUpdate { enum ChatContextQueryUpdate {
case remove case remove
case update(ChatPresentationInputQuery, Signal<(ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?, NoError>) case update(ChatPresentationInputQuery, Signal<(ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?, ChatContextQueryError>)
} }
func contextQueryResultStateForChatInterfacePresentationState(_ chatPresentationInterfaceState: ChatPresentationInterfaceState, context: AccountContext, currentQueryStates: inout [ChatPresentationInputQueryKind: (ChatPresentationInputQuery, Disposable)]) -> [ChatPresentationInputQueryKind: ChatContextQueryUpdate] { func contextQueryResultStateForChatInterfacePresentationState(_ chatPresentationInterfaceState: ChatPresentationInterfaceState, context: AccountContext, currentQueryStates: inout [ChatPresentationInputQueryKind: (ChatPresentationInputQuery, Disposable)]) -> [ChatPresentationInputQueryKind: ChatContextQueryUpdate] {
@ -55,10 +59,10 @@ func contextQueryResultStateForChatInterfacePresentationState(_ chatPresentation
return updates return updates
} }
private func updatedContextQueryResultStateForQuery(context: AccountContext, peer: Peer, inputQuery: ChatPresentationInputQuery, previousQuery: ChatPresentationInputQuery?) -> Signal<(ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?, NoError> { private func updatedContextQueryResultStateForQuery(context: AccountContext, peer: Peer, inputQuery: ChatPresentationInputQuery, previousQuery: ChatPresentationInputQuery?) -> Signal<(ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?, ChatContextQueryError> {
switch inputQuery { switch inputQuery {
case let .emoji(query): case let .emoji(query):
var signal: Signal<(ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?, NoError> = .complete() var signal: Signal<(ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?, ChatContextQueryError> = .complete()
if let previousQuery = previousQuery { if let previousQuery = previousQuery {
switch previousQuery { switch previousQuery {
case .emoji: case .emoji:
@ -69,11 +73,12 @@ private func updatedContextQueryResultStateForQuery(context: AccountContext, pee
} else { } else {
signal = .single({ _ in return .stickers([]) }) signal = .single({ _ in return .stickers([]) })
} }
let stickers: Signal<(ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?, NoError> = context.sharedContext.accountManager.transaction { transaction -> StickerSettings in let stickers: Signal<(ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?, ChatContextQueryError> = context.sharedContext.accountManager.transaction { transaction -> StickerSettings in
let stickerSettings: StickerSettings = (transaction.getSharedData(ApplicationSpecificSharedDataKeys.stickerSettings) as? StickerSettings) ?? .defaultSettings let stickerSettings: StickerSettings = (transaction.getSharedData(ApplicationSpecificSharedDataKeys.stickerSettings) as? StickerSettings) ?? .defaultSettings
return stickerSettings return stickerSettings
} }
|> mapToSignal { stickerSettings -> Signal<[FoundStickerItem], NoError> in |> introduceError(ChatContextQueryError.self)
|> mapToSignal { stickerSettings -> Signal<[FoundStickerItem], ChatContextQueryError> in
let scope: SearchStickersScope let scope: SearchStickersScope
switch stickerSettings.emojiStickerSuggestionMode { switch stickerSettings.emojiStickerSuggestionMode {
case .none: case .none:
@ -84,6 +89,7 @@ private func updatedContextQueryResultStateForQuery(context: AccountContext, pee
scope = [.installed] scope = [.installed]
} }
return searchStickers(account: context.account, query: query.trimmedEmoji, scope: scope) return searchStickers(account: context.account, query: query.trimmedEmoji, scope: scope)
|> introduceError(ChatContextQueryError.self)
} }
|> map { stickers -> (ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult? in |> map { stickers -> (ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult? in
return { _ in return { _ in
@ -92,7 +98,7 @@ private func updatedContextQueryResultStateForQuery(context: AccountContext, pee
} }
return signal |> then(stickers) return signal |> then(stickers)
case let .hashtag(query): case let .hashtag(query):
var signal: Signal<(ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?, NoError> = .complete() var signal: Signal<(ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?, ChatContextQueryError> = .complete()
if let previousQuery = previousQuery { if let previousQuery = previousQuery {
switch previousQuery { switch previousQuery {
case .hashtag: case .hashtag:
@ -104,7 +110,8 @@ private func updatedContextQueryResultStateForQuery(context: AccountContext, pee
signal = .single({ _ in return .hashtags([]) }) signal = .single({ _ in return .hashtags([]) })
} }
let hashtags: Signal<(ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?, NoError> = recentlyUsedHashtags(postbox: context.account.postbox) |> map { hashtags -> (ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult? in let hashtags: Signal<(ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?, ChatContextQueryError> = recentlyUsedHashtags(postbox: context.account.postbox)
|> map { hashtags -> (ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult? in
let normalizedQuery = query.lowercased() let normalizedQuery = query.lowercased()
var result: [String] = [] var result: [String] = []
for hashtag in hashtags { for hashtag in hashtags {
@ -114,12 +121,13 @@ private func updatedContextQueryResultStateForQuery(context: AccountContext, pee
} }
return { _ in return .hashtags(result) } return { _ in return .hashtags(result) }
} }
|> introduceError(ChatContextQueryError.self)
return signal |> then(hashtags) return signal |> then(hashtags)
case let .mention(query, types): case let .mention(query, types):
let normalizedQuery = query.lowercased() let normalizedQuery = query.lowercased()
var signal: Signal<(ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?, NoError> = .complete() var signal: Signal<(ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?, ChatContextQueryError> = .complete()
if let previousQuery = previousQuery { if let previousQuery = previousQuery {
switch previousQuery { switch previousQuery {
case .mention: case .mention:
@ -168,12 +176,13 @@ private func updatedContextQueryResultStateForQuery(context: AccountContext, pee
} }
return { _ in return .mentions(sortedPeers) } return { _ in return .mentions(sortedPeers) }
} }
|> introduceError(ChatContextQueryError.self)
return signal |> then(participants) return signal |> then(participants)
case let .command(query): case let .command(query):
let normalizedQuery = query.lowercased() let normalizedQuery = query.lowercased()
var signal: Signal<(ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?, NoError> = .complete() var signal: Signal<(ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?, ChatContextQueryError> = .complete()
if let previousQuery = previousQuery { if let previousQuery = previousQuery {
switch previousQuery { switch previousQuery {
case .command: case .command:
@ -185,22 +194,22 @@ private func updatedContextQueryResultStateForQuery(context: AccountContext, pee
signal = .single({ _ in return .commands([]) }) signal = .single({ _ in return .commands([]) })
} }
let participants = peerCommands(account: context.account, id: peer.id) let commands = peerCommands(account: context.account, id: peer.id)
|> map { commands -> (ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult? in |> map { commands -> (ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult? in
let filteredCommands = commands.commands.filter { command in let filteredCommands = commands.commands.filter { command in
if command.command.text.hasPrefix(normalizedQuery) { if command.command.text.hasPrefix(normalizedQuery) {
return true return true
}
return false
} }
let sortedCommands = filteredCommands return false
return { _ in return .commands(sortedCommands) } }
let sortedCommands = filteredCommands
return { _ in return .commands(sortedCommands) }
} }
|> introduceError(ChatContextQueryError.self)
return signal |> then(participants) return signal |> then(commands)
case let .contextRequest(addressName, query): case let .contextRequest(addressName, query):
var delayRequest = true var delayRequest = true
var signal: Signal<(ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?, NoError> = .complete() var signal: Signal<(ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?, ChatContextQueryError> = .complete()
if let previousQuery = previousQuery { if let previousQuery = previousQuery {
switch previousQuery { switch previousQuery {
case let .contextRequest(currentAddressName, currentContextQuery) where currentAddressName == addressName: case let .contextRequest(currentAddressName, currentContextQuery) where currentAddressName == addressName:
@ -228,16 +237,20 @@ private func updatedContextQueryResultStateForQuery(context: AccountContext, pee
return .single(nil) return .single(nil)
} }
} }
|> mapToSignal { peer -> Signal<(ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?, NoError> in |> introduceError(ChatContextQueryError.self)
|> mapToSignal { peer -> Signal<(ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?, ChatContextQueryError> 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 contextResults = requestChatContextResults(account: context.account, botId: user.id, peerId: chatPeer.id, query: query, offset: "") let contextResults = requestChatContextResults(account: context.account, botId: user.id, peerId: chatPeer.id, query: query, offset: "")
|> mapError { error -> ChatContextQueryError in
return .inlineBotLocationRequest(user.id)
}
|> map { results -> (ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult? in |> map { results -> (ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult? in
return { _ in return { _ in
return .contextRequestResult(user, results) return .contextRequestResult(user, results)
} }
} }
let botResult: Signal<(ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?, NoError> = .single({ previousResult in let botResult: Signal<(ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?, ChatContextQueryError> = .single({ previousResult in
var passthroughPreviousResult: ChatContextResultCollection? var passthroughPreviousResult: ChatContextResultCollection?
if let previousResult = previousResult { if let previousResult = previousResult {
if case let .contextRequestResult(previousUser, previousResults) = previousResult { if case let .contextRequestResult(previousUser, previousResults) = previousResult {
@ -249,9 +262,10 @@ private func updatedContextQueryResultStateForQuery(context: AccountContext, pee
return .contextRequestResult(user, passthroughPreviousResult) return .contextRequestResult(user, passthroughPreviousResult)
}) })
let maybeDelayedContextResults: Signal<(ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?, NoError> let maybeDelayedContextResults: Signal<(ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?, ChatContextQueryError>
if delayRequest { if delayRequest {
maybeDelayedContextResults = contextResults |> delay(0.4, queue: Queue.concurrentDefaultQueue()) maybeDelayedContextResults = contextResults
|> delay(0.4, queue: Queue.concurrentDefaultQueue())
} else { } else {
maybeDelayedContextResults = contextResults maybeDelayedContextResults = contextResults
} }
@ -291,6 +305,7 @@ private func updatedContextQueryResultStateForQuery(context: AccountContext, pee
|> map { result -> (ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult? in |> map { result -> (ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult? in
return { _ in return .emojis(result, range) } return { _ in return .emojis(result, range) }
} }
|> introduceError(ChatContextQueryError.self)
} }
} }

View File

@ -107,7 +107,8 @@ private final class ChatMessageActionButtonNode: ASDisplayNode {
} }
} }
let (titleSize, titleApply) = titleLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: title, font: titleFont, textColor: incoming ? bubbleVariableColor(variableColor: theme.theme.chat.message.incoming.actionButtonsTextColor, wallpaper: theme.wallpaper) : bubbleVariableColor(variableColor: theme.theme.chat.message.outgoing.actionButtonsTextColor, wallpaper: theme.wallpaper)), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: max(44.0, constrainedWidth - minimumSideInset - minimumSideInset), height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets(top: 1.0, left: 0.0, bottom: 1.0, right: 0.0))) let messageTheme = incoming ? theme.theme.chat.message.incoming : theme.theme.chat.message.outgoing
let (titleSize, titleApply) = titleLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: title, font: titleFont, textColor: bubbleVariableColor(variableColor: messageTheme.actionButtonsTextColor, wallpaper: theme.wallpaper)), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: max(44.0, constrainedWidth - minimumSideInset - minimumSideInset), height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets(top: 1.0, left: 0.0, bottom: 1.0, right: 0.0)))
let backgroundImage: UIImage? let backgroundImage: UIImage?
switch position { switch position {

View File

@ -381,6 +381,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView {
let content = item.content let content = item.content
let firstMessage = content.firstMessage let firstMessage = content.firstMessage
let incoming = item.content.effectivelyIncoming(item.context.account.peerId) let incoming = item.content.effectivelyIncoming(item.context.account.peerId)
let messageTheme = incoming ? item.presentationData.theme.theme.chat.message.incoming : item.presentationData.theme.theme.chat.message.outgoing
var sourceReference: SourceReferenceMessageAttribute? var sourceReference: SourceReferenceMessageAttribute?
for attribute in item.content.firstMessage.attributes { for attribute in item.content.firstMessage.attributes {
@ -857,14 +858,14 @@ class ChatMessageBubbleItemNode: ChatMessageItemView {
headerSize.height += 5.0 headerSize.height += 5.0
} }
let inlineBotNameColor = incoming ? item.presentationData.theme.theme.chat.message.incoming.accentTextColor : item.presentationData.theme.theme.chat.message.outgoing.accentTextColor let inlineBotNameColor = messageTheme.accentTextColor
let attributedString: NSAttributedString let attributedString: NSAttributedString
var adminBadgeString: NSAttributedString? var adminBadgeString: NSAttributedString?
if authorIsAdmin { if authorIsAdmin {
adminBadgeString = NSAttributedString(string: " \(item.presentationData.strings.Conversation_Admin)", font: inlineBotPrefixFont, textColor: incoming ? item.presentationData.theme.theme.chat.message.incoming.secondaryTextColor : item.presentationData.theme.theme.chat.message.outgoing.secondaryTextColor) adminBadgeString = NSAttributedString(string: " \(item.presentationData.strings.Conversation_Admin)", font: inlineBotPrefixFont, textColor: messageTheme.secondaryTextColor)
} else if authorIsChannel { } else if authorIsChannel {
adminBadgeString = NSAttributedString(string: " \(item.presentationData.strings.Channel_Status)", font: inlineBotPrefixFont, textColor: incoming ? item.presentationData.theme.theme.chat.message.incoming.secondaryTextColor : item.presentationData.theme.theme.chat.message.outgoing.secondaryTextColor) adminBadgeString = NSAttributedString(string: " \(item.presentationData.strings.Channel_Status)", font: inlineBotPrefixFont, textColor: messageTheme.secondaryTextColor)
} }
if let authorNameString = authorNameString, let authorNameColor = authorNameColor, let inlineBotNameString = inlineBotNameString { if let authorNameString = authorNameString, let authorNameColor = authorNameColor, let inlineBotNameString = inlineBotNameString {
let mutableString = NSMutableAttributedString(string: "\(authorNameString) ", attributes: [NSAttributedStringKey.font: nameFont, NSAttributedStringKey.foregroundColor: authorNameColor]) let mutableString = NSMutableAttributedString(string: "\(authorNameString) ", attributes: [NSAttributedStringKey.font: nameFont, NSAttributedStringKey.foregroundColor: authorNameColor])

View File

@ -53,6 +53,9 @@ func legacyLocationPickerController(context: AccountContext, selfPeer: Peer, pee
return .single(nil) return .single(nil)
} }
return requestChatContextResults(account: context.account, botId: peerId, peerId: selfPeer.id, query: query ?? "", location: .single((location?.coordinate.latitude ?? 0.0, location?.coordinate.longitude ?? 0.0)), offset: "") return requestChatContextResults(account: context.account, botId: peerId, peerId: selfPeer.id, query: query ?? "", location: .single((location?.coordinate.latitude ?? 0.0, location?.coordinate.longitude ?? 0.0)), offset: "")
|> `catch` { error -> Signal<ChatContextResultCollection?, NoError> in
return .single(nil)
}
} }
|> mapToSignal { contextResult -> Signal<[TGLocationVenue], NoError> in |> mapToSignal { contextResult -> Signal<[TGLocationVenue], NoError> in
guard let contextResult = contextResult else { guard let contextResult = contextResult else {

View File

@ -158,6 +158,11 @@ private struct ApplicationSpecificNoticeKeys {
private static let globalNamespace: Int32 = 2 private static let globalNamespace: Int32 = 2
private static let permissionsNamespace: Int32 = 3 private static let permissionsNamespace: Int32 = 3
private static let peerReportNamespace: Int32 = 4 private static let peerReportNamespace: Int32 = 4
private static let inlineBotLocationRequestNamespace: Int32 = 1
static func inlineBotLocationRequestNotice(peerId: PeerId) -> NoticeEntryKey {
return NoticeEntryKey(namespace: noticeNamespace(namespace: inlineBotLocationRequestNamespace), key: noticeKey(peerId: peerId, key: 0))
}
static func botPaymentLiabilityNotice(peerId: PeerId) -> NoticeEntryKey { static func botPaymentLiabilityNotice(peerId: PeerId) -> NoticeEntryKey {
return NoticeEntryKey(namespace: noticeNamespace(namespace: botPaymentLiabilityNamespace), key: noticeKey(peerId: peerId, key: 0)) return NoticeEntryKey(namespace: noticeNamespace(namespace: botPaymentLiabilityNamespace), key: noticeKey(peerId: peerId, key: 0))
@ -251,6 +256,22 @@ public struct ApplicationSpecificNotice {
} }
} }
static func getInlineBotLocationRequest(accountManager: AccountManager, peerId: PeerId) -> Signal<Int32?, NoError> {
return accountManager.transaction { transaction -> Int32? in
if let notice = transaction.getNotice(ApplicationSpecificNoticeKeys.inlineBotLocationRequestNotice(peerId: peerId)) as? ApplicationSpecificTimestampNotice {
return notice.value
} else {
return nil
}
}
}
static func setInlineBotLocationRequest(accountManager: AccountManager, peerId: PeerId, value: Int32) -> Signal<Void, NoError> {
return accountManager.transaction { transaction -> Void in
transaction.setNotice(ApplicationSpecificNoticeKeys.inlineBotLocationRequestNotice(peerId: peerId), ApplicationSpecificTimestampNotice(value: value))
}
}
static func getSecretChatInlineBotUsage(accountManager: AccountManager) -> Signal<Bool, NoError> { static func getSecretChatInlineBotUsage(accountManager: AccountManager) -> Signal<Bool, NoError> {
return accountManager.transaction { transaction -> Bool in return accountManager.transaction { transaction -> Bool in
if let _ = transaction.getNotice(ApplicationSpecificNoticeKeys.secretChatInlineBotUsage()) as? ApplicationSpecificBoolNotice { if let _ = transaction.getNotice(ApplicationSpecificNoticeKeys.secretChatInlineBotUsage()) as? ApplicationSpecificBoolNotice {

View File

@ -477,6 +477,9 @@ final class ThemeGridSearchContentNode: SearchDisplayControllerContentNode {
if let _ = searchContext.loadMoreIndex, let nextOffset = searchContext.result.nextOffset { if let _ = searchContext.loadMoreIndex, let nextOffset = searchContext.result.nextOffset {
let collection = searchContext.result.collection let collection = searchContext.result.collection
return requestChatContextResults(account: self.context.account, botId: collection.botId, peerId: collection.peerId, query: searchContext.result.query, location: .single(collection.geoPoint), offset: nextOffset) return requestChatContextResults(account: self.context.account, botId: collection.botId, peerId: collection.peerId, query: searchContext.result.query, location: .single(collection.geoPoint), offset: nextOffset)
|> `catch` { error -> Signal<ChatContextResultCollection?, NoError> in
return .single(nil)
}
|> map { nextResults -> (ChatContextResultCollection, String?) in |> map { nextResults -> (ChatContextResultCollection, String?) in
var results: [ChatContextResult] = [] var results: [ChatContextResult] = []
var existingIds = Set<String>() var existingIds = Set<String>()

View File

@ -748,6 +748,9 @@ final class WatchLocationHandler: WatchRequestHandler {
return .single(nil) return .single(nil)
} }
return requestChatContextResults(account: context.account, botId: peerId, peerId: context.account.peerId, query: "", location: .single((args.coordinate.latitude, args.coordinate.longitude)), offset: "") return requestChatContextResults(account: context.account, botId: peerId, peerId: context.account.peerId, query: "", location: .single((args.coordinate.latitude, args.coordinate.longitude)), offset: "")
|> `catch` { error -> Signal<ChatContextResultCollection?, NoError> in
return .single(nil)
}
} }
|> mapToSignal { contextResult -> Signal<[ChatContextResultMessage], NoError> in |> mapToSignal { contextResult -> Signal<[ChatContextResultMessage], NoError> in
guard let contextResult = contextResult else { guard let contextResult = contextResult else {

View File

@ -10,6 +10,9 @@ import TelegramUIPreferences
func requestContextResults(account: Account, botId: PeerId, query: String, peerId: PeerId, offset: String = "", existingResults: ChatContextResultCollection? = nil, limit: Int = 60) -> Signal<ChatContextResultCollection?, NoError> { func requestContextResults(account: Account, botId: PeerId, query: String, peerId: PeerId, offset: String = "", existingResults: ChatContextResultCollection? = nil, limit: Int = 60) -> Signal<ChatContextResultCollection?, NoError> {
return requestChatContextResults(account: account, botId: botId, peerId: peerId, query: query, offset: offset) return requestChatContextResults(account: account, botId: botId, peerId: peerId, query: query, offset: offset)
|> `catch` { error -> Signal<ChatContextResultCollection?, NoError> in
return .single(nil)
}
|> mapToSignal { results -> Signal<ChatContextResultCollection?, NoError> in |> mapToSignal { results -> Signal<ChatContextResultCollection?, NoError> in
var collection = existingResults var collection = existingResults
var updated: Bool = false var updated: Bool = false