diff --git a/submodules/ChatListUI/Sources/ChatListFilterTabContainerNode.swift b/submodules/ChatListUI/Sources/ChatListFilterTabContainerNode.swift index 2f8c6cb13d..fc090573b9 100644 --- a/submodules/ChatListUI/Sources/ChatListFilterTabContainerNode.swift +++ b/submodules/ChatListUI/Sources/ChatListFilterTabContainerNode.swift @@ -632,7 +632,7 @@ final class ChatListFilterTabContainerNode: ASDisplayNode { context.fillEllipse(in: CGRect(origin: CGPoint(x: size.width - 3.0, y: 0.0), size: CGSize(width: 3.0, height: 3.0))) context.fill(CGRect(x: 1.5, y: 0.0, width: size.width - 3.0, height: 3.0)) context.fill(CGRect(x: 0.0, y: 2.0, width: size.width, height: 2.0)) - })?.resizableImage(withCapInsets: UIEdgeInsets(top: 3.0, left: 2.5, bottom: 0.0, right: 2.5), resizingMode: .stretch) + })?.resizableImage(withCapInsets: UIEdgeInsets(top: 3.0, left: 3.0, bottom: 0.0, right: 3.0), resizingMode: .stretch) } if isReordering { diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index 7b043f4f00..6ede82d2b3 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -3646,7 +3646,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G if let pinnedMessageId = pinnedMessageId { if let cachedDataMessages = combinedInitialData.cachedDataMessages { if let message = cachedDataMessages[pinnedMessageId] { - pinnedMessage = ChatPinnedMessage(message: message, index: 1, totalCount: 1, topMessageId: message.id) + pinnedMessage = ChatPinnedMessage(message: message, index: 0, totalCount: 1, topMessageId: message.id) } } } @@ -3798,7 +3798,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } if let pinnedMessageId = pinnedMessageId { if let message = messages?[pinnedMessageId] { - pinnedMessage = ChatPinnedMessage(message: message, index: 1, totalCount: 1, topMessageId: message.id) + pinnedMessage = ChatPinnedMessage(message: message, index: 0, totalCount: 1, topMessageId: message.id) } } case .peer: @@ -5097,18 +5097,18 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } } - if let peer = peer as? TelegramUser, let contextController = contextController { + if let peer = peer as? TelegramUser, peer.id != strongSelf.context.account.peerId, let contextController = contextController { var contextItems: [ContextMenuItem] = [] contextItems.append(.action(ContextMenuActionItem(text: strongSelf.presentationData.strings.Conversation_PinMessagesFor(peer.compactDisplayTitle).0, textColor: .primary, icon: { _ in nil }, action: { c, _ in c.dismiss(completion: { - pinAction(true, true) + pinAction(true, false) }) }))) contextItems.append(.action(ContextMenuActionItem(text: strongSelf.presentationData.strings.Conversation_PinMessagesForMe, textColor: .primary, icon: { _ in nil }, action: { c, _ in c.dismiss(completion: { - pinAction(true, false) + pinAction(true, true) }) }))) @@ -5116,59 +5116,71 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G return } else { - contextController?.dismiss(completion: {}) - } - - var pinImmediately = false - if let channel = peer as? TelegramChannel, case .broadcast = channel.info { - pinImmediately = true - } else if let _ = peer as? TelegramUser { - pinImmediately = true - } - - if pinImmediately { - pinAction(true, false) - } else { - let topPinnedMessage: Signal = strongSelf.topPinnedMessageSignal(latest: true) - |> take(1) - - let _ = (topPinnedMessage - |> deliverOnMainQueue).start(next: { value in + let continueAction: () -> Void = { guard let strongSelf = self else { return } - let title: String? - let text: String - let actionLayout: TextAlertContentActionLayout - let actions: [TextAlertAction] - if let value = value, value.message.id > messageId { - title = strongSelf.presentationData.strings.Conversation_PinOlderMessageAlertTitle - text = strongSelf.presentationData.strings.Conversation_PinOlderMessageAlertText - actionLayout = .vertical - actions = [ - TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Conversation_PinMessageAlertPin, action: { - pinAction(false, false) - }), - TextAlertAction(type: .genericAction, title: strongSelf.presentationData.strings.Common_Cancel, action: { - }) - ] - } else { - title = nil - text = strongSelf.presentationData.strings.Conversation_PinMessageAlertGroup - actionLayout = .horizontal - actions = [ - TextAlertAction(type: .genericAction, title: strongSelf.presentationData.strings.Conversation_PinMessageAlert_OnlyPin, action: { - pinAction(false, false) - }), - TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_Yes, action: { - pinAction(true, false) - }) - ] + var pinImmediately = false + if let channel = peer as? TelegramChannel, case .broadcast = channel.info { + pinImmediately = true + } else if let _ = peer as? TelegramUser { + pinImmediately = true } - strongSelf.present(textAlertController(context: strongSelf.context, title: title, text: text, actions: actions, actionLayout: actionLayout), in: .window(.root)) - }) + if pinImmediately { + pinAction(true, false) + } else { + let topPinnedMessage: Signal = strongSelf.topPinnedMessageSignal(latest: true) + |> take(1) + + let _ = (topPinnedMessage + |> deliverOnMainQueue).start(next: { value in + guard let strongSelf = self else { + return + } + + let title: String? + let text: String + let actionLayout: TextAlertContentActionLayout + let actions: [TextAlertAction] + if let value = value, value.message.id > messageId { + title = strongSelf.presentationData.strings.Conversation_PinOlderMessageAlertTitle + text = strongSelf.presentationData.strings.Conversation_PinOlderMessageAlertText + actionLayout = .vertical + actions = [ + TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Conversation_PinMessageAlertPin, action: { + pinAction(false, false) + }), + TextAlertAction(type: .genericAction, title: strongSelf.presentationData.strings.Common_Cancel, action: { + }) + ] + } else { + title = nil + text = strongSelf.presentationData.strings.Conversation_PinMessageAlertGroup + actionLayout = .horizontal + actions = [ + TextAlertAction(type: .genericAction, title: strongSelf.presentationData.strings.Conversation_PinMessageAlert_OnlyPin, action: { + pinAction(false, false) + }), + TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_Yes, action: { + pinAction(true, false) + }) + ] + } + + strongSelf.present(textAlertController(context: strongSelf.context, title: title, text: text, actions: actions, actionLayout: actionLayout), in: .window(.root)) + }) + } + } + + if let contextController = contextController { + contextController.dismiss(completion: { + continueAction() + }) + } else { + continueAction() + } } } else { if let topPinnedMessageId = strongSelf.presentationInterfaceState.pinnedMessage?.topMessageId { diff --git a/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift b/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift index 131f271b51..4606d3d9fc 100644 --- a/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift +++ b/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift @@ -344,6 +344,16 @@ func contextMenuForChatPresentationIntefaceState(chatPresentationInterfaceState: canPin = false } + if let peer = messages[0].peers[messages[0].id.peerId] { + if peer.isDeleted { + canPin = false + } + if !(peer is TelegramSecretChat) && messages[0].id.namespace != Namespaces.Message.Cloud { + canPin = false + canReply = false + } + } + var loadStickerSaveStatusSignal: Signal = .single(nil) if loadStickerSaveStatus != nil { loadStickerSaveStatusSignal = context.account.postbox.transaction { transaction -> Bool? in diff --git a/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift index d7a87fd8da..686d95a78b 100644 --- a/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift @@ -60,7 +60,7 @@ class ChatMessageShareButton: HighlightableButtonNode { fatalError("init(coder:) has not been implemented") } - func update(presentationData: ChatPresentationData, chatLocation: ChatLocation, message: Message, account: Account) -> CGSize { + func update(presentationData: ChatPresentationData, chatLocation: ChatLocation, subject: ChatControllerSubject?, message: Message, account: Account) -> CGSize { var isReplies = false var replyCount = 0 if let channel = message.peers[message.id.peerId] as? TelegramChannel, case .broadcast = channel.info { @@ -84,7 +84,9 @@ class ChatMessageShareButton: HighlightableButtonNode { let graphics = PresentationResourcesChat.additionalGraphics(presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper, bubbleCorners: presentationData.chatBubbleCorners) var updatedShareButtonBackground: UIImage? var updatedIconImage: UIImage? - if isReplies { + if case .pinnedMessages = subject { + updatedShareButtonBackground = graphics.chatBubbleNavigateButtonImage + } else 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.isRepliesOrSavedMessages(accountPeerId: account.peerId) { @@ -607,7 +609,9 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { let isFailed = item.content.firstMessage.effectivelyFailed(timestamp: item.context.account.network.getApproximateRemoteTimestamp()) var needShareButton = false - if isFailed || Namespaces.Message.allScheduled.contains(item.message.id.namespace) { + if case .pinnedMessages = item.associatedData.subject { + needShareButton = true + } else if isFailed || Namespaces.Message.allScheduled.contains(item.message.id.namespace) { needShareButton = false } else if item.message.id.peerId.isRepliesOrSavedMessages(accountPeerId: item.context.account.peerId) { for attribute in item.content.firstMessage.attributes { @@ -941,7 +945,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { strongSelf.addSubnode(updatedShareButtonNode) updatedShareButtonNode.addTarget(strongSelf, action: #selector(strongSelf.shareButtonPressed), forControlEvents: .touchUpInside) } - let buttonSize = updatedShareButtonNode.update(presentationData: item.presentationData, chatLocation: item.chatLocation, message: item.message, account: item.context.account) + let buttonSize = updatedShareButtonNode.update(presentationData: item.presentationData, chatLocation: item.chatLocation, subject: item.associatedData.subject, message: item.message, account: item.context.account) updatedShareButtonNode.frame = CGRect(origin: CGPoint(x: updatedImageFrame.maxX + 8.0, y: updatedImageFrame.maxY - buttonSize.height - 4.0), size: buttonSize) } else if let shareButtonNode = strongSelf.shareButtonNode { shareButtonNode.removeFromSupernode() @@ -1266,6 +1270,11 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { @objc func shareButtonPressed() { if let item = self.item { + if case .pinnedMessages = item.associatedData.subject { + item.controllerInteraction.navigateToMessageStandalone(item.content.firstMessage.id) + return + } + if let channel = item.message.peers[item.message.id.peerId] as? TelegramChannel, case .broadcast = channel.info { for attribute in item.message.attributes { if let _ = attribute as? ReplyThreadMessageAttribute { diff --git a/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift index a2346cffdd..bc18880374 100644 --- a/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift @@ -162,7 +162,9 @@ private func contentNodeMessagesAndClassesForItem(_ item: ChatMessageItem) -> ([ if hasDiscussion { var canComment = false - if firstMessage.id.namespace == Namespaces.Message.Local { + if case .pinnedMessages = item.associatedData.subject { + canComment = false + } else if firstMessage.id.namespace == Namespaces.Message.Local { canComment = true } else { for attribute in firstMessage.attributes { diff --git a/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift index 7232246a2e..45caac741f 100644 --- a/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift @@ -216,7 +216,9 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView { let isFailed = item.content.firstMessage.effectivelyFailed(timestamp: item.context.account.network.getApproximateRemoteTimestamp()) var needShareButton = false - if isFailed || Namespaces.Message.allScheduled.contains(item.message.id.namespace) { + if case .pinnedMessages = item.associatedData.subject { + needShareButton = true + } else if isFailed || Namespaces.Message.allScheduled.contains(item.message.id.namespace) { needShareButton = false } else if item.message.id.peerId == item.context.account.peerId { @@ -473,7 +475,7 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView { strongSelf.addSubnode(updatedShareButtonNode) updatedShareButtonNode.addTarget(strongSelf, action: #selector(strongSelf.shareButtonPressed), forControlEvents: .touchUpInside) } - let buttonSize = updatedShareButtonNode.update(presentationData: item.presentationData, chatLocation: item.chatLocation, message: item.message, account: item.context.account) + let buttonSize = updatedShareButtonNode.update(presentationData: item.presentationData, chatLocation: item.chatLocation, subject: item.associatedData.subject, message: item.message, account: item.context.account) updatedShareButtonNode.frame = CGRect(origin: CGPoint(x: videoFrame.maxX - 7.0, y: videoFrame.maxY - 24.0 - buttonSize.height), size: buttonSize) } else if let shareButtonNode = strongSelf.shareButtonNode { shareButtonNode.removeFromSupernode() @@ -745,6 +747,11 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView { @objc func shareButtonPressed() { if let item = self.item { + if case .pinnedMessages = item.associatedData.subject { + item.controllerInteraction.navigateToMessageStandalone(item.content.firstMessage.id) + return + } + if let channel = item.message.peers[item.message.id.peerId] as? TelegramChannel, case .broadcast = channel.info { for attribute in item.message.attributes { if let _ = attribute as? ReplyThreadMessageAttribute { diff --git a/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift index b06c633de4..6943596335 100644 --- a/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift @@ -279,7 +279,9 @@ class ChatMessageStickerItemNode: ChatMessageItemView { let isFailed = item.content.firstMessage.effectivelyFailed(timestamp: item.context.account.network.getApproximateRemoteTimestamp()) var needShareButton = false - if isFailed || Namespaces.Message.allScheduled.contains(item.message.id.namespace) { + if case .pinnedMessages = item.associatedData.subject { + needShareButton = true + } else if isFailed || Namespaces.Message.allScheduled.contains(item.message.id.namespace) { needShareButton = false } else if item.message.id.peerId == item.context.account.peerId { for attribute in item.content.firstMessage.attributes { @@ -568,7 +570,7 @@ class ChatMessageStickerItemNode: ChatMessageItemView { strongSelf.addSubnode(updatedShareButtonNode) updatedShareButtonNode.addTarget(strongSelf, action: #selector(strongSelf.shareButtonPressed), forControlEvents: .touchUpInside) } - let buttonSize = updatedShareButtonNode.update(presentationData: item.presentationData, chatLocation: item.chatLocation, message: item.message, account: item.context.account) + let buttonSize = updatedShareButtonNode.update(presentationData: item.presentationData, chatLocation: item.chatLocation, subject: item.associatedData.subject, message: item.message, account: item.context.account) let shareButtonFrame = CGRect(origin: CGPoint(x: baseShareButtonFrame.minX, y: baseShareButtonFrame.maxY - buttonSize.height), size: buttonSize) transition.updateFrame(node: updatedShareButtonNode, frame: shareButtonFrame) } else if let shareButtonNode = strongSelf.shareButtonNode { @@ -811,6 +813,11 @@ class ChatMessageStickerItemNode: ChatMessageItemView { @objc func shareButtonPressed() { if let item = self.item { + if case .pinnedMessages = item.associatedData.subject { + item.controllerInteraction.navigateToMessageStandalone(item.content.firstMessage.id) + return + } + if let channel = item.message.peers[item.message.id.peerId] as? TelegramChannel, case .broadcast = channel.info { for attribute in item.message.attributes { if let _ = attribute as? ReplyThreadMessageAttribute {