mirror of
https://github.com/TelegramMessenger/Telegram-iOS.git
synced 2026-06-20 18:24:43 +00:00
175 lines
7.9 KiB
Swift
175 lines
7.9 KiB
Swift
import Foundation
|
|
import UIKit
|
|
import Display
|
|
import AsyncDisplayKit
|
|
import TelegramCore
|
|
import TelegramPresentationData
|
|
import LocalizedPeerData
|
|
import TelegramStringFormatting
|
|
import TelegramNotices
|
|
import AnimatedAvatarSetNode
|
|
import AccountContext
|
|
import ChatPresentationInterfaceState
|
|
import LegacyChatHeaderPanelComponent
|
|
|
|
final class ChatInviteRequestsTitlePanelNode: ChatTitleAccessoryPanelNode {
|
|
private final class Params {
|
|
let width: CGFloat
|
|
let leftInset: CGFloat
|
|
let rightInset: CGFloat
|
|
let interfaceState: ChatPresentationInterfaceState
|
|
|
|
init(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, interfaceState: ChatPresentationInterfaceState) {
|
|
self.width = width
|
|
self.leftInset = leftInset
|
|
self.rightInset = rightInset
|
|
self.interfaceState = interfaceState
|
|
}
|
|
}
|
|
|
|
private let context: AccountContext
|
|
|
|
private let separatorNode: ASDisplayNode
|
|
|
|
private let closeButton: HighlightableButtonNode
|
|
private let button: HighlightableButtonNode
|
|
private let buttonTitle: ImmediateTextNode
|
|
|
|
private let avatarsContext: AnimatedAvatarSetContext
|
|
private var avatarsContent: AnimatedAvatarSetContext.Content?
|
|
private let avatarsNode: AnimatedAvatarSetNode
|
|
|
|
private let activateAreaNode: AccessibilityAreaNode
|
|
|
|
private var theme: PresentationTheme?
|
|
|
|
private var peerId: EnginePeer.Id?
|
|
private var peers: [EnginePeer] = []
|
|
private var count: Int32 = 0
|
|
|
|
private var params: Params?
|
|
|
|
init(context: AccountContext) {
|
|
self.context = context
|
|
|
|
self.separatorNode = ASDisplayNode()
|
|
self.separatorNode.isLayerBacked = true
|
|
|
|
self.closeButton = HighlightableButtonNode()
|
|
self.closeButton.hitTestSlop = UIEdgeInsets(top: -8.0, left: -8.0, bottom: -8.0, right: -8.0)
|
|
self.closeButton.displaysAsynchronously = false
|
|
|
|
self.button = HighlightableButtonNode()
|
|
self.buttonTitle = ImmediateTextNode()
|
|
self.buttonTitle.anchorPoint = CGPoint()
|
|
|
|
self.avatarsContext = AnimatedAvatarSetContext()
|
|
self.avatarsNode = AnimatedAvatarSetNode()
|
|
|
|
self.activateAreaNode = AccessibilityAreaNode()
|
|
self.activateAreaNode.accessibilityTraits = .button
|
|
|
|
super.init()
|
|
|
|
self.addSubnode(self.separatorNode)
|
|
|
|
self.closeButton.addTarget(self, action: #selector(self.closePressed), forControlEvents: [.touchUpInside])
|
|
self.addSubnode(self.closeButton)
|
|
|
|
self.button.addTarget(self, action: #selector(self.buttonPressed), forControlEvents: .touchUpInside)
|
|
self.addSubnode(self.button)
|
|
|
|
self.buttonTitle.isUserInteractionEnabled = false
|
|
self.button.addSubnode(self.buttonTitle)
|
|
|
|
self.addSubnode(self.avatarsNode)
|
|
|
|
self.addSubnode(self.activateAreaNode)
|
|
}
|
|
|
|
|
|
func update(peerId: EnginePeer.Id, peers: [EnginePeer], count: Int32) {
|
|
self.peerId = peerId
|
|
self.peers = peers
|
|
self.count = count
|
|
|
|
self.avatarsContent = self.avatarsContext.update(peers: peers, animated: false)
|
|
|
|
if let params = self.params {
|
|
let _ = self.updateLayout(width: params.width, leftInset: params.leftInset, rightInset: params.rightInset, transition: .immediate, interfaceState: params.interfaceState)
|
|
}
|
|
}
|
|
|
|
override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState) -> LayoutResult {
|
|
self.params = Params(width: width, leftInset: leftInset, rightInset: rightInset, interfaceState: interfaceState)
|
|
|
|
if interfaceState.theme !== self.theme {
|
|
self.theme = interfaceState.theme
|
|
|
|
self.closeButton.setImage(generateImage(CGSize(width: 12.0, height: 12.0), contextGenerator: { size, context in
|
|
context.clear(CGRect(origin: CGPoint(), size: size))
|
|
context.setStrokeColor(interfaceState.theme.chat.inputPanel.panelControlColor.cgColor)
|
|
context.setLineWidth(1.33)
|
|
context.setLineCap(.round)
|
|
context.move(to: CGPoint(x: 1.0, y: 1.0))
|
|
context.addLine(to: CGPoint(x: size.width - 1.0, y: size.height - 1.0))
|
|
context.strokePath()
|
|
context.move(to: CGPoint(x: size.width - 1.0, y: 1.0))
|
|
context.addLine(to: CGPoint(x: 1.0, y: size.height - 1.0))
|
|
context.strokePath()
|
|
}), for: [])
|
|
self.separatorNode.backgroundColor = interfaceState.theme.rootController.navigationBar.separatorColor
|
|
}
|
|
|
|
let panelHeight: CGFloat = 40.0
|
|
|
|
let contentRightInset: CGFloat = 14.0 + rightInset
|
|
|
|
let closeButtonSize = self.closeButton.measure(CGSize(width: 100.0, height: 100.0))
|
|
transition.updateFrame(node: self.closeButton, frame: CGRect(origin: CGPoint(x: width - contentRightInset - closeButtonSize.width - 3.0, y: floorToScreenPixels((panelHeight - closeButtonSize.height) / 2.0)), size: closeButtonSize))
|
|
|
|
self.buttonTitle.attributedText = NSAttributedString(string: interfaceState.strings.Conversation_RequestsToJoin(self.count), font: Font.medium(15.0), textColor: interfaceState.theme.chat.inputPanel.panelControlColor)
|
|
|
|
transition.updateFrame(node: self.button, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: width, height: panelHeight)))
|
|
|
|
let titleSize = self.buttonTitle.updateLayout(CGSize(width: width - leftInset - 90.0 - contentRightInset, height: 100.0))
|
|
var buttonTitleFrame = CGRect(origin: CGPoint(x: leftInset + floor((width - leftInset - titleSize.width) * 0.5), y: floor((panelHeight - titleSize.height) * 0.5) + 1.0), size: titleSize)
|
|
buttonTitleFrame.origin.x = max(buttonTitleFrame.minX, leftInset + 90.0)
|
|
transition.updatePosition(node: self.buttonTitle, position: buttonTitleFrame.origin)
|
|
self.buttonTitle.bounds = CGRect(origin: CGPoint(), size: buttonTitleFrame.size)
|
|
|
|
let initialPanelHeight = panelHeight
|
|
transition.updateFrame(node: self.separatorNode, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: width, height: UIScreenPixel)))
|
|
|
|
if let avatarsContent = self.avatarsContent {
|
|
let avatarsSize = self.avatarsNode.update(context: self.context, content: avatarsContent, itemSize: CGSize(width: 32.0, height: 32.0), animated: true, synchronousLoad: true)
|
|
transition.updateFrame(node: self.avatarsNode, frame: CGRect(origin: CGPoint(x: leftInset + 4.0, y: floor((panelHeight - avatarsSize.height) / 2.0)), size: avatarsSize))
|
|
}
|
|
|
|
self.activateAreaNode.frame = CGRect(origin: .zero, size: CGSize(width: width, height: panelHeight))
|
|
self.activateAreaNode.accessibilityLabel = interfaceState.strings.Conversation_RequestsToJoin(self.count)
|
|
|
|
return LayoutResult(backgroundHeight: initialPanelHeight, insetHeight: panelHeight, hitTestSlop: 0.0)
|
|
}
|
|
|
|
@objc func buttonPressed() {
|
|
self.interfaceInteraction?.openInviteRequests()
|
|
}
|
|
|
|
@objc func closePressed() {
|
|
guard let peerId = self.peerId else {
|
|
return
|
|
}
|
|
|
|
let ids = peers.map { $0.id.toInt64() }
|
|
let _ = ApplicationSpecificNotice.setDismissedInvitationRequests(accountManager: context.sharedContext.accountManager, peerId: peerId, values: ids).startStandalone()
|
|
}
|
|
|
|
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
|
|
if let result = self.closeButton.hitTest(CGPoint(x: point.x - self.closeButton.frame.minX, y: point.y - self.closeButton.frame.minY), with: event) {
|
|
return result
|
|
}
|
|
return super.hitTest(point, with: event)
|
|
}
|
|
}
|