@@ -129,13 +129,18 @@ final class MessageItemComponent: Component {
129129 self . container. transform = . identity
130130 superview. addSubview ( self . container)
131131
132+ let hasRTL = ( self . text. view as? MultilineTextWithEntitiesComponent . View) ? . hasRTL ?? false
133+ let direction : CGFloat = hasRTL ? - 1.0 : 1.0
134+ let initialSize = self . background. frame. size
135+
132136 self . container. addSubview ( textSnapshotView)
133137 transition. setAlpha ( view: textSnapshotView, alpha: 0.0 , completion: { _ in
134138 textSnapshotView. removeFromSuperview ( )
135139 } )
136- transition. setPosition ( view: textSnapshotView, position: CGPoint ( x: textSnapshotView. center. x + 71.0 , y: textSnapshotView. center. y) )
137140
138- let initialSize = self . background. frame. size
141+ let additionalOffset = hasRTL ? globalFrame. size. width - initialSize. width : 0.0
142+ transition. setPosition ( view: textSnapshotView, position: CGPoint ( x: textSnapshotView. center. x + 71.0 * direction - additionalOffset, y: textSnapshotView. center. y) )
143+
139144 self . background. update ( size: globalFrame. size, cornerRadius: cornerRadius, isDark: true , tintColor: . init( kind: . custom, color: glassColor) , transition: . immediate)
140145 self . background. update ( size: initialSize, cornerRadius: 18.0 , isDark: true , tintColor: . init( kind: . custom, color: glassColor) , transition: transition)
141146
@@ -151,7 +156,7 @@ final class MessageItemComponent: Component {
151156 } )
152157
153158 if let textView = self . text. view {
154- transition. animatePosition ( view: textView, from: CGPoint ( x: - 71.0 , y: 0.0 ) , to: . zero, additive: true )
159+ transition. animatePosition ( view: textView, from: CGPoint ( x: - 71.0 * direction , y: 0.0 ) , to: . zero, additive: true )
155160 transition. animateAlpha ( view: textView, from: 0.0 , to: 1.0 )
156161 }
157162 transition. animateAlpha ( view: self . avatarNode. view, from: 0.0 , to: 1.0 )
@@ -183,9 +188,7 @@ final class MessageItemComponent: Component {
183188 let avatarSpacing : CGFloat = 10.0
184189 let iconSpacing : CGFloat = 10.0
185190 let rightInset : CGFloat = component. isNotification ? 15.0 : 13.0
186-
187- let avatarFrame = CGRect ( origin: CGPoint ( x: avatarInset, y: avatarInset) , size: avatarSize)
188-
191+
189192 var peerName = " "
190193 if !component. isNotification, case let . peer( peer) = component. icon {
191194 peerName = peer. compactDisplayTitle
@@ -244,7 +247,7 @@ final class MessageItemComponent: Component {
244247 } else {
245248 let textWithAppliedEntities = stringWithAppliedEntities ( text, entities: entities, baseColor: textColor, linkColor: linkColor, baseFont: textFont, linkFont: textFont, boldFont: boldTextFont, italicFont: italicFont, boldItalicFont: boldItalicTextFont, fixedFont: monospaceFont, blockQuoteFont: textFont, message: nil , entityFiles: self . entityFiles) . mutableCopy ( ) as! NSMutableAttributedString
246249 if !peerName. isEmpty {
247- textWithAppliedEntities. insert ( NSAttributedString ( string: peerName + " " , font: boldTextFont, textColor: textColor) , at: 0 )
250+ textWithAppliedEntities. insert ( NSAttributedString ( string: " \u{2066} \( peerName ) \u{2069} " , font: boldTextFont, textColor: textColor) , at: 0 )
248251 }
249252 attributedText = textWithAppliedEntities
250253 }
@@ -276,7 +279,12 @@ final class MessageItemComponent: Component {
276279 containerSize: CGSize ( width: availableSize. width - avatarInset - avatarSize. width - spacing - rightInset, height: . greatestFiniteMagnitude)
277280 )
278281
279- let size = CGSize ( width: avatarInset + avatarSize. width + spacing + textSize. width + rightInset, height: max ( minimalHeight, textSize. height + 15.0 ) )
282+ let hasRTL = ( self . text. view as? MultilineTextWithEntitiesComponent . View) ? . hasRTL ?? false
283+
284+ let size = CGSize (
285+ width: avatarInset + avatarSize. width + spacing + textSize. width + rightInset,
286+ height: max ( minimalHeight, textSize. height + 15.0 )
287+ )
280288
281289 switch component. icon {
282290 case let . peer( peer) :
@@ -302,10 +310,11 @@ final class MessageItemComponent: Component {
302310 displayDimensions: avatarSize
303311 )
304312 }
313+ let avatarFrame = CGRect ( origin: CGPoint ( x: avatarInset, y: avatarInset) , size: avatarSize)
305314 if self . avatarNode. bounds. isEmpty {
306- self . avatarNode. frame = avatarFrame
315+ self . avatarNode. frame = mappedFrame ( avatarFrame, containerSize : size , hasRTL : hasRTL )
307316 } else {
308- transition. setFrame ( view: self . avatarNode. view, frame: avatarFrame)
317+ transition. setFrame ( view: self . avatarNode. view, frame: mappedFrame ( avatarFrame, containerSize : size , hasRTL : hasRTL ) )
309318 }
310319 self . avatarNode. isHidden = false
311320 case let . icon( iconName) :
@@ -315,12 +324,18 @@ final class MessageItemComponent: Component {
315324 environment: { } ,
316325 containerSize: CGSize ( width: 44.0 , height: 44.0 )
317326 )
318- let iconFrame = CGRect ( origin: CGPoint ( x: avatarInset, y: floorToScreenPixels ( ( size. height - iconSize. height) / 2.0 ) ) , size: iconSize)
327+ let iconFrame = CGRect (
328+ origin: CGPoint (
329+ x: avatarInset,
330+ y: floorToScreenPixels ( ( size. height - iconSize. height) / 2.0 )
331+ ) ,
332+ size: iconSize
333+ )
319334 if let iconView = self . icon. view {
320335 if iconView. superview == nil {
321336 self . container. addSubview ( iconView)
322337 }
323- transition. setFrame ( view: iconView, frame: iconFrame)
338+ transition. setFrame ( view: iconView, frame: mappedFrame ( iconFrame, containerSize : size , hasRTL : hasRTL ) )
324339 }
325340 self . avatarNode. isHidden = true
326341 case let . animation( animationName) :
@@ -338,23 +353,42 @@ final class MessageItemComponent: Component {
338353 environment: { } ,
339354 containerSize: CGSize ( width: 40.0 , height: 40.0 )
340355 )
341- let iconFrame = CGRect ( origin: CGPoint ( x: avatarInset - 3.0 , y: floorToScreenPixels ( ( size. height - iconSize. height) / 2.0 ) ) , size: iconSize)
356+ let iconFrame = CGRect (
357+ origin: CGPoint (
358+ x: avatarInset - 3.0 ,
359+ y: floorToScreenPixels ( ( size. height - iconSize. height) / 2.0 )
360+ ) ,
361+ size: iconSize
362+ )
342363 if let iconView = self . icon. view as? LottieComponent . View {
343364 if iconView. superview == nil {
344365 self . container. addSubview ( iconView)
345366 iconView. playOnce ( )
346367 }
347- transition. setFrame ( view: iconView, frame: iconFrame)
368+ transition. setFrame ( view: iconView, frame: mappedFrame ( iconFrame, containerSize : size , hasRTL : hasRTL ) )
348369 }
349370 self . avatarNode. isHidden = true
350371 }
351372
352- let textFrame = CGRect ( origin: CGPoint ( x: avatarInset + avatarSize. width + spacing, y: floorToScreenPixels ( ( size. height - textSize. height) / 2.0 ) ) , size: textSize)
373+ func mappedFrame( _ frame: CGRect , containerSize: CGSize , hasRTL: Bool ) -> CGRect {
374+ return CGRect (
375+ origin: CGPoint ( x: hasRTL ? containerSize. width - frame. minX - frame. width : frame. minX, y: frame. origin. y) ,
376+ size: frame. size
377+ )
378+ }
379+
380+ let textFrame = CGRect (
381+ origin: CGPoint (
382+ x: avatarInset + avatarSize. width + spacing,
383+ y: floorToScreenPixels ( ( size. height - textSize. height) / 2.0 )
384+ ) ,
385+ size: textSize
386+ )
353387 if let textView = self . text. view {
354388 if textView. superview == nil {
355389 self . container. addSubview ( textView)
356390 }
357- transition. setFrame ( view: textView, frame: textFrame)
391+ transition. setFrame ( view: textView, frame: mappedFrame ( textFrame, containerSize : size , hasRTL : hasRTL ) )
358392 }
359393
360394 transition. setFrame ( view: self . container, frame: CGRect ( origin: CGPoint ( ) , size: size) )
0 commit comments