parent
06938208cb
commit
eb3ca43256
|
@ -132,8 +132,6 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
[self.bubbleImageView autoPinToSuperviewEdges];
|
||||
|
||||
self.textView = [UITextView new];
|
||||
// Honor dynamic type in the message bodies.
|
||||
self.textView.font = [self textMessageFont];
|
||||
self.textView.backgroundColor = [UIColor clearColor];
|
||||
self.textView.opaque = NO;
|
||||
self.textView.editable = NO;
|
||||
|
@ -182,6 +180,23 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
|
||||
- (UIFont *)textMessageFont
|
||||
{
|
||||
OWSAssert(DisplayableText.kMaxJumbomojiCount == 5);
|
||||
|
||||
if (self.displayableText.jumbomojiCount) {
|
||||
switch (self.displayableText.jumbomojiCount.integerValue) {
|
||||
case 1:
|
||||
return [UIFont ows_regularFontWithSize:35.f];
|
||||
case 2:
|
||||
return [UIFont ows_regularFontWithSize:30.f];
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
return [UIFont ows_regularFontWithSize:25.f];
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return [UIFont ows_dynamicTypeBodyFont];
|
||||
}
|
||||
|
||||
|
@ -627,6 +642,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
self.textView.text = self.displayableText.displayText;
|
||||
UIColor *textColor = [self textColor];
|
||||
self.textView.textColor = textColor;
|
||||
// Honor dynamic type in the message bodies.
|
||||
self.textView.font = [self textMessageFont];
|
||||
|
||||
// Don't link outgoing messages that haven't been sent yet, as
|
||||
|
@ -848,6 +864,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
const int maxTextWidth = (int)floor(maxMessageWidth - (leftMargin + rightMargin));
|
||||
|
||||
self.textView.text = self.displayableText.displayText;
|
||||
// Honor dynamic type in the message bodies.
|
||||
self.textView.font = [self textMessageFont];
|
||||
CGSize textSize = [self.textView sizeThatFits:CGSizeMake(maxTextWidth, CGFLOAT_MAX)];
|
||||
CGFloat tapForMoreHeight = (self.displayableText.isTextTruncated ? [self tapForMoreHeight] : 0.f);
|
||||
|
|
|
@ -323,8 +323,12 @@ NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType)
|
|||
displayText = @"";
|
||||
}
|
||||
|
||||
displayableText =
|
||||
[[DisplayableText alloc] initWithFullText:fullText displayText:displayText isTextTruncated:isTextTruncated];
|
||||
NSNumber *_Nullable jumbomojiCount = [DisplayableText jumbomojiCountTo:fullText];
|
||||
|
||||
displayableText = [[DisplayableText alloc] initWithFullText:fullText
|
||||
displayText:displayText
|
||||
isTextTruncated:isTextTruncated
|
||||
jumbomojiCount:jumbomojiCount];
|
||||
|
||||
[[self displayableTextCache] setObject:displayableText forKey:interactionId];
|
||||
}
|
||||
|
|
|
@ -11,13 +11,83 @@ import Foundation
|
|||
let fullText: String
|
||||
let displayText: String
|
||||
let isTextTruncated: Bool
|
||||
let jumbomojiCount: NSNumber?
|
||||
|
||||
static let kMaxJumbomojiCount: UInt = 5
|
||||
|
||||
// MARK: Initializers
|
||||
|
||||
init(fullText: String, displayText: String, isTextTruncated: Bool) {
|
||||
init(fullText: String, displayText: String, isTextTruncated: Bool, jumbomojiCount: NSNumber?) {
|
||||
self.fullText = fullText
|
||||
self.displayText = displayText
|
||||
self.isTextTruncated = isTextTruncated
|
||||
self.jumbomojiCount = jumbomojiCount
|
||||
}
|
||||
|
||||
// MARK: Emoji
|
||||
|
||||
private class func canDetectEmoji() -> Bool {
|
||||
if #available(iOS 10.0, *) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// If the string is...
|
||||
//
|
||||
// * Non-empty
|
||||
// * Only contains emoji
|
||||
// * Contains <= maxEmojiCount emoji
|
||||
//
|
||||
// ...return the number of emoji in the string. Otherwise return nil.
|
||||
//
|
||||
// On iOS 9 and earler, always returns nil.
|
||||
@objc public class func jumbomojiCount(to string: String) -> NSNumber? {
|
||||
if string == "" {
|
||||
return nil
|
||||
}
|
||||
if string.characters.count > Int(kMaxJumbomojiCount) {
|
||||
return nil
|
||||
}
|
||||
if !canDetectEmoji() {
|
||||
return nil
|
||||
}
|
||||
var didFail = false
|
||||
var emojiCount: UInt = 0
|
||||
let attributes = [NSFontAttributeName: UIFont.systemFont(ofSize:12)]
|
||||
let attributedString = NSMutableAttributedString(string: string, attributes: attributes)
|
||||
let range = NSRange(location: 0, length: string.characters.count)
|
||||
attributedString.fixAttributes(in: range)
|
||||
attributedString.enumerateAttribute(NSFontAttributeName,
|
||||
in: range,
|
||||
options: [],
|
||||
using: {(_ value: Any?, range: NSRange, stop: UnsafeMutablePointer<ObjCBool>) -> Void in
|
||||
guard emojiCount < kMaxJumbomojiCount else {
|
||||
didFail = true
|
||||
stop.pointee = true
|
||||
return
|
||||
}
|
||||
guard let rangeFont = value as? UIFont else {
|
||||
didFail = true
|
||||
stop.pointee = true
|
||||
return
|
||||
}
|
||||
guard rangeFont.fontName == ".AppleColorEmojiUI" else {
|
||||
didFail = true
|
||||
stop.pointee = true
|
||||
return
|
||||
}
|
||||
if rangeFont.fontName == ".AppleColorEmojiUI" {
|
||||
Logger.verbose("Detected Emoji at location: \(range.location), for length: \(range.length)")
|
||||
emojiCount += UInt(range.length)
|
||||
}
|
||||
})
|
||||
|
||||
guard !didFail else {
|
||||
return nil
|
||||
}
|
||||
return NSNumber(value: emojiCount)
|
||||
}
|
||||
|
||||
// MARK: Filter Methods
|
||||
|
|
Loading…
Reference in New Issue