mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-22 22:25:57 +00:00
Merge branch 'master' into glass
# Conflicts: # submodules/AttachmentUI/Sources/AttachmentPanel.swift # submodules/ChatPresentationInterfaceState/Sources/ChatPanelInterfaceInteraction.swift # submodules/TelegramUI/BUILD # submodules/TelegramUI/Components/Chat/ChatRecentActionsController/Sources/ChatRecentActionsController.swift # submodules/TelegramUI/Components/Chat/ChatTextInputActionButtonsNode/Sources/ChatTextInputActionButtonsNode.swift # submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/Sources/ChatTextInputPanelNode.swift # submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift # submodules/TelegramUI/Components/PeerSelectionController/Sources/PeerSelectionControllerNode.swift # submodules/TelegramUI/Sources/Chat/ChatControllerLoadDisplayNode.swift # submodules/TelegramUI/Sources/ChatInterfaceStateInputPanels.swift
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
import Foundation
|
||||
import UIKit
|
||||
import Display
|
||||
import AsyncDisplayKit
|
||||
import TelegramPresentationData
|
||||
import SwiftSignalKit
|
||||
import ChatPresentationInterfaceState
|
||||
import AnimatedCountLabelNode
|
||||
import TelegramStringFormatting
|
||||
|
||||
private func generateClearImage(color: UIColor) -> UIImage? {
|
||||
return generateImage(CGSize(width: 17.0, height: 17.0), rotatedContext: { size, context in
|
||||
context.clear(CGRect(origin: CGPoint(), size: size))
|
||||
context.setFillColor(color.cgColor)
|
||||
context.fillEllipse(in: CGRect(origin: CGPoint(), size: size))
|
||||
context.setBlendMode(.copy)
|
||||
context.setStrokeColor(UIColor.clear.cgColor)
|
||||
context.setLineCap(.round)
|
||||
context.setLineWidth(1.66)
|
||||
context.move(to: CGPoint(x: 6.0, y: 6.0))
|
||||
context.addLine(to: CGPoint(x: 11.0, y: 11.0))
|
||||
context.strokePath()
|
||||
context.move(to: CGPoint(x: size.width - 6.0, y: 6.0))
|
||||
context.addLine(to: CGPoint(x: size.width - 11.0, y: 11.0))
|
||||
context.strokePath()
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
final class BoostSlowModeButton: HighlightTrackingButtonNode {
|
||||
let containerNode: ASDisplayNode
|
||||
let backgroundNode: ASImageNode
|
||||
let textNode: ImmediateAnimatedCountLabelNode
|
||||
let iconNode: ASImageNode
|
||||
|
||||
private var updateTimer: SwiftSignalKit.Timer?
|
||||
|
||||
var requestUpdate: () -> Void = {}
|
||||
|
||||
override init(pointerStyle: PointerStyle? = nil) {
|
||||
self.containerNode = ASDisplayNode()
|
||||
|
||||
self.backgroundNode = ASImageNode()
|
||||
self.backgroundNode.displaysAsynchronously = false
|
||||
self.backgroundNode.clipsToBounds = true
|
||||
self.backgroundNode.image = generateGradientImage(size: CGSize(width: 100.0, height: 2.0), scale: 1.0, colors: [UIColor(rgb: 0x9076ff), UIColor(rgb: 0xbc6de8)], locations: [0.0, 1.0], direction: .horizontal)
|
||||
|
||||
self.iconNode = ASImageNode()
|
||||
self.iconNode.displaysAsynchronously = false
|
||||
self.iconNode.image = generateClearImage(color: .white)
|
||||
|
||||
self.textNode = ImmediateAnimatedCountLabelNode()
|
||||
self.textNode.alwaysOneDirection = true
|
||||
self.textNode.isUserInteractionEnabled = false
|
||||
|
||||
super.init(pointerStyle: pointerStyle)
|
||||
|
||||
self.addSubnode(self.containerNode)
|
||||
self.containerNode.addSubnode(self.backgroundNode)
|
||||
self.containerNode.addSubnode(self.iconNode)
|
||||
self.containerNode.addSubnode(self.textNode)
|
||||
|
||||
self.highligthedChanged = { [weak self] highlighted in
|
||||
if let self {
|
||||
if highlighted {
|
||||
self.containerNode.layer.animateScale(from: 1.0, to: 0.75, duration: 0.4, removeOnCompletion: false)
|
||||
} else if let presentationLayer = self.containerNode.layer.presentation() {
|
||||
self.containerNode.layer.animateScale(from: CGFloat((presentationLayer.value(forKeyPath: "transform.scale.y") as? NSNumber)?.floatValue ?? 1.0), to: 1.0, duration: 0.25, removeOnCompletion: false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func update(size: CGSize, interfaceState: ChatPresentationInterfaceState) -> CGSize {
|
||||
var text = ""
|
||||
if let slowmodeState = interfaceState.slowmodeState {
|
||||
let relativeTimestamp: CGFloat
|
||||
switch slowmodeState.variant {
|
||||
case let .timestamp(validUntilTimestamp):
|
||||
let timestamp = CGFloat(Date().timeIntervalSince1970)
|
||||
relativeTimestamp = CGFloat(validUntilTimestamp) - timestamp
|
||||
case .pendingMessages:
|
||||
relativeTimestamp = CGFloat(slowmodeState.timeout)
|
||||
}
|
||||
|
||||
self.updateTimer?.invalidate()
|
||||
|
||||
if relativeTimestamp >= 0.0 {
|
||||
text = stringForDuration(Int32(relativeTimestamp))
|
||||
|
||||
self.updateTimer = SwiftSignalKit.Timer(timeout: 1.0 / 60.0, repeat: false, completion: { [weak self] in
|
||||
self?.requestUpdate()
|
||||
}, queue: .mainQueue())
|
||||
self.updateTimer?.start()
|
||||
}
|
||||
} else {
|
||||
self.updateTimer?.invalidate()
|
||||
self.updateTimer = nil
|
||||
}
|
||||
|
||||
let font = Font.with(size: 15.0, design: .round, weight: .semibold, traits: [.monospacedNumbers])
|
||||
let textColor = UIColor.white
|
||||
|
||||
var segments: [AnimatedCountLabelNode.Segment] = []
|
||||
var textCount = 0
|
||||
|
||||
for char in text {
|
||||
if let intValue = Int(String(char)) {
|
||||
segments.append(.number(intValue, NSAttributedString(string: String(char), font: font, textColor: textColor)))
|
||||
} else {
|
||||
segments.append(.text(textCount, NSAttributedString(string: String(char), font: font, textColor: textColor)))
|
||||
textCount += 1
|
||||
}
|
||||
}
|
||||
self.textNode.segments = segments
|
||||
|
||||
let textSize = self.textNode.updateLayout(size: CGSize(width: 200.0, height: 100.0), animated: true)
|
||||
let totalSize = CGSize(width: textSize.width > 0.0 ? textSize.width + 38.0 : 33.0, height: 33.0)
|
||||
|
||||
self.containerNode.bounds = CGRect(origin: .zero, size: totalSize)
|
||||
self.containerNode.position = CGPoint(x: totalSize.width / 2.0, y: totalSize.height / 2.0)
|
||||
self.backgroundNode.frame = CGRect(origin: .zero, size: totalSize)
|
||||
self.backgroundNode.cornerRadius = totalSize.height / 2.0
|
||||
self.textNode.frame = CGRect(origin: CGPoint(x: 9.0, y: floorToScreenPixels((totalSize.height - textSize.height) / 2.0)), size: textSize)
|
||||
if let icon = self.iconNode.image {
|
||||
self.iconNode.frame = CGRect(origin: CGPoint(x: totalSize.width - icon.size.width - 7.0, y: floorToScreenPixels((totalSize.height - icon.size.height) / 2.0)), size: icon.size)
|
||||
}
|
||||
return totalSize
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user