mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Voice Chat UI fixes
This commit is contained in:
parent
2cac381736
commit
824ed99d2c
@ -13,7 +13,7 @@ private let green = UIColor(rgb: 0x33c659)
|
|||||||
private let deviceScale = UIScreen.main.scale
|
private let deviceScale = UIScreen.main.scale
|
||||||
private let colorSpace = CGColorSpaceCreateDeviceRGB()
|
private let colorSpace = CGColorSpaceCreateDeviceRGB()
|
||||||
|
|
||||||
private let radialMaskImage = generateImage(CGSize(width: 300.0, height: 300.0), contextGenerator: { size, context in
|
private let radialMaskImage = generateImage(CGSize(width: 200.0, height: 200.0), contextGenerator: { size, context in
|
||||||
context.clear(CGRect(origin: CGPoint(), size: size))
|
context.clear(CGRect(origin: CGPoint(), size: size))
|
||||||
var locations: [CGFloat] = [0.0, 1.0]
|
var locations: [CGFloat] = [0.0, 1.0]
|
||||||
|
|
||||||
@ -22,7 +22,7 @@ private let radialMaskImage = generateImage(CGSize(width: 300.0, height: 300.0),
|
|||||||
let maskGradientCenter = CGPoint(x: size.width / 2.0, y: size.height / 2.0)
|
let maskGradientCenter = CGPoint(x: size.width / 2.0, y: size.height / 2.0)
|
||||||
|
|
||||||
context.drawRadialGradient(maskGradient, startCenter: maskGradientCenter, startRadius: 0.0, endCenter: maskGradientCenter, endRadius: size.width / 2.0, options: .drawsAfterEndLocation)
|
context.drawRadialGradient(maskGradient, startCenter: maskGradientCenter, startRadius: 0.0, endCenter: maskGradientCenter, endRadius: size.width / 2.0, options: .drawsAfterEndLocation)
|
||||||
}, opaque: false, scale: deviceScale)!
|
}, opaque: false, scale: 1.0)!
|
||||||
|
|
||||||
enum VoiceChatActionButtonState {
|
enum VoiceChatActionButtonState {
|
||||||
enum ActiveState {
|
enum ActiveState {
|
||||||
@ -51,17 +51,10 @@ private protocol VoiceChatActionButtonBackgroundNodeContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private protocol VoiceChatActionButtonBackgroundNodeState: NSObjectProtocol {
|
private protocol VoiceChatActionButtonBackgroundNodeState: NSObjectProtocol {
|
||||||
var blueGradient: UIImage? { get set }
|
|
||||||
var greenGradient: UIImage? { get set }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private final class VoiceChatActionButtonBackgroundNodeConnectingContext: VoiceChatActionButtonBackgroundNodeContext {
|
private final class VoiceChatActionButtonBackgroundNodeConnectingContext: VoiceChatActionButtonBackgroundNodeContext {
|
||||||
var blueGradient: UIImage?
|
|
||||||
|
|
||||||
init(blueGradient: UIImage?) {
|
|
||||||
self.blueGradient = blueGradient
|
|
||||||
}
|
|
||||||
|
|
||||||
var isAnimating: Bool {
|
var isAnimating: Bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -78,17 +71,12 @@ private final class VoiceChatActionButtonBackgroundNodeConnectingContext: VoiceC
|
|||||||
}
|
}
|
||||||
|
|
||||||
func drawingState(transition: VoiceChatActionButtonBackgroundNodeTransitionState?) -> VoiceChatActionButtonBackgroundNodeState {
|
func drawingState(transition: VoiceChatActionButtonBackgroundNodeTransitionState?) -> VoiceChatActionButtonBackgroundNodeState {
|
||||||
return VoiceChatActionButtonBackgroundNodeConnectingState(blueGradient: self.blueGradient)
|
return VoiceChatActionButtonBackgroundNodeConnectingState()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final class VoiceChatActionButtonBackgroundNodeConnectingState: NSObject, VoiceChatActionButtonBackgroundNodeState {
|
private final class VoiceChatActionButtonBackgroundNodeConnectingState: NSObject, VoiceChatActionButtonBackgroundNodeState {
|
||||||
var blueGradient: UIImage?
|
|
||||||
var greenGradient: UIImage?
|
|
||||||
|
|
||||||
init(blueGradient: UIImage?) {
|
|
||||||
self.blueGradient = blueGradient
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private final class VoiceChatActionButtonBackgroundNodeDisabledContext: VoiceChatActionButtonBackgroundNodeContext {
|
private final class VoiceChatActionButtonBackgroundNodeDisabledContext: VoiceChatActionButtonBackgroundNodeContext {
|
||||||
@ -113,8 +101,7 @@ private final class VoiceChatActionButtonBackgroundNodeDisabledContext: VoiceCha
|
|||||||
}
|
}
|
||||||
|
|
||||||
private final class VoiceChatActionButtonBackgroundNodeDisabledState: NSObject, VoiceChatActionButtonBackgroundNodeState {
|
private final class VoiceChatActionButtonBackgroundNodeDisabledState: NSObject, VoiceChatActionButtonBackgroundNodeState {
|
||||||
var blueGradient: UIImage?
|
|
||||||
var greenGradient: UIImage?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private final class Blob {
|
private final class Blob {
|
||||||
@ -287,9 +274,6 @@ private final class Blob {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private final class VoiceChatActionButtonBackgroundNodeBlobContext: VoiceChatActionButtonBackgroundNodeContext {
|
private final class VoiceChatActionButtonBackgroundNodeBlobContext: VoiceChatActionButtonBackgroundNodeContext {
|
||||||
var blueGradient: UIImage?
|
|
||||||
var greenGradient: UIImage?
|
|
||||||
|
|
||||||
var isAnimating: Bool {
|
var isAnimating: Bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -309,12 +293,10 @@ private final class VoiceChatActionButtonBackgroundNodeBlobContext: VoiceChatAct
|
|||||||
typealias BlobRange = (min: CGFloat, max: CGFloat)
|
typealias BlobRange = (min: CGFloat, max: CGFloat)
|
||||||
let blobs: [Blob]
|
let blobs: [Blob]
|
||||||
|
|
||||||
init(size: CGSize, active: Bool, blueGradient: UIImage, greenGradient: UIImage) {
|
init(size: CGSize, active: Bool) {
|
||||||
self.size = size
|
self.size = size
|
||||||
self.active = active
|
self.active = active
|
||||||
self.blueGradient = blueGradient
|
|
||||||
self.greenGradient = greenGradient
|
|
||||||
|
|
||||||
let mediumBlobRange: BlobRange = (0.69, 0.87)
|
let mediumBlobRange: BlobRange = (0.69, 0.87)
|
||||||
let bigBlobRange: BlobRange = (0.71, 1.00)
|
let bigBlobRange: BlobRange = (0.71, 1.00)
|
||||||
|
|
||||||
@ -368,7 +350,7 @@ private final class VoiceChatActionButtonBackgroundNodeBlobContext: VoiceChatAct
|
|||||||
blobs.append(BlobDrawingState(size: blob.size, path: path.cgPath, scale: blob.currentScale, alpha: blob.alpha))
|
blobs.append(BlobDrawingState(size: blob.size, path: path.cgPath, scale: blob.currentScale, alpha: blob.alpha))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return VoiceChatActionButtonBackgroundNodeBlobState(size: self.size, active: self.active, activeTransitionArguments: self.activeTransitionArguments, blueGradient: self.blueGradient, greenGradient: self.greenGradient, blobs: blobs)
|
return VoiceChatActionButtonBackgroundNodeBlobState(size: self.size, active: self.active, activeTransitionArguments: self.activeTransitionArguments, blobs: blobs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -387,19 +369,13 @@ private class BlobDrawingState: NSObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private final class VoiceChatActionButtonBackgroundNodeBlobState: NSObject, VoiceChatActionButtonBackgroundNodeState {
|
private final class VoiceChatActionButtonBackgroundNodeBlobState: NSObject, VoiceChatActionButtonBackgroundNodeState {
|
||||||
var blueGradient: UIImage?
|
|
||||||
var greenGradient: UIImage?
|
|
||||||
|
|
||||||
let active: Bool
|
let active: Bool
|
||||||
let activeTransitionArguments: (startTime: Double, duration: Double)?
|
let activeTransitionArguments: (startTime: Double, duration: Double)?
|
||||||
|
|
||||||
let blobs: [BlobDrawingState]
|
let blobs: [BlobDrawingState]
|
||||||
|
|
||||||
init(size: CGSize, active: Bool, activeTransitionArguments: (startTime: Double, duration: Double)?, blueGradient: UIImage?, greenGradient: UIImage?, blobs: [BlobDrawingState]) {
|
init(size: CGSize, active: Bool, activeTransitionArguments: (startTime: Double, duration: Double)?, blobs: [BlobDrawingState]) {
|
||||||
self.active = active
|
self.active = active
|
||||||
self.activeTransitionArguments = activeTransitionArguments
|
self.activeTransitionArguments = activeTransitionArguments
|
||||||
self.blueGradient = blueGradient
|
|
||||||
self.greenGradient = greenGradient
|
|
||||||
self.blobs = blobs
|
self.blobs = blobs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -436,9 +412,16 @@ private final class VoiceChatActionButtonBackgroundNodeTransitionContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func transition(time: Double) -> CGFloat {
|
||||||
|
var transition = CGFloat(max(0.0, min(1.0, (time - startTime) / duration)))
|
||||||
|
if previousState.type == .connecting {
|
||||||
|
transition *= transition
|
||||||
|
}
|
||||||
|
return transition
|
||||||
|
}
|
||||||
|
|
||||||
func drawingTransitionState(time: Double) -> VoiceChatActionButtonBackgroundNodeTransitionState {
|
func drawingTransitionState(time: Double) -> VoiceChatActionButtonBackgroundNodeTransitionState {
|
||||||
let transition = CGFloat(max(0.0, min(1.0, (time - startTime) / duration)))
|
return VoiceChatActionButtonBackgroundNodeTransitionState(startTime: self.startTime, transition: self.transition(time: time), previousState: previousState.type)
|
||||||
return VoiceChatActionButtonBackgroundNodeTransitionState(startTime: self.startTime, transition: transition, previousState: previousState.type)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -482,10 +465,11 @@ private class VoiceChatActionButtonBackgroundNode: ASDisplayNode {
|
|||||||
private var animator: ConstantDisplayLinkAnimator?
|
private var animator: ConstantDisplayLinkAnimator?
|
||||||
|
|
||||||
override init() {
|
override init() {
|
||||||
self.state = VoiceChatActionButtonBackgroundNodeConnectingContext(blueGradient: nil)
|
self.state = VoiceChatActionButtonBackgroundNodeConnectingContext()
|
||||||
|
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
|
self.isLayerBacked = true
|
||||||
self.isOpaque = false
|
self.isOpaque = false
|
||||||
self.displaysAsynchronously = true
|
self.displaysAsynchronously = true
|
||||||
}
|
}
|
||||||
@ -503,7 +487,15 @@ private class VoiceChatActionButtonBackgroundNode: ASDisplayNode {
|
|||||||
|
|
||||||
if state.type != self.state.type || !hadState {
|
if state.type != self.state.type || !hadState {
|
||||||
if animated {
|
if animated {
|
||||||
self.transition = VoiceChatActionButtonBackgroundNodeTransitionContext(startTime: CACurrentMediaTime(), duration: 0.45, previousState: self.state)
|
let duration: Double
|
||||||
|
if self.state.type == .connecting {
|
||||||
|
duration = 0.7
|
||||||
|
} else if self.state.type == .disabled {
|
||||||
|
duration = 0.3
|
||||||
|
} else {
|
||||||
|
duration = 0.3
|
||||||
|
}
|
||||||
|
self.transition = VoiceChatActionButtonBackgroundNodeTransitionContext(startTime: CACurrentMediaTime(), duration: duration, previousState: self.state)
|
||||||
}
|
}
|
||||||
self.state = state
|
self.state = state
|
||||||
} else if let blobState = self.state as? VoiceChatActionButtonBackgroundNodeBlobContext, let nextState = state as? VoiceChatActionButtonBackgroundNodeBlobContext {
|
} else if let blobState = self.state as? VoiceChatActionButtonBackgroundNodeBlobContext, let nextState = state as? VoiceChatActionButtonBackgroundNodeBlobContext {
|
||||||
@ -590,7 +582,7 @@ private class VoiceChatActionButtonBackgroundNode: ASDisplayNode {
|
|||||||
self.animator = animator
|
self.animator = animator
|
||||||
}
|
}
|
||||||
animator.isPaused = false
|
animator.isPaused = false
|
||||||
if self.transition == nil {
|
if self.transition == nil || self.transition!.transition(time: timestamp) > 0.5 {
|
||||||
animator.frameInterval = state.frameInterval
|
animator.frameInterval = state.frameInterval
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -608,13 +600,7 @@ private class VoiceChatActionButtonBackgroundNode: ASDisplayNode {
|
|||||||
|
|
||||||
@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) {
|
||||||
let context = UIGraphicsGetCurrentContext()!
|
let context = UIGraphicsGetCurrentContext()!
|
||||||
|
|
||||||
if !isRasterizing {
|
|
||||||
context.setBlendMode(.copy)
|
|
||||||
context.setFillColor(UIColor.clear.cgColor)
|
|
||||||
context.fill(bounds)
|
|
||||||
}
|
|
||||||
|
|
||||||
guard let parameters = parameters as? VoiceChatActionButtonBackgroundNodeDrawingState else {
|
guard let parameters = parameters as? VoiceChatActionButtonBackgroundNodeDrawingState else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -641,7 +627,7 @@ private class VoiceChatActionButtonBackgroundNode: ASDisplayNode {
|
|||||||
if let transition = parameters.transition, transition.previousState == .connecting || transition.previousState == .disabled {
|
if let transition = parameters.transition, transition.previousState == .connecting || transition.previousState == .disabled {
|
||||||
appearanceProgress = transition.transition
|
appearanceProgress = transition.transition
|
||||||
}
|
}
|
||||||
|
|
||||||
let width: Int = Int(bounds.width * deviceScale)
|
let width: Int = Int(bounds.width * deviceScale)
|
||||||
let height: Int = Int(bounds.height * deviceScale)
|
let height: Int = Int(bounds.height * deviceScale)
|
||||||
let bytesPerRow = width
|
let bytesPerRow = width
|
||||||
@ -659,7 +645,13 @@ private class VoiceChatActionButtonBackgroundNode: ASDisplayNode {
|
|||||||
maskContext.interpolationQuality = .low
|
maskContext.interpolationQuality = .low
|
||||||
maskContext.scaleBy(x: CGFloat(width) / bounds.width, y: CGFloat(height) / bounds.height)
|
maskContext.scaleBy(x: CGFloat(width) / bounds.width, y: CGFloat(height) / bounds.height)
|
||||||
|
|
||||||
if let blobsState = parameters.state as? VoiceChatActionButtonBackgroundNodeBlobState {
|
var skipBlobs = false
|
||||||
|
if parameters.state is VoiceChatActionButtonBackgroundNodeBlobState, let transition = parameters.transition, transition.previousState == .connecting, transition.transition < 0.5 {
|
||||||
|
skipBlobs = true
|
||||||
|
}
|
||||||
|
|
||||||
|
var drawGradient = false
|
||||||
|
if let blobsState = parameters.state as? VoiceChatActionButtonBackgroundNodeBlobState, !skipBlobs {
|
||||||
gradientTransition = blobsState.active ? 1.0 : 0.0
|
gradientTransition = blobsState.active ? 1.0 : 0.0
|
||||||
if let transition = blobsState.activeTransitionArguments {
|
if let transition = blobsState.activeTransitionArguments {
|
||||||
gradientTransition = CGFloat((parameters.timestamp - transition.startTime) / transition.duration)
|
gradientTransition = CGFloat((parameters.timestamp - transition.startTime) / transition.duration)
|
||||||
@ -669,27 +661,24 @@ private class VoiceChatActionButtonBackgroundNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
glowScale += gradientTransition * 0.3
|
glowScale += gradientTransition * 0.3
|
||||||
|
|
||||||
|
simpleColor = blue.interpolateTo(green, fraction: gradientTransition)!
|
||||||
firstColor = firstColor.interpolateTo(blue, fraction: gradientTransition)!
|
firstColor = firstColor.interpolateTo(blue, fraction: gradientTransition)!
|
||||||
secondColor = secondColor.interpolateTo(green, fraction: gradientTransition)!
|
secondColor = secondColor.interpolateTo(green, fraction: gradientTransition)!
|
||||||
|
|
||||||
let progress = 1.0 - (appearanceProgress * glowScale)
|
let progress = 1.0 - (appearanceProgress * glowScale)
|
||||||
let maskBounds = bounds.insetBy(dx: bounds.width / 3.0 * progress, dy: bounds.width / 3.0 * progress)
|
let maskBounds = bounds.insetBy(dx: bounds.width / 3.0 * progress, dy: bounds.width / 3.0 * progress)
|
||||||
|
|
||||||
if let radialMask = radialMaskImage.cgImage {
|
if let radialMask = radialMaskImage.cgImage {
|
||||||
maskContext.setBlendMode(.copy)
|
maskContext.setBlendMode(.copy)
|
||||||
maskContext.draw(radialMask, in: maskBounds)
|
maskContext.draw(radialMask, in: maskBounds)
|
||||||
maskContext.setBlendMode(.normal)
|
maskContext.setBlendMode(.normal)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
var drawGradient = false
|
|
||||||
if let blobsState = parameters.state as? VoiceChatActionButtonBackgroundNodeBlobState {
|
|
||||||
drawGradient = true
|
|
||||||
for blob in blobsState.blobs {
|
for blob in blobsState.blobs {
|
||||||
maskContext.addPath(blob.path)
|
maskContext.addPath(blob.path)
|
||||||
maskContext.setFillColor(UIColor(rgb: 0xffffff, alpha: blob.alpha).cgColor)
|
maskContext.setFillColor(UIColor(rgb: 0xffffff, alpha: blob.alpha).cgColor)
|
||||||
maskContext.fillPath()
|
maskContext.fillPath()
|
||||||
}
|
}
|
||||||
|
drawGradient = true
|
||||||
}
|
}
|
||||||
|
|
||||||
var skipProgressDrawing = true
|
var skipProgressDrawing = true
|
||||||
@ -748,9 +737,7 @@ private class VoiceChatActionButtonBackgroundNode: ASDisplayNode {
|
|||||||
|
|
||||||
var clearInsideTransition: CGFloat?
|
var clearInsideTransition: CGFloat?
|
||||||
if parameters.state is VoiceChatActionButtonBackgroundNodeBlobState {
|
if parameters.state is VoiceChatActionButtonBackgroundNodeBlobState {
|
||||||
if !skipProgressDrawing {
|
if skipProgressDrawing {
|
||||||
|
|
||||||
} else {
|
|
||||||
maskContext.setFillColor(UIColor(rgb: 0xffffff).cgColor)
|
maskContext.setFillColor(UIColor(rgb: 0xffffff).cgColor)
|
||||||
maskContext.fillEllipse(in: buttonRect.insetBy(dx: -lineWidth / 2.0, dy: -lineWidth / 2.0))
|
maskContext.fillEllipse(in: buttonRect.insetBy(dx: -lineWidth / 2.0, dy: -lineWidth / 2.0))
|
||||||
}
|
}
|
||||||
@ -768,7 +755,7 @@ private class VoiceChatActionButtonBackgroundNode: ASDisplayNode {
|
|||||||
|
|
||||||
context.setFillColor(greyColor.cgColor)
|
context.setFillColor(greyColor.cgColor)
|
||||||
context.fillEllipse(in: buttonRect)
|
context.fillEllipse(in: buttonRect)
|
||||||
|
|
||||||
if drawGradient {
|
if drawGradient {
|
||||||
context.saveGState()
|
context.saveGState()
|
||||||
if let alphaMask = maskContext.makeImage() {
|
if let alphaMask = maskContext.makeImage() {
|
||||||
@ -783,7 +770,7 @@ private class VoiceChatActionButtonBackgroundNode: ASDisplayNode {
|
|||||||
var locations: [CGFloat] = [0.0, 1.0]
|
var locations: [CGFloat] = [0.0, 1.0]
|
||||||
let gradientStartRadius: CGFloat = 0.0
|
let gradientStartRadius: CGFloat = 0.0
|
||||||
let gradientEndRadius: CGFloat = 141.0
|
let gradientEndRadius: CGFloat = 141.0
|
||||||
|
|
||||||
let colors: [CGColor] = [firstColor.cgColor, secondColor.cgColor]
|
let colors: [CGColor] = [firstColor.cgColor, secondColor.cgColor]
|
||||||
let gradient = CGGradient(colorsSpace: colorSpace, colors: colors as CFArray, locations: &locations)!
|
let gradient = CGGradient(colorsSpace: colorSpace, colors: colors as CFArray, locations: &locations)!
|
||||||
context.drawRadialGradient(gradient, startCenter: gradientCenter, startRadius: gradientStartRadius, endCenter: gradientCenter, endRadius: gradientEndRadius, options: .drawsAfterEndLocation)
|
context.drawRadialGradient(gradient, startCenter: gradientCenter, startRadius: gradientStartRadius, endCenter: gradientCenter, endRadius: gradientEndRadius, options: .drawsAfterEndLocation)
|
||||||
@ -793,8 +780,10 @@ private class VoiceChatActionButtonBackgroundNode: ASDisplayNode {
|
|||||||
|
|
||||||
if let transition = clearInsideTransition {
|
if let transition = clearInsideTransition {
|
||||||
context.setFillColor(greyColor.cgColor)
|
context.setFillColor(greyColor.cgColor)
|
||||||
context.fillEllipse(in: buttonRect.insetBy(dx: transition * radius, dy: transition * radius))
|
context.fillEllipse(in: buttonRect.insetBy(dx: lineWidth / 2.0 + transition * radius, dy: lineWidth / 2.0 + transition * radius))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// print("drawn in \(CACurrentMediaTime() - start)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -804,10 +793,7 @@ final class VoiceChatActionButton: HighlightTrackingButtonNode {
|
|||||||
let iconNode: VoiceChatMicrophoneNode
|
let iconNode: VoiceChatMicrophoneNode
|
||||||
let titleLabel: ImmediateTextNode
|
let titleLabel: ImmediateTextNode
|
||||||
let subtitleLabel: ImmediateTextNode
|
let subtitleLabel: ImmediateTextNode
|
||||||
|
|
||||||
let blueGradient: UIImage
|
|
||||||
let greenGradient: UIImage
|
|
||||||
|
|
||||||
private var currentParams: (size: CGSize, buttonSize: CGSize, state: VoiceChatActionButtonState, title: String, subtitle: String)?
|
private var currentParams: (size: CGSize, buttonSize: CGSize, state: VoiceChatActionButtonState, title: String, subtitle: String)?
|
||||||
|
|
||||||
var pressing: Bool = false {
|
var pressing: Bool = false {
|
||||||
@ -830,34 +816,6 @@ final class VoiceChatActionButton: HighlightTrackingButtonNode {
|
|||||||
self.titleLabel = ImmediateTextNode()
|
self.titleLabel = ImmediateTextNode()
|
||||||
self.subtitleLabel = ImmediateTextNode()
|
self.subtitleLabel = ImmediateTextNode()
|
||||||
|
|
||||||
self.blueGradient = generateImage(CGSize(width: 180.0, height: 180.0), contextGenerator: { size, context in
|
|
||||||
let firstColor = lightBlue
|
|
||||||
let secondColor = blue
|
|
||||||
|
|
||||||
var locations: [CGFloat] = [0.0, 1.0]
|
|
||||||
let gradientCenter = CGPoint(x: size.width / 2.0, y: size.height / 2.0)
|
|
||||||
let gradientStartRadius: CGFloat = 0.0
|
|
||||||
let gradientEndRadius: CGFloat = 85.0
|
|
||||||
|
|
||||||
let colors: [CGColor] = [firstColor.cgColor, secondColor.cgColor]
|
|
||||||
let gradient = CGGradient(colorsSpace: colorSpace, colors: colors as CFArray, locations: &locations)!
|
|
||||||
context.drawRadialGradient(gradient, startCenter: gradientCenter, startRadius: gradientStartRadius, endCenter: gradientCenter, endRadius: gradientEndRadius, options: .drawsAfterEndLocation)
|
|
||||||
}, opaque: true, scale: min(2.0, deviceScale))!
|
|
||||||
|
|
||||||
self.greenGradient = generateImage(CGSize(width: 180.0, height: 180.0), contextGenerator: { size, context in
|
|
||||||
let firstColor = blue
|
|
||||||
let secondColor = green
|
|
||||||
|
|
||||||
var locations: [CGFloat] = [0.0, 1.0]
|
|
||||||
let gradientCenter = CGPoint(x: size.width / 2.0, y: size.height / 2.0)
|
|
||||||
let gradientStartRadius: CGFloat = 0.0
|
|
||||||
let gradientEndRadius: CGFloat = 85.0
|
|
||||||
|
|
||||||
let colors: [CGColor] = [firstColor.cgColor, secondColor.cgColor]
|
|
||||||
let gradient = CGGradient(colorsSpace: colorSpace, colors: colors as CFArray, locations: &locations)!
|
|
||||||
context.drawRadialGradient(gradient, startCenter: gradientCenter, startRadius: gradientStartRadius, endCenter: gradientCenter, endRadius: gradientEndRadius, options: .drawsAfterEndLocation)
|
|
||||||
}, opaque: true, scale: min(2.0, deviceScale))!
|
|
||||||
|
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
self.addSubnode(self.titleLabel)
|
self.addSubnode(self.titleLabel)
|
||||||
@ -906,15 +864,15 @@ final class VoiceChatActionButton: HighlightTrackingButtonNode {
|
|||||||
switch state {
|
switch state {
|
||||||
case .on:
|
case .on:
|
||||||
iconMuted = false
|
iconMuted = false
|
||||||
backgroundState = VoiceChatActionButtonBackgroundNodeBlobContext(size: blobSize, active: true, blueGradient: self.blueGradient, greenGradient: self.greenGradient)
|
backgroundState = VoiceChatActionButtonBackgroundNodeBlobContext(size: blobSize, active: true)
|
||||||
case .muted:
|
case .muted:
|
||||||
backgroundState = VoiceChatActionButtonBackgroundNodeBlobContext(size: blobSize, active: false, blueGradient: self.blueGradient, greenGradient: self.greenGradient)
|
backgroundState = VoiceChatActionButtonBackgroundNodeBlobContext(size: blobSize, active: false)
|
||||||
case .cantSpeak:
|
case .cantSpeak:
|
||||||
iconColor = UIColor(rgb: 0xff3b30)
|
iconColor = UIColor(rgb: 0xff3b30)
|
||||||
backgroundState = VoiceChatActionButtonBackgroundNodeDisabledContext()
|
backgroundState = VoiceChatActionButtonBackgroundNodeDisabledContext()
|
||||||
}
|
}
|
||||||
case .connecting:
|
case .connecting:
|
||||||
backgroundState = VoiceChatActionButtonBackgroundNodeConnectingContext(blueGradient: self.blueGradient)
|
backgroundState = VoiceChatActionButtonBackgroundNodeConnectingContext()
|
||||||
}
|
}
|
||||||
self.backgroundNode.update(state: backgroundState, simplified: simplified, animated: true)
|
self.backgroundNode.update(state: backgroundState, simplified: simplified, animated: true)
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ public extension TelegramChannel {
|
|||||||
if let defaultBannedRights = self.defaultBannedRights, defaultBannedRights.flags.contains(.banAddMembers) {
|
if let defaultBannedRights = self.defaultBannedRights, defaultBannedRights.flags.contains(.banAddMembers) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return false
|
||||||
}
|
}
|
||||||
case .editAllMessages:
|
case .editAllMessages:
|
||||||
if let adminRights = self.adminRights, adminRights.flags.contains(.canEditMessages) {
|
if let adminRights = self.adminRights, adminRights.flags.contains(.canEditMessages) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user