diff --git a/submodules/TelegramUI/TelegramUI/ChatBotStartInputPanelNode.swift b/submodules/TelegramUI/TelegramUI/ChatBotStartInputPanelNode.swift index 75e3b5baf7..76a553af44 100644 --- a/submodules/TelegramUI/TelegramUI/ChatBotStartInputPanelNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatBotStartInputPanelNode.swift @@ -89,7 +89,7 @@ final class ChatBotStartInputPanelNode: ChatInputPanelNode { self.interfaceInteraction?.sendBotStart(presentationInterfaceState.botStartPayload) } - override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, maxHeight: CGFloat, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics) -> CGFloat { + override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, maxHeight: CGFloat, isSecondary: Bool, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics) -> CGFloat { if self.presentationInterfaceState != interfaceState { let previousState = self.presentationInterfaceState self.presentationInterfaceState = interfaceState diff --git a/submodules/TelegramUI/TelegramUI/ChatChannelSubscriberInputPanelNode.swift b/submodules/TelegramUI/TelegramUI/ChatChannelSubscriberInputPanelNode.swift index abe3761c10..a7ea5825db 100644 --- a/submodules/TelegramUI/TelegramUI/ChatChannelSubscriberInputPanelNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatChannelSubscriberInputPanelNode.swift @@ -161,7 +161,7 @@ final class ChatChannelSubscriberInputPanelNode: ChatInputPanelNode { } } - override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, maxHeight: CGFloat, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics) -> CGFloat { + override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, maxHeight: CGFloat, isSecondary: Bool, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics) -> CGFloat { self.layoutData = (width, leftInset, rightInset) if self.presentationInterfaceState != interfaceState { diff --git a/submodules/TelegramUI/TelegramUI/ChatFeedNavigationInputPanelNode.swift b/submodules/TelegramUI/TelegramUI/ChatFeedNavigationInputPanelNode.swift index 0fadbb4b0d..215edbb68f 100644 --- a/submodules/TelegramUI/TelegramUI/ChatFeedNavigationInputPanelNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatFeedNavigationInputPanelNode.swift @@ -54,7 +54,7 @@ final class ChatFeedNavigationInputPanelNode: ChatInputPanelNode { self.interfaceInteraction?.navigateFeed() } - override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, maxHeight: CGFloat, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics) -> CGFloat { + override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, maxHeight: CGFloat, isSecondary: Bool, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics) -> CGFloat { if self.presentationInterfaceState != interfaceState { self.presentationInterfaceState = interfaceState } diff --git a/submodules/TelegramUI/TelegramUI/ChatInputPanelNode.swift b/submodules/TelegramUI/TelegramUI/ChatInputPanelNode.swift index d3ea2d179f..6228bafa19 100644 --- a/submodules/TelegramUI/TelegramUI/ChatInputPanelNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatInputPanelNode.swift @@ -11,7 +11,7 @@ class ChatInputPanelNode: ASDisplayNode { var context: AccountContext? var interfaceInteraction: ChatPanelInterfaceInteraction? - func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, maxHeight: CGFloat, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics) -> CGFloat { + func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, maxHeight: CGFloat, isSecondary: Bool, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics) -> CGFloat { return 0.0 } diff --git a/submodules/TelegramUI/TelegramUI/ChatInterfaceStateInputPanels.swift b/submodules/TelegramUI/TelegramUI/ChatInterfaceStateInputPanels.swift index 9f7c2a2f19..e90a54544b 100644 --- a/submodules/TelegramUI/TelegramUI/ChatInterfaceStateInputPanels.swift +++ b/submodules/TelegramUI/TelegramUI/ChatInterfaceStateInputPanels.swift @@ -5,56 +5,66 @@ import TelegramCore import SyncCore import AccountContext -func inputPanelForChatPresentationIntefaceState(_ chatPresentationInterfaceState: ChatPresentationInterfaceState, context: AccountContext, currentPanel: ChatInputPanelNode?, textInputPanelNode: ChatTextInputPanelNode?, interfaceInteraction: ChatPanelInterfaceInteraction?) -> ChatInputPanelNode? { +func inputPanelForChatPresentationIntefaceState(_ chatPresentationInterfaceState: ChatPresentationInterfaceState, context: AccountContext, currentPanel: ChatInputPanelNode?, currentSecondaryPanel: ChatInputPanelNode?, textInputPanelNode: ChatTextInputPanelNode?, interfaceInteraction: ChatPanelInterfaceInteraction?) -> (primary: ChatInputPanelNode?, secondary: ChatInputPanelNode?) { if let renderedPeer = chatPresentationInterfaceState.renderedPeer, renderedPeer.peer?.restrictionText(platform: "ios") != nil { - return nil + return (nil, nil) } if chatPresentationInterfaceState.isNotAccessible { - return nil + return (nil, nil) } if let _ = chatPresentationInterfaceState.search { - var hasSelection = false - if let selectionState = chatPresentationInterfaceState.interfaceState.selectionState, !selectionState.selectedIds.isEmpty { - hasSelection = true - } - if !hasSelection { - if let currentPanel = currentPanel as? ChatSearchInputPanelNode { + var selectionPanel: ChatMessageSelectionInputPanelNode? + if let selectionState = chatPresentationInterfaceState.interfaceState.selectionState { + if let currentPanel = (currentPanel as? ChatMessageSelectionInputPanelNode) ?? (currentSecondaryPanel as? ChatMessageSelectionInputPanelNode) { + currentPanel.selectedMessages = selectionState.selectedIds currentPanel.interfaceInteraction = interfaceInteraction - return currentPanel + currentPanel.updateTheme(theme: chatPresentationInterfaceState.theme) + selectionPanel = currentPanel } else { - let panel = ChatSearchInputPanelNode(theme: chatPresentationInterfaceState.theme) + let panel = ChatMessageSelectionInputPanelNode(theme: chatPresentationInterfaceState.theme, strings: chatPresentationInterfaceState.strings) panel.context = context + panel.selectedMessages = selectionState.selectedIds panel.interfaceInteraction = interfaceInteraction - return panel + selectionPanel = panel } } + + if let currentPanel = (currentPanel as? ChatSearchInputPanelNode) ?? (currentSecondaryPanel as? ChatSearchInputPanelNode) { + currentPanel.interfaceInteraction = interfaceInteraction + return (currentPanel, selectionPanel) + } else { + let panel = ChatSearchInputPanelNode(theme: chatPresentationInterfaceState.theme) + panel.context = context + panel.interfaceInteraction = interfaceInteraction + return (panel, selectionPanel) + } } if let selectionState = chatPresentationInterfaceState.interfaceState.selectionState { - if let currentPanel = currentPanel as? ChatMessageSelectionInputPanelNode { + if let currentPanel = (currentPanel as? ChatMessageSelectionInputPanelNode) ?? (currentSecondaryPanel as? ChatMessageSelectionInputPanelNode) { currentPanel.selectedMessages = selectionState.selectedIds currentPanel.interfaceInteraction = interfaceInteraction currentPanel.updateTheme(theme: chatPresentationInterfaceState.theme) - return currentPanel + return (currentPanel, nil) } else { let panel = ChatMessageSelectionInputPanelNode(theme: chatPresentationInterfaceState.theme, strings: chatPresentationInterfaceState.strings) panel.context = context panel.selectedMessages = selectionState.selectedIds panel.interfaceInteraction = interfaceInteraction - return panel + return (panel, nil) } } if chatPresentationInterfaceState.peerIsBlocked { - if let currentPanel = currentPanel as? ChatUnblockInputPanelNode { + if let currentPanel = (currentPanel as? ChatUnblockInputPanelNode) ?? (currentSecondaryPanel as? ChatUnblockInputPanelNode) { currentPanel.interfaceInteraction = interfaceInteraction currentPanel.updateThemeAndStrings(theme: chatPresentationInterfaceState.theme, strings: chatPresentationInterfaceState.strings) - return currentPanel + return (currentPanel, nil) } else { let panel = ChatUnblockInputPanelNode(theme: chatPresentationInterfaceState.theme, strings: chatPresentationInterfaceState.strings) panel.context = context panel.interfaceInteraction = interfaceInteraction - return panel + return (panel, nil) } } @@ -64,22 +74,22 @@ func inputPanelForChatPresentationIntefaceState(_ chatPresentationInterfaceState if let secretChat = peer as? TelegramSecretChat { switch secretChat.embeddedState { case .handshake: - if let currentPanel = currentPanel as? SecretChatHandshakeStatusInputPanelNode { - return currentPanel + if let currentPanel = (currentPanel as? SecretChatHandshakeStatusInputPanelNode) ?? (currentSecondaryPanel as? SecretChatHandshakeStatusInputPanelNode) { + return (currentPanel, nil) } else { let panel = SecretChatHandshakeStatusInputPanelNode() panel.context = context panel.interfaceInteraction = interfaceInteraction - return panel + return (panel, nil) } case .terminated: - if let currentPanel = currentPanel as? DeleteChatInputPanelNode { - return currentPanel + if let currentPanel = (currentPanel as? DeleteChatInputPanelNode) ?? (currentSecondaryPanel as? DeleteChatInputPanelNode) { + return (currentPanel, nil) } else { let panel = DeleteChatInputPanelNode() panel.context = context panel.interfaceInteraction = interfaceInteraction - return panel + return (panel, nil) } case .active: break @@ -88,13 +98,13 @@ func inputPanelForChatPresentationIntefaceState(_ chatPresentationInterfaceState var isMember: Bool = false switch channel.participationStatus { case .kicked: - if let currentPanel = currentPanel as? DeleteChatInputPanelNode { - return currentPanel + if let currentPanel = (currentPanel as? DeleteChatInputPanelNode) ?? (currentSecondaryPanel as? DeleteChatInputPanelNode) { + return (currentPanel, nil) } else { let panel = DeleteChatInputPanelNode() panel.context = context panel.interfaceInteraction = interfaceInteraction - return panel + return (panel, nil) } case .member: isMember = true @@ -103,13 +113,13 @@ func inputPanelForChatPresentationIntefaceState(_ chatPresentationInterfaceState } if isMember && channel.hasBannedPermission(.banSendMessages) != nil { - if let currentPanel = currentPanel as? ChatRestrictedInputPanelNode { - return currentPanel + if let currentPanel = (currentPanel as? ChatRestrictedInputPanelNode) ?? (currentSecondaryPanel as? ChatRestrictedInputPanelNode) { + return (currentPanel, nil) } else { let panel = ChatRestrictedInputPanelNode() panel.context = context panel.interfaceInteraction = interfaceInteraction - return panel + return (panel, nil) } } @@ -118,25 +128,25 @@ func inputPanelForChatPresentationIntefaceState(_ chatPresentationInterfaceState if chatPresentationInterfaceState.interfaceState.editMessage != nil, channel.hasPermission(.editAllMessages) { displayInputTextPanel = true } else if !channel.hasPermission(.sendMessages) { - if let currentPanel = currentPanel as? ChatChannelSubscriberInputPanelNode { - return currentPanel + if let currentPanel = (currentPanel as? ChatChannelSubscriberInputPanelNode) ?? (currentSecondaryPanel as? ChatChannelSubscriberInputPanelNode) { + return (currentPanel, nil) } else { let panel = ChatChannelSubscriberInputPanelNode() panel.interfaceInteraction = interfaceInteraction panel.context = context - return panel + return (panel, nil) } } case .group: switch channel.participationStatus { case .kicked, .left: - if let currentPanel = currentPanel as? ChatChannelSubscriberInputPanelNode { - return currentPanel + if let currentPanel = (currentPanel as? ChatChannelSubscriberInputPanelNode) ?? (currentSecondaryPanel as? ChatChannelSubscriberInputPanelNode) { + return (currentPanel, nil) } else { let panel = ChatChannelSubscriberInputPanelNode() panel.interfaceInteraction = interfaceInteraction panel.context = context - return panel + return (panel, nil) } case .member: break @@ -145,26 +155,26 @@ func inputPanelForChatPresentationIntefaceState(_ chatPresentationInterfaceState } else if let group = peer as? TelegramGroup { switch group.membership { case .Removed, .Left: - if let currentPanel = currentPanel as? DeleteChatInputPanelNode { - return currentPanel + if let currentPanel = (currentPanel as? DeleteChatInputPanelNode) ?? (currentSecondaryPanel as? DeleteChatInputPanelNode) { + return (currentPanel, nil) } else { let panel = DeleteChatInputPanelNode() panel.context = context panel.interfaceInteraction = interfaceInteraction - return panel + return (panel, nil) } case .Member: break } if group.hasBannedPermission(.banSendMessages) { - if let currentPanel = currentPanel as? ChatRestrictedInputPanelNode { - return currentPanel + if let currentPanel = (currentPanel as? ChatRestrictedInputPanelNode) ?? (currentSecondaryPanel as? ChatRestrictedInputPanelNode) { + return (currentPanel, nil) } else { let panel = ChatRestrictedInputPanelNode() panel.context = context panel.interfaceInteraction = interfaceInteraction - return panel + return (panel, nil) } } } @@ -183,25 +193,24 @@ func inputPanelForChatPresentationIntefaceState(_ chatPresentationInterfaceState } if displayBotStartPanel { - if let currentPanel = currentPanel as? ChatBotStartInputPanelNode { + if let currentPanel = (currentPanel as? ChatBotStartInputPanelNode) ?? (currentSecondaryPanel as? ChatBotStartInputPanelNode) { currentPanel.updateThemeAndStrings(theme: chatPresentationInterfaceState.theme, strings: chatPresentationInterfaceState.strings) - return currentPanel + return (currentPanel, nil) } else { let panel = ChatBotStartInputPanelNode(theme: chatPresentationInterfaceState.theme, strings: chatPresentationInterfaceState.strings) panel.context = context panel.interfaceInteraction = interfaceInteraction - return panel + return (panel, nil) } } else { if let _ = chatPresentationInterfaceState.recordedMediaPreview { - if let currentPanel = currentPanel as? ChatRecordingPreviewInputPanelNode { - //currentPanel.updateThemeAndStrings(theme: chatPresentationInterfaceState.theme, strings: chatPresentationInterfaceState.strings) - return currentPanel + if let currentPanel = (currentPanel as? ChatRecordingPreviewInputPanelNode) ?? (currentSecondaryPanel as? ChatRecordingPreviewInputPanelNode) { + return (currentPanel, nil) } else { let panel = ChatRecordingPreviewInputPanelNode(theme: chatPresentationInterfaceState.theme) panel.context = context panel.interfaceInteraction = interfaceInteraction - return panel + return (panel, nil) } } @@ -214,14 +223,14 @@ func inputPanelForChatPresentationIntefaceState(_ chatPresentationInterfaceState } if displayInputTextPanel { - if let currentPanel = currentPanel as? ChatTextInputPanelNode { + if let currentPanel = (currentPanel as? ChatTextInputPanelNode) ?? (currentSecondaryPanel as? ChatTextInputPanelNode) { currentPanel.interfaceInteraction = interfaceInteraction - return currentPanel + return (currentPanel, nil) } else { if let textInputPanelNode = textInputPanelNode { textInputPanelNode.interfaceInteraction = interfaceInteraction textInputPanelNode.context = context - return textInputPanelNode + return (textInputPanelNode, nil) } else { let panel = ChatTextInputPanelNode(presentationInterfaceState: chatPresentationInterfaceState, presentController: { [weak interfaceInteraction] controller in interfaceInteraction?.presentController(controller, nil) @@ -229,10 +238,10 @@ func inputPanelForChatPresentationIntefaceState(_ chatPresentationInterfaceState panel.interfaceInteraction = interfaceInteraction panel.context = context - return panel + return (panel, nil) } } } else { - return nil + return (nil, nil) } } diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageSelectionInputPanelNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageSelectionInputPanelNode.swift index 1f2423e1a6..7587b9dad7 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageSelectionInputPanelNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageSelectionInputPanelNode.swift @@ -15,8 +15,9 @@ final class ChatMessageSelectionInputPanelNode: ChatInputPanelNode { private let reportButton: HighlightableButtonNode private let forwardButton: HighlightableButtonNode private let shareButton: HighlightableButtonNode + private let separatorNode: ASDisplayNode - private var validLayout: (width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, maxHeight: CGFloat, metrics: LayoutMetrics)? + private var validLayout: (width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, maxHeight: CGFloat, metrics: LayoutMetrics, isSecondary: Bool)? private var presentationInterfaceState: ChatPresentationInterfaceState? private var actions: ChatAvailableMessageActions? @@ -31,8 +32,8 @@ final class ChatMessageSelectionInputPanelNode: ChatInputPanelNode { if self.selectedMessages.isEmpty { self.actions = nil - if let (width, leftInset, rightInset, maxHeight, metrics) = self.validLayout, let interfaceState = self.presentationInterfaceState { - let _ = self.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, maxHeight: maxHeight, transition: .immediate, interfaceState: interfaceState, metrics: metrics) + if let (width, leftInset, rightInset, maxHeight, metrics, isSecondary) = self.validLayout, let interfaceState = self.presentationInterfaceState { + let _ = self.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, maxHeight: maxHeight, isSecondary: isSecondary, transition: .immediate, interfaceState: interfaceState, metrics: metrics) } self.canDeleteMessagesDisposable.set(nil) } else if let context = self.context { @@ -40,8 +41,8 @@ final class ChatMessageSelectionInputPanelNode: ChatInputPanelNode { |> deliverOnMainQueue).start(next: { [weak self] actions in if let strongSelf = self { strongSelf.actions = actions - if let (width, leftInset, rightInset, maxHeight, metrics) = strongSelf.validLayout, let interfaceState = strongSelf.presentationInterfaceState { - let _ = strongSelf.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, maxHeight: maxHeight, transition: .immediate, interfaceState: interfaceState, metrics: metrics) + if let (width, leftInset, rightInset, maxHeight, metrics, isSecondary) = strongSelf.validLayout, let interfaceState = strongSelf.presentationInterfaceState { + let _ = strongSelf.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, maxHeight: maxHeight, isSecondary: isSecondary, transition: .immediate, interfaceState: interfaceState, metrics: metrics) } } })) @@ -81,12 +82,16 @@ final class ChatMessageSelectionInputPanelNode: ChatInputPanelNode { self.shareButton.setImage(generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Accessory Panels/MessageSelectionAction"), color: theme.chat.inputPanel.panelControlAccentColor), for: [.normal]) self.shareButton.setImage(generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Accessory Panels/MessageSelectionAction"), color: theme.chat.inputPanel.panelControlDisabledColor), for: [.disabled]) + self.separatorNode = ASDisplayNode() + self.separatorNode.backgroundColor = theme.chat.inputPanel.panelSeparatorColor + super.init() self.addSubnode(self.deleteButton) self.addSubnode(self.reportButton) self.addSubnode(self.forwardButton) self.addSubnode(self.shareButton) + self.addSubnode(self.separatorNode) self.forwardButton.isEnabled = false @@ -110,6 +115,8 @@ final class ChatMessageSelectionInputPanelNode: ChatInputPanelNode { self.reportButton.setImage(generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Accessory Panels/MessageSelectionReport"), color: theme.chat.inputPanel.panelControlDisabledColor), for: [.disabled]) self.forwardButton.setImage(generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Accessory Panels/MessageSelectionForward"), color: theme.chat.inputPanel.panelControlAccentColor), for: [.normal]) self.forwardButton.setImage(generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Accessory Panels/MessageSelectionForward"), color: theme.chat.inputPanel.panelControlDisabledColor), for: [.disabled]) + + self.separatorNode.backgroundColor = theme.chat.inputPanel.panelSeparatorColor } } @@ -129,8 +136,8 @@ final class ChatMessageSelectionInputPanelNode: ChatInputPanelNode { self.interfaceInteraction?.shareSelectedMessages() } - override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, maxHeight: CGFloat, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics) -> CGFloat { - self.validLayout = (width, leftInset, rightInset, maxHeight, metrics) + override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, maxHeight: CGFloat, isSecondary: Bool, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics) -> CGFloat { + self.validLayout = (width, leftInset, rightInset, maxHeight, metrics, isSecondary) let panelHeight = defaultHeight(metrics: metrics) @@ -196,6 +203,9 @@ final class ChatMessageSelectionInputPanelNode: ChatInputPanelNode { self.shareButton.frame = CGRect(origin: CGPoint(x: floor((width - rightInset - 57.0) / 2.0), y: 0.0), size: CGSize(width: 57.0, height: panelHeight)) } + transition.updateAlpha(node: self.separatorNode, alpha: isSecondary ? 1.0 : 0.0) + self.separatorNode.frame = CGRect(origin: CGPoint(x: 0.0, y: panelHeight), size: CGSize(width: width, height: UIScreenPixel)) + return panelHeight } diff --git a/submodules/TelegramUI/TelegramUI/ChatRestrictedInputPanelNode.swift b/submodules/TelegramUI/TelegramUI/ChatRestrictedInputPanelNode.swift index 11764aa82e..32b6829c4a 100644 --- a/submodules/TelegramUI/TelegramUI/ChatRestrictedInputPanelNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatRestrictedInputPanelNode.swift @@ -23,7 +23,7 @@ final class ChatRestrictedInputPanelNode: ChatInputPanelNode { self.addSubnode(self.textNode) } - override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, maxHeight: CGFloat, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics) -> CGFloat { + override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, maxHeight: CGFloat, isSecondary: Bool, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics) -> CGFloat { if self.presentationInterfaceState != interfaceState { self.presentationInterfaceState = interfaceState } diff --git a/submodules/TelegramUI/TelegramUI/ChatSearchInputPanelNode.swift b/submodules/TelegramUI/TelegramUI/ChatSearchInputPanelNode.swift index d66c1d5c96..aaaedf9446 100644 --- a/submodules/TelegramUI/TelegramUI/ChatSearchInputPanelNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatSearchInputPanelNode.swift @@ -28,7 +28,7 @@ final class ChatSearchInputPanelNode: ChatInputPanelNode { private var needsSearchResultsTooltip = true - private var validLayout: (CGFloat, CGFloat, CGFloat, CGFloat, LayoutMetrics)? + private var validLayout: (CGFloat, CGFloat, CGFloat, CGFloat, LayoutMetrics, Bool)? override var interfaceInteraction: ChatPanelInterfaceInteraction? { didSet { @@ -39,7 +39,7 @@ final class ChatSearchInputPanelNode: ChatInputPanelNode { strongSelf.displayActivity = value strongSelf.activityIndicator.isHidden = !value if let interfaceState = strongSelf.presentationInterfaceState, let validLayout = strongSelf.validLayout { - strongSelf.updateLayout(width: validLayout.0, leftInset: validLayout.1, rightInset: validLayout.2, maxHeight: validLayout.3, transition: .immediate, interfaceState: interfaceState, metrics: validLayout.4) + strongSelf.updateLayout(width: validLayout.0, leftInset: validLayout.1, rightInset: validLayout.2, maxHeight: validLayout.3, isSecondary: validLayout.5, transition: .immediate, interfaceState: interfaceState, metrics: validLayout.4) } } })) @@ -125,8 +125,8 @@ final class ChatSearchInputPanelNode: ChatInputPanelNode { } } - override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, maxHeight: CGFloat, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics) -> CGFloat { - self.validLayout = (width, leftInset, rightInset, maxHeight, metrics) + override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, maxHeight: CGFloat, isSecondary: Bool, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics) -> CGFloat { + self.validLayout = (width, leftInset, rightInset, maxHeight, metrics, isSecondary) if self.presentationInterfaceState != interfaceState { let themeUpdated = self.presentationInterfaceState?.theme !== interfaceState.theme diff --git a/submodules/TelegramUI/TelegramUI/ChatTextInputPanelNode.swift b/submodules/TelegramUI/TelegramUI/ChatTextInputPanelNode.swift index 345b205cd2..2b44953eab 100644 --- a/submodules/TelegramUI/TelegramUI/ChatTextInputPanelNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatTextInputPanelNode.swift @@ -225,7 +225,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate { private var accessoryItemButtons: [(ChatTextInputAccessoryItem, AccessoryItemIconButton)] = [] - private var validLayout: (CGFloat, CGFloat, CGFloat, CGFloat, LayoutMetrics)? + private var validLayout: (CGFloat, CGFloat, CGFloat, CGFloat, LayoutMetrics, Bool)? var displayAttachmentMenu: () -> Void = { } var sendMessage: () -> Void = { } @@ -396,8 +396,8 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate { self.addSubnode(self.actionButtons) - self.actionButtons.sendButtonLongPressed = { [weak self] in - self?.interfaceInteraction?.displaySendMessageOptions() + self.actionButtons.sendButtonLongPressed = { [weak self] node, gesture in + self?.interfaceInteraction?.displaySendMessageOptions(node, gesture) } self.actionButtons.micButton.recordingDisabled = { [weak self] in @@ -431,8 +431,8 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate { } self.actionButtons.micButton.offsetRecordingControls = { [weak self] in if let strongSelf = self, let presentationInterfaceState = strongSelf.presentationInterfaceState { - if let (width, leftInset, rightInset, maxHeight, metrics) = strongSelf.validLayout { - let _ = strongSelf.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, maxHeight: maxHeight, transition: .immediate, interfaceState: presentationInterfaceState, metrics: metrics) + if let (width, leftInset, rightInset, maxHeight, metrics, isSecondary) = strongSelf.validLayout { + let _ = strongSelf.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, maxHeight: maxHeight, isSecondary: isSecondary, transition: .immediate, interfaceState: presentationInterfaceState, metrics: metrics) } } } @@ -452,7 +452,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate { } } - self.actionButtons.sendButton.addTarget(self, action: #selector(self.sendButtonPressed), for: .touchUpInside) + self.actionButtons.sendButton.addTarget(self, action: #selector(self.sendButtonPressed), forControlEvents: .touchUpInside) self.actionButtons.sendButton.alpha = 0.0 self.actionButtons.updateAccessibility() @@ -633,8 +633,8 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate { return minimalHeight } - override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, maxHeight: CGFloat, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics) -> CGFloat { - self.validLayout = (width, leftInset, rightInset, maxHeight, metrics) + override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, maxHeight: CGFloat, isSecondary: Bool, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics) -> CGFloat { + self.validLayout = (width, leftInset, rightInset, maxHeight, metrics, isSecondary) let baseWidth = width - leftInset - rightInset var wasEditingMedia = false @@ -785,17 +785,19 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate { if updateSendButtonIcon { if !self.actionButtons.animatingSendButton { - if transition.isAnimated && !self.actionButtons.sendButton.alpha.isZero && self.actionButtons.sendButton.layer.animation(forKey: "opacity") == nil, let imageView = self.actionButtons.sendButton.imageView, let previousImage = imageView.image { + let imageNode = self.actionButtons.sendButton.imageNode + + if transition.isAnimated && !self.actionButtons.sendButton.alpha.isZero && self.actionButtons.sendButton.layer.animation(forKey: "opacity") == nil, let previousImage = imageNode.image { let tempView = UIImageView(image: previousImage) - self.actionButtons.sendButton.addSubview(tempView) - tempView.frame = imageView.frame + self.actionButtons.sendButton.view.addSubview(tempView) + tempView.frame = imageNode.frame tempView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { [weak tempView] _ in tempView?.removeFromSuperview() }) tempView.layer.animateScale(from: 1.0, to: 0.2, duration: 0.2, removeOnCompletion: false) - imageView.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2) - imageView.layer.animateScale(from: 0.2, to: 1.0, duration: 0.2) + imageNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2) + imageNode.layer.animateScale(from: 0.2, to: 1.0, duration: 0.2) } self.actionButtons.sendButtonHasApplyIcon = sendButtonHasApplyIcon if self.actionButtons.sendButtonHasApplyIcon { @@ -1395,7 +1397,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate { } private func updateTextHeight(animated: Bool) { - if let (width, leftInset, rightInset, maxHeight, metrics) = self.validLayout { + if let (width, leftInset, rightInset, maxHeight, metrics, _) = self.validLayout { let (_, textFieldHeight) = self.calculateTextFieldMetrics(width: width - leftInset - rightInset, maxHeight: maxHeight, metrics: metrics) let panelHeight = self.panelHeight(textFieldHeight: textFieldHeight, metrics: metrics) if !self.bounds.size.height.isEqual(to: panelHeight) { @@ -1405,7 +1407,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate { } @objc func editableTextNodeShouldReturn(_ editableTextNode: ASEditableTextNode) -> Bool { - if self.actionButtons.sendButton.superview != nil && !self.actionButtons.sendButton.isHidden && !self.actionButtons.sendButton.alpha.isZero { + if self.actionButtons.sendButton.supernode != nil && !self.actionButtons.sendButton.isHidden && !self.actionButtons.sendButton.alpha.isZero { self.sendButtonPressed() } return false diff --git a/submodules/TelegramUI/TelegramUI/ChatUnblockInputPanelNode.swift b/submodules/TelegramUI/TelegramUI/ChatUnblockInputPanelNode.swift index f549a5e64c..79c9aff082 100644 --- a/submodules/TelegramUI/TelegramUI/ChatUnblockInputPanelNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatUnblockInputPanelNode.swift @@ -82,7 +82,7 @@ final class ChatUnblockInputPanelNode: ChatInputPanelNode { self.interfaceInteraction?.unblockPeer() } - override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, maxHeight: CGFloat, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics) -> CGFloat { + override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, maxHeight: CGFloat, isSecondary: Bool, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics) -> CGFloat { if self.presentationInterfaceState != interfaceState { self.presentationInterfaceState = interfaceState diff --git a/submodules/TelegramUI/TelegramUI/DeleteChatInputPanelNode.swift b/submodules/TelegramUI/TelegramUI/DeleteChatInputPanelNode.swift index 9223a84239..6206cc5ed7 100644 --- a/submodules/TelegramUI/TelegramUI/DeleteChatInputPanelNode.swift +++ b/submodules/TelegramUI/TelegramUI/DeleteChatInputPanelNode.swift @@ -35,7 +35,7 @@ final class DeleteChatInputPanelNode: ChatInputPanelNode { self.interfaceInteraction?.deleteChat() } - override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, maxHeight: CGFloat, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics) -> CGFloat { + override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, maxHeight: CGFloat, isSecondary: Bool, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics) -> CGFloat { if self.presentationInterfaceState != interfaceState { self.presentationInterfaceState = interfaceState diff --git a/submodules/TelegramUI/TelegramUI/PeerMediaCollectionControllerNode.swift b/submodules/TelegramUI/TelegramUI/PeerMediaCollectionControllerNode.swift index f83818d8fd..8097b052c7 100644 --- a/submodules/TelegramUI/TelegramUI/PeerMediaCollectionControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/PeerMediaCollectionControllerNode.swift @@ -258,7 +258,7 @@ class PeerMediaCollectionControllerNode: ASDisplayNode { if let selectionPanel = self.selectionPanel { selectionPanel.selectedMessages = selectionState.selectedIds - let panelHeight = selectionPanel.updateLayout(width: layout.size.width, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, maxHeight: 0.0, transition: transition, interfaceState: interfaceState, metrics: layout.metrics) + let panelHeight = selectionPanel.updateLayout(width: layout.size.width, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, maxHeight: 0.0, isSecondary: false, transition: transition, interfaceState: interfaceState, metrics: layout.metrics) transition.updateFrame(node: selectionPanel, frame: CGRect(origin: CGPoint(x: 0.0, y: layout.size.height - insets.bottom - panelHeight), size: CGSize(width: layout.size.width, height: panelHeight))) if let selectionPanelSeparatorNode = self.selectionPanelSeparatorNode { transition.updateFrame(node: selectionPanelSeparatorNode, frame: CGRect(origin: CGPoint(x: 0.0, y: layout.size.height - insets.bottom - panelHeight), size: CGSize(width: layout.size.width, height: UIScreenPixel))) @@ -278,7 +278,7 @@ class PeerMediaCollectionControllerNode: ASDisplayNode { selectionPanel.backgroundColor = self.presentationData.theme.chat.inputPanel.panelBackgroundColor selectionPanel.interfaceInteraction = self.interfaceInteraction selectionPanel.selectedMessages = selectionState.selectedIds - let panelHeight = selectionPanel.updateLayout(width: layout.size.width, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, maxHeight: 0.0, transition: .immediate, interfaceState: interfaceState, metrics: layout.metrics) + let panelHeight = selectionPanel.updateLayout(width: layout.size.width, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, maxHeight: 0.0, isSecondary: false, transition: .immediate, interfaceState: interfaceState, metrics: layout.metrics) self.selectionPanel = selectionPanel self.addSubnode(selectionPanel) diff --git a/submodules/TelegramUI/TelegramUI/SecretChatHandshakeStatusInputPanelNode.swift b/submodules/TelegramUI/TelegramUI/SecretChatHandshakeStatusInputPanelNode.swift index 4533f217fd..c554fb0f1a 100644 --- a/submodules/TelegramUI/TelegramUI/SecretChatHandshakeStatusInputPanelNode.swift +++ b/submodules/TelegramUI/TelegramUI/SecretChatHandshakeStatusInputPanelNode.swift @@ -44,7 +44,7 @@ final class SecretChatHandshakeStatusInputPanelNode: ChatInputPanelNode { self.interfaceInteraction?.unblockPeer() } - override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, maxHeight: CGFloat, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics) -> CGFloat { + override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, maxHeight: CGFloat, isSecondary: Bool, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics) -> CGFloat { if self.presentationInterfaceState != interfaceState { self.presentationInterfaceState = interfaceState