Improve sticker pack display on iPad

This commit is contained in:
Ilya Laktyushin 2023-03-10 01:55:48 +04:00
parent 7fcce53b2c
commit c6ca35292b
10 changed files with 268 additions and 91 deletions

View File

@ -667,4 +667,5 @@ public enum FileMediaResourceMediaStatus: Equatable {
public protocol ChatMessageItemNodeProtocol: ListViewItemNode {
func targetReactionView(value: MessageReaction.Reaction) -> UIView?
func contentFrame() -> CGRect
}

View File

@ -45,6 +45,7 @@ public final class OpenChatMessageParams {
public let playlistLocation: PeerMessagesPlaylistLocation?
public let gallerySource: GalleryControllerItemSource?
public let centralItemUpdated: ((MessageId) -> Void)?
public let getSourceRect: (() -> CGRect?)?
public init(
context: AccountContext,
@ -72,7 +73,8 @@ public final class OpenChatMessageParams {
actionInteraction: GalleryControllerActionInteraction? = nil,
playlistLocation: PeerMessagesPlaylistLocation? = nil,
gallerySource: GalleryControllerItemSource? = nil,
centralItemUpdated: ((MessageId) -> Void)? = nil
centralItemUpdated: ((MessageId) -> Void)? = nil,
getSourceRect: (() -> CGRect?)? = nil
) {
self.context = context
self.updatedPresentationData = updatedPresentationData
@ -100,5 +102,6 @@ public final class OpenChatMessageParams {
self.playlistLocation = playlistLocation
self.gallerySource = gallerySource
self.centralItemUpdated = centralItemUpdated
self.getSourceRect = getSourceRect
}
}

View File

@ -255,9 +255,11 @@ private final class StickerPackContainer: ASDisplayNode {
guard let strongSelf = self, !strongSelf.isDismissed else {
return
}
if let (layout, _, _, _) = strongSelf.validLayout, case .regular = layout.metrics.widthClass {
return
}
let contentOffset = strongSelf.gridNode.scrollView.contentOffset
let insets = strongSelf.gridNode.scrollView.contentInset
if contentOffset.y <= -insets.top - 30.0 {
strongSelf.isDismissed = true
DispatchQueue.main.async {
@ -1203,7 +1205,9 @@ private final class StickerPackContainer: ASDisplayNode {
func updateLayout(layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
var insets = layout.insets(options: [.statusBar])
if case .compact = layout.metrics.widthClass, layout.size.width > layout.size.height {
if case .regular = layout.metrics.widthClass {
insets.top = 0.0
} else if case .compact = layout.metrics.widthClass, layout.size.width > layout.size.height {
insets.top = 0.0
} else {
insets.top += 10.0
@ -1271,11 +1275,14 @@ private final class StickerPackContainer: ASDisplayNode {
let initialRevealedRowCount: CGFloat = 4.5
let topInset = max(0.0, layout.size.height - floor(initialRevealedRowCount * itemWidth) - insets.top - actionAreaHeight - titleAreaInset)
let topInset: CGFloat
if case .regular = layout.metrics.widthClass {
topInset = 0.0
} else {
topInset = insets.top + max(0.0, layout.size.height - floor(initialRevealedRowCount * itemWidth) - insets.top - actionAreaHeight - titleAreaInset)
}
let additionalGridBottomInset = max(0.0, gridFrame.size.height - actionAreaHeight - contentHeight)
let gridInsets = UIEdgeInsets(top: insets.top + topInset, left: gridLeftInset, bottom: actionAreaHeight + additionalGridBottomInset, right: layout.size.width - fillingWidth - gridLeftInset)
let gridInsets = UIEdgeInsets(top: topInset, left: gridLeftInset, bottom: actionAreaHeight + additionalGridBottomInset, right: layout.size.width - fillingWidth - gridLeftInset)
let firstTime = self.validLayout == nil
self.validLayout = (layout, gridFrame, titleAreaInset, gridInsets)
@ -1354,9 +1361,16 @@ private final class StickerPackContainer: ASDisplayNode {
self.titleSeparatorNode.layer.removeAllAnimations()
}
let backgroundFrame = CGRect(origin: CGPoint(x: 0.0, y: max(minBackgroundY, unclippedBackgroundY)), size: CGSize(width: layout.size.width, height: layout.size.height))
var backgroundFrame = CGRect(origin: CGPoint(x: 0.0, y: max(minBackgroundY, unclippedBackgroundY)), size: CGSize(width: layout.size.width, height: layout.size.height))
var titleContainerFrame: CGRect
if case .regular = layout.metrics.widthClass {
backgroundFrame.origin.y = min(0.0, backgroundFrame.origin.y)
titleContainerFrame = CGRect(origin: CGPoint(x: backgroundFrame.minX + floor((backgroundFrame.width) / 2.0), y: floor((56.0) / 2.0)), size: CGSize())
} else {
titleContainerFrame = CGRect(origin: CGPoint(x: backgroundFrame.minX + floor((backgroundFrame.width) / 2.0), y: backgroundFrame.minY + floor((56.0) / 2.0)), size: CGSize())
}
transition.updateFrame(node: self.backgroundNode, frame: backgroundFrame)
transition.updateFrame(node: self.titleContainer, frame: CGRect(origin: CGPoint(x: backgroundFrame.minX + floor((backgroundFrame.width) / 2.0), y: backgroundFrame.minY + floor((56.0) / 2.0)), size: CGSize()))
transition.updateFrame(node: self.titleContainer, frame: titleContainerFrame)
transition.updateFrame(node: self.titleSeparatorNode, frame: CGRect(origin: CGPoint(x: backgroundFrame.minX, y: backgroundFrame.minY + 56.0 - UIScreenPixel), size: CGSize(width: backgroundFrame.width, height: UIScreenPixel)))
transition.updateFrame(node: self.titleBackgroundnode, frame: CGRect(origin: CGPoint(x: backgroundFrame.minX, y: backgroundFrame.minY), size: CGSize(width: backgroundFrame.width, height: 56.0)))
self.titleBackgroundnode.update(size: CGSize(width: layout.size.width, height: 56.0), transition: .immediate)
@ -1427,6 +1441,8 @@ private final class StickerPackScreenNode: ViewControllerTracingNode {
private let openMention: (String) -> Void
private let dimNode: ASDisplayNode
private let shadowNode: ASImageNode
private let arrowNode: ASImageNode
private let containerContainingNode: ASDisplayNode
private var containers: [Int: StickerPackContainer] = [:]
@ -1475,12 +1491,23 @@ private final class StickerPackScreenNode: ViewControllerTracingNode {
self.dimNode.backgroundColor = UIColor(white: 0.0, alpha: 0.25)
self.dimNode.alpha = 0.0
self.shadowNode = ASImageNode()
self.shadowNode.displaysAsynchronously = false
self.shadowNode.isUserInteractionEnabled = false
self.arrowNode = ASImageNode()
self.arrowNode.displaysAsynchronously = false
self.arrowNode.isUserInteractionEnabled = false
self.arrowNode.image = generateArrowImage(color: self.presentationData.theme.actionSheet.opaqueItemBackgroundColor)
self.containerContainingNode = ASDisplayNode()
self.containerContainingNode.clipsToBounds = true
super.init()
self.addSubnode(self.dimNode)
self.addSubnode(self.shadowNode)
self.addSubnode(self.arrowNode)
self.addSubnode(self.containerContainingNode)
}
@ -1494,6 +1521,7 @@ private final class StickerPackScreenNode: ViewControllerTracingNode {
for (_, container) in self.containers {
container.updatePresentationData(presentationData)
}
self.arrowNode.image = generateArrowImage(color: presentationData.theme.actionSheet.opaqueItemBackgroundColor)
}
func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
@ -1502,10 +1530,65 @@ private final class StickerPackScreenNode: ViewControllerTracingNode {
self.validLayout = layout
transition.updateFrame(node: self.dimNode, frame: CGRect(origin: CGPoint(), size: layout.size))
transition.updateFrame(node: self.containerContainingNode, frame: CGRect(origin: CGPoint(), size: layout.size))
let containerContainingFrame: CGRect
let containerInsets: UIEdgeInsets
if case .regular = layout.metrics.widthClass {
self.dimNode.backgroundColor = UIColor(white: 0.0, alpha: 0.01)
self.containerContainingNode.cornerRadius = 10.0
let size = CGSize(width: 390.0, height: min(620.0, layout.size.height - 60.0))
var contentRect: CGRect
if let sourceRect = self.controller?.getSourceRect?() {
let sideSpacing: CGFloat = 10.0
let margin: CGFloat = 64.0
contentRect = CGRect(origin: CGPoint(x: sourceRect.maxX + sideSpacing, y: floor(sourceRect.midY - size.height / 2.0)), size: size)
contentRect.origin.y = min(layout.size.height - margin - size.height - layout.intrinsicInsets.bottom, max(margin, contentRect.origin.y))
let arrowSize = CGSize(width: 23.0, height: 12.0)
let arrowFrame: CGRect
if contentRect.maxX > layout.size.width {
contentRect.origin.x = sourceRect.minX - size.width - sideSpacing
arrowFrame = CGRect(origin: CGPoint(x: contentRect.maxX - (arrowSize.width - arrowSize.height) / 2.0, y: floor(sourceRect.midY - arrowSize.height / 2.0)), size: arrowSize)
self.arrowNode.transform = CATransform3DMakeRotation(-.pi / 2.0, 0.0, 0.0, 1.0)
} else {
arrowFrame = CGRect(origin: CGPoint(x: contentRect.minX - arrowSize.width + (arrowSize.width - arrowSize.height) / 2.0, y: floor(sourceRect.midY - arrowSize.height / 2.0)), size: arrowSize)
self.arrowNode.transform = CATransform3DMakeRotation(.pi / 2.0, 0.0, 0.0, 1.0)
}
self.arrowNode.frame = arrowFrame
self.arrowNode.isHidden = false
} else {
let masterWidth = min(max(320.0, floor(layout.size.width / 3.0)), floor(layout.size.width / 2.0))
let detailWidth = layout.size.width - masterWidth
contentRect = CGRect(origin: CGPoint(x: masterWidth + floor((detailWidth - size.width) / 2.0), y: floor((layout.size.height - size.height) / 2.0)), size: size)
self.arrowNode.isHidden = true
}
containerContainingFrame = contentRect
containerInsets = .zero
self.shadowNode.alpha = 1.0
if self.shadowNode.image == nil {
self.shadowNode.image = generateShadowImage()
}
} else {
self.containerContainingNode.cornerRadius = 0.0
self.dimNode.backgroundColor = UIColor(white: 0.0, alpha: 0.25)
containerContainingFrame = CGRect(origin: CGPoint(), size: layout.size)
containerInsets = layout.intrinsicInsets
self.arrowNode.isHidden = true
self.shadowNode.alpha = 0.0
}
transition.updateFrame(node: self.containerContainingNode, frame: containerContainingFrame)
let shadowFrame = containerContainingFrame.insetBy(dx: -60.0, dy: -60.0)
transition.updateFrame(node: self.shadowNode, frame: shadowFrame)
let expandProgress: CGFloat = 1.0
let scaledInset: CGFloat = 12.0
let scaledDistance: CGFloat = 4.0
let minScale = (layout.size.width - scaledInset * 2.0) / layout.size.width
@ -1593,11 +1676,15 @@ private final class StickerPackScreenNode: ViewControllerTracingNode {
self.containers[i] = container
}
let containerFrame = CGRect(origin: CGPoint(x: CGFloat(indexOffset) * layout.size.width + self.relativeToSelectedStickerPackTransition + scaledOffset, y: containerVerticalOffset), size: layout.size)
let containerFrame = CGRect(origin: CGPoint(x: CGFloat(indexOffset) * containerContainingFrame.size.width + self.relativeToSelectedStickerPackTransition + scaledOffset, y: containerVerticalOffset), size: containerContainingFrame.size)
containerTransition.updateFrame(node: container, frame: containerFrame, beginWithCurrentState: true)
containerTransition.updateSublayerTransformScaleAndOffset(node: container, scale: containerScale, offset: CGPoint(), beginWithCurrentState: true)
var containerLayout = layout
containerLayout.size = containerFrame.size
containerLayout.intrinsicInsets = containerInsets
if container.validLayout?.0 != layout {
container.updateLayout(layout: layout, transition: containerTransition)
container.updateLayout(layout: containerLayout, transition: containerTransition)
}
if wasAdded {
@ -1680,23 +1767,40 @@ private final class StickerPackScreenNode: ViewControllerTracingNode {
}
func animateIn() {
guard let layout = self.validLayout else {
return
}
self.dimNode.alpha = 1.0
self.dimNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.3)
let minInset: CGFloat = (self.containers.map { (_, container) -> CGFloat in container.topContentInset }).max() ?? 0.0
self.containerContainingNode.layer.animatePosition(from: CGPoint(x: 0.0, y: self.containerContainingNode.bounds.height - minInset), to: CGPoint(), duration: 0.5, timingFunction: kCAMediaTimingFunctionSpring, additive: true)
if case .regular = layout.metrics.widthClass {
} else {
let minInset: CGFloat = (self.containers.map { (_, container) -> CGFloat in container.topContentInset }).max() ?? 0.0
self.containerContainingNode.layer.animatePosition(from: CGPoint(x: 0.0, y: self.containerContainingNode.bounds.height - minInset), to: CGPoint(), duration: 0.5, timingFunction: kCAMediaTimingFunctionSpring, additive: true)
}
}
func animateOut(completion: @escaping () -> Void) {
guard let layout = self.validLayout else {
return
}
self.dimNode.alpha = 0.0
self.dimNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2)
let minInset: CGFloat = (self.containers.map { (_, container) -> CGFloat in container.topContentInset }).max() ?? 0.0
self.containerContainingNode.layer.animatePosition(from: CGPoint(), to: CGPoint(x: 0.0, y: self.containerContainingNode.bounds.height - minInset), duration: 0.2, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, removeOnCompletion: false, additive: true, completion: { _ in
completion()
})
self.modalProgressUpdated(0.0, .animated(duration: 0.2, curve: .easeInOut))
if case .regular = layout.metrics.widthClass {
self.layer.allowsGroupOpacity = true
self.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false, completion: { _ in
completion()
})
} else {
let minInset: CGFloat = (self.containers.map { (_, container) -> CGFloat in container.topContentInset }).max() ?? 0.0
self.containerContainingNode.layer.animatePosition(from: CGPoint(), to: CGPoint(x: 0.0, y: self.containerContainingNode.bounds.height - minInset), duration: 0.2, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, removeOnCompletion: false, additive: true, completion: { _ in
completion()
})
self.modalProgressUpdated(0.0, .animated(duration: 0.2, curve: .easeInOut))
}
}
func dismiss() {
@ -1782,6 +1886,8 @@ public final class StickerPackScreenImpl: ViewController {
public var dismissed: (() -> Void)?
public var actionPerformed: (([(StickerPackCollectionInfo, [StickerPackItem], StickerPackScreenPerformedAction)]) -> Void)?
public var getSourceRect: (() -> CGRect?)?
private let _ready = Promise<Bool>()
override public var ready: Promise<Bool> {
return self._ready
@ -2032,8 +2138,9 @@ public func StickerPackScreen(
sendSticker: ((FileMediaReference, UIView, CGRect) -> Bool)? = nil,
sendEmoji: ((String, ChatTextInputTextCustomEmojiAttribute) -> Void)? = nil,
actionPerformed: (([(StickerPackCollectionInfo, [StickerPackItem], StickerPackScreenPerformedAction)]) -> Void)? = nil,
dismissed: (() -> Void)? = nil) -> ViewController
{
dismissed: (() -> Void)? = nil,
getSourceRect: (() -> CGRect?)? = nil
) -> ViewController {
let controller = StickerPackScreenImpl(
context: context,
stickerPacks: stickerPacks,
@ -2045,6 +2152,7 @@ public func StickerPackScreen(
actionPerformed: actionPerformed
)
controller.dismissed = dismissed
controller.getSourceRect = getSourceRect
return controller
}
@ -2062,3 +2170,34 @@ private final class StickerPackContextReferenceContentSource: ContextReferenceCo
return ContextControllerReferenceViewInfo(referenceView: self.sourceNode.view, contentAreaInScreenSpace: UIScreen.main.bounds)
}
}
private func generateShadowImage() -> UIImage? {
return generateImage(CGSize(width: 140.0, height: 140.0), rotatedContext: { size, context in
context.clear(CGRect(origin: CGPoint(), size: size))
context.saveGState()
context.setShadow(offset: CGSize(), blur: 60.0, color: UIColor(white: 0.0, alpha: 0.4).cgColor)
let path = UIBezierPath(roundedRect: CGRect(x: 60.0, y: 60.0, width: 20.0, height: 20.0), cornerRadius: 10.0).cgPath
context.addPath(path)
context.fillPath()
context.restoreGState()
context.setBlendMode(.clear)
context.addPath(path)
context.fillPath()
})?.stretchableImage(withLeftCapWidth: 70, topCapHeight: 70)
}
private func generateArrowImage(color: UIColor) -> UIImage? {
return generateImage(CGSize(width: 23.0, height: 12.0), rotatedContext: { size, context in
context.clear(CGRect(origin: CGPoint(), size: size))
context.setFillColor(color.cgColor)
context.translateBy(x: -183.0, y: -209.0)
try? drawSvgPath(context, path: "M183.219,208.89 H206.781 C205.648,208.89 204.567,209.371 203.808,210.214 L197.23,217.523 C196.038,218.848 193.962,218.848 192.77,217.523 L186.192,210.214 C185.433,209.371 184.352,208.89 183.219,208.89 Z ")
})
}

View File

@ -996,78 +996,92 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
}))
}
}, actionInteraction: GalleryControllerActionInteraction(openUrl: { [weak self] url, concealed in
if let strongSelf = self {
strongSelf.openUrl(url, concealed: concealed, message: nil)
}
}, openUrlIn: { [weak self] url in
if let strongSelf = self {
strongSelf.openUrlIn(url)
}
}, openPeerMention: { [weak self] mention in
if let strongSelf = self {
strongSelf.controllerInteraction?.openPeerMention(mention)
}
}, openPeer: { [weak self] peer in
if let strongSelf = self {
strongSelf.controllerInteraction?.openPeer(peer, .default, nil, .default)
}
}, openHashtag: { [weak self] peerName, hashtag in
if let strongSelf = self {
strongSelf.controllerInteraction?.openHashtag(peerName, hashtag)
}
}, openBotCommand: { [weak self] command in
if let strongSelf = self {
strongSelf.controllerInteraction?.sendBotCommand(nil, command)
}
}, addContact: { [weak self] phoneNumber in
if let strongSelf = self {
strongSelf.controllerInteraction?.addContact(phoneNumber)
}
}, storeMediaPlaybackState: { [weak self] messageId, timestamp, playbackRate in
guard let strongSelf = self else {
return
}
var storedState: MediaPlaybackStoredState?
if let timestamp = timestamp {
storedState = MediaPlaybackStoredState(timestamp: timestamp, playbackRate: AudioPlaybackRate(playbackRate))
}
let _ = updateMediaPlaybackStoredStateInteractively(engine: strongSelf.context.engine, messageId: messageId, state: storedState).start()
}, editMedia: { [weak self] messageId, snapshots, transitionCompletion in
guard let strongSelf = self else {
return
}
let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Messages.Message(id: messageId))
|> deliverOnMainQueue).start(next: { [weak self] message in
guard let strongSelf = self, let message = message else {
}, actionInteraction: GalleryControllerActionInteraction(
openUrl: { [weak self] url, concealed in
if let strongSelf = self {
strongSelf.openUrl(url, concealed: concealed, message: nil)
}
}, openUrlIn: { [weak self] url in
if let strongSelf = self {
strongSelf.openUrlIn(url)
}
}, openPeerMention: { [weak self] mention in
if let strongSelf = self {
strongSelf.controllerInteraction?.openPeerMention(mention)
}
}, openPeer: { [weak self] peer in
if let strongSelf = self {
strongSelf.controllerInteraction?.openPeer(peer, .default, nil, .default)
}
}, openHashtag: { [weak self] peerName, hashtag in
if let strongSelf = self {
strongSelf.controllerInteraction?.openHashtag(peerName, hashtag)
}
}, openBotCommand: { [weak self] command in
if let strongSelf = self {
strongSelf.controllerInteraction?.sendBotCommand(nil, command)
}
}, addContact: { [weak self] phoneNumber in
if let strongSelf = self {
strongSelf.controllerInteraction?.addContact(phoneNumber)
}
}, storeMediaPlaybackState: { [weak self] messageId, timestamp, playbackRate in
guard let strongSelf = self else {
return
}
var storedState: MediaPlaybackStoredState?
if let timestamp = timestamp {
storedState = MediaPlaybackStoredState(timestamp: timestamp, playbackRate: AudioPlaybackRate(playbackRate))
}
let _ = updateMediaPlaybackStoredStateInteractively(engine: strongSelf.context.engine, messageId: messageId, state: storedState).start()
}, editMedia: { [weak self] messageId, snapshots, transitionCompletion in
guard let strongSelf = self else {
return
}
var mediaReference: AnyMediaReference?
for media in message.media {
if let image = media as? TelegramMediaImage {
mediaReference = AnyMediaReference.standalone(media: image)
} else if let file = media as? TelegramMediaFile {
mediaReference = AnyMediaReference.standalone(media: file)
let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Messages.Message(id: messageId))
|> deliverOnMainQueue).start(next: { [weak self] message in
guard let strongSelf = self, let message = message else {
return
}
}
if let mediaReference = mediaReference, let peer = message.peers[message.id.peerId] {
legacyMediaEditor(context: strongSelf.context, peer: peer, threadTitle: strongSelf.threadInfo?.title, media: mediaReference, initialCaption: NSAttributedString(), snapshots: snapshots, transitionCompletion: {
transitionCompletion()
}, getCaptionPanelView: { [weak self] in
return self?.getCaptionPanelView()
}, sendMessagesWithSignals: { [weak self] signals, _, _ in
if let strongSelf = self {
strongSelf.enqueueMediaMessages(signals: signals, silentPosting: false)
var mediaReference: AnyMediaReference?
for media in message.media {
if let image = media as? TelegramMediaImage {
mediaReference = AnyMediaReference.standalone(media: image)
} else if let file = media as? TelegramMediaFile {
mediaReference = AnyMediaReference.standalone(media: file)
}
}, present: { [weak self] c, a in
self?.present(c, in: .window(.root), with: a)
})
}
if let mediaReference = mediaReference, let peer = message.peers[message.id.peerId] {
legacyMediaEditor(context: strongSelf.context, peer: peer, threadTitle: strongSelf.threadInfo?.title, media: mediaReference, initialCaption: NSAttributedString(), snapshots: snapshots, transitionCompletion: {
transitionCompletion()
}, getCaptionPanelView: { [weak self] in
return self?.getCaptionPanelView()
}, sendMessagesWithSignals: { [weak self] signals, _, _ in
if let strongSelf = self {
strongSelf.enqueueMediaMessages(signals: signals, silentPosting: false)
}
}, present: { [weak self] c, a in
self?.present(c, in: .window(.root), with: a)
})
}
})
}),
getSourceRect: { [weak self] in
guard let strongSelf = self else {
return nil
}
})
})))
var rect: CGRect?
strongSelf.chatDisplayNode.historyNode.forEachVisibleMessageItemNode({ itemNode in
if itemNode.item?.message.id == message.id {
rect = itemNode.view.convert(itemNode.contentFrame(), to: nil)
}
})
return rect
}
))
}, openPeer: { [weak self] peer, navigation, fromMessage, source in
self?.openPeer(peer: peer, navigation: navigation, fromMessage: fromMessage, fromReactionMessageId: source == .reaction ? fromMessage?.id : nil, expandAvatar: source == .groupParticipant)
}, openPeerMention: { [weak self] name in

View File

@ -2889,6 +2889,10 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
override func unreadMessageRangeUpdated() {
self.updateVisibility()
}
override func contentFrame() -> CGRect {
return self.imageNode.frame
}
}
struct AnimatedEmojiSoundsConfiguration {

View File

@ -4562,4 +4562,8 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
}
return false
}
override func contentFrame() -> CGRect {
return self.backgroundNode.frame
}
}

View File

@ -1399,4 +1399,8 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView, UIGestureRecognizerD
}
return nil
}
override func contentFrame() -> CGRect {
return self.interactiveVideoNode.frame
}
}

View File

@ -951,4 +951,8 @@ public class ChatMessageItemView: ListViewItemNode, ChatMessageItemNodeProtocol
func unreadMessageRangeUpdated() {
}
public func contentFrame() -> CGRect {
return self.bounds
}
}

View File

@ -1833,4 +1833,8 @@ class ChatMessageStickerItemNode: ChatMessageItemView {
}
return nil
}
override func contentFrame() -> CGRect {
return self.imageNode.frame
}
}

View File

@ -113,7 +113,7 @@ func openChatMessageImpl(_ params: OpenChatMessageParams) -> Bool {
}))
}
}
})
}, getSourceRect: params.getSourceRect)
params.dismissInput()
params.present(controller, nil)
return true