diff --git a/submodules/ChatListUI/Sources/ChatListSearchContainerNode.swift b/submodules/ChatListUI/Sources/ChatListSearchContainerNode.swift index d75ff72adc..da6911a3a5 100644 --- a/submodules/ChatListUI/Sources/ChatListSearchContainerNode.swift +++ b/submodules/ChatListUI/Sources/ChatListSearchContainerNode.swift @@ -762,7 +762,30 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo ) ) let location: SearchMessagesLocation - location = .general(tags: nil) + let messageTags: MessageTags? + if query.hasPrefix("%media ") { + messageTags = .photoOrVideo + } else if query.hasPrefix("%photo ") { + messageTags = .photo + } else if query.hasPrefix("%video ") { + messageTags = .video + } else if query.hasPrefix("%file ") { + messageTags = .file + } else if query.hasPrefix("%music ") { + messageTags = .music + } else if query.hasPrefix("%link ") { + messageTags = .webPage + } else if query.hasPrefix("%gif ") { + messageTags = .gif + } else { + messageTags = nil + } + location = .general(tags: messageTags) + + var finalQuery = query + if let _ = messageTags, let index = finalQuery.firstIndex(of: " ") { + finalQuery = String(finalQuery.suffix(from: finalQuery.index(after: index))) + } updateSearchContext { _ in return (nil, true) @@ -771,22 +794,22 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo if filter.contains(.doNotSearchMessages) { foundRemoteMessages = .single((([], [:], 0), false)) } else { - if !query.isEmpty { + if !finalQuery.isEmpty { addAppLogEvent(postbox: context.account.postbox, time: Date().timeIntervalSince1970, type: "search_global_query", peerId: nil, data: .dictionary([:])) } - let searchSignal = searchMessages(account: context.account, location: location, query: query, state: nil, limit: 50) + let searchSignal = searchMessages(account: context.account, location: location, query: finalQuery, state: nil, limit: 50) |> map { result, updatedState -> ChatListSearchMessagesResult in - return ChatListSearchMessagesResult(query: query, messages: result.messages.sorted(by: { $0.index > $1.index }), readStates: result.readStates, hasMore: !result.completed, state: updatedState) + return ChatListSearchMessagesResult(query: finalQuery, messages: result.messages.sorted(by: { $0.index > $1.index }), readStates: result.readStates, hasMore: !result.completed, state: updatedState) } let loadMore = searchContext.get() |> mapToSignal { searchContext -> Signal<(([Message], [PeerId: CombinedPeerReadState], Int32), Bool), NoError> in if let searchContext = searchContext { if let _ = searchContext.loadMoreIndex { - return searchMessages(account: context.account, location: location, query: query, state: searchContext.result.state, limit: 80) + return searchMessages(account: context.account, location: location, query: finalQuery, state: searchContext.result.state, limit: 80) |> map { result, updatedState -> ChatListSearchMessagesResult in - return ChatListSearchMessagesResult(query: query, messages: result.messages.sorted(by: { $0.index > $1.index }), readStates: result.readStates, hasMore: !result.completed, state: updatedState) + return ChatListSearchMessagesResult(query: finalQuery, messages: result.messages.sorted(by: { $0.index > $1.index }), readStates: result.readStates, hasMore: !result.completed, state: updatedState) } |> mapToSignal { foundMessages -> Signal<(([Message], [PeerId: CombinedPeerReadState], Int32), Bool), NoError> in updateSearchContext { previous in @@ -818,7 +841,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo } let resolvedMessage = .single(nil) - |> then(context.sharedContext.resolveUrl(account: context.account, url: query) + |> then(context.sharedContext.resolveUrl(account: context.account, url: finalQuery) |> mapToSignal { resolvedUrl -> Signal in if case let .channelMessage(peerId, messageId) = resolvedUrl { return downloadMessage(postbox: context.account.postbox, network: context.account.network, messageId: messageId) @@ -904,7 +927,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo globalExpandType = .none } - let lowercasedQuery = query.lowercased() + let lowercasedQuery = finalQuery.lowercased() if presentationData.strings.DialogList_SavedMessages.lowercased().hasPrefix(lowercasedQuery) || "saved messages".hasPrefix(lowercasedQuery) { if !existingPeerIds.contains(accountPeer.id), filteredPeer(accountPeer, accountPeer) { existingPeerIds.insert(accountPeer.id) @@ -986,8 +1009,8 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo } } - if addContact != nil && isViablePhoneNumber(query) { - entries.append(.addContact(query, presentationData.theme, presentationData.strings)) + if addContact != nil && isViablePhoneNumber(finalQuery) { + entries.append(.addContact(finalQuery, presentationData.theme, presentationData.strings)) } return (entries, isSearching) diff --git a/submodules/SyncCore/Sources/Namespaces.swift b/submodules/SyncCore/Sources/Namespaces.swift index 1cc493ca0f..6a7ddf90d5 100644 --- a/submodules/SyncCore/Sources/Namespaces.swift +++ b/submodules/SyncCore/Sources/Namespaces.swift @@ -96,8 +96,10 @@ public extension MessageTags { static let unseenPersonalMessage = MessageTags(rawValue: 1 << 5) static let liveLocation = MessageTags(rawValue: 1 << 6) static let gif = MessageTags(rawValue: 1 << 7) + static let photo = MessageTags(rawValue: 1 << 8) + static let video = MessageTags(rawValue: 1 << 9) - static let all: MessageTags = [.photoOrVideo, .file, .music, .webPage, .voiceOrInstantVideo, .unseenPersonalMessage, .liveLocation, .gif] + static let all: MessageTags = [.photoOrVideo, .file, .music, .webPage, .voiceOrInstantVideo, .unseenPersonalMessage, .liveLocation, .gif, .photo, .video] } public extension GlobalMessageTags { diff --git a/submodules/TelegramCore/Sources/Holes.swift b/submodules/TelegramCore/Sources/Holes.swift index c4aebc3daf..53c07bf180 100644 --- a/submodules/TelegramCore/Sources/Holes.swift +++ b/submodules/TelegramCore/Sources/Holes.swift @@ -9,6 +9,10 @@ import SyncCore func messageFilterForTagMask(_ tagMask: MessageTags) -> Api.MessagesFilter? { if tagMask == .photoOrVideo { return Api.MessagesFilter.inputMessagesFilterPhotoVideo + } else if tagMask == .photo { + return Api.MessagesFilter.inputMessagesFilterPhotos + } else if tagMask == .video { + return Api.MessagesFilter.inputMessagesFilterVideo } else if tagMask == .file { return Api.MessagesFilter.inputMessagesFilterDocument } else if tagMask == .music { diff --git a/submodules/TelegramCore/Sources/SearchMessages.swift b/submodules/TelegramCore/Sources/SearchMessages.swift index 583f406f0c..e0e3f0a79c 100644 --- a/submodules/TelegramCore/Sources/SearchMessages.swift +++ b/submodules/TelegramCore/Sources/SearchMessages.swift @@ -192,20 +192,7 @@ public func searchMessages(account: Account, location: SearchMessagesLocation, q } } - let filter: Api.MessagesFilter - if let tags = tags { - 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 - } + let filter: Api.MessagesFilter = tags.flatMap { messageFilterForTagMask($0) } ?? .inputMessagesFilterEmpty remoteSearchResult = account.postbox.transaction { transaction -> (peer: Peer, additionalPeer: Peer?, from: Peer?)? in guard let peer = transaction.getPeer(peerId) else { return nil diff --git a/submodules/TelegramCore/Sources/StoreMessage_Telegram.swift b/submodules/TelegramCore/Sources/StoreMessage_Telegram.swift index fd4d4f3d25..02fd29efd6 100644 --- a/submodules/TelegramCore/Sources/StoreMessage_Telegram.swift +++ b/submodules/TelegramCore/Sources/StoreMessage_Telegram.swift @@ -30,6 +30,7 @@ public func tagsForStoreMessage(incoming: Bool, attributes: [MessageAttribute], if let _ = attachment as? TelegramMediaImage { if !isSecret { tags.insert(.photoOrVideo) + tags.insert(.photo) } } else if let file = attachment as? TelegramMediaFile { var refinedTag: MessageTags? = .file @@ -41,7 +42,7 @@ public func tagsForStoreMessage(incoming: Bool, attributes: [MessageAttribute], refinedTag = .voiceOrInstantVideo } else { if !isSecret { - refinedTag = .photoOrVideo + refinedTag = [.photoOrVideo, .video] } else { refinedTag = nil }