mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-22 22:25:57 +00:00
Refactoring [skip ci]
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")
|
||||
|
||||
swift_library(
|
||||
name = "ChatMessageSelectionInputPanelNode",
|
||||
module_name = "ChatMessageSelectionInputPanelNode",
|
||||
srcs = glob([
|
||||
"Sources/**/*.swift",
|
||||
]),
|
||||
copts = [
|
||||
"-warnings-as-errors",
|
||||
],
|
||||
deps = [
|
||||
"//submodules/AsyncDisplayKit",
|
||||
"//submodules/Display",
|
||||
"//submodules/Postbox",
|
||||
"//submodules/TelegramCore",
|
||||
"//submodules/SSignalKit/SwiftSignalKit",
|
||||
"//submodules/TelegramPresentationData",
|
||||
"//submodules/AppBundle",
|
||||
"//submodules/ChatPresentationInterfaceState",
|
||||
"//submodules/TelegramUI/Components/Chat/ChatInputPanelNode",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
],
|
||||
)
|
||||
@@ -0,0 +1,248 @@
|
||||
import Foundation
|
||||
import UIKit
|
||||
import AsyncDisplayKit
|
||||
import Display
|
||||
import Postbox
|
||||
import TelegramCore
|
||||
import SwiftSignalKit
|
||||
import TelegramPresentationData
|
||||
import AccountContext
|
||||
import AppBundle
|
||||
import ChatPresentationInterfaceState
|
||||
import ChatInputPanelNode
|
||||
|
||||
public final class ChatMessageSelectionInputPanelNode: ChatInputPanelNode {
|
||||
private let deleteButton: HighlightableButtonNode
|
||||
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, bottomInset: CGFloat, additionalSideInsets: UIEdgeInsets, maxHeight: CGFloat, metrics: LayoutMetrics, isSecondary: Bool, isMediaInputExpanded: Bool)?
|
||||
private var presentationInterfaceState: ChatPresentationInterfaceState?
|
||||
private var actions: ChatAvailableMessageActions?
|
||||
|
||||
private var theme: PresentationTheme
|
||||
private let peerMedia: Bool
|
||||
|
||||
private let canDeleteMessagesDisposable = MetaDisposable()
|
||||
|
||||
public var selectedMessages = Set<MessageId>() {
|
||||
didSet {
|
||||
if oldValue != self.selectedMessages {
|
||||
self.forwardButton.isEnabled = self.selectedMessages.count != 0
|
||||
|
||||
if self.selectedMessages.isEmpty {
|
||||
self.actions = nil
|
||||
if let (width, leftInset, rightInset, bottomInset, additionalSideInsets, maxHeight, metrics, isSecondary, isMediaInputExpanded) = self.validLayout, let interfaceState = self.presentationInterfaceState {
|
||||
let _ = self.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, additionalSideInsets: additionalSideInsets, maxHeight: maxHeight, isSecondary: isSecondary, transition: .immediate, interfaceState: interfaceState, metrics: metrics, isMediaInputExpanded: isMediaInputExpanded)
|
||||
}
|
||||
self.canDeleteMessagesDisposable.set(nil)
|
||||
} else if let context = self.context {
|
||||
self.canDeleteMessagesDisposable.set((context.sharedContext.chatAvailableMessageActions(engine: context.engine, accountPeerId: context.account.peerId, messageIds: self.selectedMessages)
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] actions in
|
||||
if let strongSelf = self {
|
||||
strongSelf.actions = actions
|
||||
if let (width, leftInset, rightInset, bottomInset, additionalSideInsets, maxHeight, metrics, isSecondary, isMediaInputExpanded) = strongSelf.validLayout, let interfaceState = strongSelf.presentationInterfaceState {
|
||||
let _ = strongSelf.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, additionalSideInsets: additionalSideInsets, maxHeight: maxHeight, isSecondary: isSecondary, transition: .immediate, interfaceState: interfaceState, metrics: metrics, isMediaInputExpanded: isMediaInputExpanded)
|
||||
}
|
||||
}
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public init(theme: PresentationTheme, strings: PresentationStrings, peerMedia: Bool = false) {
|
||||
self.theme = theme
|
||||
self.peerMedia = peerMedia
|
||||
|
||||
self.deleteButton = HighlightableButtonNode(pointerStyle: .rectangle(CGSize(width: 56.0, height: 40.0)))
|
||||
self.deleteButton.isEnabled = false
|
||||
self.deleteButton.isAccessibilityElement = true
|
||||
self.deleteButton.accessibilityLabel = strings.VoiceOver_MessageContextDelete
|
||||
|
||||
self.reportButton = HighlightableButtonNode(pointerStyle: .rectangle(CGSize(width: 56.0, height: 40.0)))
|
||||
self.reportButton.isEnabled = false
|
||||
self.reportButton.isAccessibilityElement = true
|
||||
self.reportButton.accessibilityLabel = strings.VoiceOver_MessageContextReport
|
||||
|
||||
self.forwardButton = HighlightableButtonNode(pointerStyle: .rectangle(CGSize(width: 56.0, height: 40.0)))
|
||||
self.forwardButton.isAccessibilityElement = true
|
||||
self.forwardButton.accessibilityLabel = strings.VoiceOver_MessageContextForward
|
||||
|
||||
self.shareButton = HighlightableButtonNode(pointerStyle: .rectangle(CGSize(width: 56.0, height: 40.0)))
|
||||
self.shareButton.isAccessibilityElement = true
|
||||
self.shareButton.accessibilityLabel = strings.VoiceOver_MessageContextShare
|
||||
|
||||
self.deleteButton.setImage(generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Accessory Panels/MessageSelectionTrash"), color: theme.chat.inputPanel.panelControlAccentColor), for: [.normal])
|
||||
self.deleteButton.setImage(generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Accessory Panels/MessageSelectionTrash"), color: theme.chat.inputPanel.panelControlDisabledColor), for: [.disabled])
|
||||
self.reportButton.setImage(generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Accessory Panels/MessageSelectionReport"), color: theme.chat.inputPanel.panelControlAccentColor), for: [.normal])
|
||||
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.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.isImplicitlyDisabled = true
|
||||
self.shareButton.isImplicitlyDisabled = true
|
||||
|
||||
self.deleteButton.addTarget(self, action: #selector(self.deleteButtonPressed), forControlEvents: .touchUpInside)
|
||||
self.reportButton.addTarget(self, action: #selector(self.reportButtonPressed), forControlEvents: .touchUpInside)
|
||||
self.forwardButton.addTarget(self, action: #selector(self.forwardButtonPressed), forControlEvents: .touchUpInside)
|
||||
self.shareButton.addTarget(self, action: #selector(self.shareButtonPressed), forControlEvents: .touchUpInside)
|
||||
}
|
||||
|
||||
deinit {
|
||||
self.canDeleteMessagesDisposable.dispose()
|
||||
}
|
||||
|
||||
public func updateTheme(theme: PresentationTheme) {
|
||||
if self.theme !== theme {
|
||||
self.theme = theme
|
||||
|
||||
self.deleteButton.setImage(generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Accessory Panels/MessageSelectionTrash"), color: theme.chat.inputPanel.panelControlAccentColor), for: [.normal])
|
||||
self.deleteButton.setImage(generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Accessory Panels/MessageSelectionTrash"), color: theme.chat.inputPanel.panelControlDisabledColor), for: [.disabled])
|
||||
self.reportButton.setImage(generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Accessory Panels/MessageSelectionReport"), color: theme.chat.inputPanel.panelControlAccentColor), for: [.normal])
|
||||
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.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.backgroundColor = theme.chat.inputPanel.panelSeparatorColor
|
||||
}
|
||||
}
|
||||
|
||||
@objc private func deleteButtonPressed() {
|
||||
self.interfaceInteraction?.deleteSelectedMessages()
|
||||
}
|
||||
|
||||
@objc private func reportButtonPressed() {
|
||||
self.interfaceInteraction?.reportSelectedMessages()
|
||||
}
|
||||
|
||||
@objc private func forwardButtonPressed() {
|
||||
if let _ = self.presentationInterfaceState?.renderedPeer?.peer as? TelegramSecretChat {
|
||||
return
|
||||
}
|
||||
if let actions = self.actions, actions.isCopyProtected {
|
||||
self.interfaceInteraction?.displayCopyProtectionTip(self.forwardButton, false)
|
||||
} else if !self.forwardButton.isImplicitlyDisabled {
|
||||
self.interfaceInteraction?.forwardSelectedMessages()
|
||||
}
|
||||
}
|
||||
|
||||
@objc private func shareButtonPressed() {
|
||||
if let _ = self.presentationInterfaceState?.renderedPeer?.peer as? TelegramSecretChat {
|
||||
return
|
||||
}
|
||||
if let actions = self.actions, actions.isCopyProtected {
|
||||
self.interfaceInteraction?.displayCopyProtectionTip(self.shareButton, true)
|
||||
} else if !self.shareButton.isImplicitlyDisabled {
|
||||
self.interfaceInteraction?.shareSelectedMessages()
|
||||
}
|
||||
}
|
||||
|
||||
override public func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, additionalSideInsets: UIEdgeInsets, maxHeight: CGFloat, isSecondary: Bool, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics, isMediaInputExpanded: Bool) -> CGFloat {
|
||||
self.validLayout = (width, leftInset, rightInset, bottomInset, additionalSideInsets, maxHeight, metrics, isSecondary, isMediaInputExpanded)
|
||||
|
||||
let panelHeight = defaultHeight(metrics: metrics)
|
||||
|
||||
if self.presentationInterfaceState != interfaceState {
|
||||
self.presentationInterfaceState = interfaceState
|
||||
}
|
||||
if let actions = self.actions {
|
||||
self.deleteButton.isEnabled = false
|
||||
self.reportButton.isEnabled = false
|
||||
self.forwardButton.isImplicitlyDisabled = !actions.options.contains(.forward)
|
||||
|
||||
if self.peerMedia {
|
||||
self.deleteButton.isEnabled = !actions.options.intersection([.deleteLocally, .deleteGlobally]).isEmpty
|
||||
} else {
|
||||
self.deleteButton.isEnabled = !actions.disableDelete
|
||||
}
|
||||
self.shareButton.isImplicitlyDisabled = actions.options.intersection(.forward).isEmpty || actions.options.intersection(.externalShare).isEmpty
|
||||
self.reportButton.isEnabled = !actions.options.intersection([.report]).isEmpty
|
||||
|
||||
if self.peerMedia {
|
||||
self.deleteButton.isHidden = !self.deleteButton.isEnabled
|
||||
} else {
|
||||
self.deleteButton.isHidden = false
|
||||
}
|
||||
self.reportButton.isHidden = !self.reportButton.isEnabled
|
||||
} else {
|
||||
self.deleteButton.isEnabled = false
|
||||
self.deleteButton.isHidden = self.peerMedia
|
||||
self.reportButton.isEnabled = false
|
||||
self.reportButton.isHidden = true
|
||||
self.forwardButton.isImplicitlyDisabled = true
|
||||
self.shareButton.isImplicitlyDisabled = true
|
||||
}
|
||||
|
||||
if self.reportButton.isHidden || (self.peerMedia && self.deleteButton.isHidden && self.reportButton.isHidden) {
|
||||
if let peer = interfaceState.renderedPeer?.peer as? TelegramChannel, case .broadcast = peer.info {
|
||||
self.reportButton.isHidden = false
|
||||
} else if self.peerMedia {
|
||||
self.deleteButton.isHidden = false
|
||||
}
|
||||
}
|
||||
|
||||
var width = width
|
||||
if additionalSideInsets.right > 0.0 {
|
||||
width -= additionalSideInsets.right
|
||||
}
|
||||
|
||||
if self.reportButton.isHidden {
|
||||
self.deleteButton.frame = CGRect(origin: CGPoint(x: leftInset, y: 0.0), size: CGSize(width: 57.0, height: panelHeight))
|
||||
self.forwardButton.frame = CGRect(origin: CGPoint(x: width - rightInset - 57.0, y: 0.0), size: CGSize(width: 57.0, height: panelHeight))
|
||||
self.shareButton.frame = CGRect(origin: CGPoint(x: floor((width - rightInset - 57.0) / 2.0), y: 0.0), size: CGSize(width: 57.0, height: panelHeight))
|
||||
} else if !self.deleteButton.isHidden {
|
||||
let buttons: [HighlightableButtonNode] = [
|
||||
self.deleteButton,
|
||||
self.reportButton,
|
||||
self.shareButton,
|
||||
self.forwardButton
|
||||
]
|
||||
let buttonSize = CGSize(width: 57.0, height: panelHeight)
|
||||
|
||||
let availableWidth = width - leftInset - rightInset
|
||||
let spacing: CGFloat = floor((availableWidth - buttonSize.width * CGFloat(buttons.count)) / CGFloat(buttons.count - 1))
|
||||
var offset: CGFloat = leftInset
|
||||
for i in 0 ..< buttons.count {
|
||||
let button = buttons[i]
|
||||
if i == buttons.count - 1 {
|
||||
button.frame = CGRect(origin: CGPoint(x: width - rightInset - buttonSize.width, y: 0.0), size: buttonSize)
|
||||
} else {
|
||||
button.frame = CGRect(origin: CGPoint(x: offset, y: 0.0), size: buttonSize)
|
||||
}
|
||||
offset += buttonSize.width + spacing
|
||||
}
|
||||
} else {
|
||||
self.deleteButton.frame = CGRect(origin: CGPoint(x: leftInset, y: 0.0), size: CGSize(width: 53.0, height: panelHeight))
|
||||
self.forwardButton.frame = CGRect(origin: CGPoint(x: width - rightInset - 57.0, y: 0.0), size: CGSize(width: 57.0, height: panelHeight))
|
||||
self.reportButton.frame = CGRect(origin: CGPoint(x: leftInset, y: 0.0), size: CGSize(width: 53.0, height: 47.0))
|
||||
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
|
||||
}
|
||||
|
||||
override public func minimalHeight(interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics) -> CGFloat {
|
||||
return defaultHeight(metrics: metrics)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user