mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-08-02 00:17:02 +00:00
Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios
This commit is contained in:
commit
010d7d7412
@ -122,6 +122,7 @@ public final class CallListController: TelegramBaseController {
|
|||||||
|
|
||||||
self.segmentedTitleView.indexUpdated = { [weak self] index in
|
self.segmentedTitleView.indexUpdated = { [weak self] index in
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
|
strongSelf.segmentedTitleView.index = index
|
||||||
strongSelf.controllerNode.updateType(index == 0 ? .all : .missed)
|
strongSelf.controllerNode.updateType(index == 0 ? .all : .missed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1158,7 +1158,33 @@ private func addAttachment(attachment: UIImage, line: TextNodeLine, ascent: CGFl
|
|||||||
}
|
}
|
||||||
|
|
||||||
open class TextNode: ASDisplayNode {
|
open class TextNode: ASDisplayNode {
|
||||||
|
public struct RenderContentTypes: OptionSet {
|
||||||
|
public var rawValue: Int
|
||||||
|
|
||||||
|
public init(rawValue: Int) {
|
||||||
|
self.rawValue = rawValue
|
||||||
|
}
|
||||||
|
|
||||||
|
public static let text = RenderContentTypes(rawValue: 1 << 0)
|
||||||
|
public static let emoji = RenderContentTypes(rawValue: 1 << 1)
|
||||||
|
|
||||||
|
public static let all: RenderContentTypes = [.text, .emoji]
|
||||||
|
}
|
||||||
|
|
||||||
|
private final class DrawingParameters: NSObject {
|
||||||
|
let cachedLayout: TextNodeLayout?
|
||||||
|
let renderContentTypes: RenderContentTypes
|
||||||
|
|
||||||
|
init(cachedLayout: TextNodeLayout?, renderContentTypes: RenderContentTypes) {
|
||||||
|
self.cachedLayout = cachedLayout
|
||||||
|
self.renderContentTypes = renderContentTypes
|
||||||
|
|
||||||
|
super.init()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public internal(set) var cachedLayout: TextNodeLayout?
|
public internal(set) var cachedLayout: TextNodeLayout?
|
||||||
|
public var renderContentTypes: RenderContentTypes = .all
|
||||||
|
|
||||||
override public init() {
|
override public init() {
|
||||||
super.init()
|
super.init()
|
||||||
@ -2169,7 +2195,7 @@ open class TextNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override public func drawParameters(forAsyncLayer layer: _ASDisplayLayer) -> NSObjectProtocol? {
|
override public func drawParameters(forAsyncLayer layer: _ASDisplayLayer) -> NSObjectProtocol? {
|
||||||
return self.cachedLayout
|
return DrawingParameters(cachedLayout: self.cachedLayout, renderContentTypes: self.renderContentTypes)
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc override public class func draw(_ bounds: CGRect, withParameters parameters: Any?, isCancelled: () -> Bool, isRasterizing: Bool) {
|
@objc override public class func draw(_ bounds: CGRect, withParameters parameters: Any?, isCancelled: () -> Bool, isRasterizing: Bool) {
|
||||||
@ -2192,8 +2218,13 @@ open class TextNode: ASDisplayNode {
|
|||||||
|
|
||||||
var blendMode: CGBlendMode = .normal
|
var blendMode: CGBlendMode = .normal
|
||||||
|
|
||||||
|
var renderContentTypes: RenderContentTypes = .all
|
||||||
|
if let parameters = parameters as? DrawingParameters {
|
||||||
|
renderContentTypes = parameters.renderContentTypes
|
||||||
|
}
|
||||||
|
|
||||||
var clearRects: [CGRect] = []
|
var clearRects: [CGRect] = []
|
||||||
if let layout = parameters as? TextNodeLayout {
|
if let layout = (parameters as? DrawingParameters)?.cachedLayout {
|
||||||
if !isRasterizing || layout.backgroundColor != nil {
|
if !isRasterizing || layout.backgroundColor != nil {
|
||||||
context.setBlendMode(.copy)
|
context.setBlendMode(.copy)
|
||||||
blendMode = .copy
|
blendMode = .copy
|
||||||
@ -2409,6 +2440,18 @@ open class TextNode: ASDisplayNode {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if renderContentTypes != .all {
|
||||||
|
if let font = attributes["NSFont"] as? UIFont, font.fontName.contains("ColorEmoji") {
|
||||||
|
if !renderContentTypes.contains(.emoji) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if !renderContentTypes.contains(.text) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var fixDoubleEmoji = false
|
var fixDoubleEmoji = false
|
||||||
if glyphCount == 2, let font = attributes["NSFont"] as? UIFont, font.fontName.contains("ColorEmoji"), let string = layout.attributedString {
|
if glyphCount == 2, let font = attributes["NSFont"] as? UIFont, font.fontName.contains("ColorEmoji"), let string = layout.attributedString {
|
||||||
let range = CTRunGetStringRange(run)
|
let range = CTRunGetStringRange(run)
|
||||||
|
@ -600,7 +600,8 @@ public final class PeerAvatarBottomShadowNode: ASDisplayNode {
|
|||||||
return UIColor(white: 1.0, alpha: 1.0).cgColor
|
return UIColor(white: 1.0, alpha: 1.0).cgColor
|
||||||
} else {
|
} else {
|
||||||
let step: CGFloat = CGFloat(i - firstStep) / CGFloat(numSteps - firstStep - 1)
|
let step: CGFloat = CGFloat(i - firstStep) / CGFloat(numSteps - firstStep - 1)
|
||||||
return UIColor(white: 1.0, alpha: baseGradientAlpha * (1.0 - pow(step, 3.0))).cgColor
|
let value: CGFloat = 1.0 - bezierPoint(0.42, 0.0, 0.58, 1.0, step)
|
||||||
|
return UIColor(white: 1.0, alpha: baseGradientAlpha * value).cgColor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.backgroundGradientMaskLayer.locations = (0 ..< numSteps).map { i -> NSNumber in
|
self.backgroundGradientMaskLayer.locations = (0 ..< numSteps).map { i -> NSNumber in
|
||||||
@ -662,6 +663,7 @@ public final class AvatarListContentNode: ASDisplayNode {
|
|||||||
|
|
||||||
if value {
|
if value {
|
||||||
replicatorLayer.instanceAlphaOffset = -1.0
|
replicatorLayer.instanceAlphaOffset = -1.0
|
||||||
|
replicatorLayer.animate(from: 0.0 as NSNumber, to: -1.0 as NSNumber, keyPath: "instanceAlphaOffset", timingFunction: CAMediaTimingFunctionName.linear.rawValue, duration: 0.3)
|
||||||
} else {
|
} else {
|
||||||
replicatorLayer.instanceAlphaOffset = 0.0
|
replicatorLayer.instanceAlphaOffset = 0.0
|
||||||
replicatorLayer.animate(from: -1.0 as NSNumber, to: 1.0 as NSNumber, keyPath: "instanceAlphaOffset", timingFunction: CAMediaTimingFunctionName.linear.rawValue, duration: 0.3)
|
replicatorLayer.animate(from: -1.0 as NSNumber, to: 1.0 as NSNumber, keyPath: "instanceAlphaOffset", timingFunction: CAMediaTimingFunctionName.linear.rawValue, duration: 0.3)
|
||||||
|
@ -418,7 +418,7 @@ public final class EmojiStatusComponent: Component {
|
|||||||
if transition.animation.isImmediate {
|
if transition.animation.isImmediate {
|
||||||
iconView.tintColor = iconTintColor
|
iconView.tintColor = iconTintColor
|
||||||
} else {
|
} else {
|
||||||
transition.setTintColor(layer: iconView.layer, color: iconTintColor)
|
transition.setTintColor(view: iconView, color: iconTintColor)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
iconView.tintColor = nil
|
iconView.tintColor = nil
|
||||||
|
@ -4,17 +4,24 @@ import AsyncDisplayKit
|
|||||||
import Display
|
import Display
|
||||||
|
|
||||||
private final class MultiScaleTextStateNode: ASDisplayNode {
|
private final class MultiScaleTextStateNode: ASDisplayNode {
|
||||||
let textNode: ImmediateTextNode
|
let tintTextNode: ImmediateTextNode
|
||||||
|
let noTintTextNode: ImmediateTextNode
|
||||||
|
|
||||||
var currentLayout: MultiScaleTextLayout?
|
var currentLayout: MultiScaleTextLayout?
|
||||||
|
|
||||||
override init() {
|
override init() {
|
||||||
self.textNode = ImmediateTextNode()
|
self.tintTextNode = ImmediateTextNode()
|
||||||
self.textNode.displaysAsynchronously = false
|
self.tintTextNode.displaysAsynchronously = false
|
||||||
|
self.tintTextNode.renderContentTypes = TextNode.RenderContentTypes.all.subtracting(TextNode.RenderContentTypes.emoji)
|
||||||
|
|
||||||
|
self.noTintTextNode = ImmediateTextNode()
|
||||||
|
self.noTintTextNode.displaysAsynchronously = false
|
||||||
|
self.noTintTextNode.renderContentTypes = .emoji
|
||||||
|
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
self.addSubnode(self.textNode)
|
self.addSubnode(self.tintTextNode)
|
||||||
|
self.addSubnode(self.noTintTextNode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,12 +67,12 @@ public final class MultiScaleTextNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public func stateNode(forKey key: AnyHashable) -> ASDisplayNode? {
|
public func stateNode(forKey key: AnyHashable) -> ASDisplayNode? {
|
||||||
return self.stateNodes[key]?.textNode
|
return self.stateNodes[key]?.tintTextNode
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updateTintColor(color: UIColor, transition: ContainedViewLayoutTransition) {
|
public func updateTintColor(color: UIColor, transition: ContainedViewLayoutTransition) {
|
||||||
for (_, node) in self.stateNodes {
|
for (_, node) in self.stateNodes {
|
||||||
transition.updateTintColor(layer: node.textNode.layer, color: color)
|
transition.updateTintColor(layer: node.tintTextNode.layer, color: color)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,10 +84,13 @@ public final class MultiScaleTextNode: ASDisplayNode {
|
|||||||
var mainLayout: MultiScaleTextLayout?
|
var mainLayout: MultiScaleTextLayout?
|
||||||
for (key, state) in states {
|
for (key, state) in states {
|
||||||
if let node = self.stateNodes[key] {
|
if let node = self.stateNodes[key] {
|
||||||
node.textNode.attributedText = NSAttributedString(string: text, font: state.attributes.font, textColor: state.attributes.color)
|
node.tintTextNode.attributedText = NSAttributedString(string: text, font: state.attributes.font, textColor: state.attributes.color)
|
||||||
node.textNode.isAccessibilityElement = true
|
node.noTintTextNode.attributedText = NSAttributedString(string: text, font: state.attributes.font, textColor: state.attributes.color)
|
||||||
node.textNode.accessibilityLabel = text
|
node.tintTextNode.isAccessibilityElement = true
|
||||||
let nodeSize = node.textNode.updateLayout(state.constrainedSize)
|
node.tintTextNode.accessibilityLabel = text
|
||||||
|
node.noTintTextNode.isAccessibilityElement = false
|
||||||
|
let nodeSize = node.tintTextNode.updateLayout(state.constrainedSize)
|
||||||
|
let _ = node.noTintTextNode.updateLayout(state.constrainedSize)
|
||||||
let nodeLayout = MultiScaleTextLayout(size: nodeSize)
|
let nodeLayout = MultiScaleTextLayout(size: nodeSize)
|
||||||
if key == mainState {
|
if key == mainState {
|
||||||
mainLayout = nodeLayout
|
mainLayout = nodeLayout
|
||||||
@ -93,7 +103,9 @@ public final class MultiScaleTextNode: ASDisplayNode {
|
|||||||
let mainBounds = CGRect(origin: CGPoint(x: -mainLayout.size.width / 2.0, y: -mainLayout.size.height / 2.0), size: mainLayout.size)
|
let mainBounds = CGRect(origin: CGPoint(x: -mainLayout.size.width / 2.0, y: -mainLayout.size.height / 2.0), size: mainLayout.size)
|
||||||
for (key, _) in states {
|
for (key, _) in states {
|
||||||
if let node = self.stateNodes[key], let nodeLayout = result[key] {
|
if let node = self.stateNodes[key], let nodeLayout = result[key] {
|
||||||
node.textNode.frame = CGRect(origin: CGPoint(x: mainBounds.minX, y: mainBounds.minY + floor((mainBounds.height - nodeLayout.size.height) / 2.0)), size: nodeLayout.size)
|
let textFrame = CGRect(origin: CGPoint(x: mainBounds.minX, y: mainBounds.minY + floor((mainBounds.height - nodeLayout.size.height) / 2.0)), size: nodeLayout.size)
|
||||||
|
node.tintTextNode.frame = textFrame
|
||||||
|
node.noTintTextNode.frame = textFrame
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1106,7 +1106,7 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||||||
|
|
||||||
var bottomShadowHeight: CGFloat = 88.0
|
var bottomShadowHeight: CGFloat = 88.0
|
||||||
if !self.isSettings {
|
if !self.isSettings {
|
||||||
bottomShadowHeight += 90.0
|
bottomShadowHeight += 110.0
|
||||||
}
|
}
|
||||||
let bottomShadowFrame = CGRect(origin: CGPoint(x: 0.0, y: expandedAvatarHeight - bottomShadowHeight), size: CGSize(width: width, height: bottomShadowHeight))
|
let bottomShadowFrame = CGRect(origin: CGPoint(x: 0.0, y: expandedAvatarHeight - bottomShadowHeight), size: CGSize(width: width, height: bottomShadowHeight))
|
||||||
transition.updateFrame(node: self.avatarListNode.listContainerNode.bottomShadowNode, frame: bottomShadowFrame, beginWithCurrentState: true)
|
transition.updateFrame(node: self.avatarListNode.listContainerNode.bottomShadowNode, frame: bottomShadowFrame, beginWithCurrentState: true)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user