diff --git a/submodules/AttachmentUI/Sources/AttachmentPanel.swift b/submodules/AttachmentUI/Sources/AttachmentPanel.swift index 096cae3fe6..fad73f715b 100644 --- a/submodules/AttachmentUI/Sources/AttachmentPanel.swift +++ b/submodules/AttachmentUI/Sources/AttachmentPanel.swift @@ -764,6 +764,7 @@ final class AttachmentPanel: ASDisplayNode, UIScrollViewDelegate { self.interfaceInteraction = ChatPanelInterfaceInteraction(setupReplyMessage: { _, _ in }, setupEditMessage: { _, _ in }, beginMessageSelection: { _, _ in + }, cancelMessageSelection: { _ in }, deleteSelectedMessages: { }, reportSelectedMessages: { }, reportMessages: { _, _ in diff --git a/submodules/ChatPresentationInterfaceState/Sources/ChatPanelInterfaceInteraction.swift b/submodules/ChatPresentationInterfaceState/Sources/ChatPanelInterfaceInteraction.swift index 34aaeff47b..cdeb3d6ee8 100644 --- a/submodules/ChatPresentationInterfaceState/Sources/ChatPanelInterfaceInteraction.swift +++ b/submodules/ChatPresentationInterfaceState/Sources/ChatPanelInterfaceInteraction.swift @@ -72,6 +72,7 @@ public final class ChatPanelInterfaceInteraction { public let setupReplyMessage: (MessageId?, @escaping (ContainedViewLayoutTransition, @escaping () -> Void) -> Void) -> Void public let setupEditMessage: (MessageId?, @escaping (ContainedViewLayoutTransition) -> Void) -> Void public let beginMessageSelection: ([MessageId], @escaping (ContainedViewLayoutTransition) -> Void) -> Void + public let cancelMessageSelection: (ContainedViewLayoutTransition) -> Void public let deleteSelectedMessages: () -> Void public let reportSelectedMessages: () -> Void public let reportMessages: ([Message], ContextControllerProtocol?) -> Void @@ -182,6 +183,7 @@ public final class ChatPanelInterfaceInteraction { setupReplyMessage: @escaping (MessageId?, @escaping (ContainedViewLayoutTransition, @escaping () -> Void) -> Void) -> Void, setupEditMessage: @escaping (MessageId?, @escaping (ContainedViewLayoutTransition) -> Void) -> Void, beginMessageSelection: @escaping ([MessageId], @escaping (ContainedViewLayoutTransition) -> Void) -> Void, + cancelMessageSelection: @escaping (ContainedViewLayoutTransition) -> Void, deleteSelectedMessages: @escaping () -> Void, reportSelectedMessages: @escaping () -> Void, reportMessages: @escaping ([Message], ContextControllerProtocol?) -> Void, @@ -291,6 +293,7 @@ public final class ChatPanelInterfaceInteraction { self.setupReplyMessage = setupReplyMessage self.setupEditMessage = setupEditMessage self.beginMessageSelection = beginMessageSelection + self.cancelMessageSelection = cancelMessageSelection self.deleteSelectedMessages = deleteSelectedMessages self.reportSelectedMessages = reportSelectedMessages self.reportMessages = reportMessages @@ -407,6 +410,7 @@ public final class ChatPanelInterfaceInteraction { self.init(setupReplyMessage: { _, _ in }, setupEditMessage: { _, _ in }, beginMessageSelection: { _, _ in + }, cancelMessageSelection: { _ in }, deleteSelectedMessages: { }, reportSelectedMessages: { }, reportMessages: { _, _ in diff --git a/submodules/ContextUI/Sources/ContextSourceContainer.swift b/submodules/ContextUI/Sources/ContextSourceContainer.swift index d027596dfa..d6c7ec6e7e 100644 --- a/submodules/ContextUI/Sources/ContextSourceContainer.swift +++ b/submodules/ContextUI/Sources/ContextSourceContainer.swift @@ -377,10 +377,7 @@ final class ContextSourceContainer: ASDisplayNode { super.init() - #if DEBUG - #else self.addSubnode(self.backgroundNode) - #endif for i in 0 ..< configuration.sources.count { let source = configuration.sources[i] diff --git a/submodules/TelegramBaseController/Sources/TelegramBaseController.swift b/submodules/TelegramBaseController/Sources/TelegramBaseController.swift index 23a9fb7336..49069c9aef 100644 --- a/submodules/TelegramBaseController/Sources/TelegramBaseController.swift +++ b/submodules/TelegramBaseController/Sources/TelegramBaseController.swift @@ -65,6 +65,8 @@ open class TelegramBaseController: ViewController, KeyShortcutResponder { public private(set) var accessoryPanelContainerHeight: CGFloat = 0.0 public let mediaAccessoryPanelVisibility: MediaAccessoryPanelVisibility + public var tempHideAccessoryPanels: Bool = false + public let locationBroadcastPanelSource: LocationBroadcastPanelSource public let groupCallPanelSource: GroupCallPanelSource @@ -408,13 +410,17 @@ open class TelegramBaseController: ViewController, KeyShortcutResponder { let navigationHeight = super.navigationLayout(layout: layout).navigationFrame.height - self.additionalNavigationBarHeight let mediaAccessoryPanelHidden: Bool - switch self.mediaAccessoryPanelVisibility { - case .always: - mediaAccessoryPanelHidden = false - case .none: + if self.tempHideAccessoryPanels { mediaAccessoryPanelHidden = true - case let .specific(size): - mediaAccessoryPanelHidden = size != layout.metrics.widthClass + } else { + switch self.mediaAccessoryPanelVisibility { + case .always: + mediaAccessoryPanelHidden = false + case .none: + mediaAccessoryPanelHidden = true + case let .specific(size): + mediaAccessoryPanelHidden = size != layout.metrics.widthClass + } } var additionalHeight: CGFloat = 0.0 diff --git a/submodules/TelegramCore/Sources/State/MessageReactions.swift b/submodules/TelegramCore/Sources/State/MessageReactions.swift index df29cf521f..2f305cdd06 100644 --- a/submodules/TelegramCore/Sources/State/MessageReactions.swift +++ b/submodules/TelegramCore/Sources/State/MessageReactions.swift @@ -18,7 +18,7 @@ public enum UpdateMessageReaction { } } -public func updateMessageReactionsInteractively(account: Account, messageId: MessageId, reactions: [UpdateMessageReaction], isLarge: Bool, storeAsRecentlyUsed: Bool) -> Signal { +public func updateMessageReactionsInteractively(account: Account, messageId: MessageId, reactions: [UpdateMessageReaction], isLarge: Bool, storeAsRecentlyUsed: Bool, add: Bool = false) -> Signal { return account.postbox.transaction { transaction -> Void in var sendAsPeerId = account.peerId if let cachedData = transaction.getPeerCachedData(peerId: messageId.peerId) { @@ -40,6 +40,25 @@ public func updateMessageReactionsInteractively(account: Account, messageId: Mes } var mappedReactions: [PendingReactionsMessageAttribute.PendingReaction] = [] + + var reactions: [UpdateMessageReaction] = reactions + if add { + if let message = transaction.getMessage(messageId), let effectiveReactions = message.effectiveReactions(isTags: message.areReactionsTags(accountPeerId: account.peerId)) { + for reaction in effectiveReactions { + if !reactions.contains(where: { $0.reaction == reaction.value }) { + let mappedValue: UpdateMessageReaction + switch reaction.value { + case let .builtin(value): + mappedValue = .builtin(value) + case let .custom(fileId): + mappedValue = .custom(fileId: fileId, file: nil) + } + reactions.append(mappedValue) + } + } + } + } + for reaction in reactions { switch reaction { case let .custom(fileId, file): diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Messages/TelegramEngineMessages.swift b/submodules/TelegramCore/Sources/TelegramEngine/Messages/TelegramEngineMessages.swift index 1d59a89927..9868273863 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Messages/TelegramEngineMessages.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Messages/TelegramEngineMessages.swift @@ -307,7 +307,22 @@ public extension TelegramEngine { messageId: id, reactions: reactions, isLarge: false, - storeAsRecentlyUsed: false + storeAsRecentlyUsed: false, + add: false + ).start() + } + + public func addMessageReactions( + id: EngineMessage.Id, + reactions: [UpdateMessageReaction] + ) { + let _ = updateMessageReactionsInteractively( + account: self.account, + messageId: id, + reactions: reactions, + isLarge: false, + storeAsRecentlyUsed: false, + add: true ).start() } diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageSelectionInputPanelNode/Sources/ChatMessageSelectionInputPanelNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageSelectionInputPanelNode/Sources/ChatMessageSelectionInputPanelNode.swift index 5f71bfcce7..1e5c3f1381 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageSelectionInputPanelNode/Sources/ChatMessageSelectionInputPanelNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageSelectionInputPanelNode/Sources/ChatMessageSelectionInputPanelNode.swift @@ -310,24 +310,29 @@ public final class ChatMessageSelectionInputPanelNode: ChatInputPanelNode { return } - var reactions = actions.editTags - if reactions.contains(updateReaction.reaction) { - reactions.remove(updateReaction.reaction) - } else { - reactions.insert(updateReaction.reaction) - } - let mappedUpdatedReactions = reactions.map { reaction -> UpdateMessageReaction in - switch reaction { - case let .builtin(value): - return .builtin(value) - case let .custom(fileId): - return .custom(fileId: fileId, file: nil) - } - } + self.interfaceInteraction?.cancelMessageSelection(.animated(duration: 0.4, curve: .spring)) - if let selectionState = presentationInterfaceState.interfaceState.selectionState { - for id in selectionState.selectedIds { - context.engine.messages.setMessageReactions(id: id, reactions: mappedUpdatedReactions) + if actions.editTags.contains(updateReaction.reaction) { + var reactions = actions.editTags + reactions.remove(updateReaction.reaction) + let mappedUpdatedReactions = reactions.map { reaction -> UpdateMessageReaction in + switch reaction { + case let .builtin(value): + return .builtin(value) + case let .custom(fileId): + return .custom(fileId: fileId, file: nil) + } + } + if let selectionState = presentationInterfaceState.interfaceState.selectionState { + for id in selectionState.selectedIds { + context.engine.messages.setMessageReactions(id: id, reactions: mappedUpdatedReactions) + } + } + } else { + if let selectionState = presentationInterfaceState.interfaceState.selectionState { + for id in selectionState.selectedIds { + context.engine.messages.addMessageReactions(id: id, reactions: [updateReaction]) + } } } diff --git a/submodules/TelegramUI/Components/Chat/ChatRecentActionsController/Sources/ChatRecentActionsController.swift b/submodules/TelegramUI/Components/Chat/ChatRecentActionsController/Sources/ChatRecentActionsController.swift index edd4d3de12..82039d606a 100644 --- a/submodules/TelegramUI/Components/Chat/ChatRecentActionsController/Sources/ChatRecentActionsController.swift +++ b/submodules/TelegramUI/Components/Chat/ChatRecentActionsController/Sources/ChatRecentActionsController.swift @@ -63,6 +63,7 @@ public final class ChatRecentActionsController: TelegramBaseController { self.panelInteraction = ChatPanelInterfaceInteraction(setupReplyMessage: { _, _ in }, setupEditMessage: { _, _ in }, beginMessageSelection: { _, _ in + }, cancelMessageSelection: { _ in }, deleteSelectedMessages: { }, reportSelectedMessages: { }, reportMessages: { _, _ in diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift index e5493d0b6d..61fb388a88 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift @@ -305,6 +305,7 @@ final class PeerInfoSelectionPanelNode: ASDisplayNode { let interfaceInteraction = ChatPanelInterfaceInteraction(setupReplyMessage: { _, _ in }, setupEditMessage: { _, _ in }, beginMessageSelection: { _, _ in + }, cancelMessageSelection: { _ in }, deleteSelectedMessages: { deleteMessages() }, reportSelectedMessages: { @@ -11301,7 +11302,7 @@ public final class PeerInfoScreenImpl: ViewController, PeerInfoScreen, KeyShortc //TODO:localize items.append(.action(ContextMenuActionItem(text: "View as Chats", icon: { theme in if !isViewingAsTopics { - return nil + return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: .clear) } return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) }, iconPosition: .left, action: { [weak sourceController] _, a in @@ -11319,7 +11320,7 @@ public final class PeerInfoScreenImpl: ViewController, PeerInfoScreen, KeyShortc }))) items.append(.action(ContextMenuActionItem(text: strings.Chat_ContextViewAsMessages, icon: { theme in if isViewingAsTopics { - return nil + return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: .clear) } return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) }, iconPosition: .left, action: { [weak sourceController] _, a in diff --git a/submodules/TelegramUI/Components/PeerSelectionController/Sources/PeerSelectionControllerNode.swift b/submodules/TelegramUI/Components/PeerSelectionController/Sources/PeerSelectionControllerNode.swift index 08025717ac..da98736c5d 100644 --- a/submodules/TelegramUI/Components/PeerSelectionController/Sources/PeerSelectionControllerNode.swift +++ b/submodules/TelegramUI/Components/PeerSelectionController/Sources/PeerSelectionControllerNode.swift @@ -337,6 +337,7 @@ final class PeerSelectionControllerNode: ASDisplayNode { self.interfaceInteraction = ChatPanelInterfaceInteraction(setupReplyMessage: { _, _ in }, setupEditMessage: { _, _ in }, beginMessageSelection: { _, _ in + }, cancelMessageSelection: { _ in }, deleteSelectedMessages: { }, reportSelectedMessages: { }, reportMessages: { _, _ in diff --git a/submodules/TelegramUI/Sources/Chat/UpdateChatPresentationInterfaceState.swift b/submodules/TelegramUI/Sources/Chat/UpdateChatPresentationInterfaceState.swift index 1b3537f7a2..3bdee209cc 100644 --- a/submodules/TelegramUI/Sources/Chat/UpdateChatPresentationInterfaceState.swift +++ b/submodules/TelegramUI/Sources/Chat/UpdateChatPresentationInterfaceState.swift @@ -414,6 +414,8 @@ func updateChatPresentationInterfaceStateImpl( selfController.chatDisplayNode.collapseInput() } + selfController.tempHideAccessoryPanels = selfController.presentationInterfaceState.search != nil + if selfController.isNodeLoaded { selfController.chatDisplayNode.updateChatPresentationInterfaceState(updatedChatPresentationInterfaceState, transition: transition, interactive: interactive, completion: completion) } else { diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index 112009a023..1e37226b40 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -8639,6 +8639,11 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } else { completion(.immediate) } + }, cancelMessageSelection: { [weak self] transition in + guard let self else { + return + } + self.updateChatPresentationInterfaceState(transition: transition, interactive: true, { $0.updatedInterfaceState { $0.withoutSelectionState() } }) }, deleteSelectedMessages: { [weak self] in if let strongSelf = self { if let messageIds = strongSelf.presentationInterfaceState.interfaceState.selectionState?.selectedIds, !messageIds.isEmpty { diff --git a/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift b/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift index 18b4e5ef99..06d5a218bd 100644 --- a/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift +++ b/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift @@ -1656,7 +1656,12 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState isSending = true title = chatPresentationInterfaceState.strings.Conversation_ContextMenuCancelSending } else { - title = chatPresentationInterfaceState.strings.Conversation_ContextMenuDelete + if case .peer(context.account.peerId) = chatPresentationInterfaceState.chatLocation, message.effectivelyIncoming(context.account.peerId) { + //TODO:localize + title = "Remove" + } else { + title = chatPresentationInterfaceState.strings.Conversation_ContextMenuDelete + } } if let autoremoveDeadline = autoremoveDeadline, !isEditing, !isSending { diff --git a/submodules/TelegramUI/Sources/ChatInterfaceStateNavigationButtons.swift b/submodules/TelegramUI/Sources/ChatInterfaceStateNavigationButtons.swift index a7364265f0..f07cc50c99 100644 --- a/submodules/TelegramUI/Sources/ChatInterfaceStateNavigationButtons.swift +++ b/submodules/TelegramUI/Sources/ChatInterfaceStateNavigationButtons.swift @@ -184,6 +184,9 @@ func rightNavigationButtonForChatInterfaceState(context: AccountContext, present } func secondaryRightNavigationButtonForChatInterfaceState(context: AccountContext, presentationInterfaceState: ChatPresentationInterfaceState, strings: PresentationStrings, currentButton: ChatNavigationButton?, target: Any?, selector: Selector?, chatInfoNavigationButton: ChatNavigationButton?, moreInfoNavigationButton: ChatNavigationButton?) -> ChatNavigationButton? { + if presentationInterfaceState.interfaceState.selectionState != nil { + return nil + } if case .peer(context.account.peerId) = presentationInterfaceState.chatLocation { return moreInfoNavigationButton } diff --git a/submodules/TelegramUI/Sources/ChatTagSearchInputPanelNode.swift b/submodules/TelegramUI/Sources/ChatTagSearchInputPanelNode.swift index 2f29cd56e6..40a403c964 100644 --- a/submodules/TelegramUI/Sources/ChatTagSearchInputPanelNode.swift +++ b/submodules/TelegramUI/Sources/ChatTagSearchInputPanelNode.swift @@ -262,7 +262,7 @@ final class ChatTagSearchInputPanelNode: ChatInputPanelNode { } } - var nextLeftX: CGFloat = 11.0 + var nextLeftX: CGFloat = 12.0 let calendarButtonSize = self.calendarButton.update( transition: .immediate, @@ -372,7 +372,7 @@ final class ChatTagSearchInputPanelNode: ChatInputPanelNode { environment: {}, containerSize: size ) - let resultsTextFrame = CGRect(origin: CGPoint(x: nextLeftX, y: floor((size.height - resultsTextSize.height) * 0.5)), size: resultsTextSize) + let resultsTextFrame = CGRect(origin: CGPoint(x: nextLeftX - 3.0, y: floor((size.height - resultsTextSize.height) * 0.5)), size: resultsTextSize) if let resultsTextView = resultsText.view { if resultsTextView.superview == nil { resultsTextView.alpha = 0.0 @@ -381,7 +381,7 @@ final class ChatTagSearchInputPanelNode: ChatInputPanelNode { resultsTextTransition.setFrame(view: resultsTextView, frame: resultsTextFrame) transition.setAlpha(view: resultsTextView, alpha: 1.0) } - nextLeftX += resultsTextSize.width + nextLeftX += -3.0 + resultsTextSize.width } else { if let resultsText = self.resultsText { self.resultsText = nil