33#import " OWSMessagesBubblesSizeCalculator.h"
44#import " OWSDisplayedMessageCollectionViewCell.h"
55#import " TSMessageAdapter.h"
6+ #import " UIFont+OWS.h"
67#import " tgmath.h" // generic math allows fmax to handle CGFLoat correctly on 32 & 64bit.
78#import < JSQMessagesViewController/JSQMessagesCollectionViewFlowLayout.h>
89
@@ -41,8 +42,14 @@ - (CGSize)messageBubbleSizeForMessageData:(id<JSQMessageData>)messageData
4142 atIndexPath : (NSIndexPath *)indexPath
4243 withLayout : (JSQMessagesCollectionViewFlowLayout *)layout
4344{
44- CGSize size;
45+ if ([messageData isKindOfClass: [TSMessageAdapter class ]]) {
46+ TSMessageAdapter *message = (TSMessageAdapter *)messageData;
47+ if (message.messageType == TSInfoMessageAdapter || message.messageType == TSErrorMessageAdapter) {
48+ return [self messageBubbleSizeForInfoMessageData: messageData atIndexPath: indexPath withLayout: layout];
49+ }
50+ }
4551
52+ CGSize size;
4653 // BEGIN HACK iOS10EmojiBug see: https://github.com/WhisperSystems/Signal-iOS/issues/1368
4754 BOOL isIOS10OrGreater =
4855 [[NSProcessInfo processInfo ] isOperatingSystemAtLeastVersion: (NSOperatingSystemVersion ){.majorVersion = 10 }];
@@ -55,22 +62,8 @@ - (CGSize)messageBubbleSizeForMessageData:(id<JSQMessageData>)messageData
5562 }
5663 // END HACK iOS10EmojiBug see: https://github.com/WhisperSystems/Signal-iOS/issues/1368
5764
58- if ([messageData isKindOfClass: [TSMessageAdapter class ]]) {
59- TSMessageAdapter *message = (TSMessageAdapter *)messageData;
6065
6166
62- if (message.messageType == TSInfoMessageAdapter || message.messageType == TSErrorMessageAdapter) {
63- // DDLogVerbose(@"[OWSMessagesBubblesSizeCalculator] superSize.height:%f, superSize.width:%f",
64- // superSize.height,
65- // superSize.width);
66-
67- // header icon hangs ouside of the frame a bit.
68- CGFloat headerIconProtrusion = 30 .0f ; // too much padding with normal font.
69- // CGFloat headerIconProtrusion = 18.0f; // clips
70- size.height += headerIconProtrusion;
71- }
72- }
73-
7467 return size;
7568}
7669
@@ -173,6 +166,83 @@ - (CGSize)withiOS10EmojiFixSuperMessageBubbleSizeForMessageData:(id<JSQMessageDa
173166 return finalSize;
174167}
175168
169+
170+ - (CGSize)messageBubbleSizeForInfoMessageData : (id <JSQMessageData>)messageData
171+ atIndexPath : (NSIndexPath *)indexPath
172+ withLayout : (JSQMessagesCollectionViewFlowLayout *)layout
173+ {
174+ NSValue *cachedSize = [self .cache objectForKey: @([messageData messageHash ])];
175+ if (cachedSize != nil ) {
176+ return [cachedSize CGSizeValue ];
177+ }
178+
179+ CGSize finalSize = CGSizeZero;
180+
181+ if ([messageData isMediaMessage ]) {
182+ finalSize = [[messageData media ] mediaViewDisplaySize ];
183+ } else {
184+ // /////////////////
185+ // BEGIN InfoMessage sizing HACK
186+ // Braindead, and painstakingly produced.
187+ // If you want to change, check for clipping / excess space on 1, 2, and 3 line messages with short and long
188+ // words very near the edge.
189+
190+ // CGSize avatarSize = [self jsq_avatarSizeForMessageData:messageData withLayout:layout];
191+ // // from the cell xibs, there is a 2 point space between avatar and bubble
192+ // CGFloat spacingBetweenAvatarAndBubble = 2.0f;
193+ // CGFloat horizontalContainerInsets = layout.messageBubbleTextViewTextContainerInsets.left + layout.messageBubbleTextViewTextContainerInsets.right;
194+ // CGFloat horizontalFrameInsets = layout.messageBubbleTextViewFrameInsets.left + layout.messageBubbleTextViewFrameInsets.right;
195+ // CGFloat horizontalInsetsTotal = horizontalContainerInsets + horizontalFrameInsets + spacingBetweenAvatarAndBubble;
196+ // CGFloat maximumTextWidth = [self textBubbleWidthForLayout:layout] - avatarSize.width - layout.messageBubbleLeftRightMargin - horizontalInsetsTotal;
197+
198+ // The full layout width, less the textView margins from xib.
199+ // CGFloat horizontalInsetsTotal = 12.0; cropped 3rd line
200+ CGFloat horizontalInsetsTotal = 50.0 ;
201+ CGFloat maximumTextWidth = [self textBubbleWidthForLayout: layout] - horizontalInsetsTotal;
202+
203+ CGRect stringRect = [[messageData text ]
204+ boundingRectWithSize: CGSizeMake (maximumTextWidth, CGFLOAT_MAX)
205+ options: (NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading)
206+ attributes: @{
207+ NSFontAttributeName : [UIFont ows_dynamicTypeBodyFont ]
208+ } // Hack to use a slightly larger than actual font, because I'm seeing messages with higher line count get clipped.
209+ context: nil ];
210+ // END InfoMessage sizing HACK
211+ // //////////////////
212+
213+ CGSize stringSize = CGRectIntegral (stringRect).size ;
214+
215+ CGFloat verticalContainerInsets = layout.messageBubbleTextViewTextContainerInsets .top
216+ + layout.messageBubbleTextViewTextContainerInsets .bottom ;
217+
218+ CGFloat verticalFrameInsets
219+ = layout.messageBubbleTextViewFrameInsets .top + layout.messageBubbleTextViewFrameInsets .bottom ;
220+ // /////////////////
221+ // BEGIN InfoMessage sizing HACK
222+
223+ CGFloat topIconPortrusion = 28 ;
224+
225+ verticalFrameInsets += topIconPortrusion;
226+
227+ // END InfoMessage sizing HACK
228+ // /////////////////
229+
230+ // add extra 2 points of space (`self.additionalInset`), because `boundingRectWithSize:` is slightly off
231+ // not sure why. magix. (shrug) if you know, submit a PR
232+ CGFloat verticalInsets = verticalContainerInsets + verticalFrameInsets + self.additionalInset ;
233+
234+ // same as above, an extra 2 points of magix
235+ CGFloat finalWidth
236+ = MAX (stringSize.width + horizontalInsetsTotal, self.minimumBubbleWidth ) + self.additionalInset ;
237+
238+ finalSize = CGSizeMake (finalWidth, stringSize.height + verticalInsets);
239+ }
240+
241+ [self .cache setObject: [NSValue valueWithCGSize: finalSize] forKey: @([messageData messageHash ])];
242+
243+ return finalSize;
244+ }
245+
176246@end
177247
178248NS_ASSUME_NONNULL_END
0 commit comments