diff --git a/TelegramCore/PendingMessageManager.swift b/TelegramCore/PendingMessageManager.swift index bcc4b3a977..60b66ced2b 100644 --- a/TelegramCore/PendingMessageManager.swift +++ b/TelegramCore/PendingMessageManager.swift @@ -303,6 +303,7 @@ public final class PendingMessageManager { } else if let peer = modifier.getPeer(message.id.peerId), let inputPeer = apiInputPeer(peer) { var uniqueId: Int64 = 0 var forwardSourceInfoAttribute: ForwardSourceInfoAttribute? + var messageEntities: [Api.MessageEntity]? var replyMessageId: Int32? for attribute in message.attributes { @@ -312,6 +313,8 @@ public final class PendingMessageManager { uniqueId = outgoingInfo.uniqueId } else if let attribute = attribute as? ForwardSourceInfoAttribute { forwardSourceInfoAttribute = attribute + } else if let attribute = attribute as? TextEntitiesMessageAttribute { + messageEntities = apiTextAttributeEntities(attribute, associatedPeers: message.peers) } } @@ -319,13 +322,16 @@ public final class PendingMessageManager { if let _ = replyMessageId { flags |= Int32(1 << 0) } + if let _ = messageEntities { + flags |= Int32(1 << 3) + } let dependencyTag = PendingMessageRequestDependencyTag(messageId: message.id) let sendMessageRequest: Signal switch content { case .text: - sendMessageRequest = network.request(Api.functions.messages.sendMessage(flags: flags, peer: inputPeer, replyToMsgId: replyMessageId, message: message.text, randomId: uniqueId, replyMarkup: nil, entities: nil), tag: dependencyTag) + sendMessageRequest = network.request(Api.functions.messages.sendMessage(flags: flags, peer: inputPeer, replyToMsgId: replyMessageId, message: message.text, randomId: uniqueId, replyMarkup: nil, entities: messageEntities), tag: dependencyTag) |> mapError { _ -> NoError in return NoError() } diff --git a/TelegramCore/RequestEditMessage.swift b/TelegramCore/RequestEditMessage.swift index 749d36096b..c96e9866a8 100644 --- a/TelegramCore/RequestEditMessage.swift +++ b/TelegramCore/RequestEditMessage.swift @@ -9,12 +9,35 @@ import Foundation import MtProtoKitDynamic #endif -public func requestEditMessage(account: Account, messageId: MessageId, text: String) -> Signal { - return account.postbox.loadedPeerWithId(messageId.peerId) +public func requestEditMessage(account: Account, messageId: MessageId, text: String, entities:TextEntitiesMessageAttribute? = nil) -> Signal { + return account.postbox.modify { modifier -> (Peer?, SimpleDictionary) in + var peers:SimpleDictionary = SimpleDictionary() + + if let entities = entities { + for peerId in entities.associatedPeerIds { + if let peer = modifier.getPeer(peerId) { + peers[peer.id] = peer + } + } + } + return (modifier.getPeer(messageId.peerId), peers) + } |> take(1) - |> mapToSignal { peer in - if let inputPeer = apiInputPeer(peer) { - return account.network.request(Api.functions.messages.editMessage(flags: (1 << 11), peer: inputPeer, id: messageId.id, message: text, replyMarkup: nil, entities: nil)) + |> mapToSignal { peer, associatedPeers in + if let peer = peer, let inputPeer = apiInputPeer(peer) { + + var flags:Int32 = (1 << 11) + + + var apiEntities:[Api.MessageEntity]? + if let entities = entities { + apiEntities = apiTextAttributeEntities(entities, associatedPeers: associatedPeers) + flags |= Int32(1 << 3) + } + + + + return account.network.request(Api.functions.messages.editMessage(flags: flags, peer: inputPeer, id: messageId.id, message: text, replyMarkup: nil, entities: apiEntities)) |> map { result -> Api.Updates? in return result } diff --git a/TelegramCore/SearchMessages.swift b/TelegramCore/SearchMessages.swift index acdbe13394..99ac57421e 100644 --- a/TelegramCore/SearchMessages.swift +++ b/TelegramCore/SearchMessages.swift @@ -31,13 +31,30 @@ private func locallyRenderedMessage(message: StoreMessage, peers: [PeerId: Peer] return Message(stableId: 0, stableVersion: 0, id: id, globallyUniqueId: nil, timestamp: message.timestamp, flags: MessageFlags(message.flags), tags: message.tags, forwardInfo: nil, author: author, text: message.text, attributes: message.attributes, media: message.media, peers: messagePeers, associatedMessages: SimpleDictionary(), associatedMessageIds: []) } -public func searchMessages(account: Account, peerId: PeerId?, query: String) -> Signal<[Message], NoError> { +public func searchMessages(account: Account, peerId: PeerId?, query: String, tagMask:MessageTags? = nil) -> Signal<[Message], NoError> { let searchResult: Signal + + let filter:Api.MessagesFilter + + if let tags = tagMask { + if tags.contains(.File) { + filter = .inputMessagesFilterDocument + } else if tags.contains(.Music) { + filter = .inputMessagesFilterMusic + } else if tags.contains(.WebPage) { + filter = .inputMessagesFilterUrl + } else { + filter = .inputMessagesFilterEmpty + } + } else { + filter = .inputMessagesFilterEmpty + } + if let peerId = peerId { searchResult = account.postbox.loadedPeerWithId(peerId) |> mapToSignal { peer -> Signal in if let inputPeer = apiInputPeer(peer) { - return account.network.request(Api.functions.messages.search(flags: 0, peer: inputPeer, q: query, filter: .inputMessagesFilterEmpty, minDate: 0, maxDate: Int32.max - 1, offset: 0, maxId: Int32.max - 1, limit: 64)) + return account.network.request(Api.functions.messages.search(flags: 0, peer: inputPeer, q: query, filter: filter, minDate: 0, maxDate: Int32.max - 1, offset: 0, maxId: Int32.max - 1, limit: 64)) |> retryRequest } else { return .never() diff --git a/TelegramCore/SearchPeers.swift b/TelegramCore/SearchPeers.swift index b431ca0739..2afbea344e 100644 --- a/TelegramCore/SearchPeers.swift +++ b/TelegramCore/SearchPeers.swift @@ -11,11 +11,14 @@ import Foundation public func searchPeers(account: Account, query: String) -> Signal<[Peer], NoError> { let searchResult = account.network.request(Api.functions.contacts.search(q: query, limit: 10)) - |> retryRequest - + |> map { Optional($0) } + |> `catch` { _ in + return Signal.single(nil) + } let processedSearchResult = searchResult |> mapToSignal { result -> Signal<[Peer], NoError> in - switch result { + if let result = result { + switch result { case let .found(results, chats, users): return account.postbox.modify { modifier -> [Peer] in var peers: [PeerId: Peer] = [:] @@ -36,12 +39,12 @@ public func searchPeers(account: Account, query: String) -> Signal<[Peer], NoErr for result in results { let peerId: PeerId switch result { - case let .peerUser(userId): - peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: userId) - case let .peerChat(chatId): - peerId = PeerId(namespace: Namespaces.Peer.CloudGroup, id: chatId) - case let .peerChannel(channelId): - peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: channelId) + case let .peerUser(userId): + peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: userId) + case let .peerChat(chatId): + peerId = PeerId(namespace: Namespaces.Peer.CloudGroup, id: chatId) + case let .peerChannel(channelId): + peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: channelId) } if let peer = peers[peerId] { renderedPeers.append(peer) @@ -49,8 +52,12 @@ public func searchPeers(account: Account, query: String) -> Signal<[Peer], NoErr } return renderedPeers + } } + } else { + return .single([]) } + } return processedSearchResult diff --git a/TelegramCore/TextEntitiesMessageAttribute.swift b/TelegramCore/TextEntitiesMessageAttribute.swift index bb560ba0c7..d72148973f 100644 --- a/TelegramCore/TextEntitiesMessageAttribute.swift +++ b/TelegramCore/TextEntitiesMessageAttribute.swift @@ -82,7 +82,7 @@ public enum MessageTextEntityType: Equatable { return false } case let .TextUrl(url): - if case let .TextUrl(url) = rhs { + if case .TextUrl(url) = rhs { return true } else { return false @@ -207,3 +207,44 @@ public class TextEntitiesMessageAttribute: MessageAttribute, Equatable { return lhs.entities == rhs.entities } } + + +func apiTextAttributeEntities(_ attribute: TextEntitiesMessageAttribute, associatedPeers:SimpleDictionary) -> [Api.MessageEntity] { + var entities:[Api.MessageEntity] = [] + + for entity in attribute.entities { + let offset:Int32 = Int32(entity.range.lowerBound) + let length:Int32 = Int32(entity.range.upperBound - entity.range.lowerBound) + switch entity.type { + case .Unknown: + break + case .Mention: + entities.append(.messageEntityMention(offset: offset, length: length)) + case .Hashtag: + entities.append(.messageEntityHashtag(offset: offset, length: length)) + case .BotCommand: + entities.append(.messageEntityBotCommand(offset: offset, length: length)) + case .Url: + entities.append(.messageEntityUrl(offset: offset, length: length)) + case .Email: + entities.append(.messageEntityEmail(offset: offset, length: length)) + case .Bold: + entities.append(.messageEntityBold(offset: offset, length: length)) + case .Italic: + entities.append(.messageEntityItalic(offset: offset, length: length)) + case .Code: + entities.append(.messageEntityCode(offset: offset, length: length)) + case .Pre: + entities.append(.messageEntityPre(offset: offset, length: length, language: "")) + case let .TextUrl(url): + entities.append(.messageEntityTextUrl(offset: offset, length: length, url: url)) + case let .TextMention(peerId): + if let peer = associatedPeers[peerId], let inputUser = apiInputUser(peer) { + entities.append(.inputMessageEntityMentionName(offset: offset, length: length, userId: inputUser)) + } + } + } + return entities +} + +