UI improvements and API update

This commit is contained in:
Ali 2022-06-02 14:56:07 +04:00
parent e55e22e074
commit dd366395c1
9 changed files with 74 additions and 69 deletions

View File

@ -1274,6 +1274,18 @@ public final class ChatListNode: ListView {
let previousActivities = Atomic<ChatListNodePeerInputActivities?>(value: nil)
self.activityStatusesDisposable = (context.account.allPeerInputActivities()
|> mapToSignal { activitiesByPeerId -> Signal<[EnginePeer.Id: [(EnginePeer, PeerInputActivity)]], NoError> in
var activitiesByPeerId = activitiesByPeerId
for key in activitiesByPeerId.keys {
activitiesByPeerId[key]?.removeAll(where: { _, activity in
switch activity {
case .interactingWithEmoji:
return true
default:
return false
}
})
}
var foundAllPeers = true
var cachedResult: [EnginePeer.Id: [(EnginePeer, PeerInputActivity)]] = [:]
previousPeerCache.with { dict -> Void in

View File

@ -360,7 +360,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-1678949555] = { return Api.InputWebDocument.parse_inputWebDocument($0) }
dict[-1625153079] = { return Api.InputWebFileLocation.parse_inputWebFileGeoPointLocation($0) }
dict[-1036396922] = { return Api.InputWebFileLocation.parse_inputWebFileLocation($0) }
dict[1475721060] = { return Api.Invoice.parse_invoice($0) }
dict[1048946971] = { return Api.Invoice.parse_invoice($0) }
dict[-1059185703] = { return Api.JSONObjectValue.parse_jsonObjectValue($0) }
dict[-146520221] = { return Api.JSONValue.parse_jsonArray($0) }
dict[-952869270] = { return Api.JSONValue.parse_jsonBool($0) }
@ -918,7 +918,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[415997816] = { return Api.help.InviteText.parse_inviteText($0) }
dict[-1600596305] = { return Api.help.PassportConfig.parse_passportConfig($0) }
dict[-1078332329] = { return Api.help.PassportConfig.parse_passportConfigNotModified($0) }
dict[1065019118] = { return Api.help.PremiumPromo.parse_premiumPromo($0) }
dict[-533328101] = { return Api.help.PremiumPromo.parse_premiumPromo($0) }
dict[-1942390465] = { return Api.help.PromoData.parse_promoData($0) }
dict[-1728664459] = { return Api.help.PromoData.parse_promoDataEmpty($0) }
dict[235081943] = { return Api.help.RecentMeUrls.parse_recentMeUrls($0) }

View File

@ -212,13 +212,13 @@ public extension Api.help {
}
public extension Api.help {
enum PremiumPromo: TypeConstructorDescription {
case premiumPromo(statusText: String, statusEntities: [Api.MessageEntity], videoSections: [String], videos: [Api.Document])
case premiumPromo(statusText: String, statusEntities: [Api.MessageEntity], videoSections: [String], videos: [Api.Document], currency: String, monthlyAmount: Int64)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .premiumPromo(let statusText, let statusEntities, let videoSections, let videos):
case .premiumPromo(let statusText, let statusEntities, let videoSections, let videos, let currency, let monthlyAmount):
if boxed {
buffer.appendInt32(1065019118)
buffer.appendInt32(-533328101)
}
serializeString(statusText, buffer: buffer, boxed: false)
buffer.appendInt32(481674261)
@ -236,14 +236,16 @@ public extension Api.help {
for item in videos {
item.serialize(buffer, true)
}
serializeString(currency, buffer: buffer, boxed: false)
serializeInt64(monthlyAmount, buffer: buffer, boxed: false)
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .premiumPromo(let statusText, let statusEntities, let videoSections, let videos):
return ("premiumPromo", [("statusText", String(describing: statusText)), ("statusEntities", String(describing: statusEntities)), ("videoSections", String(describing: videoSections)), ("videos", String(describing: videos))])
case .premiumPromo(let statusText, let statusEntities, let videoSections, let videos, let currency, let monthlyAmount):
return ("premiumPromo", [("statusText", String(describing: statusText)), ("statusEntities", String(describing: statusEntities)), ("videoSections", String(describing: videoSections)), ("videos", String(describing: videos)), ("currency", String(describing: currency)), ("monthlyAmount", String(describing: monthlyAmount))])
}
}
@ -262,12 +264,18 @@ public extension Api.help {
if let _ = reader.readInt32() {
_4 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Document.self)
}
var _5: String?
_5 = parseString(reader)
var _6: Int64?
_6 = reader.readInt64()
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
let _c4 = _4 != nil
if _c1 && _c2 && _c3 && _c4 {
return Api.help.PremiumPromo.premiumPromo(statusText: _1!, statusEntities: _2!, videoSections: _3!, videos: _4!)
let _c5 = _5 != nil
let _c6 = _6 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 {
return Api.help.PremiumPromo.premiumPromo(statusText: _1!, statusEntities: _2!, videoSections: _3!, videos: _4!, currency: _5!, monthlyAmount: _6!)
}
else {
return nil

View File

@ -6350,13 +6350,13 @@ public extension Api.functions.payments {
}
}
public extension Api.functions.payments {
static func requestRecurrentPayment(userId: Int64, recurrentInitCharge: String, invoiceMedia: Api.InputMedia) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
static func requestRecurringPayment(userId: Api.InputUser, recurringInitCharge: String, invoiceMedia: Api.InputMedia) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
let buffer = Buffer()
buffer.appendInt32(-1329030023)
serializeInt64(userId, buffer: buffer, boxed: false)
serializeString(recurrentInitCharge, buffer: buffer, boxed: false)
buffer.appendInt32(342791565)
userId.serialize(buffer, true)
serializeString(recurringInitCharge, buffer: buffer, boxed: false)
invoiceMedia.serialize(buffer, true)
return (FunctionDescription(name: "payments.requestRecurrentPayment", parameters: [("userId", String(describing: userId)), ("recurrentInitCharge", String(describing: recurrentInitCharge)), ("invoiceMedia", String(describing: invoiceMedia))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in
return (FunctionDescription(name: "payments.requestRecurringPayment", parameters: [("userId", String(describing: userId)), ("recurringInitCharge", String(describing: recurringInitCharge)), ("invoiceMedia", String(describing: invoiceMedia))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in
let reader = BufferReader(buffer)
var result: Api.Updates?
if let signature = reader.readInt32() {

View File

@ -898,13 +898,13 @@ public extension Api {
}
public extension Api {
enum Invoice: TypeConstructorDescription {
case invoice(flags: Int32, currency: String, prices: [Api.LabeledPrice], maxTipAmount: Int64?, suggestedTipAmounts: [Int64]?, recurrentTermsUrl: String?)
case invoice(flags: Int32, currency: String, prices: [Api.LabeledPrice], maxTipAmount: Int64?, suggestedTipAmounts: [Int64]?, recurringTermsUrl: String?)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .invoice(let flags, let currency, let prices, let maxTipAmount, let suggestedTipAmounts, let recurrentTermsUrl):
case .invoice(let flags, let currency, let prices, let maxTipAmount, let suggestedTipAmounts, let recurringTermsUrl):
if boxed {
buffer.appendInt32(1475721060)
buffer.appendInt32(1048946971)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeString(currency, buffer: buffer, boxed: false)
@ -919,15 +919,15 @@ public extension Api {
for item in suggestedTipAmounts! {
serializeInt64(item, buffer: buffer, boxed: false)
}}
if Int(flags) & Int(1 << 9) != 0 {serializeString(recurrentTermsUrl!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 9) != 0 {serializeString(recurringTermsUrl!, buffer: buffer, boxed: false)}
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .invoice(let flags, let currency, let prices, let maxTipAmount, let suggestedTipAmounts, let recurrentTermsUrl):
return ("invoice", [("flags", String(describing: flags)), ("currency", String(describing: currency)), ("prices", String(describing: prices)), ("maxTipAmount", String(describing: maxTipAmount)), ("suggestedTipAmounts", String(describing: suggestedTipAmounts)), ("recurrentTermsUrl", String(describing: recurrentTermsUrl))])
case .invoice(let flags, let currency, let prices, let maxTipAmount, let suggestedTipAmounts, let recurringTermsUrl):
return ("invoice", [("flags", String(describing: flags)), ("currency", String(describing: currency)), ("prices", String(describing: prices)), ("maxTipAmount", String(describing: maxTipAmount)), ("suggestedTipAmounts", String(describing: suggestedTipAmounts)), ("recurringTermsUrl", String(describing: recurringTermsUrl))])
}
}
@ -955,7 +955,7 @@ public extension Api {
let _c5 = (Int(_1!) & Int(1 << 8) == 0) || _5 != nil
let _c6 = (Int(_1!) & Int(1 << 9) == 0) || _6 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 {
return Api.Invoice.invoice(flags: _1!, currency: _2!, prices: _3!, maxTipAmount: _4, suggestedTipAmounts: _5, recurrentTermsUrl: _6)
return Api.Invoice.invoice(flags: _1!, currency: _2!, prices: _3!, maxTipAmount: _4, suggestedTipAmounts: _5, recurringTermsUrl: _6)
}
else {
return nil

View File

@ -54,7 +54,7 @@ private func updatePremiumPromoConfiguration(transaction: Transaction, _ f: (Pre
private extension PremiumPromoConfiguration {
init(apiPremiumPromo: Api.help.PremiumPromo) {
switch apiPremiumPromo {
case let .premiumPromo(statusText, statusEntities, videoSections, videoFiles):
case let .premiumPromo(statusText, statusEntities, videoSections, videoFiles, _, _):
self.status = statusText
self.statusEntities = messageTextEntitiesFromApiEntities(statusEntities)

View File

@ -41,9 +41,10 @@ public final class AudioTranscriptionButtonComponent: Component {
private var component: AudioTranscriptionButtonComponent?
private let backgroundLayer: SimpleLayer
private var inProgressLayer: SimpleShapeLayer?
private let animationView: ComponentHostView<Empty>
private var progressAnimationView: ComponentHostView<Empty>?
override init(frame: CGRect) {
self.backgroundLayer = SimpleLayer()
self.animationView = ComponentHostView<Empty>()
@ -76,53 +77,20 @@ public final class AudioTranscriptionButtonComponent: Component {
if self.component?.transcriptionState != component.transcriptionState {
switch component.transcriptionState {
case .inProgress:
if self.inProgressLayer == nil {
let inProgressLayer = SimpleShapeLayer()
inProgressLayer.isOpaque = false
inProgressLayer.backgroundColor = nil
inProgressLayer.fillColor = nil
inProgressLayer.lineCap = .round
inProgressLayer.lineWidth = 1.0
let path = UIBezierPath(roundedRect: CGRect(origin: CGPoint(), size: CGSize(width: 30.0, height: 30.0)), cornerRadius: 9.0).cgPath
inProgressLayer.path = path
self.inProgressLayer = inProgressLayer
inProgressLayer.didEnterHierarchy = { [weak inProgressLayer] in
guard let inProgressLayer = inProgressLayer else {
return
}
let endAnimation = CABasicAnimation(keyPath: "strokeEnd")
endAnimation.fromValue = CGFloat(0.0) as NSNumber
endAnimation.toValue = CGFloat(1.0) as NSNumber
endAnimation.duration = 1.25
endAnimation.timingFunction = CAMediaTimingFunction(name: .easeOut)
endAnimation.fillMode = .forwards
endAnimation.repeatCount = .infinity
inProgressLayer.add(endAnimation, forKey: "strokeEnd")
let startAnimation = CABasicAnimation(keyPath: "strokeStart")
startAnimation.fromValue = CGFloat(0.0) as NSNumber
startAnimation.toValue = CGFloat(1.0) as NSNumber
startAnimation.duration = 1.25
startAnimation.timingFunction = CAMediaTimingFunction(name: .easeIn)
startAnimation.fillMode = .forwards
startAnimation.repeatCount = .infinity
inProgressLayer.add(startAnimation, forKey: "strokeStart")
}
self.layer.addSublayer(inProgressLayer)
if self.progressAnimationView == nil {
let progressAnimationView = ComponentHostView<Empty>()
self.progressAnimationView = progressAnimationView
self.addSubview(progressAnimationView)
}
default:
if let inProgressLayer = self.inProgressLayer {
self.inProgressLayer = nil
if let progressAnimationView = self.progressAnimationView {
self.progressAnimationView = nil
if case .none = transition.animation {
inProgressLayer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, removeOnCompletion: false, completion: { [weak inProgressLayer] _ in
inProgressLayer?.removeFromSuperlayer()
progressAnimationView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, removeOnCompletion: false, completion: { [weak progressAnimationView] _ in
progressAnimationView?.removeFromSuperview()
})
} else {
inProgressLayer.removeFromSuperlayer()
progressAnimationView.removeFromSuperview()
}
}
}
@ -162,13 +130,29 @@ public final class AudioTranscriptionButtonComponent: Component {
}
self.backgroundLayer.backgroundColor = component.theme.bubble.withWallpaper.reactionInactiveBackground.cgColor
self.inProgressLayer?.strokeColor = foregroundColor.cgColor
self.component = component
self.backgroundLayer.frame = CGRect(origin: CGPoint(), size: size)
if let inProgressLayer = self.inProgressLayer {
inProgressLayer.frame = CGRect(origin: CGPoint(), size: size)
if let progressAnimationView = self.progressAnimationView {
let progressFrame = CGRect(origin: CGPoint(), size: size).insetBy(dx: -1.0, dy: -1.0)
let _ = progressAnimationView.update(
transition: transition,
component: AnyComponent(LottieAnimationComponent(
animation: LottieAnimationComponent.Animation(
name: "voicets_progress",
colors: [
"Rectangle 60.Rectangle 60.Stroke 1": foregroundColor
],
mode: .animating(loop: true)
),
size: progressFrame.size
)),
environment: {},
containerSize: progressFrame.size
)
progressAnimationView.frame = progressFrame
}
return CGSize(width: min(availableSize.width, size.width), height: min(availableSize.height, size.height))

View File

@ -0,0 +1 @@
{"v":"5.8.1","fr":60,"ip":0,"op":120,"w":320,"h":320,"nm":"Comp 1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Rectangle 60","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":270,"ix":10},"p":{"a":0,"k":[160,160,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[-100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.863,-1.693],[0,-5.04],[0,0],[-0.981,-1.925],[-1.693,-0.863],[-5.04,0],[0,0],[-1.925,0.981],[-0.863,1.693],[0,5.04],[0,0],[0.981,1.925],[1.693,0.863],[5.04,0],[0,0],[1.925,-0.981]],"o":[[-0.981,1.925],[0,0],[0,5.04],[0.863,1.693],[1.925,0.981],[0,0],[5.04,0],[1.693,-0.863],[0.981,-1.925],[0,0],[0,-5.04],[-0.863,-1.693],[-1.925,-0.981],[0,0],[-5.04,0],[-1.693,0.863]],"v":[[-14.019,-10.086],[-15,-0.6],[-15,0.6],[-14.019,10.086],[-10.086,14.019],[-0.6,15],[0.6,15],[10.086,14.019],[14.019,10.086],[15,0.6],[15,-0.6],[14.019,-10.086],[10.086,-14.019],[0.6,-15],[-0.6,-15],[-10.086,-14.019]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.33,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[1000,1000],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 60","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[1]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":59,"s":[95]},{"t":119,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":59,"s":[25]},{"t":119,"s":[99]}],"ix":2},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[30]},{"t":119,"s":[389]}],"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":120,"st":0,"bm":0}],"markers":[]}

View File

@ -155,7 +155,7 @@ public func generateChatInputTextEntities(_ text: NSAttributedString, maxAnimate
if !emoji.isEmpty && emoji.isSingleEmoji {
let mappedRange = NSRange(substringRange, in: text.string)
entities.append(MessageTextEntity(range: mappedRange.lowerBound ..< mappedRange.upperBound, type: .AnimatedEmoji))
entities.append(MessageTextEntity(range: mappedRange.lowerBound ..< mappedRange.upperBound, type: .AnimatedEmoji(nil)))
count += 1
if count >= maxAnimatedEmojisInText {