Allow message selection during search

This commit is contained in:
Ali 2019-11-12 17:48:37 +04:00
parent bbe4a24262
commit 9f40bb0f2f
13 changed files with 111 additions and 90 deletions

View File

@ -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

View File

@ -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 {

View File

@ -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
}

View File

@ -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
}

View File

@ -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)
}
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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