diff --git a/submodules/ChatListUI/Sources/Node/ChatListNode.swift b/submodules/ChatListUI/Sources/Node/ChatListNode.swift index 4f9f7c51a8..5220892de5 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListNode.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListNode.swift @@ -1274,6 +1274,18 @@ public final class ChatListNode: ListView { let previousActivities = Atomic(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 diff --git a/submodules/TelegramApi/Sources/Api0.swift b/submodules/TelegramApi/Sources/Api0.swift index 3ff0ecd247..2906cb9b13 100644 --- a/submodules/TelegramApi/Sources/Api0.swift +++ b/submodules/TelegramApi/Sources/Api0.swift @@ -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) } diff --git a/submodules/TelegramApi/Sources/Api23.swift b/submodules/TelegramApi/Sources/Api23.swift index ff75cb25b6..7f3d25e3f8 100644 --- a/submodules/TelegramApi/Sources/Api23.swift +++ b/submodules/TelegramApi/Sources/Api23.swift @@ -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 diff --git a/submodules/TelegramApi/Sources/Api27.swift b/submodules/TelegramApi/Sources/Api27.swift index 26acc8dd95..010a2edf20 100644 --- a/submodules/TelegramApi/Sources/Api27.swift +++ b/submodules/TelegramApi/Sources/Api27.swift @@ -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) { + static func requestRecurringPayment(userId: Api.InputUser, recurringInitCharge: String, invoiceMedia: Api.InputMedia) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { 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() { diff --git a/submodules/TelegramApi/Sources/Api9.swift b/submodules/TelegramApi/Sources/Api9.swift index db9a66bf37..fc80ab45ba 100644 --- a/submodules/TelegramApi/Sources/Api9.swift +++ b/submodules/TelegramApi/Sources/Api9.swift @@ -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 diff --git a/submodules/TelegramCore/Sources/State/ManagedPremiumPromoConfigurationUpdates.swift b/submodules/TelegramCore/Sources/State/ManagedPremiumPromoConfigurationUpdates.swift index 910c11c1ec..dea49afd7d 100644 --- a/submodules/TelegramCore/Sources/State/ManagedPremiumPromoConfigurationUpdates.swift +++ b/submodules/TelegramCore/Sources/State/ManagedPremiumPromoConfigurationUpdates.swift @@ -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) diff --git a/submodules/TelegramUI/Components/AudioTranscriptionButtonComponent/Sources/AudioTranscriptionButtonComponent.swift b/submodules/TelegramUI/Components/AudioTranscriptionButtonComponent/Sources/AudioTranscriptionButtonComponent.swift index b131136b8a..96dc7d7529 100644 --- a/submodules/TelegramUI/Components/AudioTranscriptionButtonComponent/Sources/AudioTranscriptionButtonComponent.swift +++ b/submodules/TelegramUI/Components/AudioTranscriptionButtonComponent/Sources/AudioTranscriptionButtonComponent.swift @@ -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 + private var progressAnimationView: ComponentHostView? + override init(frame: CGRect) { self.backgroundLayer = SimpleLayer() self.animationView = ComponentHostView() @@ -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() + 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)) diff --git a/submodules/TelegramUI/Resources/Animations/voicets_progress.json b/submodules/TelegramUI/Resources/Animations/voicets_progress.json new file mode 100644 index 0000000000..a3ed0a307a --- /dev/null +++ b/submodules/TelegramUI/Resources/Animations/voicets_progress.json @@ -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":[]} \ No newline at end of file diff --git a/submodules/TextFormat/Sources/GenerateTextEntities.swift b/submodules/TextFormat/Sources/GenerateTextEntities.swift index 4c4cc9a152..7074cb85f5 100644 --- a/submodules/TextFormat/Sources/GenerateTextEntities.swift +++ b/submodules/TextFormat/Sources/GenerateTextEntities.swift @@ -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 {