From 7927493e2fefeb32e44e6a93e54f1d2657aab83a Mon Sep 17 00:00:00 2001 From: Ali <> Date: Fri, 27 Mar 2020 20:27:16 +0400 Subject: [PATCH 1/6] Check bazel version in wallet_env --- wallet_env.sh | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/wallet_env.sh b/wallet_env.sh index 57b7fdddf1..1ec7b2a210 100755 --- a/wallet_env.sh +++ b/wallet_env.sh @@ -1,5 +1,25 @@ #!/bin/sh +set -e + +REQUIRED_BAZEL_VERSION="$(cat build-system/bazel_version)" + +if which bazel >/dev/null 2>&1; then + export BAZEL="$(which bazel)" +else + echo "bazel not found in PATH" + echo "Please download bazel version $REQUIRED_BAZEL_VERSION:" + echo "https://github.com/bazelbuild/bazel/releases" + exit 1 +fi + +BAZEL_VERSION="$($BAZEL --version | sed -e 's/^bazel '//)" + +if [ "$BAZEL_VERSION" != "$REQUIRED_BAZEL_VERSION" ]; then + echo "Required bazel version is \"$REQUIRED_BAZEL_VERSION\", you have \"$BAZEL_VERSION\" installed ($BAZEL)" + exit 1 +fi + if [ "$DEVELOPMENT_CODE_SIGN_IDENTITY" == "" ]; then echo "Set DEVELOPMENT_CODE_SIGN_IDENTITY to the name of a valid development certificate\nExample: export DEVELOPMENT_CODE_SIGN_IDENTITY=\"iPhone Developer: XXXXXXXXXX (XXXXXXXXXX)\"" exit 1 From a453f2d86edf03453e42df03bdbc223202cc3984 Mon Sep 17 00:00:00 2001 From: Ali <> Date: Tue, 31 Mar 2020 15:33:14 +0400 Subject: [PATCH 2/6] Post-release bug fixes --- Makefile | 2 +- buildbox/build-telegram.sh | 2 +- .../Sources/AnimatedStickerNode.swift | 13 +- .../ChatListFilterTabContainerNode.swift | 2 +- .../Sources/Node/ChatListItem.swift | 11 +- .../TabBarChatListFilterController.swift | 29 ++- .../ContextUI/Sources/ContextController.swift | 27 ++- .../Source/ContextControllerSourceNode.swift | 6 +- .../Display/Source/ContextGesture.swift | 4 +- .../TelegramUI/Sources/ChatBotInfoItem.swift | 2 +- .../ChatMessageAnimatedStickerItemNode.swift | 201 ++++++++++----- .../ChatMessageBubbleContentNode.swift | 1 + .../Sources/ChatMessageBubbleItemNode.swift | 16 +- .../ChatMessageInstantVideoItemNode.swift | 228 +++++++++++------- ...atMessageInteractiveInstantVideoNode.swift | 11 +- .../ChatMessagePollBubbleContentNode.swift | 3 +- .../Sources/ChatMessageStickerItemNode.swift | 170 +++++++++---- .../ContactMultiselectionControllerNode.swift | 15 +- .../Sources/ForwardAccessoryPanelNode.swift | 2 + .../ChatBubbleInstantVideoDecoration.swift | 8 +- 20 files changed, 502 insertions(+), 251 deletions(-) diff --git a/Makefile b/Makefile index 7c8dbd64b0..10e5f089c6 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ include Utils.makefile -APP_VERSION="6.0" +APP_VERSION="6.0.1" CORE_COUNT=$(shell sysctl -n hw.logicalcpu) CORE_COUNT_MINUS_ONE=$(shell expr ${CORE_COUNT} \- 1) diff --git a/buildbox/build-telegram.sh b/buildbox/build-telegram.sh index 3cd566c890..8a98f552d6 100644 --- a/buildbox/build-telegram.sh +++ b/buildbox/build-telegram.sh @@ -5,7 +5,7 @@ set -e BUILD_TELEGRAM_VERSION="1" MACOS_VERSION="10.15" -XCODE_VERSION="11.4" +XCODE_VERSION="11.2" GUEST_SHELL="bash" VM_BASE_NAME="macos$(echo $MACOS_VERSION | sed -e 's/\.'/_/g)_Xcode$(echo $XCODE_VERSION | sed -e 's/\.'/_/g)" diff --git a/submodules/AnimatedStickerNode/Sources/AnimatedStickerNode.swift b/submodules/AnimatedStickerNode/Sources/AnimatedStickerNode.swift index d072e2a7f2..13fc7fb465 100644 --- a/submodules/AnimatedStickerNode/Sources/AnimatedStickerNode.swift +++ b/submodules/AnimatedStickerNode/Sources/AnimatedStickerNode.swift @@ -30,9 +30,16 @@ private class AnimatedStickerNodeDisplayEvents: ASDisplayNode { override func didExitHierarchy() { super.didExitHierarchy() - if self.value { - self.value = false - self.updated?(false) + DispatchQueue.main.async { [weak self] in + guard let strongSelf = self else { + return + } + if !strongSelf.isInHierarchy { + if strongSelf.value { + strongSelf.value = false + strongSelf.updated?(false) + } + } } } } diff --git a/submodules/ChatListUI/Sources/ChatListFilterTabContainerNode.swift b/submodules/ChatListUI/Sources/ChatListFilterTabContainerNode.swift index 3efe36c618..d7c12d1c90 100644 --- a/submodules/ChatListUI/Sources/ChatListFilterTabContainerNode.swift +++ b/submodules/ChatListUI/Sources/ChatListFilterTabContainerNode.swift @@ -300,7 +300,7 @@ private final class ItemNode: ASDisplayNode { width = badgeBackgroundFrame.maxX } - return (width, shortTitleSize.width - self.shortTitleNode.insets.left - self.shortTitleNode.insets.right + 5.0) + return (width, shortTitleSize.width - self.shortTitleNode.insets.left - self.shortTitleNode.insets.right) } func updateArea(size: CGSize, sideInset: CGFloat, useShortTitle: Bool, transition: ContainedViewLayoutTransition) { diff --git a/submodules/ChatListUI/Sources/Node/ChatListItem.swift b/submodules/ChatListUI/Sources/Node/ChatListItem.swift index d480d67503..c7fb656660 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListItem.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListItem.swift @@ -715,7 +715,9 @@ class ChatListItemNode: ItemListRevealOptionsItemNode { } else { isRemovedFromTotalUnreadCount = isRemovedFromTotalUnreadCountValue } - peerPresence = peerPresenceValue + peerPresence = (peerPresenceValue as? TelegramUserPresence).flatMap { presence -> TelegramUserPresence in + TelegramUserPresence(status: presence.status, lastActivity: 0) + } embeddedState = embeddedStateValue summaryInfo = summaryInfoValue inputActivities = inputActivitiesValue @@ -1180,7 +1182,8 @@ class ChatListItemNode: ItemListRevealOptionsItemNode { switch item.content { case let .peer(_, renderedPeer, _, _, presence, _ ,_ ,_, _, _, displayAsMessage, _): if !displayAsMessage, let peer = renderedPeer.peer as? TelegramUser, let presence = presence as? TelegramUserPresence, !isServicePeer(peer) && !peer.flags.contains(.isSupport) && peer.id != item.context.account.peerId { - let relativeStatus = relativeUserPresenceStatus(presence, relativeTo: timestamp) + var updatedPresence = TelegramUserPresence(status: presence.status, lastActivity: 0) + let relativeStatus = relativeUserPresenceStatus(updatedPresence, relativeTo: timestamp) if case .online = relativeStatus { online = true } @@ -1608,7 +1611,7 @@ class ChatListItemNode: ItemListRevealOptionsItemNode { strongSelf.highlightedBackgroundNode.frame = CGRect(origin: CGPoint(x: 0.0, y: layoutOffset - separatorHeight - topNegativeInset), size: CGSize(width: layout.contentSize.width, height: layout.contentSize.height + separatorHeight + topNegativeInset)) if let peerPresence = peerPresence as? TelegramUserPresence { - strongSelf.peerPresenceManager?.reset(presence: peerPresence) + strongSelf.peerPresenceManager?.reset(presence: TelegramUserPresence(status: peerPresence.status, lastActivity: 0)) } strongSelf.updateLayout(size: layout.contentSize, leftInset: params.leftInset, rightInset: params.rightInset) @@ -1739,7 +1742,7 @@ class ChatListItemNode: ItemListRevealOptionsItemNode { transition.updateFrame(node: self.badgeNode, frame: updatedBadgeFrame) var mentionBadgeFrame = self.mentionBadgeNode.frame - if updatedBadgeFrame.width.isZero { + if updatedBadgeFrame.width.isZero || self.badgeNode.isHidden { mentionBadgeFrame.origin.x = updatedBadgeFrame.minX - mentionBadgeFrame.width } else { mentionBadgeFrame.origin.x = updatedBadgeFrame.minX - 6.0 - mentionBadgeFrame.width diff --git a/submodules/ChatListUI/Sources/TabBarChatListFilterController.swift b/submodules/ChatListUI/Sources/TabBarChatListFilterController.swift index 18d16492de..5ba23bbe7c 100644 --- a/submodules/ChatListUI/Sources/TabBarChatListFilterController.swift +++ b/submodules/ChatListUI/Sources/TabBarChatListFilterController.swift @@ -51,7 +51,7 @@ func chatListFilterItems(postbox: Postbox) -> Signal<(Int, [(ChatListFilter, Int var result: [(ChatListFilter, Int, Bool)] = [] - var peerTagAndCount: [PeerId: (PeerSummaryCounterTags, Int, Bool, PeerGroupId?)] = [:] + var peerTagAndCount: [PeerId: (PeerSummaryCounterTags, Int, Bool, PeerGroupId?, Bool)] = [:] var totalStates: [PeerGroupId: ChatListTotalUnreadState] = [:] for entry in unreadCounts.entries { @@ -71,9 +71,9 @@ func chatListFilterItems(postbox: Postbox) -> Signal<(Int, [(ChatListFilter, Int } if let notificationSettings = peerView.notificationSettings as? TelegramPeerNotificationSettings, case .muted = notificationSettings.muteState { - peerTagAndCount[peerId] = (tag, peerCount, false, peerView.groupId) + peerTagAndCount[peerId] = (tag, peerCount, false, peerView.groupId, true) } else { - peerTagAndCount[peerId] = (tag, peerCount, true, peerView.groupId) + peerTagAndCount[peerId] = (tag, peerCount, true, peerView.groupId, false) } } } @@ -147,8 +147,15 @@ func chatListFilterItems(postbox: Postbox) -> Signal<(Int, [(ChatListFilter, Int } } for peerId in filter.data.includePeers.peers { - if let (tag, peerCount, hasUnmuted, groupId) = peerTagAndCount[peerId] { - if let groupId = groupId, !tags.contains(tag) { + if let (tag, peerCount, hasUnmuted, groupIdValue, isMuted) = peerTagAndCount[peerId], peerCount != 0, let groupId = groupIdValue { + var matches = true + if tags.contains(tag) { + if isMuted && filter.data.excludeMuted { + } else { + matches = false + } + } + if matches { let matchesGroup: Bool switch groupId { case .root: @@ -170,8 +177,16 @@ func chatListFilterItems(postbox: Postbox) -> Signal<(Int, [(ChatListFilter, Int } } for peerId in filter.data.excludePeers { - if let (tag, peerCount, _, groupId) = peerTagAndCount[peerId] { - if let groupId = groupId, tags.contains(tag) { + if let (tag, peerCount, _, groupIdValue, isMuted) = peerTagAndCount[peerId], peerCount != 0, let groupId = groupIdValue { + var matches = true + if tags.contains(tag) { + if isMuted && filter.data.excludeMuted { + } else { + matches = false + } + } + + if matches { let matchesGroup: Bool switch groupId { case .root: diff --git a/submodules/ContextUI/Sources/ContextController.swift b/submodules/ContextUI/Sources/ContextController.swift index f820cf0255..c55e8b0359 100644 --- a/submodules/ContextUI/Sources/ContextController.swift +++ b/submodules/ContextUI/Sources/ContextController.swift @@ -512,8 +512,8 @@ private final class ContextControllerNode: ViewControllerTracingNode, UIScrollVi self.hapticFeedback.impact() switch self.source { - case let .extracted(source): - if let contentAreaInScreenSpace = self.contentAreaInScreenSpace, let maybeContentNode = self.contentContainerNode.contentNode, case let .extracted(_, keepInPlace) = maybeContentNode { + case .extracted: + if let contentAreaInScreenSpace = self.contentAreaInScreenSpace, let maybeContentNode = self.contentContainerNode.contentNode, case .extracted = maybeContentNode { var updatedContentAreaInScreenSpace = contentAreaInScreenSpace updatedContentAreaInScreenSpace.origin.x = 0.0 updatedContentAreaInScreenSpace.size.width = self.bounds.width @@ -553,7 +553,7 @@ private final class ContextControllerNode: ViewControllerTracingNode, UIScrollVi } self.effectView.effect = makeCustomZoomBlurEffect() self.effectView.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2 * animationDurationFactor) - self.propertyAnimator = UIViewPropertyAnimator(duration: 0.2 * animationDurationFactor * UIView.animationDurationFactor(), curve: .easeInOut, animations: { [weak self] in + self.propertyAnimator = UIViewPropertyAnimator(duration: 0.2 * animationDurationFactor * UIView.animationDurationFactor(), curve: .easeInOut, animations: { }) } @@ -601,7 +601,7 @@ private final class ContextControllerNode: ViewControllerTracingNode, UIScrollVi } self.actionsContainerNode.layer.animateSpring(from: NSValue(cgPoint: CGPoint(x: localSourceFrame.center.x - self.actionsContainerNode.position.x, y: localSourceFrame.center.y - self.actionsContainerNode.position.y)), to: NSValue(cgPoint: CGPoint()), keyPath: "position", duration: springDuration, initialVelocity: 0.0, damping: springDamping, additive: true) - let contentContainerOffset = CGPoint(x: localContentSourceFrame.center.x - self.contentContainerNode.frame.center.x - contentParentNode.contentRect.minX, y: localContentSourceFrame.center.y - self.contentContainerNode.frame.center.y) + let contentContainerOffset = CGPoint(x: localContentSourceFrame.center.x - self.contentContainerNode.frame.center.x - contentParentNode.contentRect.minX, y: localContentSourceFrame.center.y - self.contentContainerNode.frame.center.y - contentParentNode.contentRect.minY) self.contentContainerNode.layer.animateSpring(from: NSValue(cgPoint: contentContainerOffset), to: NSValue(cgPoint: CGPoint()), keyPath: "position", duration: springDuration, initialVelocity: 0.0, damping: springDamping, additive: true) contentParentNode.applyAbsoluteOffsetSpring?(-contentContainerOffset.y, springDuration, springDamping) } @@ -619,8 +619,6 @@ private final class ContextControllerNode: ViewControllerTracingNode, UIScrollVi }) if let originalProjectedContentViewFrame = self.originalProjectedContentViewFrame { - let actionsSideInset: CGFloat = (validLayout?.safeInsets.left ?? 0.0) + 11.0 - let localSourceFrame = self.view.convert(CGRect(origin: CGPoint(x: originalProjectedContentViewFrame.1.minX, y: originalProjectedContentViewFrame.1.minY), size: CGSize(width: originalProjectedContentViewFrame.1.width, height: originalProjectedContentViewFrame.1.height)), to: self.scrollNode.view) self.contentContainerNode.layer.animateSpring(from: min(localSourceFrame.width / self.contentContainerNode.frame.width, localSourceFrame.height / self.contentContainerNode.frame.height) as NSNumber, to: 1.0 as NSNumber, keyPath: "transform.scale", duration: springDuration, initialVelocity: 0.0, damping: springDamping) @@ -1121,13 +1119,13 @@ private final class ContextControllerNode: ViewControllerTracingNode, UIScrollVi let originalActionsY: CGFloat if keepInPlace { originalActionsY = originalProjectedContentViewFrame.1.minY - contentActionsSpacing - actionsSize.height - preferredActionsX = originalProjectedContentViewFrame.1.maxX - actionsSize.width + preferredActionsX = max(actionsSideInset, originalProjectedContentViewFrame.1.maxX - actionsSize.width) } else { originalActionsY = min(originalProjectedContentViewFrame.1.maxY + contentActionsSpacing, maximumActionsFrameOrigin) preferredActionsX = originalProjectedContentViewFrame.1.minX } var originalActionsFrame = CGRect(origin: CGPoint(x: max(actionsSideInset, min(layout.size.width - actionsSize.width - actionsSideInset, preferredActionsX)), y: originalActionsY), size: actionsSize) - var originalContentX: CGFloat = originalProjectedContentViewFrame.1.minX + let originalContentX: CGFloat = originalProjectedContentViewFrame.1.minX let originalContentY: CGFloat if keepInPlace { originalContentY = originalProjectedContentViewFrame.1.minY @@ -1152,15 +1150,26 @@ private final class ContextControllerNode: ViewControllerTracingNode, UIScrollVi } var overflowOffset: CGFloat - let contentContainerFrame: CGRect + var contentContainerFrame: CGRect if keepInPlace { overflowOffset = min(0.0, originalActionsFrame.minY - contentTopInset) contentContainerFrame = originalContentFrame.offsetBy(dx: -contentParentNode.contentRect.minX, dy: -contentParentNode.contentRect.minY) if keepInPlace && !overflowOffset.isZero { let offsetDelta = contentParentNode.contentRect.height + 4.0 overflowOffset += offsetDelta + overflowOffset = min(0.0, overflowOffset) + originalActionsFrame.origin.x -= contentParentNode.contentRect.maxX - contentParentNode.contentRect.minX + 14.0 + originalActionsFrame.origin.x = max(actionsSideInset, originalActionsFrame.origin.x) + //originalActionsFrame.origin.y += contentParentNode.contentRect.height + if originalActionsFrame.minX < contentContainerFrame.minX { + contentContainerFrame.origin.x = min(originalActionsFrame.maxX + 14.0, layout.size.width - actionsSideInset) + } originalActionsFrame.origin.y += offsetDelta + if originalActionsFrame.maxY < originalContentFrame.maxY { + originalActionsFrame.origin.y += contentParentNode.contentRect.height + originalActionsFrame.origin.y = min(originalActionsFrame.origin.y, layout.size.height - originalActionsFrame.height - actionsBottomInset) + } contentHeight -= offsetDelta } } else { diff --git a/submodules/Display/Source/ContextControllerSourceNode.swift b/submodules/Display/Source/ContextControllerSourceNode.swift index dbcd97a401..d9cb69e0d3 100644 --- a/submodules/Display/Source/ContextControllerSourceNode.swift +++ b/submodules/Display/Source/ContextControllerSourceNode.swift @@ -56,8 +56,8 @@ public final class ContextControllerSourceNode: ASDisplayNode { targetContentRect = CGRect(origin: CGPoint(), size: targetNode.bounds.size) } - let scaleSide = max(targetContentRect.width, targetContentRect.height) - let minScale: CGFloat = (scaleSide - 10.0) / scaleSide + let scaleSide = targetContentRect.width + let minScale: CGFloat = (scaleSide - 15.0) / scaleSide let currentScale = 1.0 * (1.0 - progress) + minScale * progress let originalCenterOffsetX: CGFloat = targetNode.bounds.width / 2.0 - targetContentRect.midX @@ -82,8 +82,6 @@ public final class ContextControllerSourceNode: ASDisplayNode { targetNode.layer.sublayerTransform = sublayerTransform targetNode.layer.animate(from: NSValue(caTransform3D: previousTransform), to: NSValue(caTransform3D: sublayerTransform), keyPath: "sublayerTransform", timingFunction: CAMediaTimingFunctionName.easeOut.rawValue, duration: 0.2) - - //targetNode.layer.animateSpring(from: previousScale as NSNumber, to: currentScale as NSNumber, keyPath: "sublayerTransform.scale", duration: 0.5, delay: 0.0, initialVelocity: 0.0, damping: 90.0) } } } diff --git a/submodules/Display/Source/ContextGesture.swift b/submodules/Display/Source/ContextGesture.swift index e325052136..818594b431 100644 --- a/submodules/Display/Source/ContextGesture.swift +++ b/submodules/Display/Source/ContextGesture.swift @@ -20,7 +20,7 @@ private class TimerTargetWrapper: NSObject { } } -private let beginDelay: Double = 0.1 +private let beginDelay: Double = 0.12 private func cancelParentGestures(view: UIView) { if let gestureRecognizers = view.gestureRecognizers { @@ -117,7 +117,7 @@ public final class ContextGesture: UIGestureRecognizer, UIGestureRecognizerDeleg } strongSelf.isValidated = true if strongSelf.animator == nil { - strongSelf.animator = DisplayLinkAnimator(duration: 0.3, from: 0.0, to: 1.0, update: { value in + strongSelf.animator = DisplayLinkAnimator(duration: 0.2, from: 0.0, to: 1.0, update: { value in guard let strongSelf = self else { return } diff --git a/submodules/TelegramUI/Sources/ChatBotInfoItem.swift b/submodules/TelegramUI/Sources/ChatBotInfoItem.swift index 7e6470fbf2..0b5a097f19 100644 --- a/submodules/TelegramUI/Sources/ChatBotInfoItem.swift +++ b/submodules/TelegramUI/Sources/ChatBotInfoItem.swift @@ -117,7 +117,7 @@ final class ChatBotInfoItemNode: ListViewItemNode { break case .ignore: return .fail - case .url, .peerMention, .textMention, .botCommand, .hashtag, .instantPage, .wallpaper, .theme, .call, .openMessage, .timecode, .bankCard, .tooltip: + case .url, .peerMention, .textMention, .botCommand, .hashtag, .instantPage, .wallpaper, .theme, .call, .openMessage, .timecode, .bankCard, .tooltip, .openPollResults: return .waitForSingleTap } } diff --git a/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift index 2a97553d1d..64244129be 100644 --- a/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift @@ -34,6 +34,7 @@ extension AnimatedStickerNode: GenericAnimatedStickerNode { class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { private let contextSourceNode: ContextExtractedContentContainingNode + private let containerNode: ContextControllerSourceNode let imageNode: TransformImageNode private var animationNode: GenericAnimatedStickerNode? private var didSetUpAnimationNode = false @@ -71,13 +72,54 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { required init() { self.contextSourceNode = ContextExtractedContentContainingNode() + self.containerNode = ContextControllerSourceNode() self.imageNode = TransformImageNode() self.dateAndStatusNode = ChatMessageDateAndStatusNode() super.init(layerBacked: false) + + self.containerNode.shouldBegin = { [weak self] location in + guard let strongSelf = self else { + return false + } + if !strongSelf.imageNode.frame.contains(location) { + return false + } + if let action = strongSelf.gestureRecognized(gesture: .tap, location: location, recognizer: nil) { + if case .action = action { + return false + } + } + if let action = strongSelf.gestureRecognized(gesture: .longTap, location: location, recognizer: nil) { + switch action { + case .action, .optionalAction: + return false + case .openContextMenu: + return true + } + } + return true + } + + self.containerNode.activated = { [weak self] gesture, location in + guard let strongSelf = self, let item = strongSelf.item else { + return + } + + if let action = strongSelf.gestureRecognized(gesture: .longTap, location: location, recognizer: nil) { + switch action { + case .action, .optionalAction: + break + case let .openContextMenu(tapMessage, selectAll, subFrame): + item.controllerInteraction.openMessageContextMenu(tapMessage, selectAll, strongSelf, subFrame, gesture) + } + } + } self.imageNode.displaysAsynchronously = false - self.addSubnode(self.contextSourceNode) + self.containerNode.addSubnode(self.contextSourceNode) + self.containerNode.targetNodeForActivationProgress = self.contextSourceNode.contentNode + self.addSubnode(self.containerNode) self.contextSourceNode.contentNode.addSubnode(self.imageNode) self.contextSourceNode.contentNode.addSubnode(self.dateAndStatusNode) } @@ -113,8 +155,17 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { return } //strongSelf.reactionRecognizer?.cancel() - if strongSelf.gestureRecognized(gesture: .longTap, location: point, recognizer: recognizer) { - recognizer.cancel() + if let action = strongSelf.gestureRecognized(gesture: .longTap, location: point, recognizer: recognizer) { + switch action { + case let .action(f): + f() + recognizer.cancel() + case let .optionalAction(f): + f() + recognizer.cancel() + case .openContextMenu: + break + } } } self.view.addGestureRecognizer(recognizer) @@ -655,6 +706,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { if let strongSelf = self { strongSelf.appliedForwardInfo = (forwardSource, forwardAuthorSignature) + strongSelf.containerNode.frame = CGRect(origin: CGPoint(), size: layoutSize) strongSelf.contextSourceNode.frame = CGRect(origin: CGPoint(), size: layoutSize) strongSelf.contextSourceNode.contentNode.frame = CGRect(origin: CGPoint(), size: layoutSize) @@ -677,6 +729,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { imageApply() strongSelf.contextSourceNode.contentRect = strongSelf.imageNode.frame + strongSelf.containerNode.targetNodeForActivationProgressContentRect = strongSelf.contextSourceNode.contentRect if let updatedShareButtonNode = updatedShareButtonNode { if updatedShareButtonNode !== strongSelf.shareButtonNode { @@ -855,48 +908,63 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { switch recognizer.state { case .ended: if let (gesture, location) = recognizer.lastRecognizedGestureAndLocation { - let _ = self.gestureRecognized(gesture: gesture, location: location, recognizer: nil) + if let action = self.gestureRecognized(gesture: gesture, location: location, recognizer: nil) { + if case .doubleTap = gesture { + self.containerNode.cancelGesture() + } + switch action { + case let .action(f): + f() + case let .optionalAction(f): + f() + case let .openContextMenu(tapMessage, selectAll, subFrame): + self.item?.controllerInteraction.openMessageContextMenu(tapMessage, selectAll, self, subFrame, nil) + } + } else if case .tap = gesture { + self.item?.controllerInteraction.clickThroughMessage() + } } default: break } } - private func gestureRecognized(gesture: TapLongTapOrDoubleTapGesture, location: CGPoint, recognizer: TapLongTapOrDoubleTapGestureRecognizer?) -> Bool { + private func gestureRecognized(gesture: TapLongTapOrDoubleTapGesture, location: CGPoint, recognizer: TapLongTapOrDoubleTapGestureRecognizer?) -> InternalBubbleTapAction? { switch gesture { case .tap: if let avatarNode = self.accessoryItemNode as? ChatMessageAvatarAccessoryItemNode, avatarNode.frame.contains(location) { if let item = self.item, let author = item.content.firstMessage.author { - var openPeerId = item.effectiveAuthorId ?? author.id - var navigate: ChatControllerInteractionNavigateToPeer - - if item.content.firstMessage.id.peerId == item.context.account.peerId { - navigate = .chat(textInputState: nil, subject: nil) - } else { - navigate = .info - } - - for attribute in item.content.firstMessage.attributes { - if let attribute = attribute as? SourceReferenceMessageAttribute { - openPeerId = attribute.messageId.peerId - navigate = .chat(textInputState: nil, subject: .message(attribute.messageId)) + return .optionalAction({ + var openPeerId = item.effectiveAuthorId ?? author.id + var navigate: ChatControllerInteractionNavigateToPeer + + if item.content.firstMessage.id.peerId == item.context.account.peerId { + navigate = .chat(textInputState: nil, subject: nil) + } else { + navigate = .info } - } - - if item.effectiveAuthorId?.namespace == Namespaces.Peer.Empty { - item.controllerInteraction.displayMessageTooltip(item.content.firstMessage.id, item.presentationData.strings.Conversation_ForwardAuthorHiddenTooltip, self, avatarNode.frame) - } else { - if let channel = item.content.firstMessage.forwardInfo?.author as? TelegramChannel, channel.username == nil { - if case .member = channel.participationStatus { - } else { - item.controllerInteraction.displayMessageTooltip(item.message.id, item.presentationData.strings.Conversation_PrivateChannelTooltip, self, avatarNode.frame) - return true + + for attribute in item.content.firstMessage.attributes { + if let attribute = attribute as? SourceReferenceMessageAttribute { + openPeerId = attribute.messageId.peerId + navigate = .chat(textInputState: nil, subject: .message(attribute.messageId)) } } - item.controllerInteraction.openPeer(openPeerId, navigate, item.message) - } + + if item.effectiveAuthorId?.namespace == Namespaces.Peer.Empty { + item.controllerInteraction.displayMessageTooltip(item.content.firstMessage.id, item.presentationData.strings.Conversation_ForwardAuthorHiddenTooltip, self, avatarNode.frame) + } else { + if let channel = item.content.firstMessage.forwardInfo?.author as? TelegramChannel, channel.username == nil { + if case .member = channel.participationStatus { + } else { + item.controllerInteraction.displayMessageTooltip(item.message.id, item.presentationData.strings.Conversation_PrivateChannelTooltip, self, avatarNode.frame) + } + } + item.controllerInteraction.openPeer(openPeerId, navigate, item.message) + } + }) } - return true + return nil } if let viaBotNode = self.viaBotNode, viaBotNode.frame.contains(location) { @@ -911,14 +979,15 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { } if let botAddressName = botAddressName { - item.controllerInteraction.updateInputState { textInputState in - return ChatTextInputState(inputText: NSAttributedString(string: "@" + botAddressName + " ")) - } - item.controllerInteraction.updateInputMode { _ in - return .text - } + return .optionalAction({ + item.controllerInteraction.updateInputState { textInputState in + return ChatTextInputState(inputText: NSAttributedString(string: "@" + botAddressName + " ")) + } + item.controllerInteraction.updateInputMode { _ in + return .text + } + }) } - return true } } } @@ -928,8 +997,9 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { if let item = self.item { for attribute in item.message.attributes { if let attribute = attribute as? ReplyMessageAttribute { - item.controllerInteraction.navigateToMessage(item.message.id, attribute.messageId) - return true + return .optionalAction({ + item.controllerInteraction.navigateToMessage(item.message.id, attribute.messageId) + }) } } } @@ -937,9 +1007,13 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { if let item = self.item, self.imageNode.frame.contains(location) { if let _ = self.telegramFile { - let _ = item.controllerInteraction.openMessage(item.message, .default) + return .optionalAction({ + let _ = item.controllerInteraction.openMessage(item.message, .default) + }) } else if let _ = self.telegramDice { - item.controllerInteraction.displayMessageTooltip(item.content.firstMessage.id, item.presentationData.strings.Conversation_Dice, self, self.imageNode.frame.offsetBy(dx: 0.0, dy: self.imageNode.frame.height / 3.0)) + return .optionalAction({ + item.controllerInteraction.displayMessageTooltip(item.content.firstMessage.id, item.presentationData.strings.Conversation_Dice, self, self.imageNode.frame.offsetBy(dx: 0.0, dy: self.imageNode.frame.height / 3.0)) + }) } else if let _ = self.emojiFile { if let animationNode = self.animationNode as? AnimatedStickerNode { var startTime: Signal @@ -955,39 +1029,38 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { let beatingHearts: [UInt32] = [0x2764, 0x1F90E, 0x1F9E1, 0x1F49A, 0x1F49C, 0x1F49B, 0x1F5A4, 0x1F90D] if let text = self.item?.message.text, let firstScalar = text.unicodeScalars.first, beatingHearts.contains(firstScalar.value) { - let _ = startTime.start(next: { [weak self] time in - guard let strongSelf = self else { - return - } - - let heartbeatHaptic: HeartbeatHaptic - if let current = strongSelf.heartbeatHaptic { - heartbeatHaptic = current - } else { - heartbeatHaptic = HeartbeatHaptic() - heartbeatHaptic.enabled = true - strongSelf.heartbeatHaptic = heartbeatHaptic - } - if !heartbeatHaptic.active { - heartbeatHaptic.start(time: time) - } + return .optionalAction({ + let _ = startTime.start(next: { [weak self] time in + guard let strongSelf = self else { + return + } + + let heartbeatHaptic: HeartbeatHaptic + if let current = strongSelf.heartbeatHaptic { + heartbeatHaptic = current + } else { + heartbeatHaptic = HeartbeatHaptic() + heartbeatHaptic.enabled = true + strongSelf.heartbeatHaptic = heartbeatHaptic + } + if !heartbeatHaptic.active { + heartbeatHaptic.start(time: time) + } + }) }) } } } - return true } - - self.item?.controllerInteraction.clickThroughMessage() + return nil case .longTap, .doubleTap: if let item = self.item, self.imageNode.frame.contains(location) { - item.controllerInteraction.openMessageContextMenu(item.message, false, self, self.imageNode.frame, recognizer) - return false + return .openContextMenu(tapMessage: item.message, selectAll: false, subFrame: self.imageNode.frame) } case .hold: break } - return true + return nil } @objc func shareButtonPressed() { diff --git a/submodules/TelegramUI/Sources/ChatMessageBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageBubbleContentNode.swift index a06144dee7..0269e3d6c9 100644 --- a/submodules/TelegramUI/Sources/ChatMessageBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageBubbleContentNode.swift @@ -84,6 +84,7 @@ enum ChatMessageBubbleContentTapAction { case tooltip(String, ASDisplayNode?, CGRect?) case bankCard(String) case ignore + case openPollResults(Data) } final class ChatMessageBubbleContentItem { diff --git a/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift index 35f4e2d07f..ceac6d1466 100644 --- a/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift @@ -23,7 +23,7 @@ import GridMessageSelectionNode import AppBundle import Markdown -private enum InternalBubbleTapAction { +enum InternalBubbleTapAction { case action(() -> Void) case optionalAction(() -> Void) case openContextMenu(tapMessage: Message, selectAll: Bool, subFrame: CGRect) @@ -418,7 +418,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePrevewItemNode break case .ignore: return .fail - case .url, .peerMention, .textMention, .botCommand, .hashtag, .instantPage, .wallpaper, .theme, .call, .openMessage, .timecode, .bankCard, .tooltip: + case .url, .peerMention, .textMention, .botCommand, .hashtag, .instantPage, .wallpaper, .theme, .call, .openMessage, .timecode, .bankCard, .tooltip, .openPollResults: return .waitForSingleTap } } @@ -443,7 +443,6 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePrevewItemNode f() recognizer.cancel() case .openContextMenu: - //recognizer.cancel() break } } @@ -2309,6 +2308,9 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePrevewItemNode case .ended: if let (gesture, location) = recognizer.lastRecognizedGestureAndLocation { if let action = self.gestureRecognized(gesture: gesture, location: location, recognizer: nil) { + if case .doubleTap = gesture { + self.containerNode.cancelGesture() + } switch action { case let .action(f): f() @@ -2546,6 +2548,12 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePrevewItemNode let _ = item.controllerInteraction.displayMessageTooltip(item.message.id, text, node, rect) }) } + case let .openPollResults(option): + if let item = self.item { + return .action({ + item.controllerInteraction.openMessagePollResults(item.message.id, option) + }) + } } } return nil @@ -2608,6 +2616,8 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePrevewItemNode }) case .tooltip: break + case .openPollResults: + break } } if let tapMessage = tapMessage { diff --git a/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift index f1f243a891..167704c7fe 100644 --- a/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift @@ -21,6 +21,7 @@ private let inlineBotNameFont = nameFont class ChatMessageInstantVideoItemNode: ChatMessageItemView { private let contextSourceNode: ContextExtractedContentContainingNode + private let containerNode: ContextControllerSourceNode private let interactiveVideoNode: ChatMessageInteractiveInstantVideoNode private var selectionNode: ChatMessageSelectionNode? @@ -57,11 +58,52 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView { required init() { self.contextSourceNode = ContextExtractedContentContainingNode() + self.containerNode = ContextControllerSourceNode() self.interactiveVideoNode = ChatMessageInteractiveInstantVideoNode() super.init(layerBacked: false) - self.addSubnode(self.contextSourceNode) + self.containerNode.shouldBegin = { [weak self] location in + guard let strongSelf = self else { + return false + } + if !strongSelf.interactiveVideoNode.frame.contains(location) { + return false + } + if let action = strongSelf.gestureRecognized(gesture: .tap, location: location, recognizer: nil) { + if case .action = action { + return false + } + } + if let action = strongSelf.gestureRecognized(gesture: .longTap, location: location, recognizer: nil) { + switch action { + case .action, .optionalAction: + return false + case .openContextMenu: + return true + } + } + return true + } + + self.containerNode.activated = { [weak self] gesture, location in + guard let strongSelf = self, let item = strongSelf.item else { + return + } + + if let action = strongSelf.gestureRecognized(gesture: .longTap, location: location, recognizer: nil) { + switch action { + case .action, .optionalAction: + break + case let .openContextMenu(tapMessage, selectAll, subFrame): + item.controllerInteraction.openMessageContextMenu(tapMessage, selectAll, strongSelf, subFrame, gesture) + } + } + } + + self.containerNode.addSubnode(self.contextSourceNode) + self.containerNode.targetNodeForActivationProgress = self.contextSourceNode.contentNode + self.addSubnode(self.containerNode) self.contextSourceNode.contentNode.addSubnode(self.interactiveVideoNode) } @@ -219,7 +261,6 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView { var updatedReplyBackgroundNode: ASImageNode? var replyBackgroundImage: UIImage? var replyMarkup: ReplyMarkupMessageAttribute? - var inlineBotNameString: String? let availableWidth = max(60.0, params.width - params.leftInset - params.rightInset - videoLayout.contentSize.width - 20.0 - layoutConstants.bubble.edgeInset * 2.0 - avatarInset - layoutConstants.bubble.contentInsets.left) @@ -277,12 +318,7 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView { if let replyAttribute = attribute as? ReplyMessageAttribute, let replyMessage = item.message.associatedMessages[replyAttribute.messageId] { replyInfoApply = makeReplyInfoLayout(item.presentationData, item.presentationData.strings, item.context, .standalone, replyMessage, CGSize(width: availableWidth, height: CGFloat.greatestFiniteMagnitude)) - } else if let attribute = attribute as? InlineBotMessageAttribute { - if let peerId = attribute.peerId, let bot = item.message.peers[peerId] as? TelegramUser { - inlineBotNameString = bot.username - } else { - inlineBotNameString = attribute.title - } + } else if let _ = attribute as? InlineBotMessageAttribute { } else if let attribute = attribute as? ReplyMarkupMessageAttribute, attribute.flags.contains(.inline), !attribute.rows.isEmpty { replyMarkup = attribute } @@ -389,6 +425,7 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView { return (ListViewItemNodeLayout(contentSize: layoutSize, insets: layoutInsets), { [weak self] animation, _ in if let strongSelf = self { strongSelf.contextSourceNode.frame = CGRect(origin: CGPoint(), size: layoutSize) + strongSelf.containerNode.frame = CGRect(origin: CGPoint(), size: layoutSize) strongSelf.contextSourceNode.contentNode.frame = CGRect(origin: CGPoint(), size: layoutSize) strongSelf.appliedItem = item @@ -410,6 +447,7 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView { videoApply(videoLayoutData, transition) strongSelf.contextSourceNode.contentRect = videoFrame + strongSelf.containerNode.targetNodeForActivationProgressContentRect = strongSelf.contextSourceNode.contentRect if let updatedShareButtonNode = updatedShareButtonNode { if updatedShareButtonNode !== strongSelf.shareButtonNode { @@ -580,80 +618,20 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView { switch recognizer.state { case .ended: if let (gesture, location) = recognizer.lastRecognizedGestureAndLocation { - switch gesture { - case .tap: - if let avatarNode = self.accessoryItemNode as? ChatMessageAvatarAccessoryItemNode, avatarNode.frame.contains(location) { - if let item = self.item, let author = item.content.firstMessage.author { - var openPeerId = item.effectiveAuthorId ?? author.id - var navigate: ChatControllerInteractionNavigateToPeer - - if item.content.firstMessage.id.peerId == item.context.account.peerId { - navigate = .chat(textInputState: nil, subject: nil) - } else { - navigate = .info - } - - for attribute in item.content.firstMessage.attributes { - if let attribute = attribute as? SourceReferenceMessageAttribute { - openPeerId = attribute.messageId.peerId - navigate = .chat(textInputState: nil, subject: .message(attribute.messageId)) - } - } - - if item.effectiveAuthorId?.namespace == Namespaces.Peer.Empty { - item.controllerInteraction.displayMessageTooltip(item.content.firstMessage.id, item.presentationData.strings.Conversation_ForwardAuthorHiddenTooltip, self, avatarNode.frame) - } else { - if let channel = item.content.firstMessage.forwardInfo?.author as? TelegramChannel, channel.username == nil { - if case .member = channel.participationStatus { - } else { - item.controllerInteraction.displayMessageTooltip(item.message.id, item.presentationData.strings.Conversation_PrivateChannelTooltip, self, avatarNode.frame) - return - } - } - item.controllerInteraction.openPeer(openPeerId, navigate, item.message) - } - } - return - } - - if let replyInfoNode = self.replyInfoNode, replyInfoNode.frame.contains(location) { - if let item = self.item { - for attribute in item.message.attributes { - if let attribute = attribute as? ReplyMessageAttribute { - item.controllerInteraction.navigateToMessage(item.message.id, attribute.messageId) - return - } - } - } - } - - if let forwardInfoNode = self.forwardInfoNode, forwardInfoNode.frame.contains(location) { - if let item = self.item, let forwardInfo = item.message.forwardInfo { - if let sourceMessageId = forwardInfo.sourceMessageId { - if let channel = forwardInfo.author as? TelegramChannel, channel.username == nil { - if case .member = channel.participationStatus { - } else { - item.controllerInteraction.displayMessageTooltip(item.message.id, item.presentationData.strings.Conversation_PrivateChannelTooltip, forwardInfoNode, nil) - return - } - } - item.controllerInteraction.navigateToMessage(item.message.id, sourceMessageId) - } else if let id = forwardInfo.source?.id ?? forwardInfo.author?.id { - item.controllerInteraction.openPeer(id, .chat(textInputState: nil, subject: nil), nil) - } else if let _ = forwardInfo.authorSignature { - item.controllerInteraction.displayMessageTooltip(item.message.id, item.presentationData.strings.Conversation_ForwardAuthorHiddenTooltip, forwardInfoNode, nil) - } - return - } - } - - self.item?.controllerInteraction.clickThroughMessage() - case .longTap, .doubleTap: - if let item = self.item, let videoContentNode = self.interactiveVideoNode.videoContentNode(at: self.view.convert(location, to: self.interactiveVideoNode.view)) { - item.controllerInteraction.openMessageContextMenu(item.message, false, videoContentNode, videoContentNode.bounds, nil) - } - case .hold: - break + if let action = self.gestureRecognized(gesture: gesture, location: location, recognizer: nil) { + if case .doubleTap = gesture { + self.containerNode.cancelGesture() + } + switch action { + case let .action(f): + f() + case let .optionalAction(f): + f() + case let .openContextMenu(tapMessage, selectAll, subFrame): + self.item?.controllerInteraction.openMessageContextMenu(tapMessage, selectAll, self, subFrame, nil) + } + } else if case .tap = gesture { + self.item?.controllerInteraction.clickThroughMessage() } } default: @@ -661,6 +639,92 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView { } } + private func gestureRecognized(gesture: TapLongTapOrDoubleTapGesture, location: CGPoint, recognizer: TapLongTapOrDoubleTapGestureRecognizer?) -> InternalBubbleTapAction? { + switch gesture { + case .tap: + if let avatarNode = self.accessoryItemNode as? ChatMessageAvatarAccessoryItemNode, avatarNode.frame.contains(location) { + if let item = self.item, let author = item.content.firstMessage.author { + var openPeerId = item.effectiveAuthorId ?? author.id + var navigate: ChatControllerInteractionNavigateToPeer + + if item.content.firstMessage.id.peerId == item.context.account.peerId { + navigate = .chat(textInputState: nil, subject: nil) + } else { + navigate = .info + } + + for attribute in item.content.firstMessage.attributes { + if let attribute = attribute as? SourceReferenceMessageAttribute { + openPeerId = attribute.messageId.peerId + navigate = .chat(textInputState: nil, subject: .message(attribute.messageId)) + } + } + + return .optionalAction({ + if item.effectiveAuthorId?.namespace == Namespaces.Peer.Empty { + item.controllerInteraction.displayMessageTooltip(item.content.firstMessage.id, item.presentationData.strings.Conversation_ForwardAuthorHiddenTooltip, self, avatarNode.frame) + } else { + if let channel = item.content.firstMessage.forwardInfo?.author as? TelegramChannel, channel.username == nil { + if case .member = channel.participationStatus { + } else { + item.controllerInteraction.displayMessageTooltip(item.message.id, item.presentationData.strings.Conversation_PrivateChannelTooltip, self, avatarNode.frame) + return + } + } + item.controllerInteraction.openPeer(openPeerId, navigate, item.message) + } + }) + } + } + + if let replyInfoNode = self.replyInfoNode, replyInfoNode.frame.contains(location) { + if let item = self.item { + for attribute in item.message.attributes { + if let attribute = attribute as? ReplyMessageAttribute { + return .optionalAction({ + item.controllerInteraction.navigateToMessage(item.message.id, attribute.messageId) + }) + } + } + } + } + + if let forwardInfoNode = self.forwardInfoNode, forwardInfoNode.frame.contains(location) { + if let item = self.item, let forwardInfo = item.message.forwardInfo { + if let sourceMessageId = forwardInfo.sourceMessageId { + if let channel = forwardInfo.author as? TelegramChannel, channel.username == nil { + if case .member = channel.participationStatus { + } else { + return .optionalAction({ + item.controllerInteraction.displayMessageTooltip(item.message.id, item.presentationData.strings.Conversation_PrivateChannelTooltip, forwardInfoNode, nil) + }) + } + } + return .optionalAction({ + item.controllerInteraction.navigateToMessage(item.message.id, sourceMessageId) + }) + } else if let id = forwardInfo.source?.id ?? forwardInfo.author?.id { + return .optionalAction({ + item.controllerInteraction.openPeer(id, .chat(textInputState: nil, subject: nil), nil) + }) + } else if let _ = forwardInfo.authorSignature { + return .optionalAction({ + item.controllerInteraction.displayMessageTooltip(item.message.id, item.presentationData.strings.Conversation_ForwardAuthorHiddenTooltip, forwardInfoNode, nil) + }) + } + } + } + return nil + case .longTap, .doubleTap: + if let item = self.item, let videoContentNode = self.interactiveVideoNode.videoContentNode(at: self.view.convert(location, to: self.interactiveVideoNode.view)) { + return .openContextMenu(tapMessage: item.message, selectAll: false, subFrame: videoContentNode.view.convert(videoContentNode.bounds, to: self.view)) + } + case .hold: + break + } + return nil + } + @objc func shareButtonPressed() { if let item = self.item { if item.content.firstMessage.id.peerId == item.context.account.peerId { diff --git a/submodules/TelegramUI/Sources/ChatMessageInteractiveInstantVideoNode.swift b/submodules/TelegramUI/Sources/ChatMessageInteractiveInstantVideoNode.swift index 8a35e620dc..7b34b53c9e 100644 --- a/submodules/TelegramUI/Sources/ChatMessageInteractiveInstantVideoNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageInteractiveInstantVideoNode.swift @@ -137,13 +137,10 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode { let makeDateAndStatusLayout = self.dateAndStatusNode.asyncLayout() return { item, width, displaySize, statusDisplayType, automaticDownload in - var updatedTheme: ChatPresentationThemeData? - var secretVideoPlaceholderBackgroundImage: UIImage? var updatedInfoBackgroundImage: UIImage? var updatedMuteIconImage: UIImage? if item.presentationData.theme != currentItem?.presentationData.theme { - updatedTheme = item.presentationData.theme updatedInfoBackgroundImage = PresentationResourcesChat.chatInstantMessageInfoBackgroundImage(item.presentationData.theme.theme) updatedMuteIconImage = PresentationResourcesChat.chatInstantMessageMuteIconImage(item.presentationData.theme.theme) } @@ -382,13 +379,11 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode { }) } let mediaManager = item.context.sharedContext.mediaManager - let videoNode = UniversalVideoNode(postbox: item.context.account.postbox, audioSession: mediaManager.audioSession, manager: mediaManager.universalVideoManager, decoration: ChatBubbleInstantVideoDecoration(diameter: displaySize.width + 2.0, backgroundImage: instantVideoBackgroundImage, tapped: { + let videoNode = UniversalVideoNode(postbox: item.context.account.postbox, audioSession: mediaManager.audioSession, manager: mediaManager.universalVideoManager, decoration: ChatBubbleInstantVideoDecoration(inset: 2.0, backgroundImage: instantVideoBackgroundImage, tapped: { if let strongSelf = self { if let item = strongSelf.item { if strongSelf.infoBackgroundNode.alpha.isZero { item.context.sharedContext.mediaManager.playlistControl(.playback(.togglePlayPause), type: .voice) - } else { - //let _ = item.controllerInteraction.openMessage(item.message) } } } @@ -670,9 +665,7 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode { self.item?.controllerInteraction.clickThroughMessage() case .longTap, .doubleTap: - if let item = self.item, let videoNode = self.videoNode, videoNode.frame.contains(location) { - item.controllerInteraction.openMessageContextMenu(item.message, false, self, videoNode.frame, nil) - } + break case .hold: break } diff --git a/submodules/TelegramUI/Sources/ChatMessagePollBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessagePollBubbleContentNode.swift index 8a812fe3e0..dbe07bbc9d 100644 --- a/submodules/TelegramUI/Sources/ChatMessagePollBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessagePollBubbleContentNode.swift @@ -1489,8 +1489,7 @@ class ChatMessagePollBubbleContentNode: ChatMessageBubbleContentNode { } if hasNonZeroVoters { if !isEstimating { - item.controllerInteraction.openMessagePollResults(item.message.id, option.opaqueIdentifier) - return .ignore + return .openPollResults(option.opaqueIdentifier) } return .openMessage } diff --git a/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift index d4b5f3b248..e53c1a95ca 100644 --- a/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift @@ -19,6 +19,7 @@ private let inlineBotNameFont = nameFont class ChatMessageStickerItemNode: ChatMessageItemView { private let contextSourceNode: ContextExtractedContentContainingNode + private let containerNode: ContextControllerSourceNode let imageNode: TransformImageNode var textNode: TextNode? @@ -45,13 +46,54 @@ class ChatMessageStickerItemNode: ChatMessageItemView { required init() { self.contextSourceNode = ContextExtractedContentContainingNode() + self.containerNode = ContextControllerSourceNode() self.imageNode = TransformImageNode() self.dateAndStatusNode = ChatMessageDateAndStatusNode() super.init(layerBacked: false) + self.containerNode.shouldBegin = { [weak self] location in + guard let strongSelf = self else { + return false + } + if !strongSelf.imageNode.frame.contains(location) { + return false + } + if let action = strongSelf.gestureRecognized(gesture: .tap, location: location, recognizer: nil) { + if case .action = action { + return false + } + } + if let action = strongSelf.gestureRecognized(gesture: .longTap, location: location, recognizer: nil) { + switch action { + case .action, .optionalAction: + return false + case .openContextMenu: + return true + } + } + return true + } + + self.containerNode.activated = { [weak self] gesture, location in + guard let strongSelf = self, let item = strongSelf.item else { + return + } + + if let action = strongSelf.gestureRecognized(gesture: .longTap, location: location, recognizer: nil) { + switch action { + case .action, .optionalAction: + break + case let .openContextMenu(tapMessage, selectAll, subFrame): + item.controllerInteraction.openMessageContextMenu(tapMessage, selectAll, strongSelf, subFrame, gesture) + } + } + } + self.imageNode.displaysAsynchronously = false - self.addSubnode(self.contextSourceNode) + self.containerNode.addSubnode(self.contextSourceNode) + self.containerNode.targetNodeForActivationProgress = self.contextSourceNode.contentNode + self.addSubnode(self.containerNode) self.contextSourceNode.contentNode.addSubnode(self.imageNode) self.contextSourceNode.contentNode.addSubnode(self.dateAndStatusNode) } @@ -87,8 +129,17 @@ class ChatMessageStickerItemNode: ChatMessageItemView { return } //strongSelf.reactionRecognizer?.cancel() - if strongSelf.gestureRecognized(gesture: .longTap, location: point, recognizer: recognizer) { - recognizer.cancel() + if let action = strongSelf.gestureRecognized(gesture: .longTap, location: point, recognizer: recognizer) { + switch action { + case let .action(f): + f() + recognizer.cancel() + case let .optionalAction(f): + f() + recognizer.cancel() + case .openContextMenu: + break + } } } self.view.addGestureRecognizer(recognizer) @@ -409,9 +460,6 @@ class ChatMessageStickerItemNode: ChatMessageItemView { return (ListViewItemNodeLayout(contentSize: layoutSize, insets: layoutInsets), { [weak self] animation, _ in if let strongSelf = self { - strongSelf.contextSourceNode.frame = CGRect(origin: CGPoint(), size: layoutSize) - strongSelf.contextSourceNode.contentNode.frame = CGRect(origin: CGPoint(), size: layoutSize) - var transition: ContainedViewLayoutTransition = .immediate if case let .System(duration) = animation { transition = .animated(duration: duration, curve: .spring) @@ -421,7 +469,11 @@ class ChatMessageStickerItemNode: ChatMessageItemView { transition.updateFrame(node: strongSelf.imageNode, frame: updatedImageFrame) imageApply() + strongSelf.containerNode.frame = CGRect(origin: CGPoint(), size: layoutSize) + strongSelf.contextSourceNode.frame = CGRect(origin: CGPoint(), size: layoutSize) + strongSelf.contextSourceNode.contentNode.frame = CGRect(origin: CGPoint(), size: layoutSize) strongSelf.contextSourceNode.contentRect = strongSelf.imageNode.frame + strongSelf.containerNode.targetNodeForActivationProgressContentRect = strongSelf.contextSourceNode.contentRect dateAndStatusApply(false) @@ -589,48 +641,65 @@ class ChatMessageStickerItemNode: ChatMessageItemView { switch recognizer.state { case .ended: if let (gesture, location) = recognizer.lastRecognizedGestureAndLocation { - let _ = self.gestureRecognized(gesture: gesture, location: location, recognizer: nil) + if case .doubleTap = gesture { + self.containerNode.cancelGesture() + } + if let action = self.gestureRecognized(gesture: gesture, location: location, recognizer: nil) { + if case .doubleTap = gesture { + self.containerNode.cancelGesture() + } + switch action { + case let .action(f): + f() + case let .optionalAction(f): + f() + case let .openContextMenu(tapMessage, selectAll, subFrame): + self.item?.controllerInteraction.openMessageContextMenu(tapMessage, selectAll, self, subFrame, nil) + } + } else if case .tap = gesture { + self.item?.controllerInteraction.clickThroughMessage() + } } default: break } } - private func gestureRecognized(gesture: TapLongTapOrDoubleTapGesture, location: CGPoint, recognizer: TapLongTapOrDoubleTapGestureRecognizer?) -> Bool { + private func gestureRecognized(gesture: TapLongTapOrDoubleTapGesture, location: CGPoint, recognizer: TapLongTapOrDoubleTapGestureRecognizer?) -> InternalBubbleTapAction? { switch gesture { case .tap: if let avatarNode = self.accessoryItemNode as? ChatMessageAvatarAccessoryItemNode, avatarNode.frame.contains(location) { if let item = self.item, let author = item.content.firstMessage.author { - var openPeerId = item.effectiveAuthorId ?? author.id - var navigate: ChatControllerInteractionNavigateToPeer - - if item.content.firstMessage.id.peerId == item.context.account.peerId { - navigate = .chat(textInputState: nil, subject: nil) - } else { - navigate = .info - } - - for attribute in item.content.firstMessage.attributes { - if let attribute = attribute as? SourceReferenceMessageAttribute { - openPeerId = attribute.messageId.peerId - navigate = .chat(textInputState: nil, subject: .message(attribute.messageId)) + return .optionalAction({ + var openPeerId = item.effectiveAuthorId ?? author.id + var navigate: ChatControllerInteractionNavigateToPeer + + if item.content.firstMessage.id.peerId == item.context.account.peerId { + navigate = .chat(textInputState: nil, subject: nil) + } else { + navigate = .info } - } - - if item.effectiveAuthorId?.namespace == Namespaces.Peer.Empty { - item.controllerInteraction.displayMessageTooltip(item.content.firstMessage.id, item.presentationData.strings.Conversation_ForwardAuthorHiddenTooltip, self, avatarNode.frame) - } else { - if let channel = item.content.firstMessage.forwardInfo?.author as? TelegramChannel, channel.username == nil { - if case .member = channel.participationStatus { - } else { - item.controllerInteraction.displayMessageTooltip(item.message.id, item.presentationData.strings.Conversation_PrivateChannelTooltip, self, avatarNode.frame) - return true + + for attribute in item.content.firstMessage.attributes { + if let attribute = attribute as? SourceReferenceMessageAttribute { + openPeerId = attribute.messageId.peerId + navigate = .chat(textInputState: nil, subject: .message(attribute.messageId)) } } - item.controllerInteraction.openPeer(openPeerId, navigate, item.message) - } + + if item.effectiveAuthorId?.namespace == Namespaces.Peer.Empty { + item.controllerInteraction.displayMessageTooltip(item.content.firstMessage.id, item.presentationData.strings.Conversation_ForwardAuthorHiddenTooltip, self, avatarNode.frame) + } else { + if let channel = item.content.firstMessage.forwardInfo?.author as? TelegramChannel, channel.username == nil { + if case .member = channel.participationStatus { + } else { + item.controllerInteraction.displayMessageTooltip(item.message.id, item.presentationData.strings.Conversation_PrivateChannelTooltip, self, avatarNode.frame) + } + } + item.controllerInteraction.openPeer(openPeerId, navigate, item.message) + } + }) } - return true } if let viaBotNode = self.viaBotNode, viaBotNode.frame.contains(location) { @@ -645,14 +714,15 @@ class ChatMessageStickerItemNode: ChatMessageItemView { } if let botAddressName = botAddressName { - item.controllerInteraction.updateInputState { textInputState in - return ChatTextInputState(inputText: NSAttributedString(string: "@" + botAddressName + " ")) - } - item.controllerInteraction.updateInputMode { _ in - return .text - } + return .optionalAction({ + item.controllerInteraction.updateInputState { textInputState in + return ChatTextInputState(inputText: NSAttributedString(string: "@" + botAddressName + " ")) + } + item.controllerInteraction.updateInputMode { _ in + return .text + } + }) } - return true } } } @@ -662,29 +732,29 @@ class ChatMessageStickerItemNode: ChatMessageItemView { if let item = self.item { for attribute in item.message.attributes { if let attribute = attribute as? ReplyMessageAttribute { - item.controllerInteraction.navigateToMessage(item.message.id, attribute.messageId) - return true + return .optionalAction({ + item.controllerInteraction.navigateToMessage(item.message.id, attribute.messageId) + }) } } } } if let item = self.item, self.imageNode.frame.contains(location) { - let _ = item.controllerInteraction.openMessage(item.message, .default) - return true + return .optionalAction({ + let _ = item.controllerInteraction.openMessage(item.message, .default) + }) } - self.item?.controllerInteraction.clickThroughMessage() + return nil case .longTap, .doubleTap: if let item = self.item, self.imageNode.frame.contains(location) { - item.controllerInteraction.openMessageContextMenu(item.message, false, self, self.imageNode.frame, recognizer) - return false + return .openContextMenu(tapMessage: item.message, selectAll: false, subFrame: self.imageNode.frame) } case .hold: break } - - return true + return nil } @objc func shareButtonPressed() { diff --git a/submodules/TelegramUI/Sources/ContactMultiselectionControllerNode.swift b/submodules/TelegramUI/Sources/ContactMultiselectionControllerNode.swift index bbc71b2474..6624e28bca 100644 --- a/submodules/TelegramUI/Sources/ContactMultiselectionControllerNode.swift +++ b/submodules/TelegramUI/Sources/ContactMultiselectionControllerNode.swift @@ -86,7 +86,7 @@ final class ContactMultiselectionControllerNode: ASDisplayNode { if case let .chatSelection(_, selectedChats, additionalCategories) = mode { placeholder = self.presentationData.strings.ChatListFilter_AddChatsTitle - let chatListNode = ChatListNode(context: context, groupId: .root, previewing: false, fillPreloadItems: false, mode: .peers(filter: [], isSelecting: true, additionalCategories: additionalCategories?.categories ?? []), theme: self.presentationData.theme, fontSize: self.presentationData.listsFontSize, strings: self.presentationData.strings, dateTimeFormat: self.presentationData.dateTimeFormat, nameSortOrder: self.presentationData.nameSortOrder, nameDisplayOrder: self.presentationData.nameDisplayOrder, disableAnimations: true) + let chatListNode = ChatListNode(context: context, groupId: .root, previewing: false, fillPreloadItems: false, mode: .peers(filter: [.excludeSecretChats], isSelecting: true, additionalCategories: additionalCategories?.categories ?? []), theme: self.presentationData.theme, fontSize: self.presentationData.listsFontSize, strings: self.presentationData.strings, dateTimeFormat: self.presentationData.dateTimeFormat, nameSortOrder: self.presentationData.nameSortOrder, nameDisplayOrder: self.presentationData.nameDisplayOrder, disableAnimations: true) chatListNode.updateState { state in var state = state for peerId in selectedChats { @@ -171,12 +171,15 @@ final class ContactMultiselectionControllerNode: ASDisplayNode { var searchGroups = false var searchChannels = false var globalSearch = false - if case let .peerSelection(peerSelection) = mode { - searchChatList = peerSelection.searchChatList - searchGroups = peerSelection.searchGroups - searchChannels = peerSelection.searchChannels + switch mode { + case .groupCreation, .channelCreation: globalSearch = true - } else if case .chatSelection = mode { + case let .peerSelection(searchChatListValue, searchGroupsValue, searchChannelsValue): + searchChatList = searchChatListValue + searchGroups = searchGroupsValue + searchChannels = searchChannelsValue + globalSearch = true + case .chatSelection: searchChatList = true searchGroups = true searchChannels = true diff --git a/submodules/TelegramUI/Sources/ForwardAccessoryPanelNode.swift b/submodules/TelegramUI/Sources/ForwardAccessoryPanelNode.swift index af121a5a9d..393df7c073 100644 --- a/submodules/TelegramUI/Sources/ForwardAccessoryPanelNode.swift +++ b/submodules/TelegramUI/Sources/ForwardAccessoryPanelNode.swift @@ -61,6 +61,8 @@ func textStringForForwardedMessage(_ message: Message, strings: PresentationStri return ("", true) case _ as TelegramMediaPoll: return (strings.ForwardedPolls(1), true) + case _ as TelegramMediaDice: + return ("🎲", false) default: break } diff --git a/submodules/TelegramUniversalVideoContent/Sources/ChatBubbleInstantVideoDecoration.swift b/submodules/TelegramUniversalVideoContent/Sources/ChatBubbleInstantVideoDecoration.swift index b9993b6207..e80b23197a 100644 --- a/submodules/TelegramUniversalVideoContent/Sources/ChatBubbleInstantVideoDecoration.swift +++ b/submodules/TelegramUniversalVideoContent/Sources/ChatBubbleInstantVideoDecoration.swift @@ -14,10 +14,12 @@ public final class ChatBubbleInstantVideoDecoration: UniversalVideoDecoration { private let tapped: () -> Void private var contentNode: (ASDisplayNode & UniversalVideoContentNode)? + private let inset: CGFloat private var validLayoutSize: CGSize? - public init(diameter: CGFloat, backgroundImage: UIImage?, tapped: @escaping () -> Void) { + public init(inset: CGFloat, backgroundImage: UIImage?, tapped: @escaping () -> Void) { + self.inset = inset self.tapped = tapped let backgroundNode = ASImageNode() @@ -29,7 +31,6 @@ public final class ChatBubbleInstantVideoDecoration: UniversalVideoDecoration { self.contentContainerNode = ASDisplayNode() self.contentContainerNode.clipsToBounds = true - self.contentContainerNode.cornerRadius = (diameter - 3.0) / 2.0 let foregroundNode = ASDisplayNode() self.foregroundNode = foregroundNode @@ -65,6 +66,9 @@ public final class ChatBubbleInstantVideoDecoration: UniversalVideoDecoration { public func updateLayout(size: CGSize, transition: ContainedViewLayoutTransition) { self.validLayoutSize = size + let diameter = size.width + inset + self.contentContainerNode.cornerRadius = (diameter - 3.0) / 2.0 + if let backgroundNode = self.backgroundNode { transition.updateFrame(node: backgroundNode, frame: CGRect(origin: CGPoint(), size: size)) } From 0dff5a327453bd693199363c5eec6e907228947a Mon Sep 17 00:00:00 2001 From: Ali <> Date: Tue, 31 Mar 2020 16:12:06 +0400 Subject: [PATCH 3/6] Fix video message context menu --- .../Display/Source/ContextControllerSourceNode.swift | 2 +- .../Sources/ChatMessageInstantVideoItemNode.swift | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/submodules/Display/Source/ContextControllerSourceNode.swift b/submodules/Display/Source/ContextControllerSourceNode.swift index d9cb69e0d3..d5de6f44f3 100644 --- a/submodules/Display/Source/ContextControllerSourceNode.swift +++ b/submodules/Display/Source/ContextControllerSourceNode.swift @@ -57,7 +57,7 @@ public final class ContextControllerSourceNode: ASDisplayNode { } let scaleSide = targetContentRect.width - let minScale: CGFloat = (scaleSide - 15.0) / scaleSide + let minScale: CGFloat = max(0.7, (scaleSide - 15.0) / scaleSide) let currentScale = 1.0 * (1.0 - progress) + minScale * progress let originalCenterOffsetX: CGFloat = targetNode.bounds.width / 2.0 - targetContentRect.midX diff --git a/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift index 167704c7fe..4365a1d469 100644 --- a/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift @@ -45,6 +45,8 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView { private var currentSwipeToReplyTranslation: CGFloat = 0.0 + private var recognizer: TapLongTapOrDoubleTapGestureRecognizer? + override var visibility: ListViewItemNodeVisibility { didSet { let wasVisible = oldValue != .none @@ -90,12 +92,12 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView { guard let strongSelf = self, let item = strongSelf.item else { return } - if let action = strongSelf.gestureRecognized(gesture: .longTap, location: location, recognizer: nil) { switch action { case .action, .optionalAction: break case let .openContextMenu(tapMessage, selectAll, subFrame): + strongSelf.recognizer?.cancel() item.controllerInteraction.openMessageContextMenu(tapMessage, selectAll, strongSelf, subFrame, gesture) } } @@ -115,6 +117,7 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView { super.didLoad() let recognizer = TapLongTapOrDoubleTapGestureRecognizer(target: self, action: #selector(self.tapLongTapOrDoubleTapGesture(_:))) + self.recognizer = recognizer recognizer.tapActionAtPoint = { [weak self] point in if let strongSelf = self { if let shareButtonNode = strongSelf.shareButtonNode, shareButtonNode.frame.contains(point) { @@ -716,8 +719,8 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView { } return nil case .longTap, .doubleTap: - if let item = self.item, let videoContentNode = self.interactiveVideoNode.videoContentNode(at: self.view.convert(location, to: self.interactiveVideoNode.view)) { - return .openContextMenu(tapMessage: item.message, selectAll: false, subFrame: videoContentNode.view.convert(videoContentNode.bounds, to: self.view)) + if let item = self.item, self.interactiveVideoNode.frame.contains(location) { + return .openContextMenu(tapMessage: item.message, selectAll: false, subFrame: self.interactiveVideoNode.frame) } case .hold: break From 7cc25002fc8b83d046d436d38e54160ea370d4be Mon Sep 17 00:00:00 2001 From: Ali <> Date: Tue, 31 Mar 2020 16:30:02 +0400 Subject: [PATCH 4/6] Improve editing mode --- .../Sources/ChatListController.swift | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/submodules/ChatListUI/Sources/ChatListController.swift b/submodules/ChatListUI/Sources/ChatListController.swift index 2a288463ba..53d94cc6cd 100644 --- a/submodules/ChatListUI/Sources/ChatListController.swift +++ b/submodules/ChatListUI/Sources/ChatListController.swift @@ -460,8 +460,8 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController, strongSelf.tabContainerNode.cancelAnimations() strongSelf.chatListDisplayNode.inlineTabContainerNode.cancelAnimations() } - strongSelf.tabContainerNode.update(size: CGSize(width: layout.size.width, height: 46.0), sideInset: layout.safeInsets.left, filters: tabContainerData.0, selectedFilter: filter, isReordering: strongSelf.chatListDisplayNode.isReorderingFilters || strongSelf.chatListDisplayNode.containerNode.currentItemNode.currentState.editing, isEditing: false, transitionFraction: fraction, presentationData: strongSelf.presentationData, transition: transition) - strongSelf.chatListDisplayNode.inlineTabContainerNode.update(size: CGSize(width: layout.size.width, height: 40.0), sideInset: layout.safeInsets.left, filters: tabContainerData.0, selectedFilter: filter, isReordering: strongSelf.chatListDisplayNode.isReorderingFilters || strongSelf.chatListDisplayNode.containerNode.currentItemNode.currentState.editing, isEditing: false, transitionFraction: fraction, presentationData: strongSelf.presentationData, transition: transition) + strongSelf.tabContainerNode.update(size: CGSize(width: layout.size.width, height: 46.0), sideInset: layout.safeInsets.left, filters: tabContainerData.0, selectedFilter: filter, isReordering: strongSelf.chatListDisplayNode.isReorderingFilters || (strongSelf.chatListDisplayNode.containerNode.currentItemNode.currentState.editing && !strongSelf.chatListDisplayNode.didBeginSelectingChatsWhileEditing), isEditing: false, transitionFraction: fraction, presentationData: strongSelf.presentationData, transition: transition) + strongSelf.chatListDisplayNode.inlineTabContainerNode.update(size: CGSize(width: layout.size.width, height: 40.0), sideInset: layout.safeInsets.left, filters: tabContainerData.0, selectedFilter: filter, isReordering: strongSelf.chatListDisplayNode.isReorderingFilters || (strongSelf.chatListDisplayNode.containerNode.currentItemNode.currentState.editing && !strongSelf.chatListDisplayNode.didBeginSelectingChatsWhileEditing), isEditing: false, transitionFraction: fraction, presentationData: strongSelf.presentationData, transition: transition) } self.reloadFilters() } @@ -521,8 +521,8 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController, self.navigationBar?.updatePresentationData(NavigationBarPresentationData(presentationData: self.presentationData)) if let layout = self.validLayout { - self.tabContainerNode.update(size: CGSize(width: layout.size.width, height: 46.0), sideInset: layout.safeInsets.left, filters: self.tabContainerData?.0 ?? [], selectedFilter: self.chatListDisplayNode.containerNode.currentItemFilter, isReordering: self.chatListDisplayNode.isReorderingFilters || self.chatListDisplayNode.containerNode.currentItemNode.currentState.editing, isEditing: false, transitionFraction: self.chatListDisplayNode.containerNode.transitionFraction, presentationData: self.presentationData, transition: .immediate) - self.chatListDisplayNode.inlineTabContainerNode.update(size: CGSize(width: layout.size.width, height: 40.0), sideInset: layout.safeInsets.left, filters: self.tabContainerData?.0 ?? [], selectedFilter: self.chatListDisplayNode.containerNode.currentItemFilter, isReordering: self.chatListDisplayNode.isReorderingFilters || self.chatListDisplayNode.containerNode.currentItemNode.currentState.editing, isEditing: false, transitionFraction: self.chatListDisplayNode.containerNode.transitionFraction, presentationData: self.presentationData, transition: .immediate) + self.tabContainerNode.update(size: CGSize(width: layout.size.width, height: 46.0), sideInset: layout.safeInsets.left, filters: self.tabContainerData?.0 ?? [], selectedFilter: self.chatListDisplayNode.containerNode.currentItemFilter, isReordering: self.chatListDisplayNode.isReorderingFilters || (self.chatListDisplayNode.containerNode.currentItemNode.currentState.editing && !self.chatListDisplayNode.didBeginSelectingChatsWhileEditing), isEditing: false, transitionFraction: self.chatListDisplayNode.containerNode.transitionFraction, presentationData: self.presentationData, transition: .immediate) + self.chatListDisplayNode.inlineTabContainerNode.update(size: CGSize(width: layout.size.width, height: 40.0), sideInset: layout.safeInsets.left, filters: self.tabContainerData?.0 ?? [], selectedFilter: self.chatListDisplayNode.containerNode.currentItemFilter, isReordering: self.chatListDisplayNode.isReorderingFilters || (self.chatListDisplayNode.containerNode.currentItemNode.currentState.editing && !self.chatListDisplayNode.didBeginSelectingChatsWhileEditing), isEditing: false, transitionFraction: self.chatListDisplayNode.containerNode.transitionFraction, presentationData: self.presentationData, transition: .immediate) } if self.isNodeLoaded { @@ -842,7 +842,13 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController, leftAction = ToolbarAction(title: presentationData.strings.ChatList_Read, isEnabled: enabled) } var archiveEnabled = options.delete - if archiveEnabled && strongSelf.filter == nil { + var displayArchive = true + if let filter = strongSelf.chatListDisplayNode.containerNode.currentItemNode.chatListFilter { + if !filter.data.excludeArchived { + displayArchive = false + } + } + if archiveEnabled { for peerId in peerIds { if peerId == PeerId(namespace: Namespaces.Peer.CloudUser, id: 777000) { archiveEnabled = false @@ -853,7 +859,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController, } } } - toolbar = Toolbar(leftAction: leftAction, rightAction: ToolbarAction(title: presentationData.strings.Common_Delete, isEnabled: options.delete), middleAction: strongSelf.chatListDisplayNode.containerNode.currentItemNode.chatListFilter != nil ? nil : ToolbarAction(title: presentationData.strings.ChatList_ArchiveAction, isEnabled: archiveEnabled)) + toolbar = Toolbar(leftAction: leftAction, rightAction: ToolbarAction(title: presentationData.strings.Common_Delete, isEnabled: options.delete), middleAction: displayArchive ? ToolbarAction(title: presentationData.strings.ChatList_ArchiveAction, isEnabled: archiveEnabled) : nil) } } else { if let (options, peerIds) = peerIdsAndOptions { @@ -1465,8 +1471,8 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController, strongSelf.containerLayoutUpdated(layout, transition: .immediate) (strongSelf.parent as? TabBarController)?.updateLayout() } else { - strongSelf.tabContainerNode.update(size: CGSize(width: layout.size.width, height: 46.0), sideInset: layout.safeInsets.left, filters: resolvedItems, selectedFilter: selectedEntryId, isReordering: strongSelf.chatListDisplayNode.isReorderingFilters || strongSelf.chatListDisplayNode.containerNode.currentItemNode.currentState.editing, isEditing: false, transitionFraction: strongSelf.chatListDisplayNode.containerNode.transitionFraction, presentationData: strongSelf.presentationData, transition: .animated(duration: 0.4, curve: .spring)) - strongSelf.chatListDisplayNode.inlineTabContainerNode.update(size: CGSize(width: layout.size.width, height: 40.0), sideInset: layout.safeInsets.left, filters: resolvedItems, selectedFilter: selectedEntryId, isReordering: strongSelf.chatListDisplayNode.isReorderingFilters || strongSelf.chatListDisplayNode.containerNode.currentItemNode.currentState.editing, isEditing: false, transitionFraction: strongSelf.chatListDisplayNode.containerNode.transitionFraction, presentationData: strongSelf.presentationData, transition: .animated(duration: 0.4, curve: .spring)) + strongSelf.tabContainerNode.update(size: CGSize(width: layout.size.width, height: 46.0), sideInset: layout.safeInsets.left, filters: resolvedItems, selectedFilter: selectedEntryId, isReordering: strongSelf.chatListDisplayNode.isReorderingFilters || (strongSelf.chatListDisplayNode.containerNode.currentItemNode.currentState.editing && !strongSelf.chatListDisplayNode.didBeginSelectingChatsWhileEditing), isEditing: false, transitionFraction: strongSelf.chatListDisplayNode.containerNode.transitionFraction, presentationData: strongSelf.presentationData, transition: .animated(duration: 0.4, curve: .spring)) + strongSelf.chatListDisplayNode.inlineTabContainerNode.update(size: CGSize(width: layout.size.width, height: 40.0), sideInset: layout.safeInsets.left, filters: resolvedItems, selectedFilter: selectedEntryId, isReordering: strongSelf.chatListDisplayNode.isReorderingFilters || (strongSelf.chatListDisplayNode.containerNode.currentItemNode.currentState.editing && !strongSelf.chatListDisplayNode.didBeginSelectingChatsWhileEditing), isEditing: false, transitionFraction: strongSelf.chatListDisplayNode.containerNode.transitionFraction, presentationData: strongSelf.presentationData, transition: .animated(duration: 0.4, curve: .spring)) } } From 1be6e0c3ba04c96c6b3b404a3e1ea92b132f35e2 Mon Sep 17 00:00:00 2001 From: Ali <> Date: Tue, 31 Mar 2020 16:50:17 +0400 Subject: [PATCH 5/6] Fix context menu --- .../TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift index 4365a1d469..6c3735a305 100644 --- a/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift @@ -630,8 +630,8 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView { f() case let .optionalAction(f): f() - case let .openContextMenu(tapMessage, selectAll, subFrame): - self.item?.controllerInteraction.openMessageContextMenu(tapMessage, selectAll, self, subFrame, nil) + case .openContextMenu: + break } } else if case .tap = gesture { self.item?.controllerInteraction.clickThroughMessage() From 4e8cf117b760704f94740d99435a7be48278c23b Mon Sep 17 00:00:00 2001 From: Ali <> Date: Tue, 31 Mar 2020 18:01:54 +0400 Subject: [PATCH 6/6] Trigger build --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 10e5f089c6..651cff8abe 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,7 @@ include Utils.makefile + APP_VERSION="6.0.1" CORE_COUNT=$(shell sysctl -n hw.logicalcpu) CORE_COUNT_MINUS_ONE=$(shell expr ${CORE_COUNT} \- 1)