diff --git a/Telegram/Telegram-iOS/en.lproj/Localizable.strings b/Telegram/Telegram-iOS/en.lproj/Localizable.strings index 41e48e97c8..59f136027c 100644 --- a/Telegram/Telegram-iOS/en.lproj/Localizable.strings +++ b/Telegram/Telegram-iOS/en.lproj/Localizable.strings @@ -8295,10 +8295,10 @@ Sorry for the inconvenience."; "Notification.ForumTopicHidden" = "Topic hidden"; "Notification.ForumTopicUnhidden" = "Topic unhidden"; -"Notification.ForumTopicHiddenAuthor" = "%1$@ hidden topic"; -"Notification.ForumTopicUnhiddenAuthor" = "%1$@ unhidden topic"; -"Notification.OverviewTopicHidden" = "%1$@ hidden %2$@ %3$@"; -"Notification.OverviewTopicUnhidden" = "%1$@ unhidden %2$@ %3$@"; +"Notification.ForumTopicHiddenAuthor" = "%1$@ hid topic"; +"Notification.ForumTopicUnhiddenAuthor" = "%1$@ unhid topic"; +"Notification.OverviewTopicHidden" = "%1$@ hid %2$@ %3$@"; +"Notification.OverviewTopicUnhidden" = "%1$@ unhid %2$@ %3$@"; "CreateTopic.ShowGeneral" = "Show in Topics"; "CreateTopic.ShowGeneralInfo" = "If the 'General' topic is hidden, group members can pull down in the topic list to view it."; diff --git a/submodules/ChatListUI/Sources/ChatContextMenus.swift b/submodules/ChatListUI/Sources/ChatContextMenus.swift index 9cb7a38ad3..d5164abb3a 100644 --- a/submodules/ChatListUI/Sources/ChatContextMenus.swift +++ b/submodules/ChatListUI/Sources/ChatContextMenus.swift @@ -512,14 +512,14 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId: var items: [ContextMenuItem] = [] - if let isClosed = isClosed, isClosed { + if let isClosed = isClosed, isClosed && threadId != 1 { } else { if let isPinned = isPinned, channel.hasPermission(.manageTopics) { items.append(.action(ContextMenuActionItem(text: isPinned ? presentationData.strings.ChatList_Context_Unpin : presentationData.strings.ChatList_Context_Pin, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: isPinned ? "Chat/Context Menu/Unpin": "Chat/Context Menu/Pin"), color: theme.contextMenu.primaryColor) }, action: { _, f in f(.default) let _ = (context.engine.peers.toggleForumChannelTopicPinned(id: peerId, threadId: threadId) - |> deliverOnMainQueue).start(error: { error in + |> deliverOnMainQueue).start(error: { error in switch error { case let .limitReached(count): if let chatListController = chatListController { diff --git a/submodules/GalleryUI/Sources/Items/ChatImageGalleryItem.swift b/submodules/GalleryUI/Sources/Items/ChatImageGalleryItem.swift index 392584de68..1d5f95c3de 100644 --- a/submodules/GalleryUI/Sources/Items/ChatImageGalleryItem.swift +++ b/submodules/GalleryUI/Sources/Items/ChatImageGalleryItem.swift @@ -338,75 +338,75 @@ final class ChatImageGalleryItemNode: ZoomableContentGalleryItemNode { case .medium, .full: strongSelf.statusNodeContainer.isHidden = true -// Queue.concurrentDefaultQueue().async { -// if let message = strongSelf.message, !message.isCopyProtected() && !imageReference.media.flags.contains(.hasStickers) { -// strongSelf.recognitionDisposable.set((recognizedContent(engine: strongSelf.context.engine, image: { return generate(TransformImageArguments(corners: ImageCorners(), imageSize: displaySize, boundingSize: displaySize, intrinsicInsets: UIEdgeInsets()))?.generateImage() }, messageId: message.id) -// |> deliverOnMainQueue).start(next: { [weak self] results in -// if let strongSelf = self { -// strongSelf.recognizedContentNode?.removeFromSupernode() -// if !results.isEmpty { -// let size = strongSelf.imageNode.bounds.size -// let recognizedContentNode = RecognizedContentContainer(size: size, recognitions: results, presentationData: strongSelf.context.sharedContext.currentPresentationData.with { $0 }, present: { [weak self] c, a in -// if let strongSelf = self { -// strongSelf.galleryController()?.presentInGlobalOverlay(c, with: a) -// } -// }, performAction: { [weak self] string, action in -// guard let strongSelf = self else { -// return -// } -// switch action { -// case .copy: -// UIPasteboard.general.string = string -// if let controller = strongSelf.baseNavigationController()?.topViewController as? ViewController { -// let presentationData = strongSelf.context.sharedContext.currentPresentationData.with({ $0 }) -// let tooltipController = UndoOverlayController(presentationData: presentationData, content: .copy(text: presentationData.strings.Conversation_TextCopied), elevatedLayout: true, animateInAsReplacement: false, action: { _ in return false }) -// controller.present(tooltipController, in: .window(.root)) -// } -// case .share: -// if let controller = strongSelf.baseNavigationController()?.topViewController as? ViewController { -// let shareController = ShareController(context: strongSelf.context, subject: .text(string), externalShare: true, immediateExternalShare: false, updatedPresentationData: (strongSelf.context.sharedContext.currentPresentationData.with({ $0 }), strongSelf.context.sharedContext.presentationData)) -// controller.present(shareController, in: .window(.root)) -// } -// case .lookup: -// let controller = UIReferenceLibraryViewController(term: string) -// if let window = strongSelf.baseNavigationController()?.view.window { -// controller.popoverPresentationController?.sourceView = window -// controller.popoverPresentationController?.sourceRect = CGRect(origin: CGPoint(x: window.bounds.width / 2.0, y: window.bounds.size.height - 1.0), size: CGSize(width: 1.0, height: 1.0)) -// window.rootViewController?.present(controller, animated: true) -// } -// case .speak: -// let _ = speakText(context: strongSelf.context, text: string) -// case .translate: -// if let parentController = strongSelf.baseNavigationController()?.topViewController as? ViewController { -// let controller = TranslateScreen(context: strongSelf.context, text: string, fromLanguage: nil) -// controller.pushController = { [weak parentController] c in -// (parentController?.navigationController as? NavigationController)?._keepModalDismissProgress = true -// parentController?.push(c) -// } -// controller.presentController = { [weak parentController] c in -// parentController?.present(c, in: .window(.root)) -// } -// parentController.present(controller, in: .window(.root)) -// } -// } -// }) -// recognizedContentNode.barcodeAction = { [weak self] payload, rect in -// guard let strongSelf = self, let message = strongSelf.message else { -// return -// } -// strongSelf.footerContentNode.openActionOptions?(.url(url: payload, concealed: true), message) -// } -// recognizedContentNode.alpha = 0.0 -// recognizedContentNode.frame = CGRect(origin: CGPoint(), size: size) -// recognizedContentNode.update(size: strongSelf.imageNode.bounds.size, transition: .immediate) -// strongSelf.imageNode.addSubnode(recognizedContentNode) -// strongSelf.recognizedContentNode = recognizedContentNode -// strongSelf.recognitionOverlayContentNode.transitionIn() -// } -// } -// })) -// } -// } + Queue.concurrentDefaultQueue().async { + if let message = strongSelf.message, !message.isCopyProtected() && !imageReference.media.flags.contains(.hasStickers) { + strongSelf.recognitionDisposable.set((recognizedContent(engine: strongSelf.context.engine, image: { return generate(TransformImageArguments(corners: ImageCorners(), imageSize: displaySize, boundingSize: displaySize, intrinsicInsets: UIEdgeInsets()))?.generateImage() }, messageId: message.id) + |> deliverOnMainQueue).start(next: { [weak self] results in + if let strongSelf = self { + strongSelf.recognizedContentNode?.removeFromSupernode() + if !results.isEmpty { + let size = strongSelf.imageNode.bounds.size + let recognizedContentNode = RecognizedContentContainer(size: size, recognitions: results, presentationData: strongSelf.context.sharedContext.currentPresentationData.with { $0 }, present: { [weak self] c, a in + if let strongSelf = self { + strongSelf.galleryController()?.presentInGlobalOverlay(c, with: a) + } + }, performAction: { [weak self] string, action in + guard let strongSelf = self else { + return + } + switch action { + case .copy: + UIPasteboard.general.string = string + if let controller = strongSelf.baseNavigationController()?.topViewController as? ViewController { + let presentationData = strongSelf.context.sharedContext.currentPresentationData.with({ $0 }) + let tooltipController = UndoOverlayController(presentationData: presentationData, content: .copy(text: presentationData.strings.Conversation_TextCopied), elevatedLayout: true, animateInAsReplacement: false, action: { _ in return false }) + controller.present(tooltipController, in: .window(.root)) + } + case .share: + if let controller = strongSelf.baseNavigationController()?.topViewController as? ViewController { + let shareController = ShareController(context: strongSelf.context, subject: .text(string), externalShare: true, immediateExternalShare: false, updatedPresentationData: (strongSelf.context.sharedContext.currentPresentationData.with({ $0 }), strongSelf.context.sharedContext.presentationData)) + controller.present(shareController, in: .window(.root)) + } + case .lookup: + let controller = UIReferenceLibraryViewController(term: string) + if let window = strongSelf.baseNavigationController()?.view.window { + controller.popoverPresentationController?.sourceView = window + controller.popoverPresentationController?.sourceRect = CGRect(origin: CGPoint(x: window.bounds.width / 2.0, y: window.bounds.size.height - 1.0), size: CGSize(width: 1.0, height: 1.0)) + window.rootViewController?.present(controller, animated: true) + } + case .speak: + let _ = speakText(context: strongSelf.context, text: string) + case .translate: + if let parentController = strongSelf.baseNavigationController()?.topViewController as? ViewController { + let controller = TranslateScreen(context: strongSelf.context, text: string, canCopy: true, fromLanguage: nil) + controller.pushController = { [weak parentController] c in + (parentController?.navigationController as? NavigationController)?._keepModalDismissProgress = true + parentController?.push(c) + } + controller.presentController = { [weak parentController] c in + parentController?.present(c, in: .window(.root)) + } + parentController.present(controller, in: .window(.root)) + } + } + }) + recognizedContentNode.barcodeAction = { [weak self] payload, rect in + guard let strongSelf = self, let message = strongSelf.message else { + return + } + strongSelf.footerContentNode.openActionOptions?(.url(url: payload, concealed: true), message) + } + recognizedContentNode.alpha = 0.0 + recognizedContentNode.frame = CGRect(origin: CGPoint(), size: size) + recognizedContentNode.update(size: strongSelf.imageNode.bounds.size, transition: .immediate) + strongSelf.imageNode.addSubnode(recognizedContentNode) + strongSelf.recognizedContentNode = recognizedContentNode + strongSelf.recognitionOverlayContentNode.transitionIn() + } + } + })) + } + } case .none, .blurred: strongSelf.statusNodeContainer.isHidden = false @@ -1353,6 +1353,9 @@ private class ImageRecognitionOverlayContentNode: GalleryOverlayContentNode { var action: ((Bool) -> Void)? private var appeared = false + private var validLayout: (CGSize, LayoutMetrics, UIEdgeInsets)? + private var interfaceIsHidden: Bool = false + init(theme: PresentationTheme) { self.backgroundNode = ASImageNode() self.backgroundNode.displaysAsynchronously = false @@ -1377,13 +1380,25 @@ private class ImageRecognitionOverlayContentNode: GalleryOverlayContentNode { self.selectedIconNode.isHidden = true super.init() - + self.buttonNode.addTarget(self, action: #selector(self.buttonPressed), forControlEvents: .touchUpInside) self.addSubnode(self.buttonNode) self.buttonNode.addSubnode(self.backgroundNode) self.buttonNode.addSubnode(self.selectedBackgroundNode) self.buttonNode.addSubnode(self.iconNode) self.buttonNode.addSubnode(self.selectedIconNode) + + self.buttonNode.highligthedChanged = { [weak self] highlighted in + if let strongSelf = self { + if highlighted { + strongSelf.iconNode.layer.removeAnimation(forKey: "opacity") + strongSelf.iconNode.alpha = 0.4 + } else { + strongSelf.iconNode.alpha = 1.0 + strongSelf.iconNode.layer.animateAlpha(from: 0.4, to: 1.0, duration: 0.2) + } + } + } } @objc private func buttonPressed() { @@ -1392,6 +1407,10 @@ private class ImageRecognitionOverlayContentNode: GalleryOverlayContentNode { self.selectedBackgroundNode.isHidden = !newValue self.selectedIconNode.isHidden = !newValue + if !newValue && !self.interfaceIsHidden, let (size, metrics, insets) = self.validLayout { + self.updateLayout(size: size, metrics: metrics, insets: insets, isHidden: self.interfaceIsHidden, transition: .animated(duration: 0.3, curve: .easeInOut)) + } + self.action?(newValue) if self.interfaceIsHidden && !newValue { @@ -1409,8 +1428,9 @@ private class ImageRecognitionOverlayContentNode: GalleryOverlayContentNode { self.buttonNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2) } - private var interfaceIsHidden: Bool = false override func updateLayout(size: CGSize, metrics: LayoutMetrics, insets: UIEdgeInsets, isHidden: Bool, transition: ContainedViewLayoutTransition) { + self.validLayout = (size, metrics, insets) + self.interfaceIsHidden = isHidden let buttonSize = CGSize(width: 32.0, height: 32.0) @@ -1427,7 +1447,14 @@ private class ImageRecognitionOverlayContentNode: GalleryOverlayContentNode { } } - transition.updateFrame(node: self.buttonNode, frame: CGRect(x: size.width - insets.right - buttonSize.width - 24.0, y: insets.top - 50.0, width: buttonSize.width + 24.0, height: buttonSize.height + 24.0)) + var buttonPosition: CGPoint + if isHidden && !self.buttonNode.isSelected { + buttonPosition = CGPoint(x: size.width - insets.right - buttonSize.width - 59.0, y: -50.0) + } else { + buttonPosition = CGPoint(x: size.width - insets.right - buttonSize.width - (self.buttonNode.isSelected ? 24.0 : 59.0), y: insets.top - 50.0) + } + + transition.updateFrame(node: self.buttonNode, frame: CGRect(origin: buttonPosition, size: CGSize(width: buttonSize.width + 24.0, height: buttonSize.height + 24.0))) } override func animateIn(previousContentNode: GalleryOverlayContentNode?, transition: ContainedViewLayoutTransition) { diff --git a/submodules/PeerInfoUI/Sources/ChannelAdminsController.swift b/submodules/PeerInfoUI/Sources/ChannelAdminsController.swift index cfd304e885..8e02cb0aa3 100644 --- a/submodules/PeerInfoUI/Sources/ChannelAdminsController.swift +++ b/submodules/PeerInfoUI/Sources/ChannelAdminsController.swift @@ -338,7 +338,7 @@ private struct ChannelAdminsControllerState: Equatable { } } -private func channelAdminsControllerEntries(presentationData: PresentationData, accountPeerId: PeerId, view: PeerView, state: ChannelAdminsControllerState, participants: [RenderedChannelParticipant]?, antiSpamEnabled: Bool) -> [ChannelAdminsEntry] { +private func channelAdminsControllerEntries(presentationData: PresentationData, accountPeerId: PeerId, view: PeerView, state: ChannelAdminsControllerState, participants: [RenderedChannelParticipant]?, antiSpamAvailable: Bool, antiSpamEnabled: Bool) -> [ChannelAdminsEntry] { if participants == nil || participants?.count == nil { return [] } @@ -351,7 +351,7 @@ private func channelAdminsControllerEntries(presentationData: PresentationData, } entries.append(.recentActions(presentationData.theme, presentationData.strings.Group_Info_AdminLog)) - if isGroup && peer.hasPermission(.deleteAllMessages) { + if isGroup && peer.hasPermission(.deleteAllMessages) && antiSpamAvailable { entries.append(.antiSpam(presentationData.theme, presentationData.strings.Group_Management_AntiSpam, antiSpamEnabled)) entries.append(.antiSpamInfo(presentationData.theme, presentationData.strings.Group_Management_AntiSpamInfo)) } @@ -539,10 +539,10 @@ public func channelAdminsController(context: AccountContext, updatedPresentation let adminsPromise = Promise<[RenderedChannelParticipant]?>(nil) - let antiSpamBotConfiguration = AntiSpamBotConfiguration.with(appConfiguration: context.currentAppConfiguration.with { $0 }) + let antiSpamConfiguration = AntiSpamBotConfiguration.with(appConfiguration: context.currentAppConfiguration.with { $0 }) let resolveAntiSpamPeerDisposable = MetaDisposable() - if let antiSpamBotId = antiSpamBotConfiguration.antiSpamBotId { + if let antiSpamBotId = antiSpamConfiguration.antiSpamBotId { resolveAntiSpamPeerDisposable.set( (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: antiSpamBotId)) |> mapToSignal { peer -> Signal in @@ -786,6 +786,11 @@ public func channelAdminsController(context: AccountContext, updatedPresentation |> map { presentationData, state, view, admins, antiSpamEnabled -> (ItemListControllerState, (ItemListNodeState, Any)) in let peerId = view.peerId + var antiSpamAvailable = false + if let cachedData = view.cachedData as? CachedChannelData, let memberCount = cachedData.participantsSummary.memberCount, memberCount >= antiSpamConfiguration.minimumGroupParticipants { + antiSpamAvailable = true + } + var rightNavigationButton: ItemListNavigationButton? var secondaryRightNavigationButton: ItemListNavigationButton? if let admins = admins, admins.count > 1 { @@ -857,7 +862,7 @@ public func channelAdminsController(context: AccountContext, updatedPresentation } let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text(isGroup ? presentationData.strings.ChatAdmins_Title : presentationData.strings.Channel_Management_Title), leftNavigationButton: nil, rightNavigationButton: rightNavigationButton, secondaryRightNavigationButton: secondaryRightNavigationButton, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: true) - let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: channelAdminsControllerEntries(presentationData: presentationData, accountPeerId: context.account.peerId, view: view, state: state, participants: admins, antiSpamEnabled: antiSpamEnabled), style: .blocks, emptyStateItem: emptyStateItem, searchItem: searchItem, animateChanges: previous != nil && admins != nil && previous!.count >= admins!.count) + let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: channelAdminsControllerEntries(presentationData: presentationData, accountPeerId: context.account.peerId, view: view, state: state, participants: admins, antiSpamAvailable: antiSpamAvailable, antiSpamEnabled: antiSpamEnabled), style: .blocks, emptyStateItem: emptyStateItem, searchItem: searchItem, animateChanges: previous != nil && admins != nil && previous!.count >= admins!.count) return (controllerState, (listState, arguments)) } |> afterDisposed { diff --git a/submodules/TelegramCore/Sources/ForumChannels.swift b/submodules/TelegramCore/Sources/ForumChannels.swift index 4dc641bc55..5aca44d338 100644 --- a/submodules/TelegramCore/Sources/ForumChannels.swift +++ b/submodules/TelegramCore/Sources/ForumChannels.swift @@ -340,13 +340,7 @@ func _internal_setForumChannelTopicClosed(account: Account, id: EnginePeer.Id, t } var flags: Int32 = 0 flags |= (1 << 2) - - var hidden: Api.Bool? = nil - if threadId == 1, !isClosed { - flags |= (1 << 3) - hidden = .boolFalse - } - + return account.network.request(Api.functions.channels.editForumTopic( flags: flags, channel: inputChannel, @@ -354,7 +348,7 @@ func _internal_setForumChannelTopicClosed(account: Account, id: EnginePeer.Id, t title: nil, iconEmojiId: nil, closed: isClosed ? .boolTrue : .boolFalse, - hidden: hidden + hidden: nil )) |> mapError { _ -> EditForumChannelTopicError in return .generic @@ -367,7 +361,7 @@ func _internal_setForumChannelTopicClosed(account: Account, id: EnginePeer.Id, t var data = initialData data.isClosed = isClosed - if let _ = hidden { + if !isClosed && threadId == 1 { data.isHidden = false } diff --git a/submodules/TelegramUI/Sources/ChatBotInfoItem.swift b/submodules/TelegramUI/Sources/ChatBotInfoItem.swift index fccd6bdaf1..b32b40b6f0 100644 --- a/submodules/TelegramUI/Sources/ChatBotInfoItem.swift +++ b/submodules/TelegramUI/Sources/ChatBotInfoItem.swift @@ -457,7 +457,7 @@ final class ChatBotInfoItemNode: ListViewItemNode { let _ = (item.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)) |> deliverOnMainQueue).start(next: { [weak self] peer in if let peer = peer { - self?.item?.controllerInteraction.openPeer(peer, .chat(textInputState: nil, subject: nil, peekData: nil), nil, false) + self?.item?.controllerInteraction.openPeer(peer, .chat(textInputState: nil, subject: nil, peekData: nil), nil, .default) } }) } diff --git a/submodules/TelegramUI/Sources/ChatButtonKeyboardInputNode.swift b/submodules/TelegramUI/Sources/ChatButtonKeyboardInputNode.swift index fa08c95905..f49c0a7b9b 100644 --- a/submodules/TelegramUI/Sources/ChatButtonKeyboardInputNode.swift +++ b/submodules/TelegramUI/Sources/ChatButtonKeyboardInputNode.swift @@ -409,7 +409,7 @@ final class ChatButtonKeyboardInputNode: ChatInputNode { peer = botPeer } if let peer = peer, let botPeer = botPeer, let addressName = botPeer.addressName { - self.controllerInteraction.openPeer(EnginePeer(peer), .chat(textInputState: ChatTextInputState(inputText: NSAttributedString(string: "@\(addressName) \(query)")), subject: nil, peekData: nil), nil, false) + self.controllerInteraction.openPeer(EnginePeer(peer), .chat(textInputState: ChatTextInputState(inputText: NSAttributedString(string: "@\(addressName) \(query)")), subject: nil, peekData: nil), nil, .default) } } case .payment: @@ -426,7 +426,7 @@ final class ChatButtonKeyboardInputNode: ChatInputNode { guard let self, let peer else { return } - self.controllerInteraction.openPeer(peer, .info, nil, false) + self.controllerInteraction.openPeer(peer, .info, nil, .default) }) case let .openWebView(url, simple): self.controllerInteraction.openWebView(markupButton.title, url, simple, false) diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index b8b889c4b1..b915cdb102 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -926,7 +926,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } }, openPeer: { [weak self] peer in if let strongSelf = self { - strongSelf.controllerInteraction?.openPeer(peer, .default, nil, false) + strongSelf.controllerInteraction?.openPeer(peer, .default, nil, .default) } }, openHashtag: { [weak self] peerName, hashtag in if let strongSelf = self { @@ -995,8 +995,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } }) }))) - }, openPeer: { [weak self] peer, navigation, fromMessage, isReaction in - self?.openPeer(peer: peer, navigation: navigation, fromMessage: fromMessage, fromReactionMessageId: isReaction ? fromMessage?.id : nil) + }, openPeer: { [weak self] peer, navigation, fromMessage, source in + self?.openPeer(peer: peer, navigation: navigation, fromMessage: fromMessage, fromReactionMessageId: source == .reaction ? fromMessage?.id : nil, expandAvatar: source == .groupParticipant) }, openPeerMention: { [weak self] name in self?.openPeerMention(name) }, openMessageContextMenu: { [weak self] message, selectAll, node, frame, anyRecognizer, location in @@ -13224,7 +13224,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)) |> deliverOnMainQueue).start(next: { peer in if let strongSelf = self, let peer = peer { - strongSelf.controllerInteraction?.openPeer(peer, .default, nil, false) + strongSelf.controllerInteraction?.openPeer(peer, .default, nil, .default) } }) case .longTap: @@ -13317,7 +13317,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)) |> deliverOnMainQueue).start(next: { peer in if let strongSelf = self, let peer = peer { - strongSelf.controllerInteraction?.openPeer(peer, .default, nil, false) + strongSelf.controllerInteraction?.openPeer(peer, .default, nil, .default) } }) case .longTap: @@ -13431,7 +13431,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)) |> deliverOnMainQueue).start(next: { peer in if let strongSelf = self, let peer = peer { - strongSelf.controllerInteraction?.openPeer(peer, .default, nil, false) + strongSelf.controllerInteraction?.openPeer(peer, .default, nil, .default) } }) case .longTap: diff --git a/submodules/TelegramUI/Sources/ChatControllerInteraction.swift b/submodules/TelegramUI/Sources/ChatControllerInteraction.swift index 1d91664249..14b6a9e014 100644 --- a/submodules/TelegramUI/Sources/ChatControllerInteraction.swift +++ b/submodules/TelegramUI/Sources/ChatControllerInteraction.swift @@ -60,8 +60,14 @@ struct UnreadMessageRangeKey: Hashable { } public final class ChatControllerInteraction { + enum OpenPeerSource { + case `default` + case reaction + case groupParticipant + } + let openMessage: (Message, ChatControllerInteractionOpenMessageMode) -> Bool - let openPeer: (EnginePeer, ChatControllerInteractionNavigateToPeer, MessageReference?, Bool) -> Void + let openPeer: (EnginePeer, ChatControllerInteractionNavigateToPeer, MessageReference?, OpenPeerSource) -> Void let openPeerMention: (String) -> Void let openMessageContextMenu: (Message, Bool, ASDisplayNode, CGRect, UIGestureRecognizer?, CGPoint?) -> Void let updateMessageReaction: (Message, ChatControllerInteractionReaction) -> Void @@ -170,7 +176,7 @@ public final class ChatControllerInteraction { init( openMessage: @escaping (Message, ChatControllerInteractionOpenMessageMode) -> Bool, - openPeer: @escaping (EnginePeer, ChatControllerInteractionNavigateToPeer, MessageReference?, Bool) -> Void, + openPeer: @escaping (EnginePeer, ChatControllerInteractionNavigateToPeer, MessageReference?, OpenPeerSource) -> Void, openPeerMention: @escaping (String) -> Void, openMessageContextMenu: @escaping (Message, Bool, ASDisplayNode, CGRect, UIGestureRecognizer?, CGPoint?) -> Void, openMessageReactionContextMenu: @escaping (Message, ContextExtractedContentContainingView, ContextGesture?, MessageReaction.Reaction) -> Void, diff --git a/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift b/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift index f5a706d479..496a1a4957 100644 --- a/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift +++ b/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift @@ -1689,7 +1689,7 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState actions.insert(.custom(ChatReadReportContextItem(context: context, message: message, hasReadReports: hasReadReports, stats: readStats, action: { c, f, stats, customReactionEmojiPacks, firstCustomEmojiReaction in if reactionCount == 0, let stats = stats, stats.peers.count == 1 { c.dismiss(completion: { - controllerInteraction.openPeer(stats.peers[0], .default, nil, false) + controllerInteraction.openPeer(stats.peers[0], .default, nil, .default) }) } else if (stats != nil && !stats!.peers.isEmpty) || reactionCount != 0 { var tip: ContextController.Tip? @@ -1733,7 +1733,7 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState }, openPeer: { [weak c] peer in c?.dismiss(completion: { - controllerInteraction.openPeer(peer, .default, MessageReference(message), true) + controllerInteraction.openPeer(peer, .default, MessageReference(message), .reaction) }) } )), tip: tip))) diff --git a/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift index d35aca0391..62340e33f6 100644 --- a/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift @@ -2112,7 +2112,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { } item.controllerInteraction.navigateToMessage(item.message.id, sourceMessageId) } else if let peer = forwardInfo.source ?? forwardInfo.author { - item.controllerInteraction.openPeer(EnginePeer(peer), peer is TelegramUser ? .info : .chat(textInputState: nil, subject: nil, peekData: nil), nil, false) + item.controllerInteraction.openPeer(EnginePeer(peer), peer is TelegramUser ? .info : .chat(textInputState: nil, subject: nil, peekData: nil), nil, .default) } else if let _ = forwardInfo.authorSignature { item.controllerInteraction.displayMessageTooltip(item.message.id, item.presentationData.strings.Conversation_ForwardAuthorHiddenTooltip, forwardInfoNode, nil) } diff --git a/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift index e11b2da899..8cbed73017 100644 --- a/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift @@ -3567,7 +3567,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode } else { return .optionalAction({ if let peer = item.message.peers[peerId] { - item.controllerInteraction.openPeer(EnginePeer(peer), .chat(textInputState: nil, subject: nil, peekData: nil), nil, false) + item.controllerInteraction.openPeer(EnginePeer(peer), .chat(textInputState: nil, subject: nil, peekData: nil), nil, .default) } }) } @@ -3610,7 +3610,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode } item.controllerInteraction.navigateToMessage(item.message.id, sourceMessageId) } else if let peer = forwardInfo.source ?? forwardInfo.author { - item.controllerInteraction.openPeer(EnginePeer(peer), peer is TelegramUser ? .info : .chat(textInputState: nil, subject: nil, peekData: nil), nil, false) + item.controllerInteraction.openPeer(EnginePeer(peer), peer is TelegramUser ? .info : .chat(textInputState: nil, subject: nil, peekData: nil), nil, .default) } else if let _ = forwardInfo.authorSignature { item.controllerInteraction.displayMessageTooltip(item.message.id, item.presentationData.strings.Conversation_ForwardAuthorHiddenTooltip, forwardInfoNode, nil) } @@ -3653,7 +3653,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode let _ = (item.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)) |> deliverOnMainQueue).start(next: { peer in if let self = self, let item = self.item, let peer = peer { - item.controllerInteraction.openPeer(peer, .chat(textInputState: nil, subject: nil, peekData: nil), nil, false) + item.controllerInteraction.openPeer(peer, .chat(textInputState: nil, subject: nil, peekData: nil), nil, .default) } }) } diff --git a/submodules/TelegramUI/Sources/ChatMessageDateHeader.swift b/submodules/TelegramUI/Sources/ChatMessageDateHeader.swift index 655c937f3b..151de3f2f1 100644 --- a/submodules/TelegramUI/Sources/ChatMessageDateHeader.swift +++ b/submodules/TelegramUI/Sources/ChatMessageDateHeader.swift @@ -648,9 +648,9 @@ final class ChatMessageAvatarHeaderNode: ListViewItemHeaderNode { self.controllerInteraction.activateAdAction(adMessageId) } else { if let channel = peer as? TelegramChannel, case .broadcast = channel.info { - self.controllerInteraction.openPeer(EnginePeer(peer), .chat(textInputState: nil, subject: nil, peekData: nil), self.messageReference, false) + self.controllerInteraction.openPeer(EnginePeer(peer), .chat(textInputState: nil, subject: nil, peekData: nil), self.messageReference, .default) } else { - self.controllerInteraction.openPeer(EnginePeer(peer), .info, self.messageReference, false) + self.controllerInteraction.openPeer(EnginePeer(peer), .info, self.messageReference, .groupParticipant) } } } diff --git a/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift index 13392f8999..5b41b6856b 100644 --- a/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift @@ -927,7 +927,7 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView, UIGestureRecognizerD } item.controllerInteraction.navigateToMessage(item.message.id, sourceMessageId) } else if let peer = forwardInfo.source ?? forwardInfo.author { - item.controllerInteraction.openPeer(EnginePeer(peer), peer is TelegramUser ? .info : .chat(textInputState: nil, subject: nil, peekData: nil), nil, false) + item.controllerInteraction.openPeer(EnginePeer(peer), peer is TelegramUser ? .info : .chat(textInputState: nil, subject: nil, peekData: nil), nil, .default) } else if let _ = forwardInfo.authorSignature { item.controllerInteraction.displayMessageTooltip(item.message.id, item.presentationData.strings.Conversation_ForwardAuthorHiddenTooltip, forwardInfoNode, nil) } diff --git a/submodules/TelegramUI/Sources/ChatMessageInteractiveInstantVideoNode.swift b/submodules/TelegramUI/Sources/ChatMessageInteractiveInstantVideoNode.swift index a18c097ab0..ce827ebb8a 100644 --- a/submodules/TelegramUI/Sources/ChatMessageInteractiveInstantVideoNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageInteractiveInstantVideoNode.swift @@ -1247,7 +1247,7 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode { item.controllerInteraction.navigateToMessage(item.message.id, sourceMessageId) return } else if let peer = forwardInfo.source ?? forwardInfo.author { - item.controllerInteraction.openPeer(EnginePeer(peer), peer is TelegramUser ? .info : .chat(textInputState: nil, subject: nil, peekData: nil), nil, false) + item.controllerInteraction.openPeer(EnginePeer(peer), peer is TelegramUser ? .info : .chat(textInputState: nil, subject: nil, peekData: nil), nil, .default) return } else if let _ = forwardInfo.authorSignature { item.controllerInteraction.displayMessageTooltip(item.message.id, item.presentationData.strings.Conversation_ForwardAuthorHiddenTooltip, forwardInfoNode, nil) diff --git a/submodules/TelegramUI/Sources/ChatMessageItemView.swift b/submodules/TelegramUI/Sources/ChatMessageItemView.swift index 549e1668fa..99fc9c78a8 100644 --- a/submodules/TelegramUI/Sources/ChatMessageItemView.swift +++ b/submodules/TelegramUI/Sources/ChatMessageItemView.swift @@ -855,7 +855,7 @@ public class ChatMessageItemView: ListViewItemNode, ChatMessageItemNodeProtocol let _ = (item.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)) |> deliverOnMainQueue).start(next: { peer in if let peer = peer { - item.controllerInteraction.openPeer(peer, .info, nil, false) + item.controllerInteraction.openPeer(peer, .info, nil, .default) } }) case let .openWebView(url, simple): diff --git a/submodules/TelegramUI/Sources/ChatPinnedMessageTitlePanelNode.swift b/submodules/TelegramUI/Sources/ChatPinnedMessageTitlePanelNode.swift index 6f139097d7..691833356b 100644 --- a/submodules/TelegramUI/Sources/ChatPinnedMessageTitlePanelNode.swift +++ b/submodules/TelegramUI/Sources/ChatPinnedMessageTitlePanelNode.swift @@ -854,7 +854,7 @@ final class ChatPinnedMessageTitlePanelNode: ChatTitleAccessoryPanelNode { let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)) |> deliverOnMainQueue).start(next: { peer in if let peer = peer { - controllerInteraction.openPeer(peer, .info, nil, false) + controllerInteraction.openPeer(peer, .info, nil, .default) } }) case let .openWebView(url, simple): diff --git a/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoGroupsInCommonPaneNode.swift b/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoGroupsInCommonPaneNode.swift index e7e6f19ff1..f3c856d0e8 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoGroupsInCommonPaneNode.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoGroupsInCommonPaneNode.swift @@ -186,7 +186,7 @@ final class PeerInfoGroupsInCommonPaneNode: ASDisplayNode, PeerInfoPaneNode { } } let transaction = preparedTransition(from: self.currentEntries, to: entries, context: self.context, presentationData: presentationData, openPeer: { [weak self] peer in - self?.chatControllerInteraction.openPeer(EnginePeer(peer), .default, nil, false) + self?.chatControllerInteraction.openPeer(EnginePeer(peer), .default, nil, .default) }, openPeerContextAction: { [weak self] peer, node, gesture in self?.openPeerContextAction(peer, node, gesture) }) diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift index 47811f9687..b5b3bbe1c0 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift @@ -2666,7 +2666,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate let items: [ContextMenuItem] = [ .action(ContextMenuActionItem(text: presentationData.strings.Conversation_LinkDialogOpen, icon: { _ in nil }, action: { _, f in f(.dismissWithoutContent) - self?.chatInterfaceInteraction.openPeer(EnginePeer(peer), .default, nil, false) + self?.chatInterfaceInteraction.openPeer(EnginePeer(peer), .default, nil, .default) })) ] let contextController = ContextController(account: strongSelf.context.account, presentationData: presentationData, source: .controller(ContextControllerContentSourceImpl(controller: chatController, sourceNode: node)), items: .single(ContextController.Items(content: .list(items))), gesture: gesture)