diff --git a/submodules/CallListUI/Sources/CallListCallItem.swift b/submodules/CallListUI/Sources/CallListCallItem.swift index f865d86219..da270f6aa8 100644 --- a/submodules/CallListUI/Sources/CallListCallItem.swift +++ b/submodules/CallListUI/Sources/CallListCallItem.swift @@ -197,6 +197,7 @@ class CallListCallItemNode: ItemListRevealOptionsItemNode { private let avatarNode: AvatarNode private let titleNode: TextNode + private var credibilityIconNode: ASImageNode? private let statusNode: TextNode private let dateNode: TextNode private let typeIconNode: ASImageNode @@ -475,7 +476,26 @@ class CallListCallItemNode: ItemListRevealOptionsItemNode { let (dateLayout, dateApply) = makeDateLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: dateText, font: dateFont, textColor: item.presentationData.theme.list.itemSecondaryTextColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: max(0.0, params.width - leftInset - rightInset), height: CGFloat.infinity), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) - let (titleLayout, titleApply) = makeTitleLayout(TextNodeLayoutArguments(attributedString: titleAttributedString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: max(0.0, params.width - leftInset - dateRightInset - dateLayout.size.width - (item.editing ? -30.0 : 10.0)), height: CGFloat.infinity), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) + let premiumConfiguration = PremiumConfiguration.with(appConfiguration: item.context.currentAppConfiguration.with { $0 }) + var currentCredibilityIconImage: UIImage? + if let peer = item.topMessage.peers[item.topMessage.id.peerId], peer.id != item.context.account.peerId { + if peer.isScam { + currentCredibilityIconImage = PresentationResourcesChatList.scamIcon(item.presentationData.theme, strings: item.presentationData.strings, type: .regular) + } else if peer.isFake { + currentCredibilityIconImage = PresentationResourcesChatList.fakeIcon(item.presentationData.theme, strings: item.presentationData.strings, type: .regular) + } else if peer.isVerified { + currentCredibilityIconImage = PresentationResourcesChatList.verifiedIcon(item.presentationData.theme) + } else if peer.isPremium && !premiumConfiguration.isPremiumDisabled { + currentCredibilityIconImage = PresentationResourcesChatList.premiumIcon(item.presentationData.theme) + } + } + + var additionalTitleInset: CGFloat = 0.0 + if let currentCredibilityIconImage = currentCredibilityIconImage { + additionalTitleInset += 3.0 + currentCredibilityIconImage.size.width + } + + let (titleLayout, titleApply) = makeTitleLayout(TextNodeLayoutArguments(attributedString: titleAttributedString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: max(0.0, params.width - additionalTitleInset - leftInset - dateRightInset - dateLayout.size.width - (item.editing ? -30.0 : 10.0)), height: CGFloat.infinity), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) let (statusLayout, statusApply) = makeStatusLayout(TextNodeLayoutArguments(attributedString: statusAttributedString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: max(0.0, params.width - leftInset - dateRightInset - dateLayout.size.width - (item.editing ? -30.0 : 10.0)), height: CGFloat.infinity), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) @@ -614,11 +634,31 @@ class CallListCallItemNode: ItemListRevealOptionsItemNode { transition.updateFrameAdditive(node: strongSelf.avatarNode, frame: CGRect(origin: CGPoint(x: revealOffset + leftInset - 52.0, y: floor((contentSize.height - avatarDiameter) / 2.0)), size: CGSize(width: avatarDiameter, height: avatarDiameter))) let _ = titleApply() - transition.updateFrameAdditive(node: strongSelf.titleNode, frame: CGRect(origin: CGPoint(x: revealOffset + leftInset, y: verticalInset), size: titleLayout.size)) + let titleFrame = CGRect(origin: CGPoint(x: revealOffset + leftInset, y: verticalInset), size: titleLayout.size) + transition.updateFrameAdditive(node: strongSelf.titleNode, frame: titleFrame) let _ = statusApply() transition.updateFrameAdditive(node: strongSelf.statusNode, frame: CGRect(origin: CGPoint(x: revealOffset + leftInset, y: strongSelf.titleNode.frame.maxY + titleSpacing), size: statusLayout.size)) + if let currentCredibilityIconImage = currentCredibilityIconImage { + let iconNode: ASImageNode + if let current = strongSelf.credibilityIconNode { + iconNode = current + } else { + iconNode = ASImageNode() + iconNode.isLayerBacked = true + iconNode.displaysAsynchronously = false + iconNode.displayWithoutProcessing = true + strongSelf.containerNode.addSubnode(iconNode) + strongSelf.credibilityIconNode = iconNode + } + iconNode.image = currentCredibilityIconImage + transition.updateFrame(node: iconNode, frame: CGRect(origin: CGPoint(x: titleFrame.maxX + 4.0, y: floorToScreenPixels(titleFrame.midY - currentCredibilityIconImage.size.height / 2.0) - UIScreenPixel), size: currentCredibilityIconImage.size)) + } else if let credibilityIconNode = strongSelf.credibilityIconNode { + strongSelf.credibilityIconNode = nil + credibilityIconNode.removeFromSupernode() + } + let _ = dateApply() transition.updateFrameAdditive(node: strongSelf.dateNode, frame: CGRect(origin: CGPoint(x: editingOffset + revealOffset + params.width - dateRightInset - dateLayout.size.width, y: floor((nodeLayout.contentSize.height - dateLayout.size.height) / 2.0) + 2.0), size: dateLayout.size)) diff --git a/submodules/ChatListUI/Sources/ChatListController.swift b/submodules/ChatListUI/Sources/ChatListController.swift index 1b86e0e6ee..8cd265b4c0 100644 --- a/submodules/ChatListUI/Sources/ChatListController.swift +++ b/submodules/ChatListUI/Sources/ChatListController.swift @@ -267,22 +267,15 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController let isFirstFilter = strongSelf.chatListDisplayNode.containerNode.currentItemNode.chatListFilter == strongSelf.chatListDisplayNode.containerNode.availableFilters.first?.filter if offset <= navigationBarSearchContentHeight + 1.0 && !isFirstFilter { - let _ = (strongSelf.context.engine.peers.currentChatListFilters() - |> deliverOnMainQueue).start(next: { [weak self] filters in - guard let strongSelf = self else { - return - } - let targetTab: ChatListFilterTabEntryId - let firstFilter = filters.first ?? .allChats - switch firstFilter { - case .allChats: - targetTab = .all - case let .filter(id, _, _, _): - targetTab = .filter(id) - } - - strongSelf.selectTab(id: targetTab) - }) + let firstFilter = strongSelf.chatListDisplayNode.containerNode.availableFilters.first ?? .all + let targetTab: ChatListFilterTabEntryId + switch firstFilter { + case .all: + targetTab = .all + case let .filter(filter): + targetTab = .filter(filter.id) + } + strongSelf.selectTab(id: targetTab) } else { if let searchContentNode = strongSelf.searchContentNode { searchContentNode.updateExpansionProgress(1.0, animated: true) @@ -1262,11 +1255,11 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController strongSelf.setToolbar(toolbar, transition: transition) })) - self.tabContainerNode.tabSelected = { [weak self] id, disabled in + self.tabContainerNode.tabSelected = { [weak self] id, isDisabled in guard let strongSelf = self else { return } - if disabled { + if isDisabled { let context = strongSelf.context var replaceImpl: ((ViewController) -> Void)? let controller = PremiumLimitScreen(context: context, subject: .folders, count: strongSelf.tabContainerNode.filtersCount, action: { @@ -1296,7 +1289,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController } } - let tabContextGesture: (Int32?, ContextExtractedContentContainingNode, ContextGesture, Bool) -> Void = { [weak self] id, sourceNode, gesture, keepInPlace in + let tabContextGesture: (Int32?, ContextExtractedContentContainingNode, ContextGesture, Bool, Bool) -> Void = { [weak self] id, sourceNode, gesture, keepInPlace, isDisabled in guard let strongSelf = self else { return } @@ -1319,24 +1312,37 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController guard let strongSelf = self else { return } - let _ = (strongSelf.context.engine.peers.currentChatListFilters() - |> deliverOnMainQueue).start(next: { presetList in - guard let strongSelf = self else { - return + if isDisabled { + let context = strongSelf.context + var replaceImpl: ((ViewController) -> Void)? + let controller = PremiumLimitScreen(context: context, subject: .folders, count: strongSelf.tabContainerNode.filtersCount, action: { + let controller = PremiumIntroScreen(context: context, source: .folders) + replaceImpl?(controller) + }) + replaceImpl = { [weak controller] c in + controller?.replace(with: c) } - var found = false - for filter in presetList { - if filter.id == id { - strongSelf.push(chatListFilterPresetController(context: strongSelf.context, currentPreset: filter, updated: { _ in })) - f(.dismissWithoutContent) - found = true - break + strongSelf.push(controller) + } else { + let _ = (strongSelf.context.engine.peers.currentChatListFilters() + |> deliverOnMainQueue).start(next: { presetList in + guard let strongSelf = self else { + return } - } - if !found { - f(.default) - } - }) + var found = false + for filter in presetList { + if filter.id == id { + strongSelf.push(chatListFilterPresetController(context: strongSelf.context, currentPreset: filter, updated: { _ in })) + f(.dismissWithoutContent) + found = true + break + } + } + if !found { + f(.default) + } + }) + } }) }))) @@ -1349,62 +1355,75 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController return } - let _ = combineLatest( - queue: Queue.mainQueue(), - context.engine.data.get( - TelegramEngine.EngineData.Item.Peer.Peer(id: context.account.peerId), - TelegramEngine.EngineData.Item.Configuration.UserLimits(isPremium: false), - TelegramEngine.EngineData.Item.Configuration.UserLimits(isPremium: true) - ), - strongSelf.context.engine.peers.currentChatListFilters() - ).start(next: { result, presetList in - guard let strongSelf = self else { - return + if isDisabled { + let context = strongSelf.context + var replaceImpl: ((ViewController) -> Void)? + let controller = PremiumLimitScreen(context: context, subject: .folders, count: strongSelf.tabContainerNode.filtersCount, action: { + let controller = PremiumIntroScreen(context: context, source: .folders) + replaceImpl?(controller) + }) + replaceImpl = { [weak controller] c in + controller?.replace(with: c) } - var found = false - for filter in presetList { - if filter.id == id, case let .filter(_, _, _, data) = filter { - let (accountPeer, limits, premiumLimits) = result - let isPremium = accountPeer?.isPremium ?? false - - let limit = limits.maxFolderChatsCount - let premiumLimit = premiumLimits.maxFolderChatsCount - - if data.includePeers.peers.count >= premiumLimit { - let controller = PremiumLimitScreen(context: context, subject: .chatsPerFolder, count: Int32(data.includePeers.peers.count), action: {}) - strongSelf.push(controller) - f(.dismissWithoutContent) - return - } else if data.includePeers.peers.count >= limit && !isPremium { - var replaceImpl: ((ViewController) -> Void)? - let controller = PremiumLimitScreen(context: context, subject: .chatsPerFolder, count: Int32(data.includePeers.peers.count), action: { - let controller = PremiumIntroScreen(context: context, source: .chatsPerFolder) - replaceImpl?(controller) - }) - replaceImpl = { [weak controller] c in - controller?.replace(with: c) - } - strongSelf.push(controller) - f(.dismissWithoutContent) - return - } - - let _ = (strongSelf.context.engine.peers.currentChatListFilters() - |> deliverOnMainQueue).start(next: { filters in - guard let strongSelf = self else { + strongSelf.push(controller) + } else { + let _ = combineLatest( + queue: Queue.mainQueue(), + context.engine.data.get( + TelegramEngine.EngineData.Item.Peer.Peer(id: context.account.peerId), + TelegramEngine.EngineData.Item.Configuration.UserLimits(isPremium: false), + TelegramEngine.EngineData.Item.Configuration.UserLimits(isPremium: true) + ), + strongSelf.context.engine.peers.currentChatListFilters() + ).start(next: { result, presetList in + guard let strongSelf = self else { + return + } + var found = false + for filter in presetList { + if filter.id == id, case let .filter(_, _, _, data) = filter { + let (accountPeer, limits, premiumLimits) = result + let isPremium = accountPeer?.isPremium ?? false + + let limit = limits.maxFolderChatsCount + let premiumLimit = premiumLimits.maxFolderChatsCount + + if data.includePeers.peers.count >= premiumLimit { + let controller = PremiumLimitScreen(context: context, subject: .chatsPerFolder, count: Int32(data.includePeers.peers.count), action: {}) + strongSelf.push(controller) + f(.dismissWithoutContent) + return + } else if data.includePeers.peers.count >= limit && !isPremium { + var replaceImpl: ((ViewController) -> Void)? + let controller = PremiumLimitScreen(context: context, subject: .chatsPerFolder, count: Int32(data.includePeers.peers.count), action: { + let controller = PremiumIntroScreen(context: context, source: .chatsPerFolder) + replaceImpl?(controller) + }) + replaceImpl = { [weak controller] c in + controller?.replace(with: c) + } + strongSelf.push(controller) + f(.dismissWithoutContent) return } - strongSelf.push(chatListFilterAddChatsController(context: strongSelf.context, filter: filter, allFilters: filters, limit: limits.maxFolderChatsCount, premiumLimit: premiumLimits.maxFolderChatsCount, isPremium: isPremium)) - f(.dismissWithoutContent) - }) - found = true - break + + let _ = (strongSelf.context.engine.peers.currentChatListFilters() + |> deliverOnMainQueue).start(next: { filters in + guard let strongSelf = self else { + return + } + strongSelf.push(chatListFilterAddChatsController(context: strongSelf.context, filter: filter, allFilters: filters, limit: limits.maxFolderChatsCount, premiumLimit: premiumLimits.maxFolderChatsCount, isPremium: isPremium)) + f(.dismissWithoutContent) + }) + found = true + break + } } - } - if !found { - f(.default) - } - }) + if !found { + f(.default) + } + }) + } }) }))) @@ -1472,11 +1491,11 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController strongSelf.context.sharedContext.mainWindow?.presentInGlobalOverlay(controller) }) } - self.tabContainerNode.contextGesture = { id, sourceNode, gesture in - tabContextGesture(id, sourceNode, gesture, false) + self.tabContainerNode.contextGesture = { id, sourceNode, gesture, isDisabled in + tabContextGesture(id, sourceNode, gesture, false, isDisabled) } - self.chatListDisplayNode.inlineTabContainerNode.contextGesture = { id, sourceNode, gesture in - tabContextGesture(id, sourceNode, gesture, true) + self.chatListDisplayNode.inlineTabContainerNode.contextGesture = { id, sourceNode, gesture, isDisabled in + tabContextGesture(id, sourceNode, gesture, true, isDisabled) } if case .group = self.groupId { diff --git a/submodules/ChatListUI/Sources/ChatListFilterTabContainerNode.swift b/submodules/ChatListUI/Sources/ChatListFilterTabContainerNode.swift index 38803090f6..a752b1ec32 100644 --- a/submodules/ChatListUI/Sources/ChatListFilterTabContainerNode.swift +++ b/submodules/ChatListUI/Sources/ChatListFilterTabContainerNode.swift @@ -88,7 +88,7 @@ private final class ItemNode: ASDisplayNode { private var theme: PresentationTheme? - init(pressed: @escaping (Bool) -> Void, requestedDeletion: @escaping () -> Void, contextGesture: @escaping (ContextExtractedContentContainingNode, ContextGesture) -> Void) { + init(pressed: @escaping (Bool) -> Void, requestedDeletion: @escaping () -> Void, contextGesture: @escaping (ContextExtractedContentContainingNode, ContextGesture, Bool) -> Void) { self.pressed = pressed self.requestedDeletion = requestedDeletion @@ -170,7 +170,7 @@ private final class ItemNode: ASDisplayNode { guard let strongSelf = self else { return } - contextGesture(strongSelf.extractedContainerNode, gesture) + contextGesture(strongSelf.extractedContainerNode, gesture, strongSelf.isDisabled) } self.extractedContainerNode.willUpdateIsExtractedToContextPreview = { [weak self] isExtracted, transition in @@ -467,7 +467,7 @@ final class ChatListFilterTabContainerNode: ASDisplayNode { var tabSelected: ((ChatListFilterTabEntryId, Bool) -> Void)? var tabRequestedDeletion: ((ChatListFilterTabEntryId) -> Void)? var addFilter: (() -> Void)? - var contextGesture: ((Int32?, ContextExtractedContentContainingNode, ContextGesture) -> Void)? + var contextGesture: ((Int32?, ContextExtractedContentContainingNode, ContextGesture, Bool) -> Void)? private var reorderingGesture: ReorderingGestureRecognizer? private var reorderingItem: ChatListFilterTabEntryId? @@ -739,7 +739,7 @@ final class ChatListFilterTabContainerNode: ASDisplayNode { self?.tabSelected?(filter.id, disabled) }, requestedDeletion: { [weak self] in self?.tabRequestedDeletion?(filter.id) - }, contextGesture: { [weak self] sourceNode, gesture in + }, contextGesture: { [weak self] sourceNode, gesture, isDisabled in guard let strongSelf = self else { return } @@ -748,9 +748,9 @@ final class ChatListFilterTabContainerNode: ASDisplayNode { strongSelf.scrollNode.view.setContentOffset(strongSelf.scrollNode.view.contentOffset, animated: false) switch filter { case let .filter(id, _, _): - strongSelf.contextGesture?(id, sourceNode, gesture) + strongSelf.contextGesture?(id, sourceNode, gesture, isDisabled) default: - strongSelf.contextGesture?(nil, sourceNode, gesture) + strongSelf.contextGesture?(nil, sourceNode, gesture, isDisabled) } }) self.itemNodes[filter.id] = itemNode diff --git a/submodules/ChatListUI/Sources/ChatListFilterTabInlineContainerNode.swift b/submodules/ChatListUI/Sources/ChatListFilterTabInlineContainerNode.swift index c001b7d82b..52aeae5ffb 100644 --- a/submodules/ChatListUI/Sources/ChatListFilterTabInlineContainerNode.swift +++ b/submodules/ChatListUI/Sources/ChatListFilterTabInlineContainerNode.swift @@ -374,7 +374,7 @@ final class ChatListFilterTabInlineContainerNode: ASDisplayNode { var tabSelected: ((ChatListFilterTabEntryId) -> Void)? var tabRequestedDeletion: ((ChatListFilterTabEntryId) -> Void)? var addFilter: (() -> Void)? - var contextGesture: ((Int32?, ContextExtractedContentContainingNode, ContextGesture) -> Void)? + var contextGesture: ((Int32?, ContextExtractedContentContainingNode, ContextGesture, Bool) -> Void)? private var reorderingGesture: ReorderingGestureRecognizer? private var reorderingItem: ChatListFilterTabEntryId? @@ -653,9 +653,9 @@ final class ChatListFilterTabInlineContainerNode: ASDisplayNode { strongSelf.scrollNode.view.setContentOffset(strongSelf.scrollNode.view.contentOffset, animated: false) switch filter { case let .filter(id, _, _): - strongSelf.contextGesture?(id, sourceNode, gesture) + strongSelf.contextGesture?(id, sourceNode, gesture, false) default: - strongSelf.contextGesture?(nil, sourceNode, gesture) + strongSelf.contextGesture?(nil, sourceNode, gesture, false) } }), highlighted: ItemNode(pressed: { [weak self] in self?.tabSelected?(filter.id) @@ -670,9 +670,9 @@ final class ChatListFilterTabInlineContainerNode: ASDisplayNode { strongSelf.scrollNode.view.panGestureRecognizer.isEnabled = false strongSelf.scrollNode.view.panGestureRecognizer.isEnabled = true strongSelf.scrollNode.view.setContentOffset(strongSelf.scrollNode.view.contentOffset, animated: false) - strongSelf.contextGesture?(id, sourceNode, gesture) + strongSelf.contextGesture?(id, sourceNode, gesture, false) default: - strongSelf.contextGesture?(nil, sourceNode, gesture) + strongSelf.contextGesture?(nil, sourceNode, gesture, false) } })) self.itemNodePairs[filter.id] = itemNodePair diff --git a/submodules/Components/ReactionListContextMenuContent/Sources/ReactionListContextMenuContent.swift b/submodules/Components/ReactionListContextMenuContent/Sources/ReactionListContextMenuContent.swift index 9a518fb453..35cfffdea9 100644 --- a/submodules/Components/ReactionListContextMenuContent/Sources/ReactionListContextMenuContent.swift +++ b/submodules/Components/ReactionListContextMenuContent/Sources/ReactionListContextMenuContent.swift @@ -290,6 +290,7 @@ public final class ReactionListContextMenuContent: ContextControllerItemsContent let highlightBackgroundNode: ASDisplayNode let avatarNode: AvatarNode let titleLabelNode: ImmediateTextNode + var credibilityIconNode: ASImageNode? let separatorNode: ASDisplayNode var reactionIconNode: ReactionImageNode? let action: () -> Void @@ -368,6 +369,24 @@ public final class ReactionListContextMenuContent: ContextControllerItemsContent self.accessibilityLabel = "\(item.peer.debugDisplayTitle) \(item.reaction ?? "")" } + let premiumConfiguration = PremiumConfiguration.with(appConfiguration: self.context.currentAppConfiguration.with { $0 }) + var currentCredibilityIconImage: UIImage? + if item.peer.id != self.context.account.peerId { + if item.peer.isScam { + currentCredibilityIconImage = PresentationResourcesChatList.scamIcon(presentationData.theme, strings: presentationData.strings, type: .regular) + } else if item.peer.isFake { + currentCredibilityIconImage = PresentationResourcesChatList.fakeIcon(presentationData.theme, strings: presentationData.strings, type: .regular) + } else if item.peer.isVerified { + currentCredibilityIconImage = PresentationResourcesChatList.verifiedIcon(presentationData.theme) + } else if item.peer.isPremium && !premiumConfiguration.isPremiumDisabled { + currentCredibilityIconImage = PresentationResourcesChatList.premiumIcon(presentationData.theme) + } + } + var additionalTitleInset: CGFloat = 0.0 + if let currentCredibilityIconImage = currentCredibilityIconImage { + additionalTitleInset += 3.0 + currentCredibilityIconImage.size.width + } + self.highlightBackgroundNode.backgroundColor = presentationData.theme.contextMenu.itemHighlightedBackgroundColor self.separatorNode.backgroundColor = presentationData.theme.contextMenu.itemSeparatorColor @@ -377,12 +396,32 @@ public final class ReactionListContextMenuContent: ContextControllerItemsContent self.avatarNode.setPeer(context: self.context, theme: presentationData.theme, peer: item.peer, synchronousLoad: true) self.titleLabelNode.attributedText = NSAttributedString(string: item.peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder), font: Font.regular(17.0), textColor: presentationData.theme.contextMenu.primaryColor) - var maxTextWidth: CGFloat = size.width - avatarInset - avatarSize - avatarSpacing - sideInset + var maxTextWidth: CGFloat = size.width - avatarInset - avatarSize - avatarSpacing - sideInset - additionalTitleInset if reactionIconNode != nil { maxTextWidth -= 32.0 } let titleSize = self.titleLabelNode.updateLayout(CGSize(width: maxTextWidth, height: 100.0)) - self.titleLabelNode.frame = CGRect(origin: CGPoint(x: avatarInset + avatarSize + avatarSpacing, y: floor((size.height - titleSize.height) / 2.0)), size: titleSize) + let titleFrame = CGRect(origin: CGPoint(x: avatarInset + avatarSize + avatarSpacing, y: floor((size.height - titleSize.height) / 2.0)), size: titleSize) + self.titleLabelNode.frame = titleFrame + + if let currentCredibilityIconImage = currentCredibilityIconImage { + let iconNode: ASImageNode + if let current = self.credibilityIconNode { + iconNode = current + } else { + iconNode = ASImageNode() + iconNode.isLayerBacked = true + iconNode.displaysAsynchronously = false + iconNode.displayWithoutProcessing = true + self.addSubnode(iconNode) + self.credibilityIconNode = iconNode + } + iconNode.image = currentCredibilityIconImage + iconNode.frame = CGRect(origin: CGPoint(x: titleFrame.maxX + 4.0, y: floorToScreenPixels(titleFrame.midY - currentCredibilityIconImage.size.height / 2.0) + 1.0 - UIScreenPixel), size: currentCredibilityIconImage.size) + } else if let credibilityIconNode = self.credibilityIconNode { + self.credibilityIconNode = nil + credibilityIconNode.removeFromSupernode() + } if let reactionIconNode = self.reactionIconNode { let reactionSize = CGSize(width: 22.0, height: 22.0) diff --git a/submodules/ContactsPeerItem/Sources/ContactsPeerItem.swift b/submodules/ContactsPeerItem/Sources/ContactsPeerItem.swift index 88f45371b6..70bd21072f 100644 --- a/submodules/ContactsPeerItem/Sources/ContactsPeerItem.swift +++ b/submodules/ContactsPeerItem/Sources/ContactsPeerItem.swift @@ -334,7 +334,6 @@ public class ContactsPeerItemNode: ItemListRevealOptionsItemNode { private let avatarNode: AvatarNode private let titleNode: TextNode private var credibilityIconNode: ASImageNode? - private var verificationIconNode: ASImageNode? private let statusNode: TextNode private var badgeBackgroundNode: ASImageNode? private var badgeTextNode: TextNode?