Refactor searchPeerMembers, use it for legacy suggestions

This commit is contained in:
Peter 2019-10-11 16:12:25 +04:00
parent 37f28503aa
commit 6f4aa38ab8
8 changed files with 52 additions and 45 deletions

View File

@ -24,6 +24,7 @@ static_library(
"//submodules/LegacyUI:LegacyUI", "//submodules/LegacyUI:LegacyUI",
"//submodules/MimeTypes:MimeTypes", "//submodules/MimeTypes:MimeTypes",
"//submodules/LocalMediaResources:LocalMediaResources", "//submodules/LocalMediaResources:LocalMediaResources",
"//submodules/SearchPeerMembers:SearchPeerMembers",
], ],
frameworks = [ frameworks = [
"$SDKROOT/System/Library/Frameworks/Foundation.framework", "$SDKROOT/System/Library/Frameworks/Foundation.framework",

View File

@ -20,7 +20,7 @@ public struct LegacyAttachmentMenuMediaEditing: OptionSet {
public static let imageOrVideo = LegacyAttachmentMenuMediaEditing(rawValue: 1 << 0) public static let imageOrVideo = LegacyAttachmentMenuMediaEditing(rawValue: 1 << 0)
} }
public func legacyAttachmentMenu(context: AccountContext, peer: Peer, editMediaOptions: LegacyAttachmentMenuMediaEditing?, saveEditedPhotos: Bool, allowGrouping: Bool, hasSchedule: Bool, canSendPolls: Bool, theme: PresentationTheme, strings: PresentationStrings, parentController: LegacyController, recentlyUsedInlineBots: [Peer], initialCaption: String, openGallery: @escaping () -> Void, openCamera: @escaping (TGAttachmentCameraView?, TGMenuSheetController?) -> Void, openFileGallery: @escaping () -> Void, openWebSearch: @escaping () -> Void, openMap: @escaping () -> Void, openContacts: @escaping () -> Void, openPoll: @escaping () -> Void, presentSelectionLimitExceeded: @escaping () -> Void, presentCantSendMultipleFiles: @escaping () -> Void, presentSchedulePicker: @escaping (@escaping (Int32) -> Void) -> Void, sendMessagesWithSignals: @escaping ([Any]?, Bool, Int32) -> Void, selectRecentlyUsedInlineBot: @escaping (Peer) -> Void) -> TGMenuSheetController { public func legacyAttachmentMenu(context: AccountContext, peer: Peer, editMediaOptions: LegacyAttachmentMenuMediaEditing?, saveEditedPhotos: Bool, allowGrouping: Bool, hasSchedule: Bool, canSendPolls: Bool, presentationData: PresentationData, parentController: LegacyController, recentlyUsedInlineBots: [Peer], initialCaption: String, openGallery: @escaping () -> Void, openCamera: @escaping (TGAttachmentCameraView?, TGMenuSheetController?) -> Void, openFileGallery: @escaping () -> Void, openWebSearch: @escaping () -> Void, openMap: @escaping () -> Void, openContacts: @escaping () -> Void, openPoll: @escaping () -> Void, presentSelectionLimitExceeded: @escaping () -> Void, presentCantSendMultipleFiles: @escaping () -> Void, presentSchedulePicker: @escaping (@escaping (Int32) -> Void) -> Void, sendMessagesWithSignals: @escaping ([Any]?, Bool, Int32) -> Void, selectRecentlyUsedInlineBot: @escaping (Peer) -> Void) -> TGMenuSheetController {
let isSecretChat = peer.id.namespace == Namespaces.Peer.SecretChat let isSecretChat = peer.id.namespace == Namespaces.Peer.SecretChat
let controller = TGMenuSheetController(context: parentController.context, dark: false)! let controller = TGMenuSheetController(context: parentController.context, dark: false)!
@ -56,8 +56,8 @@ public func legacyAttachmentMenu(context: AccountContext, peer: Peer, editMediaO
if canSendImageOrVideo { if canSendImageOrVideo {
let carouselItem = TGAttachmentCarouselItemView(context: parentController.context, camera: PGCamera.cameraAvailable(), selfPortrait: false, forProfilePhoto: false, assetType: TGMediaAssetAnyType, saveEditedPhotos: !isSecretChat && saveEditedPhotos, allowGrouping: editMediaOptions == nil && allowGrouping, allowSelection: editMediaOptions == nil, allowEditing: true, document: false, selectionLimit: selectionLimit)! let carouselItem = TGAttachmentCarouselItemView(context: parentController.context, camera: PGCamera.cameraAvailable(), selfPortrait: false, forProfilePhoto: false, assetType: TGMediaAssetAnyType, saveEditedPhotos: !isSecretChat && saveEditedPhotos, allowGrouping: editMediaOptions == nil && allowGrouping, allowSelection: editMediaOptions == nil, allowEditing: true, document: false, selectionLimit: selectionLimit)!
carouselItemView = carouselItem carouselItemView = carouselItem
carouselItem.suggestionContext = legacySuggestionContext(account: context.account, peerId: peer.id) carouselItem.suggestionContext = legacySuggestionContext(context: context, peerId: peer.id)
carouselItem.recipientName = peer.displayTitle carouselItem.recipientName = peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
carouselItem.cameraPressed = { [weak controller] cameraView in carouselItem.cameraPressed = { [weak controller] cameraView in
if let controller = controller { if let controller = controller {
DeviceAccess.authorizeAccess(to: .camera, presentationData: context.sharedContext.currentPresentationData.with { $0 }, present: context.sharedContext.presentGlobalController, openSettings: context.sharedContext.applicationBindings.openSettings, { value in DeviceAccess.authorizeAccess(to: .camera, presentationData: context.sharedContext.currentPresentationData.with { $0 }, present: context.sharedContext.presentGlobalController, openSettings: context.sharedContext.applicationBindings.openSettings, { value in
@ -98,7 +98,7 @@ public func legacyAttachmentMenu(context: AccountContext, peer: Peer, editMediaO
carouselItem.editingContext.setInitialCaption(initialCaption, entities: []) carouselItem.editingContext.setInitialCaption(initialCaption, entities: [])
itemViews.append(carouselItem) itemViews.append(carouselItem)
let galleryItem = TGMenuSheetButtonItemView(title: editing ? strings.Conversation_EditingMessageMediaChange : strings.AttachmentMenu_PhotoOrVideo, type: TGMenuSheetButtonTypeDefault, action: { [weak controller] in let galleryItem = TGMenuSheetButtonItemView(title: editing ? presentationData.strings.Conversation_EditingMessageMediaChange : presentationData.strings.AttachmentMenu_PhotoOrVideo, type: TGMenuSheetButtonTypeDefault, action: { [weak controller] in
controller?.dismiss(animated: true) controller?.dismiss(animated: true)
openGallery() openGallery()
})! })!
@ -116,7 +116,7 @@ public func legacyAttachmentMenu(context: AccountContext, peer: Peer, editMediaO
} }
if !editing { if !editing {
let fileItem = TGMenuSheetButtonItemView(title: strings.AttachmentMenu_File, type: TGMenuSheetButtonTypeDefault, action: {[weak controller] in let fileItem = TGMenuSheetButtonItemView(title: presentationData.strings.AttachmentMenu_File, type: TGMenuSheetButtonTypeDefault, action: {[weak controller] in
controller?.dismiss(animated: true) controller?.dismiss(animated: true)
openFileGallery() openFileGallery()
})! })!
@ -125,7 +125,7 @@ public func legacyAttachmentMenu(context: AccountContext, peer: Peer, editMediaO
} }
if canEditCurrent { if canEditCurrent {
let fileItem = TGMenuSheetButtonItemView(title: strings.AttachmentMenu_File, type: TGMenuSheetButtonTypeDefault, action: {[weak controller] in let fileItem = TGMenuSheetButtonItemView(title: presentationData.strings.AttachmentMenu_File, type: TGMenuSheetButtonTypeDefault, action: {[weak controller] in
controller?.dismiss(animated: true) controller?.dismiss(animated: true)
openFileGallery() openFileGallery()
})! })!
@ -133,21 +133,21 @@ public func legacyAttachmentMenu(context: AccountContext, peer: Peer, editMediaO
} }
if editMediaOptions == nil { if editMediaOptions == nil {
let locationItem = TGMenuSheetButtonItemView(title: strings.Conversation_Location, type: TGMenuSheetButtonTypeDefault, action: { [weak controller] in let locationItem = TGMenuSheetButtonItemView(title: presentationData.strings.Conversation_Location, type: TGMenuSheetButtonTypeDefault, action: { [weak controller] in
controller?.dismiss(animated: true) controller?.dismiss(animated: true)
openMap() openMap()
})! })!
itemViews.append(locationItem) itemViews.append(locationItem)
if (peer is TelegramGroup || peer is TelegramChannel) && canSendMessagesToPeer(peer) && canSendPolls { if (peer is TelegramGroup || peer is TelegramChannel) && canSendMessagesToPeer(peer) && canSendPolls {
let pollItem = TGMenuSheetButtonItemView(title: strings.AttachmentMenu_Poll, type: TGMenuSheetButtonTypeDefault, action: { [weak controller] in let pollItem = TGMenuSheetButtonItemView(title: presentationData.strings.AttachmentMenu_Poll, type: TGMenuSheetButtonTypeDefault, action: { [weak controller] in
controller?.dismiss(animated: true) controller?.dismiss(animated: true)
openPoll() openPoll()
})! })!
itemViews.append(pollItem) itemViews.append(pollItem)
} }
let contactItem = TGMenuSheetButtonItemView(title: strings.Conversation_Contact, type: TGMenuSheetButtonTypeDefault, action: { [weak controller] in let contactItem = TGMenuSheetButtonItemView(title: presentationData.strings.Conversation_Contact, type: TGMenuSheetButtonTypeDefault, action: { [weak controller] in
controller?.dismiss(animated: true) controller?.dismiss(animated: true)
openContacts() openContacts()
})! })!
@ -174,7 +174,7 @@ public func legacyAttachmentMenu(context: AccountContext, peer: Peer, editMediaO
carouselItemView?.remainingHeight = TGMenuSheetButtonItemViewHeight * CGFloat(itemViews.count - 1) carouselItemView?.remainingHeight = TGMenuSheetButtonItemViewHeight * CGFloat(itemViews.count - 1)
let cancelItem = TGMenuSheetButtonItemView(title: strings.Common_Cancel, type: TGMenuSheetButtonTypeCancel, action: { [weak controller] in let cancelItem = TGMenuSheetButtonItemView(title: presentationData.strings.Common_Cancel, type: TGMenuSheetButtonTypeCancel, action: { [weak controller] in
controller?.dismiss(animated: true) controller?.dismiss(animated: true)
})! })!
itemViews.append(cancelItem) itemViews.append(cancelItem)
@ -189,8 +189,8 @@ public func legacyMenuPaletteFromTheme(_ theme: PresentationTheme) -> TGMenuShee
return TGMenuSheetPallete(dark: theme.overallDarkAppearance, backgroundColor: sheetTheme.opaqueItemBackgroundColor, selectionColor: sheetTheme.opaqueItemHighlightedBackgroundColor, separatorColor: sheetTheme.opaqueItemSeparatorColor, accentColor: sheetTheme.controlAccentColor, destructiveColor: sheetTheme.destructiveActionTextColor, textColor: sheetTheme.primaryTextColor, secondaryTextColor: sheetTheme.secondaryTextColor, spinnerColor: sheetTheme.secondaryTextColor, badgeTextColor: sheetTheme.controlAccentColor, badgeImage: nil, cornersImage: generateStretchableFilledCircleImage(diameter: 11.0, color: nil, strokeColor: nil, strokeWidth: nil, backgroundColor: sheetTheme.opaqueItemBackgroundColor)) return TGMenuSheetPallete(dark: theme.overallDarkAppearance, backgroundColor: sheetTheme.opaqueItemBackgroundColor, selectionColor: sheetTheme.opaqueItemHighlightedBackgroundColor, separatorColor: sheetTheme.opaqueItemSeparatorColor, accentColor: sheetTheme.controlAccentColor, destructiveColor: sheetTheme.destructiveActionTextColor, textColor: sheetTheme.primaryTextColor, secondaryTextColor: sheetTheme.secondaryTextColor, spinnerColor: sheetTheme.secondaryTextColor, badgeTextColor: sheetTheme.controlAccentColor, badgeImage: nil, cornersImage: generateStretchableFilledCircleImage(diameter: 11.0, color: nil, strokeColor: nil, strokeWidth: nil, backgroundColor: sheetTheme.opaqueItemBackgroundColor))
} }
public func presentLegacyPasteMenu(context: AccountContext, peer: Peer, saveEditedPhotos: Bool, allowGrouping: Bool, theme: PresentationTheme, strings: PresentationStrings, images: [UIImage], sendMessagesWithSignals: @escaping ([Any]?) -> Void, present: (ViewController, Any?) -> Void, initialLayout: ContainerViewLayout? = nil) -> ViewController { public func presentLegacyPasteMenu(context: AccountContext, peer: Peer, saveEditedPhotos: Bool, allowGrouping: Bool, presentationData: PresentationData, images: [UIImage], sendMessagesWithSignals: @escaping ([Any]?) -> Void, present: (ViewController, Any?) -> Void, initialLayout: ContainerViewLayout? = nil) -> ViewController {
let legacyController = LegacyController(presentation: .custom, theme: theme, initialLayout: initialLayout) let legacyController = LegacyController(presentation: .custom, theme: presentationData.theme, initialLayout: initialLayout)
legacyController.statusBar.statusBarStyle = .Ignore legacyController.statusBar.statusBarStyle = .Ignore
legacyController.controllerLoaded = { [weak legacyController] in legacyController.controllerLoaded = { [weak legacyController] in
legacyController?.view.disablesInteractiveTransitionGestureRecognizer = true legacyController?.view.disablesInteractiveTransitionGestureRecognizer = true
@ -209,7 +209,7 @@ public func presentLegacyPasteMenu(context: AccountContext, peer: Peer, saveEdit
} }
hasSilentPosting = true hasSilentPosting = true
} }
let recipientName = peer.displayTitle let recipientName = peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
legacyController.enableSizeClassSignal = true legacyController.enableSizeClassSignal = true

View File

@ -22,7 +22,7 @@ public func configureLegacyAssetPicker(_ controller: TGMediaAssetsController, co
controller.captionsEnabled = captionsEnabled controller.captionsEnabled = captionsEnabled
controller.inhibitDocumentCaptions = false controller.inhibitDocumentCaptions = false
controller.suggestionContext = legacySuggestionContext(account: context.account, peerId: peer.id) controller.suggestionContext = legacySuggestionContext(context: context, peerId: peer.id)
if peer.id != context.account.peerId { if peer.id != context.account.peerId {
if peer is TelegramUser { if peer is TelegramUser {
controller.hasTimer = hasSchedule controller.hasTimer = hasSchedule
@ -67,7 +67,7 @@ public func legacyAssetPicker(context: AccountContext, presentationData: Present
} else { } else {
Queue.mainQueue().async { Queue.mainQueue().async {
subscriber.putNext({ context in subscriber.putNext({ context in
let controller = TGMediaAssetsController(context: context, assetGroup: group, intent: intent, recipientName: peer?.displayTitle, saveEditedPhotos: !isSecretChat && saveEditedPhotos, allowGrouping: allowGrouping, inhibitSelection: editingMedia, selectionLimit: Int32(selectionLimit)) let controller = TGMediaAssetsController(context: context, assetGroup: group, intent: intent, recipientName: peer?.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder), saveEditedPhotos: !isSecretChat && saveEditedPhotos, allowGrouping: allowGrouping, inhibitSelection: editingMedia, selectionLimit: Int32(selectionLimit))
return controller! return controller!
}) })
subscriber.putCompletion() subscriber.putCompletion()
@ -76,7 +76,7 @@ public func legacyAssetPicker(context: AccountContext, presentationData: Present
}) })
} else { } else {
subscriber.putNext({ context in subscriber.putNext({ context in
let controller = TGMediaAssetsController(context: context, assetGroup: nil, intent: intent, recipientName: peer?.displayTitle, saveEditedPhotos: !isSecretChat && saveEditedPhotos, allowGrouping: allowGrouping, selectionLimit: Int32(selectionLimit)) let controller = TGMediaAssetsController(context: context, assetGroup: nil, intent: intent, recipientName: peer?.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder), saveEditedPhotos: !isSecretChat && saveEditedPhotos, allowGrouping: allowGrouping, selectionLimit: Int32(selectionLimit))
return controller! return controller!
}) })
subscriber.putCompletion() subscriber.putCompletion()

View File

@ -5,30 +5,18 @@ import Postbox
import SwiftSignalKit import SwiftSignalKit
import LegacyComponents import LegacyComponents
import LegacyUI import LegacyUI
import SearchPeerMembers
import AccountContext
public func legacySuggestionContext(account: Account, peerId: PeerId) -> TGSuggestionContext { public func legacySuggestionContext(context: AccountContext, peerId: PeerId) -> TGSuggestionContext {
let context = TGSuggestionContext() let suggestionContext = TGSuggestionContext()
context.userListSignal = { query in suggestionContext.userListSignal = { query in
return SSignal { subscriber in return SSignal { subscriber in
if let query = query { if let query = query {
let normalizedQuery = query.lowercased() let normalizedQuery = query.lowercased()
let disposable = peerParticipants(postbox: account.postbox, id: peerId).start(next: { peers in let disposable = searchPeerMembers(context: context, peerId: peerId, query: query).start(next: { peers in
let filteredPeers = peers.filter { peer in
if peer.indexName.matchesByTokens(normalizedQuery) {
return true
}
if let addressName = peer.addressName, addressName.lowercased().hasPrefix(normalizedQuery) {
return true
}
return false
}
let sortedPeers = filteredPeers.sorted(by: { lhs, rhs in
let result = lhs.indexName.indexName(.lastNameFirst).compare(rhs.indexName.indexName(.lastNameFirst))
return result == .orderedAscending
})
let users = NSMutableArray() let users = NSMutableArray()
for peer in sortedPeers { for peer in peers {
let user = TGUser() let user = TGUser()
if let peer = peer as? TelegramUser { if let peer = peer as? TelegramUser {
user.uid = peer.id.id user.uid = peer.id.id
@ -56,9 +44,9 @@ public func legacySuggestionContext(account: Account, peerId: PeerId) -> TGSugge
} }
} }
} }
context.hashtagListSignal = { query in suggestionContext.hashtagListSignal = { query in
return SSignal { subscriber in return SSignal { subscriber in
let disposable = (recentlyUsedHashtags(postbox: account.postbox) |> map { hashtags -> [String] in let disposable = (recentlyUsedHashtags(postbox: context.account.postbox) |> map { hashtags -> [String] in
let normalizedQuery = query?.lowercased() let normalizedQuery = query?.lowercased()
var result: [String] = [] var result: [String] = []
if let normalizedQuery = normalizedQuery { if let normalizedQuery = normalizedQuery {
@ -81,12 +69,12 @@ public func legacySuggestionContext(account: Account, peerId: PeerId) -> TGSugge
} }
} }
} }
context.alphacodeSignal = { query, inputLanguageCode in suggestionContext.alphacodeSignal = { query, inputLanguageCode in
guard let query = query, let inputLanguageCode = inputLanguageCode else { guard let query = query, let inputLanguageCode = inputLanguageCode else {
return SSignal.complete() return SSignal.complete()
} }
return SSignal { subscriber in return SSignal { subscriber in
let disposable = (searchEmojiKeywords(postbox: account.postbox, inputLanguageCode: inputLanguageCode, query: query, completeMatch: query.count < 3) let disposable = (searchEmojiKeywords(postbox: context.account.postbox, inputLanguageCode: inputLanguageCode, query: query, completeMatch: query.count < 3)
|> map { keywords -> [TGAlphacodeEntry] in |> map { keywords -> [TGAlphacodeEntry] in
var result: [TGAlphacodeEntry] = [] var result: [TGAlphacodeEntry] = []
for keyword in keywords { for keyword in keywords {
@ -107,5 +95,5 @@ public func legacySuggestionContext(account: Account, peerId: PeerId) -> TGSugge
} }
} }
} }
return context return suggestionContext
} }

View File

@ -0,0 +1,17 @@
load("//Config:buck_rule_macros.bzl", "static_library")
static_library(
name = "SearchPeerMembers",
srcs = glob([
"Sources/**/*.swift",
]),
deps = [
"//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit#shared",
"//submodules/Postbox:Postbox#shared",
"//submodules/TelegramCore:TelegramCore#shared",
"//submodules/AccountContext:AccountContext",
],
frameworks = [
"$SDKROOT/System/Library/Frameworks/Foundation.framework",
],
)

View File

@ -4,7 +4,7 @@ import TelegramCore
import SwiftSignalKit import SwiftSignalKit
import AccountContext import AccountContext
func searchPeerMembers(context: AccountContext, peerId: PeerId, query: String) -> Signal<[Peer], NoError> { public func searchPeerMembers(context: AccountContext, peerId: PeerId, query: String) -> Signal<[Peer], NoError> {
if peerId.namespace == Namespaces.Peer.CloudChannel { if peerId.namespace == Namespaces.Peer.CloudChannel {
return context.account.postbox.transaction { transaction -> CachedChannelData? in return context.account.postbox.transaction { transaction -> CachedChannelData? in
return transaction.getPeerCachedData(peerId: peerId) as? CachedChannelData return transaction.getPeerCachedData(peerId: peerId) as? CachedChannelData
@ -16,7 +16,7 @@ func searchPeerMembers(context: AccountContext, peerId: PeerId, query: String) -
if case .ready = state.loadingState { if case .ready = state.loadingState {
let normalizedQuery = query.lowercased() let normalizedQuery = query.lowercased()
subscriber.putNext(state.list.compactMap { participant -> Peer? in subscriber.putNext(state.list.compactMap { participant -> Peer? in
if participant.peer.displayTitle.isEmpty { if participant.peer.isDeleted {
return nil return nil
} }
if normalizedQuery.isEmpty { if normalizedQuery.isEmpty {
@ -49,7 +49,7 @@ func searchPeerMembers(context: AccountContext, peerId: PeerId, query: String) -
let (disposable, _) = context.peerChannelMemberCategoriesContextsManager.recent(postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peerId, searchQuery: query.isEmpty ? nil : query, updated: { state in let (disposable, _) = context.peerChannelMemberCategoriesContextsManager.recent(postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peerId, searchQuery: query.isEmpty ? nil : query, updated: { state in
if case .ready = state.loadingState { if case .ready = state.loadingState {
subscriber.putNext(state.list.compactMap { participant in subscriber.putNext(state.list.compactMap { participant in
if participant.peer.displayTitle.isEmpty { if participant.peer.isDeleted {
return nil return nil
} }
return participant.peer return participant.peer

View File

@ -8,6 +8,7 @@ import LegacyComponents
import TextFormat import TextFormat
import AccountContext import AccountContext
import Emoji import Emoji
import SearchPeerMembers
enum ChatContextQueryError { enum ChatContextQueryError {
case inlineBotLocationRequest(PeerId) case inlineBotLocationRequest(PeerId)

View File

@ -57,8 +57,8 @@ func presentedLegacyCamera(context: AccountContext, peer: Peer, cameraView: TGAt
controller.allowCaptionEntities = true controller.allowCaptionEntities = true
controller.allowGrouping = mediaGrouping controller.allowGrouping = mediaGrouping
controller.inhibitDocumentCaptions = false controller.inhibitDocumentCaptions = false
controller.suggestionContext = legacySuggestionContext(account: context.account, peerId: peer.id) controller.suggestionContext = legacySuggestionContext(context: context, peerId: peer.id)
controller.recipientName = peer.displayTitle controller.recipientName = peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
if peer.id != context.account.peerId { if peer.id != context.account.peerId {
if peer is TelegramUser { if peer is TelegramUser {
controller.hasTimer = hasSchedule controller.hasTimer = hasSchedule