Business fixes

This commit is contained in:
Isaac 2024-02-29 21:35:36 +04:00
parent c88e69ec29
commit c69ba2c089
7 changed files with 204 additions and 28 deletions

View File

@ -101,6 +101,7 @@ swift_library(
"//submodules/TelegramUI/Components/Settings/ArchiveInfoScreen", "//submodules/TelegramUI/Components/Settings/ArchiveInfoScreen",
"//submodules/TelegramUI/Components/Settings/NewSessionInfoScreen", "//submodules/TelegramUI/Components/Settings/NewSessionInfoScreen",
"//submodules/TelegramUI/Components/Settings/PeerNameColorItem", "//submodules/TelegramUI/Components/Settings/PeerNameColorItem",
"//submodules/Components/MultilineTextComponent",
], ],
visibility = [ visibility = [
"//visibility:public", "//visibility:public",

View File

@ -27,6 +27,7 @@ import ComponentFlow
import EmojiStatusComponent import EmojiStatusComponent
import AvatarVideoNode import AvatarVideoNode
import AppBundle import AppBundle
import MultilineTextComponent
public enum ChatListItemContent { public enum ChatListItemContent {
public struct ThreadInfo: Equatable { public struct ThreadInfo: Equatable {
@ -269,7 +270,9 @@ private final class ChatListItemTagListComponent: Component {
func update(context: AccountContext, title: String, backgroundColor: UIColor, foregroundColor: UIColor) -> CGSize { func update(context: AccountContext, title: String, backgroundColor: UIColor, foregroundColor: UIColor) -> CGSize {
let titleSize = self.title.update( let titleSize = self.title.update(
transition: .immediate, transition: .immediate,
component: AnyComponent(Text(text: title.isEmpty ? " " : title, font: Font.semibold(11.0), color: foregroundColor)), component: AnyComponent(MultilineTextComponent(
text: .plain(NSAttributedString(string: title.isEmpty ? " " : title, font: Font.semibold(11.0), textColor: foregroundColor))
)),
environment: {}, environment: {},
containerSize: CGSize(width: 100.0, height: 100.0) containerSize: CGSize(width: 100.0, height: 100.0)
) )
@ -800,8 +803,8 @@ private let playIconImage = UIImage(bundleImageName: "Chat List/MiniThumbnailPla
private final class ChatListMediaPreviewNode: ASDisplayNode { private final class ChatListMediaPreviewNode: ASDisplayNode {
private let context: AccountContext private let context: AccountContext
private let message: EngineMessage let message: EngineMessage
private let media: EngineMedia let media: EngineMedia
private let imageNode: TransformImageNode private let imageNode: TransformImageNode
private let playIcon: ASImageNode private let playIcon: ASImageNode
@ -862,11 +865,15 @@ private final class ChatListMediaPreviewNode: ASDisplayNode {
if file.isInstantVideo { if file.isInstantVideo {
isRound = true isRound = true
} }
if file.isSticker || file.isAnimatedSticker {
self.playIcon.isHidden = true
} else {
if file.isAnimated { if file.isAnimated {
self.playIcon.isHidden = true self.playIcon.isHidden = true
} else { } else {
self.playIcon.isHidden = false self.playIcon.isHidden = false
} }
}
if let mediaDimensions = file.dimensions { if let mediaDimensions = file.dimensions {
dimensions = mediaDimensions.cgSize dimensions = mediaDimensions.cgSize
if !self.requestedImage { if !self.requestedImage {
@ -877,9 +884,18 @@ private final class ChatListMediaPreviewNode: ASDisplayNode {
} }
} }
let radius: CGFloat
if isRound {
radius = size.width / 2.0
} else if size.width >= 30.0 {
radius = 8.0
} else {
radius = 2.0
}
let makeLayout = self.imageNode.asyncLayout() let makeLayout = self.imageNode.asyncLayout()
self.imageNode.frame = CGRect(origin: CGPoint(), size: size) self.imageNode.frame = CGRect(origin: CGPoint(), size: size)
let apply = makeLayout(TransformImageArguments(corners: ImageCorners(radius: isRound ? size.width / 2.0 : 2.0), imageSize: dimensions.aspectFilled(size), boundingSize: size, intrinsicInsets: UIEdgeInsets())) let apply = makeLayout(TransformImageArguments(corners: ImageCorners(radius: radius), imageSize: dimensions.aspectFilled(size), boundingSize: size, intrinsicInsets: UIEdgeInsets()))
apply() apply()
} }
} }
@ -1142,6 +1158,18 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
} }
} }
private struct ContentImageSpec {
var message: EngineMessage
var media: EngineMedia
var size: CGSize
init(message: EngineMessage, media: EngineMedia, size: CGSize) {
self.message = message
self.media = media
self.size = size
}
}
var item: ChatListItem? var item: ChatListItem?
private let backgroundNode: ASDisplayNode private let backgroundNode: ASDisplayNode
@ -1156,7 +1184,7 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
var avatarIconComponent: EmojiStatusComponent? var avatarIconComponent: EmojiStatusComponent?
var avatarVideoNode: AvatarVideoNode? var avatarVideoNode: AvatarVideoNode?
var avatarTapRecognizer: UITapGestureRecognizer? var avatarTapRecognizer: UITapGestureRecognizer?
var avatarMediaNode: AvatarVideoNode? private var avatarMediaNode: ChatListMediaPreviewNode?
private var inlineNavigationMarkLayer: SimpleLayer? private var inlineNavigationMarkLayer: SimpleLayer?
@ -1197,7 +1225,7 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
private var cachedDataDisposable = MetaDisposable() private var cachedDataDisposable = MetaDisposable()
private var currentTextLeftCutout: CGFloat = 0.0 private var currentTextLeftCutout: CGFloat = 0.0
private var currentMediaPreviewSpecs: [(message: EngineMessage, media: EngineMedia, size: CGSize)] = [] private var currentMediaPreviewSpecs: [ContentImageSpec] = []
private var mediaPreviewNodes: [EngineMedia.Id: ChatListMediaPreviewNode] = [:] private var mediaPreviewNodes: [EngineMedia.Id: ChatListMediaPreviewNode] = [:]
var selectableControlNode: ItemListSelectableControlNode? var selectableControlNode: ItemListSelectableControlNode?
@ -2153,6 +2181,21 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
if !itemTags.isEmpty { if !itemTags.isEmpty {
forumTopicData = nil forumTopicData = nil
topForumTopicItems = [] topForumTopicItems = []
if case let .chat(itemPeer, _, _, _, _, _, _) = contentData {
if let messagePeer = itemPeer.chatMainPeer {
switch messagePeer {
case let .channel(channel):
if case .group = channel.info {
useInlineAuthorPrefix = true
}
case .legacyGroup:
useInlineAuthorPrefix = true
default:
break
}
}
}
} }
if useInlineAuthorPrefix { if useInlineAuthorPrefix {
@ -2175,7 +2218,9 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
let contentImageSpacing: CGFloat = 2.0 let contentImageSpacing: CGFloat = 2.0
let forwardedIconSpacing: CGFloat = 6.0 let forwardedIconSpacing: CGFloat = 6.0
let contentImageTrailingSpace: CGFloat = 5.0 let contentImageTrailingSpace: CGFloat = 5.0
var contentImageSpecs: [(message: EngineMessage, media: EngineMedia, size: CGSize)] = []
var contentImageSpecs: [ContentImageSpec] = []
var avatarContentImageSpec: ContentImageSpec?
var forumThread: (id: Int64, title: String, iconId: Int64?, iconColor: Int32, isUnread: Bool)? var forumThread: (id: Int64, title: String, iconId: Int64?, iconColor: Int32, isUnread: Bool)?
var displayForwardedIcon = false var displayForwardedIcon = false
@ -2494,21 +2539,31 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
if displayMediaPreviews { if displayMediaPreviews {
let contentImageFillSize = CGSize(width: 8.0, height: contentImageSize.height) let contentImageFillSize = CGSize(width: 8.0, height: contentImageSize.height)
_ = contentImageFillSize _ = contentImageFillSize
var contentImageIsDisplayedAsAvatar = false
if case let .peer(peerData) = item.content, let customMessageListData = peerData.customMessageListData, customMessageListData.commandPrefix != nil {
contentImageIsDisplayedAsAvatar = true
}
for message in messages { for message in messages {
if contentImageSpecs.count >= 3 { if contentImageSpecs.count >= 3 {
break break
} }
inner: for media in message.media { inner: for media in message.media {
if let image = media as? TelegramMediaImage { if let image = media as? TelegramMediaImage {
if let _ = largestImageRepresentation(image.representations) { if let _ = largestImageRepresentation(image.representations) {
let fitSize = contentImageSize let fitSize = contentImageSize
contentImageSpecs.append((message, .image(image), fitSize)) contentImageSpecs.append(ContentImageSpec(message: message, media: .image(image), size: fitSize))
} }
break inner break inner
} else if let file = media as? TelegramMediaFile { } else if let file = media as? TelegramMediaFile {
if file.isVideo, !file.isVideoSticker, let _ = file.dimensions { if file.isVideo, !file.isVideoSticker, let _ = file.dimensions {
let fitSize = contentImageSize let fitSize = contentImageSize
contentImageSpecs.append((message, .file(file), fitSize)) contentImageSpecs.append(ContentImageSpec(message: message, media: .file(file), size: fitSize))
} else if contentImageIsDisplayedAsAvatar && (file.isSticker || file.isVideoSticker) {
let fitSize = contentImageSize
contentImageSpecs.append(ContentImageSpec(message: message, media: .file(file), size: fitSize))
} }
break inner break inner
} else if let webpage = media as? TelegramMediaWebpage, case let .Loaded(content) = webpage.content { } else if let webpage = media as? TelegramMediaWebpage, case let .Loaded(content) = webpage.content {
@ -2516,36 +2571,41 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
if let image = content.image, let type = content.type, imageTypes.contains(type) { if let image = content.image, let type = content.type, imageTypes.contains(type) {
if let _ = largestImageRepresentation(image.representations) { if let _ = largestImageRepresentation(image.representations) {
let fitSize = contentImageSize let fitSize = contentImageSize
contentImageSpecs.append((message, .image(image), fitSize)) contentImageSpecs.append(ContentImageSpec(message: message, media: .image(image), size: fitSize))
} }
break inner break inner
} else if let file = content.file { } else if let file = content.file {
if file.isVideo, !file.isInstantVideo, let _ = file.dimensions { if file.isVideo, !file.isInstantVideo, let _ = file.dimensions {
let fitSize = contentImageSize let fitSize = contentImageSize
contentImageSpecs.append((message, .file(file), fitSize)) contentImageSpecs.append(ContentImageSpec(message: message, media: .file(file), size: fitSize))
} }
break inner break inner
} }
} else if let action = media as? TelegramMediaAction, case let .suggestedProfilePhoto(image) = action.action, let _ = image { } else if let action = media as? TelegramMediaAction, case let .suggestedProfilePhoto(image) = action.action, let _ = image {
let fitSize = contentImageSize let fitSize = contentImageSize
contentImageSpecs.append((message, .action(action), fitSize)) contentImageSpecs.append(ContentImageSpec(message: message, media: .action(action), size: fitSize))
} else if let storyMedia = media as? TelegramMediaStory, let story = message.associatedStories[storyMedia.storyId], !story.data.isEmpty, case let .item(storyItem) = story.get(Stories.StoredItem.self) { } else if let storyMedia = media as? TelegramMediaStory, let story = message.associatedStories[storyMedia.storyId], !story.data.isEmpty, case let .item(storyItem) = story.get(Stories.StoredItem.self) {
if let image = storyItem.media as? TelegramMediaImage { if let image = storyItem.media as? TelegramMediaImage {
if let _ = largestImageRepresentation(image.representations) { if let _ = largestImageRepresentation(image.representations) {
let fitSize = contentImageSize let fitSize = contentImageSize
contentImageSpecs.append((message, .image(image), fitSize)) contentImageSpecs.append(ContentImageSpec(message: message, media: .image(image), size: fitSize))
} }
break inner break inner
} else if let file = storyItem.media as? TelegramMediaFile { } else if let file = storyItem.media as? TelegramMediaFile {
if file.isVideo, !file.isInstantVideo, let _ = file.dimensions { if file.isVideo, !file.isInstantVideo, let _ = file.dimensions {
let fitSize = contentImageSize let fitSize = contentImageSize
contentImageSpecs.append((message, .file(file), fitSize)) contentImageSpecs.append(ContentImageSpec(message: message, media: .file(file), size: fitSize))
} }
break inner break inner
} }
} }
} }
} }
if contentImageIsDisplayedAsAvatar {
avatarContentImageSpec = contentImageSpecs.first
contentImageSpecs.removeAll()
}
} }
} else { } else {
attributedText = NSAttributedString(string: messageText, font: textFont, textColor: theme.messageTextColor) attributedText = NSAttributedString(string: messageText, font: textFont, textColor: theme.messageTextColor)
@ -4056,7 +4116,11 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
} }
var validMediaIds: [EngineMedia.Id] = [] var validMediaIds: [EngineMedia.Id] = []
for (message, media, mediaSize) in contentImageSpecs { for spec in contentImageSpecs {
let message = spec.message
let media = spec.media
let mediaSize = spec.size
var mediaId = media.id var mediaId = media.id
if mediaId == nil, case let .action(action) = media, case let .suggestedProfilePhoto(image) = action.action { if mediaId == nil, case let .action(action) = media, case let .suggestedProfilePhoto(image) = action.action {
mediaId = image?.id mediaId = image?.id
@ -4095,6 +4159,36 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
strongSelf.currentMediaPreviewSpecs = contentImageSpecs strongSelf.currentMediaPreviewSpecs = contentImageSpecs
strongSelf.currentTextLeftCutout = textLeftCutout strongSelf.currentTextLeftCutout = textLeftCutout
if let avatarContentImageSpec {
strongSelf.avatarNode.isHidden = true
if let previous = strongSelf.avatarMediaNode, previous.media != avatarContentImageSpec.media {
strongSelf.avatarMediaNode = nil
previous.removeFromSupernode()
}
var avatarMediaNodeTransition = transition
let avatarMediaNode: ChatListMediaPreviewNode
if let current = strongSelf.avatarMediaNode {
avatarMediaNode = current
} else {
avatarMediaNodeTransition = .immediate
avatarMediaNode = ChatListMediaPreviewNode(context: item.context, message: avatarContentImageSpec.message, media: avatarContentImageSpec.media)
strongSelf.avatarMediaNode = avatarMediaNode
strongSelf.contextContainer.addSubnode(avatarMediaNode)
}
avatarMediaNodeTransition.updateFrame(node: avatarMediaNode, frame: avatarFrame)
avatarMediaNode.updateLayout(size: avatarFrame.size, synchronousLoads: synchronousLoads)
} else {
strongSelf.avatarNode.isHidden = false
if let avatarMediaNode = strongSelf.avatarMediaNode {
strongSelf.avatarMediaNode = nil
avatarMediaNode.removeFromSupernode()
}
}
if !contentDelta.x.isZero || !contentDelta.y.isZero { if !contentDelta.x.isZero || !contentDelta.y.isZero {
let titlePosition = strongSelf.titleNode.position let titlePosition = strongSelf.titleNode.position
transition.animatePosition(node: strongSelf.titleNode, from: CGPoint(x: titlePosition.x - contentDelta.x, y: titlePosition.y - contentDelta.y)) transition.animatePosition(node: strongSelf.titleNode, from: CGPoint(x: titlePosition.x - contentDelta.x, y: titlePosition.y - contentDelta.y))

View File

@ -702,9 +702,29 @@ private struct ContactsListNodeTransition {
} }
public enum ContactListPresentation { public enum ContactListPresentation {
public struct Search {
public var signal: Signal<String, NoError>
public var searchChatList: Bool
public var searchDeviceContacts: Bool
public var searchGroups: Bool
public var searchChannels: Bool
public var globalSearch: Bool
public var displaySavedMessages: Bool
public init(signal: Signal<String, NoError>, searchChatList: Bool, searchDeviceContacts: Bool, searchGroups: Bool, searchChannels: Bool, globalSearch: Bool, displaySavedMessages: Bool) {
self.signal = signal
self.searchChatList = searchChatList
self.searchDeviceContacts = searchDeviceContacts
self.searchGroups = searchGroups
self.searchChannels = searchChannels
self.globalSearch = globalSearch
self.displaySavedMessages = displaySavedMessages
}
}
case orderedByPresence(options: [ContactListAdditionalOption]) case orderedByPresence(options: [ContactListAdditionalOption])
case natural(options: [ContactListAdditionalOption], includeChatList: Bool, topPeers: Bool) case natural(options: [ContactListAdditionalOption], includeChatList: Bool, topPeers: Bool)
case search(signal: Signal<String, NoError>, searchChatList: Bool, searchDeviceContacts: Bool, searchGroups: Bool, searchChannels: Bool, globalSearch: Bool) case search(Search)
public var sortOrder: ContactsSortOrder? { public var sortOrder: ContactsSortOrder? {
switch self { switch self {
@ -1097,7 +1117,15 @@ public final class ContactListNode: ASDisplayNode {
displayTopPeers = displayTopPeersValue displayTopPeers = displayTopPeersValue
} }
if case let .search(query, searchChatList, searchDeviceContacts, searchGroups, searchChannels, globalSearch) = presentation { if case let .search(search) = presentation {
let query = search.signal
let searchChatList = search.searchChatList
let searchDeviceContacts = search.searchDeviceContacts
let searchGroups = search.searchGroups
let searchChannels = search.searchChannels
let globalSearch = search.globalSearch
let displaySavedMessages = search.displaySavedMessages
return query return query
|> mapToSignal { query in |> mapToSignal { query in
let foundLocalContacts: Signal<([FoundPeer], [EnginePeer.Id: EnginePeer.Presence]), NoError> let foundLocalContacts: Signal<([FoundPeer], [EnginePeer.Id: EnginePeer.Presence]), NoError>
@ -1108,6 +1136,12 @@ public final class ContactListNode: ASDisplayNode {
var resultPeers: [FoundPeer] = [] var resultPeers: [FoundPeer] = []
for peer in peers { for peer in peers {
if !displaySavedMessages {
if peer.peerId == context.account.peerId {
continue
}
}
if searchGroups || searchChannels { if searchGroups || searchChannels {
let mainPeer = peer.chatMainPeer let mainPeer = peer.chatMainPeer
if let _ = mainPeer as? TelegramUser { if let _ = mainPeer as? TelegramUser {

View File

@ -354,7 +354,7 @@ public final class TelegramBusinessHours: Equatable, Codable {
} }
if minutes.isEmpty { if minutes.isEmpty {
return .closed return .closed
} else if minutes == IndexSet(integersIn: 0 ..< 24 * 60) { } else if minutes == IndexSet(integersIn: 0 ..< 24 * 60) || minutes == IndexSet(integersIn: 0 ..< (24 * 60 - 1)) {
return .open return .open
} else { } else {
return .intervals(day) return .intervals(day)

View File

@ -22,6 +22,10 @@ private func dayBusinessHoursText(presentationData: PresentationData, day: Teleg
businessHoursText += "closed" businessHoursText += "closed"
case let .intervals(intervals): case let .intervals(intervals):
func clipMinutes(_ value: Int) -> Int { func clipMinutes(_ value: Int) -> Int {
var value = value
if value < 0 {
value = 24 * 60 + value
}
return value % (24 * 60) return value % (24 * 60)
} }
@ -478,7 +482,13 @@ private final class PeerInfoScreenBusinessHoursItemNode: PeerInfoScreenItemNode
var dayHeights: CGFloat = 0.0 var dayHeights: CGFloat = 0.0
for i in 0 ..< businessDays.count { for rawI in 0 ..< businessDays.count {
if rawI == 0 {
//skip current day
continue
}
let i = (rawI + currentDayIndex) % businessDays.count
dayHeights += daySpacing dayHeights += daySpacing
var dayTransition = transition var dayTransition = transition

View File

@ -41,7 +41,7 @@ private func generateRingImage(color: UIColor, size: CGSize = CGSize(width: 40.0
}) })
} }
public func generatePeerNameColorImage(nameColor: PeerNameColors.Colors?, isDark: Bool, isLocked: Bool = false, bounds: CGSize = CGSize(width: 40.0, height: 40.0), size: CGSize = CGSize(width: 40.0, height: 40.0)) -> UIImage? { public func generatePeerNameColorImage(nameColor: PeerNameColors.Colors?, isDark: Bool, isLocked: Bool = false, isEmpty: Bool = false, bounds: CGSize = CGSize(width: 40.0, height: 40.0), size: CGSize = CGSize(width: 40.0, height: 40.0)) -> UIImage? {
return generateImage(bounds, rotatedContext: { contextSize, context in return generateImage(bounds, rotatedContext: { contextSize, context in
let bounds = CGRect(origin: CGPoint(), size: contextSize) let bounds = CGRect(origin: CGPoint(), size: contextSize)
context.clear(bounds) context.clear(bounds)
@ -105,6 +105,25 @@ public func generatePeerNameColorImage(nameColor: PeerNameColors.Colors?, isDark
context.scaleBy(x: 1.0, y: -1.0) context.scaleBy(x: 1.0, y: -1.0)
context.translateBy(x: -imageFrame.midX, y: -imageFrame.midY) context.translateBy(x: -imageFrame.midX, y: -imageFrame.midY)
if let cgImage = image.cgImage {
context.clip(to: imageFrame, mask: cgImage)
context.setFillColor(UIColor.clear.cgColor)
context.setBlendMode(.copy)
context.fill(imageFrame)
}
}
} else if isEmpty {
if let image = UIImage(bundleImageName: "Chat/Message/SideCloseIcon") {
let scaleFactor: CGFloat = 1.0
let imageSize = CGSize(width: floor(image.size.width * scaleFactor), height: floor(image.size.height * scaleFactor))
var imageFrame = CGRect(origin: CGPoint(x: circleBounds.minX + floor((circleBounds.width - imageSize.width) * 0.5), y: circleBounds.minY + floor((circleBounds.height - imageSize.height) * 0.5)), size: imageSize)
imageFrame.origin.y += 0.5
imageFrame.origin.x += 0.5
context.translateBy(x: imageFrame.midX, y: imageFrame.midY)
context.scaleBy(x: 1.0, y: -1.0)
context.translateBy(x: -imageFrame.midX, y: -imageFrame.midY)
if let cgImage = image.cgImage { if let cgImage = image.cgImage {
context.clip(to: imageFrame, mask: cgImage) context.clip(to: imageFrame, mask: cgImage)
context.setFillColor(UIColor.clear.cgColor) context.setFillColor(UIColor.clear.cgColor)
@ -212,7 +231,7 @@ private final class PeerNameColorIconItemNode : ASDisplayNode {
self.item = item self.item = item
if updatedAccentColor { if updatedAccentColor {
self.fillNode.image = generatePeerNameColorImage(nameColor: item.colors, isDark: item.isDark, isLocked: item.selected && item.isLocked, bounds: size, size: size) self.fillNode.image = generatePeerNameColorImage(nameColor: item.colors, isDark: item.isDark, isLocked: item.selected && item.isLocked, isEmpty: item.colors == nil, bounds: size, size: size)
self.ringNode.image = generateRingImage(color: item.colors?.main ?? UIColor(rgb: 0x798896), size: size) self.ringNode.image = generateRingImage(color: item.colors?.main ?? UIColor(rgb: 0x798896), size: size)
} }

View File

@ -252,6 +252,8 @@ final class ContactMultiselectionControllerNode: ASDisplayNode {
var searchGroups = false var searchGroups = false
var searchChannels = false var searchChannels = false
var globalSearch = false var globalSearch = false
var displaySavedMessages = true
var filters = filters
switch mode { switch mode {
case .groupCreation, .channelCreation: case .groupCreation, .channelCreation:
globalSearch = true globalSearch = true
@ -260,15 +262,31 @@ final class ContactMultiselectionControllerNode: ASDisplayNode {
searchGroups = searchGroupsValue searchGroups = searchGroupsValue
searchChannels = searchChannelsValue searchChannels = searchChannelsValue
globalSearch = true globalSearch = true
case .chatSelection: case let .chatSelection(chatSelection):
if chatSelection.onlyUsers {
searchChatList = true
searchGroups = false
searchChannels = false
displaySavedMessages = false
filters.append(.excludeSelf)
} else {
searchChatList = true searchChatList = true
searchGroups = true searchGroups = true
searchChannels = true searchChannels = true
}
globalSearch = false globalSearch = false
case .premiumGifting, .requestedUsersSelection: case .premiumGifting, .requestedUsersSelection:
searchChatList = true searchChatList = true
} }
let searchResultsNode = ContactListNode(context: context, presentation: .single(.search(signal: searchText.get(), searchChatList: searchChatList, searchDeviceContacts: false, searchGroups: searchGroups, searchChannels: searchChannels, globalSearch: globalSearch)), filters: filters, onlyWriteable: strongSelf.onlyWriteable, isPeerEnabled: strongSelf.isPeerEnabled, selectionState: selectionState, isSearch: true) let searchResultsNode = ContactListNode(context: context, presentation: .single(.search(ContactListPresentation.Search(
signal: searchText.get(),
searchChatList: searchChatList,
searchDeviceContacts: false,
searchGroups: searchGroups,
searchChannels: searchChannels,
globalSearch: globalSearch,
displaySavedMessages: displaySavedMessages
))), filters: filters, onlyWriteable: strongSelf.onlyWriteable, isPeerEnabled: strongSelf.isPeerEnabled, selectionState: selectionState, isSearch: true)
searchResultsNode.openPeer = { peer, _ in searchResultsNode.openPeer = { peer, _ in
self?.tokenListNode.setText("") self?.tokenListNode.setText("")
self?.openPeer?(peer) self?.openPeer?(peer)