From 98fb98a86e9218b9e36312cf42ac69f22725c703 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Thu, 25 Sep 2025 20:09:35 +0400 Subject: [PATCH] Various improvements --- .../Components/MessageItemComponent.swift | 27 +++++++++++++- .../Sources/VideoChatScreen.swift | 37 +++++++++++++------ 2 files changed, 51 insertions(+), 13 deletions(-) diff --git a/submodules/TelegramCallsUI/Sources/Components/MessageItemComponent.swift b/submodules/TelegramCallsUI/Sources/Components/MessageItemComponent.swift index 8dfcd81362..eb36b60db9 100644 --- a/submodules/TelegramCallsUI/Sources/Components/MessageItemComponent.swift +++ b/submodules/TelegramCallsUI/Sources/Components/MessageItemComponent.swift @@ -3,6 +3,7 @@ import Display import UIKit import ComponentFlow import SwiftSignalKit +import Postbox import TelegramCore import AvatarNode import GlassBackgroundComponent @@ -128,6 +129,9 @@ final class MessageItemComponent: Component { transition.animateScale(view: self.avatarNode.view, from: 0.01, to: 1.0) } + private var cachedEntities: [MessageTextEntity]? + private var entityFiles: [MediaId: TelegramMediaFile] = [:] + func update(component: MessageItemComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment, transition: ComponentTransition) -> CGSize { let isFirstTime = self.component == nil var transition = transition @@ -183,7 +187,28 @@ final class MessageItemComponent: Component { if peerName.count > 40 { peerName = "\(peerName.prefix(40))…" } - let attributedText = stringWithAppliedEntities(component.text, entities: component.entities, baseColor: textColor, linkColor: linkColor, baseFont: textFont, linkFont: textFont, boldFont: boldTextFont, italicFont: textFont, boldItalicFont: boldTextFont, fixedFont: textFont, blockQuoteFont: textFont, message: nil).mutableCopy() as! NSMutableAttributedString + + let text = component.text + var entities = component.entities + if let cachedEntities = self.cachedEntities { + entities = cachedEntities + } else if let availableReactions = component.availableReactions, text.count == 1 { + let emoji = component.text.strippedEmoji + var reactionItem: ReactionItem? + for item in availableReactions { + if case .builtin(emoji) = item.reaction.rawValue { + reactionItem = item + break + } + } + if case .builtin = reactionItem?.reaction.rawValue, let item = component.context.animatedEmojiStickersValue[emoji]?.first { + self.entityFiles[item.file.fileId] = item.file._parse() + entities.insert(MessageTextEntity(range: 0 ..< (text as NSString).length, type: .CustomEmoji(stickerPack: nil, fileId: item.file.fileId.id)), at: 0) + self.cachedEntities = entities + } + } + + let attributedText = stringWithAppliedEntities(text, entities: entities, baseColor: textColor, linkColor: linkColor, baseFont: textFont, linkFont: textFont, boldFont: boldTextFont, italicFont: textFont, boldItalicFont: boldTextFont, fixedFont: textFont, blockQuoteFont: textFont, message: nil, entityFiles: self.entityFiles).mutableCopy() as! NSMutableAttributedString attributedText.insert(NSAttributedString(string: peerName + " ", font: boldTextFont, textColor: textColor), at: 0) let textSize = self.text.update( diff --git a/submodules/TelegramCallsUI/Sources/VideoChatScreen.swift b/submodules/TelegramCallsUI/Sources/VideoChatScreen.swift index 592cf52bf2..3a9cc5c7b0 100644 --- a/submodules/TelegramCallsUI/Sources/VideoChatScreen.swift +++ b/submodules/TelegramCallsUI/Sources/VideoChatScreen.swift @@ -235,7 +235,7 @@ final class VideoChatScreenComponent: Component { var encryptionKey: ComponentView? var isEncryptionKeyExpanded: Bool = false - let videoButton = ComponentView() + var videoButton: ComponentView? let videoControlButton = ComponentView() let leaveButton = ComponentView() let microphoneButton = ComponentView() @@ -3164,8 +3164,18 @@ final class VideoChatScreenComponent: Component { } if let videoButtonContent { - let _ = self.videoButton.update( - transition: transition, + var videoButtonTransition = transition + let videoButton: ComponentView + if let current = self.videoButton { + videoButton = current + } else { + videoButtonTransition = .immediate + videoButton = ComponentView() + self.videoButton = videoButton + } + + let _ = videoButton.update( + transition: videoButtonTransition, component: AnyComponent(PlainButtonComponent( content: AnyComponent(VideoChatActionButtonComponent( strings: environment.strings, @@ -3189,19 +3199,22 @@ final class VideoChatScreenComponent: Component { environment: {}, containerSize: CGSize(width: actionButtonDiameter, height: actionButtonDiameter) ) - if let videoButtonView = self.videoButton.view { + if let videoButtonView = videoButton.view { if videoButtonView.superview == nil { self.containerView.addSubview(videoButtonView) } - transition.setPosition(view: videoButtonView, position: secondActionButtonFrame.center) - transition.setBounds(view: videoButtonView, bounds: CGRect(origin: CGPoint(), size: secondActionButtonFrame.size)) + videoButtonTransition.setPosition(view: videoButtonView, position: secondActionButtonFrame.center) + videoButtonTransition.setBounds(view: videoButtonView, bounds: CGRect(origin: CGPoint(), size: secondActionButtonFrame.size)) + } + } else if let videoButton = self.videoButton, videoButton.view?.superview != nil { + self.videoButton = nil + if let videoButtonView = videoButton.view { + let transition = ComponentTransition(animation: .curve(duration: 0.25, curve: .easeInOut)) + transition.animateScale(view: videoButtonView, from: 1.0, to: 0.01) + transition.animateAlpha(view: videoButtonView, from: 1.0, to: 0.0, completion: { _ in + videoButtonView.removeFromSuperview() + }) } - } else if let videoButtonView = self.videoButton.view { - let transition = ComponentTransition(animation: .curve(duration: 0.25, curve: .easeInOut)) - transition.animateScale(view: videoButtonView, from: 1.0, to: 0.01) - transition.animateAlpha(view: videoButtonView, from: 1.0, to: 0.0, completion: { _ in - videoButtonView.removeFromSuperview() - }) } let _ = self.messageButton.update(