mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
118 lines
5.0 KiB
Swift
118 lines
5.0 KiB
Swift
import Foundation
|
|
import UIKit
|
|
import AsyncDisplayKit
|
|
import Display
|
|
import SwiftSignalKit
|
|
import TelegramPresentationData
|
|
import TelegramStringFormatting
|
|
import AppBundle
|
|
|
|
final class ChatTextInputSlowmodePlaceholderNode: ASDisplayNode {
|
|
private var theme: PresentationTheme
|
|
private let iconNode: ASImageNode
|
|
private let iconArrowContainerNode: ASDisplayNode
|
|
private let iconArrowNode: ASImageNode
|
|
private let textNode: ImmediateTextNode
|
|
|
|
private var slowmodeState: ChatSlowmodeState?
|
|
private var validLayout: CGSize?
|
|
|
|
private var timer: SwiftSignalKit.Timer?
|
|
|
|
init(theme: PresentationTheme) {
|
|
self.theme = theme
|
|
self.textNode = ImmediateTextNode()
|
|
self.textNode.displaysAsynchronously = false
|
|
|
|
self.iconNode = ASImageNode()
|
|
self.iconNode.displaysAsynchronously = false
|
|
self.iconNode.displayWithoutProcessing = true
|
|
self.iconNode.image = generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Text/SlowmodeFrame"), color: theme.chat.inputPanel.inputPlaceholderColor)
|
|
|
|
self.iconArrowNode = ASImageNode()
|
|
self.iconArrowNode.displaysAsynchronously = false
|
|
self.iconArrowNode.displayWithoutProcessing = true
|
|
self.iconArrowNode.image = generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Text/SlowmodeArrow"), color: theme.chat.inputPanel.inputPlaceholderColor)
|
|
self.iconArrowNode.frame = CGRect(origin: CGPoint(), size: self.iconArrowNode.image?.size ?? CGSize())
|
|
|
|
self.iconArrowContainerNode = ASDisplayNode()
|
|
self.iconArrowContainerNode.addSubnode(self.iconArrowNode)
|
|
|
|
super.init()
|
|
|
|
self.isUserInteractionEnabled = false
|
|
|
|
self.addSubnode(self.iconNode)
|
|
self.addSubnode(self.iconArrowContainerNode)
|
|
self.addSubnode(self.textNode)
|
|
}
|
|
|
|
deinit {
|
|
self.timer?.invalidate()
|
|
}
|
|
|
|
func updateState(_ slowmodeState: ChatSlowmodeState) {
|
|
if self.slowmodeState != slowmodeState {
|
|
self.slowmodeState = slowmodeState
|
|
self.update()
|
|
|
|
if self.timer == nil {
|
|
let timer = SwiftSignalKit.Timer(timeout: 0.5, repeat: true, completion: { [weak self] in
|
|
self?.update()
|
|
}, queue: .mainQueue())
|
|
self.timer = timer
|
|
timer.start()
|
|
}
|
|
}
|
|
}
|
|
|
|
private func update() {
|
|
if let slowmodeState = self.slowmodeState {
|
|
switch slowmodeState.variant {
|
|
case .pendingMessages:
|
|
self.textNode.attributedText = NSAttributedString(string: stringForDuration(slowmodeState.timeout), font: Font.regular(17.0), textColor: self.theme.chat.inputPanel.inputPlaceholderColor)
|
|
case let .timestamp(timeoutTimestamp):
|
|
let timestamp = Int32(Date().timeIntervalSince1970)
|
|
let timeout = max(0, timeoutTimestamp - timestamp)
|
|
self.textNode.attributedText = NSAttributedString(string: stringForDuration(timeout), font: Font.regular(17.0), textColor: self.theme.chat.inputPanel.inputPlaceholderColor)
|
|
if timeout <= 30 {
|
|
if self.iconArrowNode.layer.animation(forKey: "rotation") == nil {
|
|
let basicAnimation = CABasicAnimation(keyPath: "transform.rotation.z")
|
|
basicAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
|
|
basicAnimation.duration = 1.0
|
|
basicAnimation.fromValue = NSNumber(value: Float(0.0))
|
|
basicAnimation.toValue = NSNumber(value: Float(Double.pi * 2.0))
|
|
basicAnimation.repeatCount = Float.infinity
|
|
basicAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear)
|
|
self.iconArrowNode.layer.add(basicAnimation, forKey: "rotation")
|
|
}
|
|
} else {
|
|
self.iconArrowNode.layer.removeAnimation(forKey: "rotation")
|
|
}
|
|
}
|
|
}
|
|
if let validLayout = self.validLayout {
|
|
self.updateLayout(size: validLayout)
|
|
}
|
|
}
|
|
|
|
func updateLayout(size: CGSize) {
|
|
self.validLayout = size
|
|
|
|
var leftInset: CGFloat = 0.0
|
|
if let image = self.iconNode.image {
|
|
let imageSize = image.size
|
|
leftInset += imageSize.width + 4.0
|
|
let iconArrowFrame = CGRect(origin: CGPoint(x: 0.0, y: 1.0), size: imageSize)
|
|
self.iconNode.frame = iconArrowFrame
|
|
|
|
if let arrowImage = self.iconArrowNode.image {
|
|
self.iconArrowContainerNode.frame = CGRect(origin: CGPoint(x: iconArrowFrame.minX, y: iconArrowFrame.maxY - arrowImage.size.height), size: arrowImage.size)
|
|
}
|
|
}
|
|
|
|
let textSize = self.textNode.updateLayout(size)
|
|
self.textNode.frame = CGRect(origin: CGPoint(x: leftInset, y: 0.0), size: textSize)
|
|
}
|
|
}
|