Voice Chat UI fixes

This commit is contained in:
Ilya Laktyushin 2020-12-03 05:22:39 +04:00
parent abe01c95cb
commit dc4eed539e
11 changed files with 2303 additions and 2270 deletions

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -5985,3 +5985,5 @@ Sorry for the inconvenience.";
"Call.VoiceChatInProgressTitle" = "Voice Chat in Progress"; "Call.VoiceChatInProgressTitle" = "Voice Chat in Progress";
"Call.VoiceChatInProgressMessageCall" = "Leave voice chat in %1$@ and start a call with %2$@?"; "Call.VoiceChatInProgressMessageCall" = "Leave voice chat in %1$@ and start a call with %2$@?";
"Conversation.Dice.u1F3B3" = "Send a bowling emoji to try your luck.";

View File

@ -41,29 +41,24 @@ private class CallStatusBarBackgroundNode: ASDisplayNode {
} }
} }
var isCurrentlyInHierarchy = false private let hierarchyTrackingNode: HierarchyTrackingNode
override func didEnterHierarchy() { private var isCurrentlyInHierarchy = false
super.didEnterHierarchy()
self.isCurrentlyInHierarchy = true
self.updateAnimations()
}
override func didExitHierarchy() {
super.didExitHierarchy()
self.isCurrentlyInHierarchy = false
self.updateAnimations()
}
override init() { override init() {
self.foregroundView = UIView() self.foregroundView = UIView()
self.foregroundGradientLayer = CAGradientLayer() self.foregroundGradientLayer = CAGradientLayer()
self.maskCurveView = VoiceCurveView(frame: CGRect(), maxLevel: 2.5, smallCurveRange: (0.0, 0.0), mediumCurveRange: (0.1, 0.55), bigCurveRange: (0.1, 1.0)) self.maskCurveView = VoiceCurveView(frame: CGRect(), maxLevel: 2.5, smallCurveRange: (0.0, 0.0), mediumCurveRange: (0.1, 0.55), bigCurveRange: (0.1, 1.0))
self.maskCurveView.setColor(UIColor(rgb: 0xffffff)) self.maskCurveView.setColor(UIColor(rgb: 0xffffff))
var updateInHierarchy: ((Bool) -> Void)?
self.hierarchyTrackingNode = HierarchyTrackingNode({ value in
updateInHierarchy?(value)
})
super.init() super.init()
self.addSubnode(self.hierarchyTrackingNode)
self.foregroundGradientLayer.colors = [blue.cgColor, lightBlue.cgColor] self.foregroundGradientLayer.colors = [blue.cgColor, lightBlue.cgColor]
self.foregroundGradientLayer.startPoint = CGPoint(x: 0.0, y: 0.5) self.foregroundGradientLayer.startPoint = CGPoint(x: 0.0, y: 0.5)
self.foregroundGradientLayer.endPoint = CGPoint(x: 2.0, y: 0.5) self.foregroundGradientLayer.endPoint = CGPoint(x: 2.0, y: 0.5)
@ -73,6 +68,13 @@ private class CallStatusBarBackgroundNode: ASDisplayNode {
self.isOpaque = false self.isOpaque = false
self.updateAnimations() self.updateAnimations()
updateInHierarchy = { [weak self] value in
if let strongSelf = self {
strongSelf.isCurrentlyInHierarchy = value
strongSelf.updateAnimations()
}
}
} }
override func didLoad() { override func didLoad() {
@ -444,7 +446,7 @@ final class CurveView: UIView {
var level: CGFloat = 0 { var level: CGFloat = 0 {
didSet { didSet {
guard self.alpha == 1.0 else { guard self.minOffset > 0.0 else {
return return
} }
CATransaction.begin() CATransaction.begin()

View File

@ -14,6 +14,9 @@ private let blue = UIColor(rgb: 0x0078ff)
private let lightBlue = UIColor(rgb: 0x59c7f8) private let lightBlue = UIColor(rgb: 0x59c7f8)
private let green = UIColor(rgb: 0x33c659) private let green = UIColor(rgb: 0x33c659)
private let areaSize = CGSize(width: 370.0, height: 370.0)
private let blobSize = CGSize(width: 244.0, height: 244.0)
final class VoiceChatActionButton: HighlightTrackingButtonNode { final class VoiceChatActionButton: HighlightTrackingButtonNode {
enum State { enum State {
enum ActiveState { enum ActiveState {
@ -27,12 +30,12 @@ final class VoiceChatActionButton: HighlightTrackingButtonNode {
} }
private let containerNode: ASDisplayNode private let containerNode: ASDisplayNode
private let backgroundNode: VoiceChatActionButtonBackgroundNewNode private let backgroundNode: VoiceChatActionButtonBackgroundNode
private let iconNode: VoiceChatMicrophoneNode private let iconNode: VoiceChatMicrophoneNode
private let titleLabel: ImmediateTextNode private let titleLabel: ImmediateTextNode
private let subtitleLabel: ImmediateTextNode private let subtitleLabel: ImmediateTextNode
private var currentParams: (size: CGSize, buttonSize: CGSize, state: VoiceChatActionButton.State, simplified: Bool, title: String, subtitle: String)? private var currentParams: (size: CGSize, buttonSize: CGSize, state: VoiceChatActionButton.State, small: Bool, title: String, subtitle: String)?
private var activePromise = ValuePromise<Bool>(false) private var activePromise = ValuePromise<Bool>(false)
private var outerColorPromise = ValuePromise<UIColor?>(nil) private var outerColorPromise = ValuePromise<UIColor?>(nil)
@ -55,7 +58,7 @@ final class VoiceChatActionButton: HighlightTrackingButtonNode {
init() { init() {
self.containerNode = ASDisplayNode() self.containerNode = ASDisplayNode()
self.backgroundNode = VoiceChatActionButtonBackgroundNewNode() self.backgroundNode = VoiceChatActionButtonBackgroundNode()
self.iconNode = VoiceChatMicrophoneNode() self.iconNode = VoiceChatMicrophoneNode()
self.titleLabel = ImmediateTextNode() self.titleLabel = ImmediateTextNode()
@ -100,7 +103,7 @@ final class VoiceChatActionButton: HighlightTrackingButtonNode {
} }
func applyParams(animated: Bool) { func applyParams(animated: Bool) {
guard let (size, _, _, simplified, title, subtitle) = self.currentParams else { guard let (size, _, _, small, title, subtitle) = self.currentParams else {
return return
} }
@ -133,14 +136,14 @@ final class VoiceChatActionButton: HighlightTrackingButtonNode {
let subtitleSize = self.subtitleLabel.updateLayout(CGSize(width: size.width, height: .greatestFiniteMagnitude)) let subtitleSize = self.subtitleLabel.updateLayout(CGSize(width: size.width, height: .greatestFiniteMagnitude))
let totalHeight = titleSize.height + subtitleSize.height + 1.0 let totalHeight = titleSize.height + subtitleSize.height + 1.0
self.titleLabel.frame = CGRect(origin: CGPoint(x: floor((size.width - titleSize.width) / 2.0), y: floor(size.height + 16.0 - totalHeight / 2.0) - 56.0), size: titleSize) self.titleLabel.frame = CGRect(origin: CGPoint(x: floor((size.width - titleSize.width) / 2.0), y: floor(size.height - totalHeight / 2.0) - 75.0), size: titleSize)
self.subtitleLabel.frame = CGRect(origin: CGPoint(x: floor((size.width - subtitleSize.width) / 2.0), y: self.titleLabel.frame.maxY + 1.0), size: subtitleSize) self.subtitleLabel.frame = CGRect(origin: CGPoint(x: floor((size.width - subtitleSize.width) / 2.0), y: self.titleLabel.frame.maxY + 1.0), size: subtitleSize)
self.containerNode.frame = CGRect(origin: CGPoint(), size: size) self.containerNode.frame = CGRect(origin: CGPoint(), size: size)
self.backgroundNode.bounds = CGRect(origin: CGPoint(), size: size) self.backgroundNode.bounds = CGRect(origin: CGPoint(), size: size)
self.backgroundNode.position = CGPoint(x: size.width / 2.0, y: size.height / 2.0) self.backgroundNode.position = CGPoint(x: size.width / 2.0, y: size.height / 2.0)
if simplified { if small {
self.backgroundNode.transform = CATransform3DMakeScale(0.85, 0.85, 1.0) self.backgroundNode.transform = CATransform3DMakeScale(0.85, 0.85, 1.0)
} else { } else {
self.backgroundNode.transform = CATransform3DIdentity self.backgroundNode.transform = CATransform3DIdentity
@ -150,13 +153,13 @@ final class VoiceChatActionButton: HighlightTrackingButtonNode {
self.iconNode.frame = CGRect(origin: CGPoint(x: floor((size.width - iconSize.width) / 2.0), y: floor((size.height - iconSize.height) / 2.0)), size: iconSize) self.iconNode.frame = CGRect(origin: CGPoint(x: floor((size.width - iconSize.width) / 2.0), y: floor((size.height - iconSize.height) / 2.0)), size: iconSize)
} }
func update(size: CGSize, buttonSize: CGSize, state: VoiceChatActionButton.State, title: String, subtitle: String, simplified: Bool, animated: Bool = false) { func update(size: CGSize, buttonSize: CGSize, state: VoiceChatActionButton.State, title: String, subtitle: String, small: Bool, animated: Bool = false) {
let previousState = self.currentParams?.state let previousState = self.currentParams?.state
self.currentParams = (size, buttonSize, state, simplified, title, subtitle) self.currentParams = (size, buttonSize, state, small, title, subtitle)
var iconMuted = true var iconMuted = true
var iconColor: UIColor = .white var iconColor: UIColor = .white
var backgroundState: VoiceChatActionButtonBackgroundNewNode.State var backgroundState: VoiceChatActionButtonBackgroundNode.State
switch state { switch state {
case let .active(state): case let .active(state):
switch state { switch state {
@ -289,7 +292,7 @@ private let progressLineWidth: CGFloat = 3.0 + UIScreenPixel
private let buttonSize = CGSize(width: 144.0, height: 144.0) private let buttonSize = CGSize(width: 144.0, height: 144.0)
private let radius = buttonSize.width / 2.0 private let radius = buttonSize.width / 2.0
private final class VoiceChatActionButtonBackgroundNewNode: ASDisplayNode { private final class VoiceChatActionButtonBackgroundNode: ASDisplayNode {
enum State: Equatable { enum State: Equatable {
case connecting case connecting
case disabled case disabled
@ -325,32 +328,24 @@ private final class VoiceChatActionButtonBackgroundNewNode: ASDisplayNode {
private let maskMediumBlobLayer = CAShapeLayer() private let maskMediumBlobLayer = CAShapeLayer()
private let maskBigBlobLayer = CAShapeLayer() private let maskBigBlobLayer = CAShapeLayer()
var isCurrentlyInHierarchy = false private let hierarchyTrackingNode: HierarchyTrackingNode
override func didEnterHierarchy() { private var isCurrentlyInHierarchy = false
super.didEnterHierarchy()
self.isCurrentlyInHierarchy = true
self.updateAnimations()
}
override func didExitHierarchy() {
super.didExitHierarchy()
self.isCurrentlyInHierarchy = false
self.updateAnimations()
}
override init() { override init() {
self.state = .connecting self.state = .connecting
let whiteColor = UIColor(rgb: 0xffffff) self.maskBlobView = VoiceBlobView(frame: CGRect(origin: CGPoint(x: (areaSize.width - blobSize.width) / 2.0, y: (areaSize.height - blobSize.height) / 2.0), size: blobSize), maxLevel: 2.5, mediumBlobRange: (0.69, 0.87), bigBlobRange: (0.71, 1.0))
self.maskBlobView.setColor(white)
let blobSize = CGSize(width: 244.0, height: 244.0) var updateInHierarchy: ((Bool) -> Void)?
self.maskBlobView = VoiceBlobView(frame: CGRect(origin: CGPoint(x: (300.0 - blobSize.width) / 2.0, y: (300.0 - blobSize.height) / 2.0), size: blobSize), maxLevel: 2.5, mediumBlobRange: (0.69, 0.87), bigBlobRange: (0.71, 1.0)) self.hierarchyTrackingNode = HierarchyTrackingNode({ value in
self.maskBlobView.setColor(UIColor(rgb: 0xffffff)) updateInHierarchy?(value)
})
super.init() super.init()
self.addSubnode(self.hierarchyTrackingNode)
let circlePath = UIBezierPath(ovalIn: CGRect(origin: CGPoint(), size: buttonSize)).cgPath let circlePath = UIBezierPath(ovalIn: CGRect(origin: CGPoint(), size: buttonSize)).cgPath
self.backgroundCircleLayer.fillColor = greyColor.cgColor self.backgroundCircleLayer.fillColor = greyColor.cgColor
self.backgroundCircleLayer.path = circlePath self.backgroundCircleLayer.path = circlePath
@ -369,7 +364,7 @@ private final class VoiceChatActionButtonBackgroundNewNode: ASDisplayNode {
self.maskView.backgroundColor = .clear self.maskView.backgroundColor = .clear
self.maskGradientLayer.type = .radial self.maskGradientLayer.type = .radial
self.maskGradientLayer.colors = [UIColor(rgb: 0xffffff, alpha: 0.8).cgColor, UIColor(rgb: 0xffffff, alpha: 0.0).cgColor] self.maskGradientLayer.colors = [UIColor(rgb: 0xffffff, alpha: 0.7).cgColor, UIColor(rgb: 0xffffff, alpha: 0.0).cgColor]
self.maskGradientLayer.startPoint = CGPoint(x: 0.5, y: 0.5) self.maskGradientLayer.startPoint = CGPoint(x: 0.5, y: 0.5)
self.maskGradientLayer.endPoint = CGPoint(x: 1.0, y: 1.0) self.maskGradientLayer.endPoint = CGPoint(x: 1.0, y: 1.0)
self.maskGradientLayer.transform = CATransform3DMakeScale(0.3, 0.3, 1.0) self.maskGradientLayer.transform = CATransform3DMakeScale(0.3, 0.3, 1.0)
@ -378,16 +373,23 @@ private final class VoiceChatActionButtonBackgroundNewNode: ASDisplayNode {
let path = CGMutablePath() let path = CGMutablePath()
path.addArc(center: CGPoint(x: (buttonSize.width + 6.0) / 2.0, y: (buttonSize.height + 6.0) / 2.0), radius: radius, startAngle: 0.0, endAngle: CGFloat.pi * 2.0, clockwise: true) path.addArc(center: CGPoint(x: (buttonSize.width + 6.0) / 2.0, y: (buttonSize.height + 6.0) / 2.0), radius: radius, startAngle: 0.0, endAngle: CGFloat.pi * 2.0, clockwise: true)
self.maskProgressLayer.strokeColor = whiteColor.cgColor self.maskProgressLayer.strokeColor = white.cgColor
self.maskProgressLayer.fillColor = UIColor.clear.cgColor self.maskProgressLayer.fillColor = UIColor.clear.cgColor
self.maskProgressLayer.lineWidth = progressLineWidth self.maskProgressLayer.lineWidth = progressLineWidth
self.maskProgressLayer.lineCap = .round self.maskProgressLayer.lineCap = .round
self.maskProgressLayer.path = path self.maskProgressLayer.path = path
let largerCirclePath = UIBezierPath(ovalIn: CGRect(origin: CGPoint(), size: CGSize(width: buttonSize.width + progressLineWidth, height: buttonSize.height + progressLineWidth))).cgPath let largerCirclePath = UIBezierPath(ovalIn: CGRect(origin: CGPoint(), size: CGSize(width: buttonSize.width + progressLineWidth, height: buttonSize.height + progressLineWidth))).cgPath
self.maskCircleLayer.fillColor = whiteColor.cgColor self.maskCircleLayer.fillColor = white.cgColor
self.maskCircleLayer.path = largerCirclePath self.maskCircleLayer.path = largerCirclePath
self.maskCircleLayer.isHidden = true self.maskCircleLayer.isHidden = true
updateInHierarchy = { [weak self] value in
if let strongSelf = self {
strongSelf.isCurrentlyInHierarchy = value
strongSelf.updateAnimations()
}
}
} }
override func didLoad() { override func didLoad() {

View File

@ -987,9 +987,9 @@ public final class VoiceChatController: ViewController {
self.listNode.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: [.Synchronous, .LowLatency], scrollToItem: nil, updateSizeAndInsets: updateSizeAndInsets, stationaryItemRange: nil, updateOpaqueState: nil, completion: { _ in }) self.listNode.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: [.Synchronous, .LowLatency], scrollToItem: nil, updateSizeAndInsets: updateSizeAndInsets, stationaryItemRange: nil, updateOpaqueState: nil, completion: { _ in })
let sideButtonSize = CGSize(width: 60.0, height: 60.0) let sideButtonSize = CGSize(width: 60.0, height: 60.0)
let centralButtonSize = CGSize(width: 300.0, height: 300.0) let centralButtonSize = CGSize(width: 370.0, height: 370.0)
let actionButtonFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - centralButtonSize.width) / 2.0), y: contentHeight - bottomAreaHeight - layout.intrinsicInsets.bottom + floor((bottomAreaHeight - centralButtonSize.height) / 2.0)), size: centralButtonSize) let actionButtonFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((layout.size.width - centralButtonSize.width) / 2.0), y: contentHeight - bottomAreaHeight - layout.intrinsicInsets.bottom + floorToScreenPixels((bottomAreaHeight - centralButtonSize.height) / 2.0)), size: centralButtonSize)
let actionButtonState: VoiceChatActionButton.State let actionButtonState: VoiceChatActionButton.State
let actionButtonTitle: String let actionButtonTitle: String
@ -1036,7 +1036,7 @@ public final class VoiceChatController: ViewController {
} }
self.actionButton.isUserInteractionEnabled = actionButtonEnabled self.actionButton.isUserInteractionEnabled = actionButtonEnabled
self.actionButton.update(size: centralButtonSize, buttonSize: CGSize(width: 144.0, height: 144.0), state: actionButtonState, title: actionButtonTitle, subtitle: actionButtonSubtitle, simplified: layout.size.width < 330.0 || layout.deviceMetrics.type == .tablet, animated: true) self.actionButton.update(size: centralButtonSize, buttonSize: CGSize(width: 144.0, height: 144.0), state: actionButtonState, title: actionButtonTitle, subtitle: actionButtonSubtitle, small: layout.size.width < 330.0, animated: true)
transition.updateFrame(node: self.actionButton, frame: actionButtonFrame) transition.updateFrame(node: self.actionButton, frame: actionButtonFrame)
var audioMode: CallControllerButtonsSpeakerMode = .none var audioMode: CallControllerButtonsSpeakerMode = .none

View File

@ -148,21 +148,26 @@ final class VoiceChatMicrophoneNode: ASDisplayNode {
guard let parameters = parameters as? VoiceChatMicrophoneNodeDrawingState else { guard let parameters = parameters as? VoiceChatMicrophoneNodeDrawingState else {
return return
} }
context.setFillColor(parameters.color.cgColor) context.setFillColor(parameters.color.cgColor)
var clearLineWidth: CGFloat = 4.0
var lineWidth: CGFloat = 1.0 + UIScreenPixel var lineWidth: CGFloat = 1.0 + UIScreenPixel
if bounds.size.width > 36.0 { if bounds.size.width > 36.0 {
context.scaleBy(x: 2.5, y: 2.5) context.scaleBy(x: 2.5, y: 2.5)
} else if bounds.size.width < 30.0 { } else if bounds.size.width < 30.0 {
context.scaleBy(x: 0.7, y: 0.7) clearLineWidth = 3.0
lineWidth = 2.0 lineWidth = 1.0
} }
context.translateBy(x: 18.0, y: 18.0)
let _ = try? drawSvgPath(context, path: "M-0.004000000189989805,-9.86400032043457 C2.2960000038146973,-9.86400032043457 4.165999889373779,-8.053999900817871 4.25600004196167,-5.77400016784668 C4.25600004196167,-5.77400016784668 4.265999794006348,-5.604000091552734 4.265999794006348,-5.604000091552734 C4.265999794006348,-5.604000091552734 4.265999794006348,-0.8040000200271606 4.265999794006348,-0.8040000200271606 C4.265999794006348,1.555999994277954 2.3559999465942383,3.4660000801086426 -0.004000000189989805,3.4660000801086426 C-2.2939999103546143,3.4660000801086426 -4.164000034332275,1.6460000276565552 -4.263999938964844,-0.6240000128746033 C-4.263999938964844,-0.6240000128746033 -4.263999938964844,-0.8040000200271606 -4.263999938964844,-0.8040000200271606 C-4.263999938964844,-0.8040000200271606 -4.263999938964844,-5.604000091552734 -4.263999938964844,-5.604000091552734 C-4.263999938964844,-7.953999996185303 -2.3540000915527344,-9.86400032043457 -0.004000000189989805,-9.86400032043457 Z ") if bounds.width < 30.0 {
context.translateBy(x: 4.0, y: 3.0)
if bounds.size.width > 30.0 { let _ = try? drawSvgPath(context, path: "M14,8.335 C14.36727,8.335 14.665,8.632731 14.665,9 C14.665,11.903515 12.48064,14.296846 9.665603,14.626311 L9.665,16 C9.665,16.367269 9.367269,16.665 9,16.665 C8.666119,16.665 8.389708,16.418942 8.34221,16.098269 L8.335,16 L8.3354,14.626428 C5.519879,14.297415 3.335,11.90386 3.335,9 C3.335,8.632731 3.632731,8.335 4,8.335 C4.367269,8.335 4.665,8.632731 4.665,9 C4.665,11.394154 6.605846,13.335 9,13.335 C11.39415,13.335 13.335,11.394154 13.335,9 C13.335,8.632731 13.63273,8.335 14,8.335 Z ")
} else {
context.translateBy(x: 18.0, y: 18.0)
let _ = try? drawSvgPath(context, path: "M-0.004000000189989805,-9.86400032043457 C2.2960000038146973,-9.86400032043457 4.165999889373779,-8.053999900817871 4.25600004196167,-5.77400016784668 C4.25600004196167,-5.77400016784668 4.265999794006348,-5.604000091552734 4.265999794006348,-5.604000091552734 C4.265999794006348,-5.604000091552734 4.265999794006348,-0.8040000200271606 4.265999794006348,-0.8040000200271606 C4.265999794006348,1.555999994277954 2.3559999465942383,3.4660000801086426 -0.004000000189989805,3.4660000801086426 C-2.2939999103546143,3.4660000801086426 -4.164000034332275,1.6460000276565552 -4.263999938964844,-0.6240000128746033 C-4.263999938964844,-0.6240000128746033 -4.263999938964844,-0.8040000200271606 -4.263999938964844,-0.8040000200271606 C-4.263999938964844,-0.8040000200271606 -4.263999938964844,-5.604000091552734 -4.263999938964844,-5.604000091552734 C-4.263999938964844,-7.953999996185303 -2.3540000915527344,-9.86400032043457 -0.004000000189989805,-9.86400032043457 Z ")
}
if bounds.width > 30.0 {
context.setBlendMode(.clear) context.setBlendMode(.clear)
let _ = try? drawSvgPath(context, path: "M0.004000000189989805,-8.53600025177002 C-1.565999984741211,-8.53600025177002 -2.8459999561309814,-7.306000232696533 -2.936000108718872,-5.75600004196167 C-2.936000108718872,-5.75600004196167 -2.936000108718872,-5.5960001945495605 -2.936000108718872,-5.5960001945495605 C-2.936000108718872,-5.5960001945495605 -2.936000108718872,-0.7960000038146973 -2.936000108718872,-0.7960000038146973 C-2.936000108718872,0.8240000009536743 -1.6260000467300415,2.134000062942505 0.004000000189989805,2.134000062942505 C1.5740000009536743,2.134000062942505 2.8540000915527344,0.9039999842643738 2.934000015258789,-0.6460000276565552 C2.934000015258789,-0.6460000276565552 2.934000015258789,-0.7960000038146973 2.934000015258789,-0.7960000038146973 C2.934000015258789,-0.7960000038146973 2.934000015258789,-5.5960001945495605 2.934000015258789,-5.5960001945495605 C2.934000015258789,-7.22599983215332 1.6239999532699585,-8.53600025177002 0.004000000189989805,-8.53600025177002 Z ") let _ = try? drawSvgPath(context, path: "M0.004000000189989805,-8.53600025177002 C-1.565999984741211,-8.53600025177002 -2.8459999561309814,-7.306000232696533 -2.936000108718872,-5.75600004196167 C-2.936000108718872,-5.75600004196167 -2.936000108718872,-5.5960001945495605 -2.936000108718872,-5.5960001945495605 C-2.936000108718872,-5.5960001945495605 -2.936000108718872,-0.7960000038146973 -2.936000108718872,-0.7960000038146973 C-2.936000108718872,0.8240000009536743 -1.6260000467300415,2.134000062942505 0.004000000189989805,2.134000062942505 C1.5740000009536743,2.134000062942505 2.8540000915527344,0.9039999842643738 2.934000015258789,-0.6460000276565552 C2.934000015258789,-0.6460000276565552 2.934000015258789,-0.7960000038146973 2.934000015258789,-0.7960000038146973 C2.934000015258789,-0.7960000038146973 2.934000015258789,-5.5960001945495605 2.934000015258789,-5.5960001945495605 C2.934000015258789,-7.22599983215332 1.6239999532699585,-8.53600025177002 0.004000000189989805,-8.53600025177002 Z ")
@ -170,23 +175,40 @@ final class VoiceChatMicrophoneNode: ASDisplayNode {
context.setBlendMode(.normal) context.setBlendMode(.normal)
} }
let _ = try? drawSvgPath(context, path: "M6.796000003814697,-1.4639999866485596 C7.165999889373779,-1.4639999866485596 7.466000080108643,-1.1640000343322754 7.466000080108643,-0.8040000200271606 C7.466000080108643,3.0959999561309814 4.47599983215332,6.296000003814697 0.6660000085830688,6.636000156402588 C0.6660000085830688,6.636000156402588 0.6660000085830688,9.196000099182129 0.6660000085830688,9.196000099182129 C0.6660000085830688,9.565999984741211 0.3659999966621399,9.866000175476074 -0.004000000189989805,9.866000175476074 C-0.33399999141693115,9.866000175476074 -0.6140000224113464,9.605999946594238 -0.6539999842643738,9.28600025177002 C-0.6539999842643738,9.28600025177002 -0.6639999747276306,9.196000099182129 -0.6639999747276306,9.196000099182129 C-0.6639999747276306,9.196000099182129 -0.6639999747276306,6.636000156402588 -0.6639999747276306,6.636000156402588 C-4.473999977111816,6.296000003814697 -7.464000225067139,3.0959999561309814 -7.464000225067139,-0.8040000200271606 C-7.464000225067139,-1.1640000343322754 -7.164000034332275,-1.4639999866485596 -6.803999900817871,-1.4639999866485596 C-6.434000015258789,-1.4639999866485596 -6.133999824523926,-1.1640000343322754 -6.133999824523926,-0.8040000200271606 C-6.133999824523926,2.5859999656677246 -3.384000062942505,5.335999965667725 -0.004000000189989805,5.335999965667725 C3.385999917984009,5.335999965667725 6.136000156402588,2.5859999656677246 6.136000156402588,-0.8040000200271606 C6.136000156402588,-1.1640000343322754 6.435999870300293,-1.4639999866485596 6.796000003814697,-1.4639999866485596 Z ") if bounds.width < 30.0 {
let _ = try? drawSvgPath(context, path: "M9,2.5 C10.38071,2.5 11.5,3.61929 11.5,5 L11.5,9 C11.5,10.380712 10.38071,11.5 9,11.5 C7.619288,11.5 6.5,10.380712 6.5,9 L6.5,5 C6.5,3.61929 7.619288,2.5 9,2.5 Z ")
context.translateBy(x: -18.0, y: -18.0)
context.translateBy(x: -4.0, y: -3.0)
} else {
let _ = try? drawSvgPath(context, path: "M6.796000003814697,-1.4639999866485596 C7.165999889373779,-1.4639999866485596 7.466000080108643,-1.1640000343322754 7.466000080108643,-0.8040000200271606 C7.466000080108643,3.0959999561309814 4.47599983215332,6.296000003814697 0.6660000085830688,6.636000156402588 C0.6660000085830688,6.636000156402588 0.6660000085830688,9.196000099182129 0.6660000085830688,9.196000099182129 C0.6660000085830688,9.565999984741211 0.3659999966621399,9.866000175476074 -0.004000000189989805,9.866000175476074 C-0.33399999141693115,9.866000175476074 -0.6140000224113464,9.605999946594238 -0.6539999842643738,9.28600025177002 C-0.6539999842643738,9.28600025177002 -0.6639999747276306,9.196000099182129 -0.6639999747276306,9.196000099182129 C-0.6639999747276306,9.196000099182129 -0.6639999747276306,6.636000156402588 -0.6639999747276306,6.636000156402588 C-4.473999977111816,6.296000003814697 -7.464000225067139,3.0959999561309814 -7.464000225067139,-0.8040000200271606 C-7.464000225067139,-1.1640000343322754 -7.164000034332275,-1.4639999866485596 -6.803999900817871,-1.4639999866485596 C-6.434000015258789,-1.4639999866485596 -6.133999824523926,-1.1640000343322754 -6.133999824523926,-0.8040000200271606 C-6.133999824523926,2.5859999656677246 -3.384000062942505,5.335999965667725 -0.004000000189989805,5.335999965667725 C3.385999917984009,5.335999965667725 6.136000156402588,2.5859999656677246 6.136000156402588,-0.8040000200271606 C6.136000156402588,-1.1640000343322754 6.435999870300293,-1.4639999866485596 6.796000003814697,-1.4639999866485596 Z ")
context.translateBy(x: -18.0, y: -18.0)
}
if parameters.transition > 0.0 { if parameters.transition > 0.0 {
let startPoint: CGPoint let startPoint: CGPoint
let endPoint: CGPoint let endPoint: CGPoint
if parameters.reverse {
startPoint = CGPoint(x: 9.0 + 17.0 * (1.0 - parameters.transition), y: 10.0 - UIScreenPixel + 17.0 * (1.0 - parameters.transition)) let origin: CGPoint
endPoint = CGPoint(x: 26.0, y: 27.0 - UIScreenPixel) let length: CGFloat
if bounds.width > 30.0 {
origin = CGPoint(x: 9.0, y: 10.0 - UIScreenPixel)
length = 17.0
} else { } else {
startPoint = CGPoint(x: 9.0, y: 10.0 - UIScreenPixel) origin = CGPoint(x: 5.0 + UIScreenPixel, y: 4.0 + UIScreenPixel)
endPoint = CGPoint(x: 9.0 + 17.0 * parameters.transition, y: 10.0 - UIScreenPixel + 17.0 * parameters.transition) length = 15.0
}
if parameters.reverse {
startPoint = CGPoint(x: origin.x + length * (1.0 - parameters.transition), y: origin.y + length * (1.0 - parameters.transition))
endPoint = CGPoint(x: origin.x + length, y: origin.y + length)
} else {
startPoint = origin
endPoint = CGPoint(x: origin.x + length * parameters.transition, y: origin.y + length * parameters.transition)
} }
context.setBlendMode(.clear) context.setBlendMode(.clear)
context.setLineWidth(4.0) context.setLineWidth(clearLineWidth)
context.move(to: startPoint) context.move(to: startPoint)
context.addLine(to: endPoint) context.addLine(to: endPoint)

View File

@ -8577,6 +8577,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
value = self.presentationData.strings.Conversation_Dice_u26BD value = self.presentationData.strings.Conversation_Dice_u26BD
case "🎰": case "🎰":
value = self.presentationData.strings.Conversation_Dice_u1F3B0 value = self.presentationData.strings.Conversation_Dice_u1F3B0
case "🎳":
value = self.presentationData.strings.Conversation_Dice_u1F3B3
default: default:
let emojiHex = emoji.unicodeScalars.map({ String(format:"%02x", $0.value) }).joined().uppercased() let emojiHex = emoji.unicodeScalars.map({ String(format:"%02x", $0.value) }).joined().uppercased()
let key = "Conversation.Dice.u\(emojiHex)" let key = "Conversation.Dice.u\(emojiHex)"

View File

@ -74,6 +74,8 @@ private func rollingAnimationItem(account: Account, emojis: Signal<[TelegramMedi
return .single(ManagedAnimationItem(source: .local("Basketball_Bouncing"), loop: true)) return .single(ManagedAnimationItem(source: .local("Basketball_Bouncing"), loop: true))
case "": case "":
return .single(ManagedAnimationItem(source: .local("Football_Bouncing"), loop: true)) return .single(ManagedAnimationItem(source: .local("Football_Bouncing"), loop: true))
case "🎳":
return .single(ManagedAnimationItem(source: .local("Bowling_Aiming"), loop: true))
default: default:
return animationItem(account: account, emojis: emojis, emoji: emoji, value: nil, loop: true) return animationItem(account: account, emojis: emojis, emoji: emoji, value: nil, loop: true)
} }