From 0fbc4f7009754114af9e65f07487cdbb9c069044 Mon Sep 17 00:00:00 2001 From: Ali <> Date: Fri, 11 Sep 2020 13:08:04 +0100 Subject: [PATCH] Comment improvements --- .../TelegramUI/Sources/ChatController.swift | 35 ++++++++++++++++--- .../Sources/ChatHistoryListNode.swift | 7 ++++ .../Sources/ChatHistoryViewForLocation.swift | 2 +- .../ChatInterfaceStateContextMenus.swift | 3 ++ .../ChatInterfaceStateNavigationButtons.swift | 33 ++++++++++++----- .../ChatMessageAnimatedStickerItemNode.swift | 10 +++--- .../Sources/ChatMessageBubbleItemNode.swift | 6 ++-- .../ChatMessageCommentFooterContentNode.swift | 13 +++---- .../ChatMessageDateAndStatusNode.swift | 14 +++++++- .../ChatMessageInstantVideoItemNode.swift | 6 ++-- .../Sources/ChatMessageStickerItemNode.swift | 6 ++-- 11 files changed, 99 insertions(+), 36 deletions(-) diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index 1f12d85357..860bdf6375 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -289,6 +289,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G private var checkedPeerChatServiceActions = false + private var didAppear = false + private var scheduledActivateInput = false + private var raiseToListen: RaiseToListenManager? private var voicePlaylistDidEndTimestamp: Double = 0.0 @@ -2196,7 +2199,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G if let result = result { if let navigationController = strongSelf.navigationController as? NavigationController { - strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .replyThread(threadMessageId: result.messageId, isChannelPost: true, maxReadMessageId: result.maxReadMessageId), keepStack: .always)) + strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .replyThread(threadMessageId: result.messageId, isChannelPost: true, maxReadMessageId: result.maxReadMessageId), activateInput: true, keepStack: .always)) } } }) @@ -3425,7 +3428,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G let callsDataUpdated = strongSelf.presentationInterfaceState.callsAvailable != callsAvailable || strongSelf.presentationInterfaceState.callsPrivate != callsPrivate - if strongSelf.presentationInterfaceState.pinnedMessageId != pinnedMessageId || strongSelf.presentationInterfaceState.pinnedMessage?.stableVersion != pinnedMessage?.stableVersion || strongSelf.presentationInterfaceState.peerIsBlocked != peerIsBlocked || pinnedMessageUpdated || callsDataUpdated || strongSelf.presentationInterfaceState.slowmodeState != slowmodeState { + if strongSelf.presentationInterfaceState.pinnedMessageId != pinnedMessageId || strongSelf.presentationInterfaceState.pinnedMessage?.stableVersion != pinnedMessage?.stableVersion || strongSelf.presentationInterfaceState.peerIsBlocked != peerIsBlocked || pinnedMessageUpdated || callsDataUpdated || strongSelf.presentationInterfaceState.slowmodeState != slowmodeState { strongSelf.updateChatPresentationInterfaceState(animated: true, interactive: true, { state in return state .updatedPinnedMessageId(pinnedMessageId) @@ -5322,11 +5325,21 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G override public func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) + + if self.scheduledActivateInput { + self.scheduledActivateInput = false + + self.updateChatPresentationInterfaceState(animated: true, interactive: true, { state in + return state.updatedInputMode({ _ in .text }) + }) + } } override public func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) + self.didAppear = true + self.chatDisplayNode.historyNode.preloadPages = true self.chatDisplayNode.historyNode.experimentalSnapScrollToItem = false self.chatDisplayNode.historyNode.canReadHistory.set(combineLatest(context.sharedContext.applicationBindings.applicationInForeground, self.canReadHistory.get()) |> map { a, b in @@ -5587,6 +5600,14 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G ), in: .window(.root)) })) } + + if self.scheduledActivateInput { + self.scheduledActivateInput = false + + self.updateChatPresentationInterfaceState(animated: true, interactive: true, { state in + return state.updatedInputMode({ _ in .text }) + }) + } } override public func viewWillDisappear(_ animated: Bool) { @@ -9705,9 +9726,13 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } func activateInput() { - self.updateChatPresentationInterfaceState(animated: true, interactive: true, { state in - return state.updatedInputMode({ _ in .text }) - }) + if self.didAppear { + self.updateChatPresentationInterfaceState(animated: true, interactive: true, { state in + return state.updatedInputMode({ _ in .text }) + }) + } else { + self.scheduledActivateInput = true + } } private func clearInputText() { diff --git a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift index b71ffff20e..41fba048d2 100644 --- a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift +++ b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift @@ -617,6 +617,13 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { additionalData.append(.totalUnreadState) } if case let .replyThread(messageId, _, _) = chatLocation { + additionalData.append(.cachedPeerData(messageId.peerId)) + additionalData.append(.peerNotificationSettings(messageId.peerId)) + if messageId.peerId.namespace == Namespaces.Peer.CloudChannel { + additionalData.append(.cacheEntry(cachedChannelAdminRanksEntryId(peerId: messageId.peerId))) + additionalData.append(.peer(messageId.peerId)) + } + additionalData.append(.message(messageId)) } diff --git a/submodules/TelegramUI/Sources/ChatHistoryViewForLocation.swift b/submodules/TelegramUI/Sources/ChatHistoryViewForLocation.swift index ac1ae864b6..79d5ffc514 100644 --- a/submodules/TelegramUI/Sources/ChatHistoryViewForLocation.swift +++ b/submodules/TelegramUI/Sources/ChatHistoryViewForLocation.swift @@ -256,7 +256,7 @@ private func extractAdditionalData(view: MessageHistoryView, chatLocation: ChatL case let .peerNotificationSettings(value): notificationSettings = value case let .cachedPeerData(peerIdValue, value): - if case .peer(peerIdValue) = chatLocation { + if chatLocation.peerId == peerIdValue { cachedData = value } case let .cachedPeerDataMessages(peerIdValue, value): diff --git a/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift b/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift index b96d8a447a..e14442ec14 100644 --- a/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift +++ b/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift @@ -1070,6 +1070,9 @@ func chatAvailableMessageActionsImpl(postbox: Postbox, accountPeerId: PeerId, me } else if limitsConfiguration.canRemoveIncomingMessagesInPrivateChats { canDeleteGlobally = true } + if user.botInfo != nil { + canDeleteGlobally = false + } let timestamp = Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970) if isDice && Int64(message.timestamp) + 60 * 60 * 24 > Int64(timestamp) { diff --git a/submodules/TelegramUI/Sources/ChatInterfaceStateNavigationButtons.swift b/submodules/TelegramUI/Sources/ChatInterfaceStateNavigationButtons.swift index a8971c99a5..91915964bb 100644 --- a/submodules/TelegramUI/Sources/ChatInterfaceStateNavigationButtons.swift +++ b/submodules/TelegramUI/Sources/ChatInterfaceStateNavigationButtons.swift @@ -75,17 +75,15 @@ func rightNavigationButtonForChatInterfaceState(_ presentationInterfaceState: Ch } } - if case .replyThread = presentationInterfaceState.chatLocation { - if case .search = currentButton?.action { - return currentButton - } else { - let buttonItem = UIBarButtonItem(image: PresentationResourcesRootController.navigationCompactSearchIcon(presentationInterfaceState.theme), style: .plain, target: target, action: selector) - buttonItem.accessibilityLabel = strings.Conversation_Search - return ChatNavigationButton(action: .search, buttonItem: buttonItem) + var hasMessages = false + if let chatHistoryState = presentationInterfaceState.chatHistoryState { + if case .loaded(false) = chatHistoryState { + hasMessages = true } } - if case let .peer(peerId) = presentationInterfaceState.chatLocation { - if peerId.isReplies { + + if case .replyThread = presentationInterfaceState.chatLocation { + if hasMessages { if case .search = currentButton?.action { return currentButton } else { @@ -93,6 +91,23 @@ func rightNavigationButtonForChatInterfaceState(_ presentationInterfaceState: Ch buttonItem.accessibilityLabel = strings.Conversation_Search return ChatNavigationButton(action: .search, buttonItem: buttonItem) } + } else { + return nil + } + } + if case let .peer(peerId) = presentationInterfaceState.chatLocation { + if peerId.isReplies { + if hasMessages { + if case .search = currentButton?.action { + return currentButton + } else { + let buttonItem = UIBarButtonItem(image: PresentationResourcesRootController.navigationCompactSearchIcon(presentationInterfaceState.theme), style: .plain, target: target, action: selector) + buttonItem.accessibilityLabel = strings.Conversation_Search + return ChatNavigationButton(action: .search, buttonItem: buttonItem) + } + } else { + return nil + } } } diff --git a/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift index 7ec359bac7..e898e0198b 100644 --- a/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift @@ -78,7 +78,7 @@ class ChatMessageShareButton: HighlightableButtonNode { if isReplies { updatedShareButtonBackground = PresentationResourcesChat.chatFreeCommentButtonBackground(presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper) updatedIconImage = PresentationResourcesChat.chatFreeCommentButtonIcon(presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper) - } else if message.id.peerId == account.peerId { + } else if message.id.peerId.isRepliesOrSavedMessages(accountPeerId: account.peerId) { updatedShareButtonBackground = graphics.chatBubbleNavigateButtonImage } else { updatedShareButtonBackground = graphics.chatBubbleShareButtonImage @@ -114,7 +114,7 @@ class ChatMessageShareButton: HighlightableButtonNode { textNode.attributedText = NSAttributedString(string: countString, font: Font.regular(11.0), textColor: textColor) let textSize = textNode.updateLayout(CGSize(width: 100.0, height: 100.0)) size.height += textSize.height - 1.0 - textNode.frame = CGRect(origin: CGPoint(x: floor((size.width - textSize.width) / 2.0), y: size.height - textSize.height - 4.0), size: textSize) + textNode.frame = CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - textSize.width) / 2.0), y: size.height - textSize.height - 4.0), size: textSize) } else if let textNode = self.textNode { self.textNode = nil textNode.removeFromSupernode() @@ -751,7 +751,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { } } - if item.message.id.peerId != item.context.account.peerId { + if item.message.id.peerId != item.context.account.peerId && !item.message.id.peerId.isReplies { for attribute in item.message.attributes { if let attribute = attribute as? SourceReferenceMessageAttribute { if let sourcePeer = item.message.peers[attribute.messageId.peerId] { @@ -1130,7 +1130,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { 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 !item.message.id.peerId.isReplies, 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) @@ -1255,7 +1255,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { } } - if item.content.firstMessage.id.peerId == item.context.account.peerId { + if item.content.firstMessage.id.peerId.isRepliesOrSavedMessages(accountPeerId: item.context.account.peerId) { for attribute in item.content.firstMessage.attributes { if let attribute = attribute as? SourceReferenceMessageAttribute { item.controllerInteraction.navigateToMessage(item.content.firstMessage.id, attribute.messageId) diff --git a/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift index 0e5911be0d..d9299f9338 100644 --- a/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift @@ -2117,7 +2117,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePrevewItemNode } if let mosaicStatusOrigin = mosaicStatusOrigin, let (size, apply) = mosaicStatusSizeAndApply { - let mosaicStatusNode = apply(false) + let mosaicStatusNode = apply(transition.isAnimated) if mosaicStatusNode !== strongSelf.mosaicStatusNode { strongSelf.mosaicStatusNode?.removeFromSupernode() strongSelf.mosaicStatusNode = mosaicStatusNode @@ -2511,7 +2511,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePrevewItemNode if item.message.id.peerId.isRepliesOrSavedMessages(accountPeerId: item.context.account.peerId), let channel = item.content.firstMessage.forwardInfo?.author as? TelegramChannel, channel.username == nil { if case let .broadcast(info) = channel.info, info.flags.contains(.hasDiscussionGroup) { } else if case .member = channel.participationStatus { - } else { + } else if !item.message.id.peerId.isReplies { item.controllerInteraction.displayMessageTooltip(item.message.id, item.presentationData.strings.Conversation_PrivateChannelTooltip, self, avatarNode.frame) return } @@ -2564,7 +2564,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePrevewItemNode if let channel = forwardInfo.author as? TelegramChannel, channel.username == nil { if case let .broadcast(info) = channel.info, info.flags.contains(.hasDiscussionGroup) { } else if case .member = channel.participationStatus { - } else { + } else if !item.message.id.peerId.isReplies { item.controllerInteraction.displayMessageTooltip(item.message.id, item.presentationData.strings.Conversation_PrivateChannelTooltip, forwardInfoNode, nil) return } diff --git a/submodules/TelegramUI/Sources/ChatMessageCommentFooterContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageCommentFooterContentNode.swift index 143fc08019..3b22bc1c83 100644 --- a/submodules/TelegramUI/Sources/ChatMessageCommentFooterContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageCommentFooterContentNode.swift @@ -43,12 +43,12 @@ final class ChatMessageCommentFooterContentNode: ChatMessageBubbleContentNode { super.init() - self.addSubnode(self.separatorNode) - self.addSubnode(self.textNode) - self.addSubnode(self.iconNode) - self.addSubnode(self.arrowNode) + self.buttonNode.addSubnode(self.separatorNode) + self.buttonNode.addSubnode(self.textNode) + self.buttonNode.addSubnode(self.iconNode) + self.buttonNode.addSubnode(self.arrowNode) + self.buttonNode.addSubnode(self.avatarsNode) self.addSubnode(self.buttonNode) - self.addSubnode(self.avatarsNode) self.buttonNode.highligthedChanged = { [weak self] highlighted in if let strongSelf = self { @@ -183,7 +183,7 @@ final class ChatMessageCommentFooterContentNode: ChatMessageBubbleContentNode { iconOffset = CGPoint(x: -4.0, y: -4.0) } else { iconImage = PresentationResourcesChat.chatMessageCommentsIcon(item.presentationData.theme.theme, incoming: incoming) - iconOffset = CGPoint() + iconOffset = CGPoint(x: 0.0, y: -1.0) } let arrowImage = PresentationResourcesChat.chatMessageCommentsArrowIcon(item.presentationData.theme.theme, incoming: incoming) @@ -250,6 +250,7 @@ final class ChatMessageCommentFooterContentNode: ChatMessageBubbleContentNode { strongSelf.buttonNode.frame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: boundingWidth, height: boundingSize.height)) strongSelf.buttonNode.isUserInteractionEnabled = item.message.id.namespace == Namespaces.Message.Cloud + strongSelf.buttonNode.alpha = item.message.id.namespace == Namespaces.Message.Cloud ? 1.0 : 0.5 } }) }) diff --git a/submodules/TelegramUI/Sources/ChatMessageDateAndStatusNode.swift b/submodules/TelegramUI/Sources/ChatMessageDateAndStatusNode.swift index e14086a7e8..5086a30fbe 100644 --- a/submodules/TelegramUI/Sources/ChatMessageDateAndStatusNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageDateAndStatusNode.swift @@ -739,12 +739,24 @@ class ChatMessageDateAndStatusNode: ASDisplayNode { if currentRepliesIcon.supernode == nil { strongSelf.repliesIcon = currentRepliesIcon strongSelf.addSubnode(currentRepliesIcon) + if animated { + currentRepliesIcon.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.15) + } } currentRepliesIcon.frame = CGRect(origin: CGPoint(x: reactionOffset - 2.0, y: backgroundInsets.top + offset + floor((date.size.height - repliesIconSize.height) / 2.0)), size: repliesIconSize) reactionOffset += 9.0 } else if let repliesIcon = strongSelf.repliesIcon { - repliesIcon.removeFromSupernode() strongSelf.repliesIcon = nil + if animated { + if let previousLayoutSize = previousLayoutSize { + repliesIcon.frame = repliesIcon.frame.offsetBy(dx: layoutSize.width - previousLayoutSize.width, dy: 0.0) + } + repliesIcon.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { [weak repliesIcon] _ in + repliesIcon?.removeFromSupernode() + }) + } else { + repliesIcon.removeFromSupernode() + } } if let (layout, apply) = replyCountLayoutAndApply { diff --git a/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift index 4dedc29798..a3c216e374 100644 --- a/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift @@ -674,7 +674,7 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView { 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 !item.message.id.peerId.isReplies, 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) @@ -703,7 +703,7 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView { if let item = self.item, let forwardInfo = item.message.forwardInfo { let performAction: () -> Void = { if let sourceMessageId = forwardInfo.sourceMessageId { - if let channel = forwardInfo.author as? TelegramChannel, channel.username == nil { + if !item.message.id.peerId.isReplies, let channel = forwardInfo.author as? TelegramChannel, channel.username == nil { if case let .broadcast(info) = channel.info, info.flags.contains(.hasDiscussionGroup) { } else if case .member = channel.participationStatus { } else { @@ -748,7 +748,7 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView { } } - if item.content.firstMessage.id.peerId == item.context.account.peerId { + if item.content.firstMessage.id.peerId.isRepliesOrSavedMessages(accountPeerId: item.context.account.peerId) { for attribute in item.content.firstMessage.attributes { if let attribute = attribute as? SourceReferenceMessageAttribute { item.controllerInteraction.navigateToMessage(item.content.firstMessage.id, attribute.messageId) diff --git a/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift index 9fd9092639..9e98a7489c 100644 --- a/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift @@ -420,7 +420,7 @@ class ChatMessageStickerItemNode: ChatMessageItemView { } } - if item.message.id.peerId != item.context.account.peerId { + if item.message.id.peerId != item.context.account.peerId && !item.message.id.peerId.isReplies{ for attribute in item.message.attributes { if let attribute = attribute as? SourceReferenceMessageAttribute { if let sourcePeer = item.message.peers[attribute.messageId.peerId] { @@ -703,7 +703,7 @@ class ChatMessageStickerItemNode: ChatMessageItemView { 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 !item.message.id.peerId.isReplies, 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) @@ -781,7 +781,7 @@ class ChatMessageStickerItemNode: ChatMessageItemView { } } - if item.content.firstMessage.id.peerId == item.context.account.peerId { + if item.content.firstMessage.id.peerId.isRepliesOrSavedMessages(accountPeerId: item.context.account.peerId) { for attribute in item.content.firstMessage.attributes { if let attribute = attribute as? SourceReferenceMessageAttribute { item.controllerInteraction.navigateToMessage(item.content.firstMessage.id, attribute.messageId)