Fixed emoji determination

This commit is contained in:
Ilya Laktyushin 2019-05-06 01:36:10 +02:00
parent 1b7f876c3f
commit 69a824f26a
6 changed files with 83 additions and 46 deletions

View File

@ -39,7 +39,7 @@ enum ChatHistoryEntry: Identifiable, Comparable {
switch self {
case let .MessageEntry(message, presentationData, _, _, _, _):
var type = 2
if presentationData.largeEmoji && message.elligibleForLargeEmoji {
if presentationData.largeEmoji && message.elligibleForLargeEmoji && messageTextIsElligibleForLargeEmoji(message.text) {
type = 3
}
return UInt64(message.stableId) | ((UInt64(type) << 40))

View File

@ -724,11 +724,13 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
switch contentData {
case let .chat(itemPeer, peer, _, messageText):
let messageText = messageText.replacingOccurrences(of: "\n\n", with: " ")
if inlineAuthorPrefix == nil, let embeddedState = embeddedState as? ChatEmbeddedInterfaceState {
hasDraft = true
authorAttributedString = NSAttributedString(string: item.presentationData.strings.DialogList_Draft, font: textFont, textColor: theme.messageDraftTextColor)
attributedText = NSAttributedString(string: embeddedState.text.string, font: textFont, textColor: theme.messageTextColor)
attributedText = NSAttributedString(string: embeddedState.text.string.replacingOccurrences(of: "\n\n", with: " "), font: textFont, textColor: theme.messageTextColor)
} else if let message = message {
if let inlineAuthorPrefix = inlineAuthorPrefix {
let composedString = NSMutableAttributedString()

View File

@ -352,7 +352,7 @@ public final class ChatMessageItem: ListViewItem, CustomStringConvertible {
}
}
if self.presentationData.largeEmoji && self.message.elligibleForLargeEmoji && viewClassName == ChatMessageBubbleItemNode.self {
if viewClassName == ChatMessageBubbleItemNode.self && self.presentationData.largeEmoji && self.message.elligibleForLargeEmoji && messageTextIsElligibleForLargeEmoji(message.text) {
viewClassName = ChatMessageStickerItemNode.self
}

View File

@ -192,17 +192,26 @@ private func matchingEmojiEntry(_ emoji: String) -> (UInt8, UInt8, UInt8)? {
return nil
}
func messageTextIsElligibleForLargeEmoji(_ emoji: String) -> Bool {
for emoji in emoji.emojis {
if let _ = matchingEmojiEntry(emoji) {
} else {
return false
}
}
return true
}
func largeEmoji(postbox: Postbox, emoji: String, outline: Bool = true) -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> {
var dataSignals: [Signal<MediaResourceData, NoError>] = []
for emoji in emoji.emojis {
let thumbnailResource = EmojiThumbnailResource(emoji: emoji)
let thumbnailRepresentation = CachedEmojiThumbnailRepresentation(outline: outline)
let thumbnailSignal = postbox.mediaBox.cachedResourceRepresentation(thumbnailResource, representation: thumbnailRepresentation, complete: true, fetch: true)
if let entry = matchingEmojiEntry(emoji) {
let thumbnailResource = EmojiThumbnailResource(emoji: emoji)
let thumbnailRepresentation = CachedEmojiThumbnailRepresentation(outline: outline)
let spriteResource = EmojiSpriteResource(packId: entry.0, stickerId: entry.1)
let representation = CachedEmojiRepresentation(tile: entry.2, outline: outline)
let thumbnailSignal = postbox.mediaBox.cachedResourceRepresentation(thumbnailResource, representation: thumbnailRepresentation, complete: true, fetch: true)
let signal: Signal<MediaResourceData?, NoError> = .single(nil) |> then(postbox.mediaBox.cachedResourceRepresentation(spriteResource, representation: representation, complete: true, fetch: true) |> map(Optional.init))
let dataSignal = thumbnailSignal
@ -217,6 +226,8 @@ func largeEmoji(postbox: Postbox, emoji: String, outline: Bool = true) -> Signal
}
}
dataSignals.append(dataSignal)
} else {
dataSignals.append(thumbnailSignal)
}
}

View File

@ -3,20 +3,28 @@ import CoreText
extension UnicodeScalar {
var isEmoji: Bool {
switch value {
switch self.value {
case 0x1F600...0x1F64F, // Emoticons
0x1F300...0x1F5FF, // Misc Symbols and Pictographs
0x1F680...0x1F6FF, // Transport and Map
0x1F1E6...0x1F1FF, // Regional country flags
0x2600...0x26FF, // Misc symbols
0x2700...0x27BF, // Dingbats
0xE0020...0xE007F, // Tags
0xFE00...0xFE0F, // Variation Selectors
0x1F900...0x1F9FF, // Supplemental Symbols and Pictographs
127000...127600, // Various asian characters
65024...65039, // Variation selector
9100...9300, // Misc items
8400...8447: // Combining Diacritical Marks for Symbols
0x1F300...0x1F5FF, // Misc Symbols and Pictographs
0x1F680...0x1F6FF, // Transport and Map
0x1F1E6...0x1F1FF, // Regional country flags
0xE0020...0xE007F, // Tags
0xFE00...0xFE0F, // Variation Selectors
0x1F900...0x1F9FF, // Supplemental Symbols and Pictographs
127000...127600, // Various asian characters
65024...65039, // Variation selector
9100...9300, // Misc items
8400...8447: // Combining Diacritical Marks for Symbols
return true
default:
return false
}
}
var maybeEmoji: Bool {
switch self.value {
case 0x2600...0x26FF, // Misc symbols
0x2700...0x27BF: // Dingbats
return true
default:
return false
@ -24,7 +32,7 @@ extension UnicodeScalar {
}
var isZeroWidthJoiner: Bool {
return value == 8205
return self.value == 8205
}
}
@ -37,34 +45,44 @@ extension String {
return t
}
var glyphCount: Int {
let richText = NSAttributedString(string: self)
let line = CTLineCreateWithAttributedString(richText)
return CTLineGetGlyphCount(line)
}
var isSingleEmoji: Bool {
return glyphCount == 1 && containsEmoji
return self.emojis.count == 1 && self.containsEmoji
}
var containsEmoji: Bool {
return unicodeScalars.contains { $0.isEmoji }
return self.unicodeScalars.contains { $0.isEmoji }
}
var containsOnlyEmoji: Bool {
return !isEmpty && !unicodeScalars.contains(where: {
!$0.isEmoji && !$0.isZeroWidthJoiner
})
guard !self.isEmpty else {
return false
}
var nextShouldBeFE0F = false
for scalar in self.unicodeScalars {
if nextShouldBeFE0F {
if scalar.value == 0xfe0f {
nextShouldBeFE0F = false
continue
} else {
return false
}
}
if scalar.maybeEmoji {
nextShouldBeFE0F = true
}
else if !scalar.isEmoji && !scalar.isZeroWidthJoiner {
return false
}
}
return !nextShouldBeFE0F
}
// The next tricks are mostly to demonstrate how tricky it can be to determine emoji's
// If anyone has suggestions how to improve this, please let me know
var emojiString: String {
return emojiScalars.map { String($0) }.reduce("", +)
return self.emojiScalars.map { String($0) }.reduce("", +)
}
var firstEmoji: String {
if let first = emojiScalars.first {
if let first = self.emojiScalars.first {
return String(first)
} else {
return ""
@ -84,7 +102,7 @@ extension String {
fileprivate var emojiScalars: [UnicodeScalar] {
var chars: [UnicodeScalar] = []
var previous: UnicodeScalar?
for cur in unicodeScalars {
for cur in self.unicodeScalars {
if let previous = previous, previous.isZeroWidthJoiner && cur.isEmoji {
chars.append(previous)
chars.append(cur)

View File

@ -158,15 +158,24 @@ final class PasscodeEntryControllerNode: ASDisplayNode {
return
}
var size = validLayout.size
if case .compact = validLayout.metrics.widthClass, size.width > size.height {
size = CGSize(width: size.height, height: size.width)
}
if let background = self.background, background.size == size {
return
}
switch self.wallpaper {
case .image, .file:
if let image = chatControllerBackgroundImage(wallpaper: self.wallpaper, mediaBox: self.context.sharedContext.accountManager.mediaBox, composed: false) {
self.background = ImageBasedPasscodeBackground(image: image, size: validLayout.size)
self.background = ImageBasedPasscodeBackground(image: image, size: size)
} else {
self.background = DefaultPasscodeBackground(size: validLayout.size)
self.background = DefaultPasscodeBackground(size: size)
}
default:
self.background = DefaultPasscodeBackground(size: validLayout.size)
self.background = DefaultPasscodeBackground(size: size)
}
if let background = self.background {
@ -313,12 +322,9 @@ final class PasscodeEntryControllerNode: ASDisplayNode {
}
func containerLayoutUpdated(_ layout: ContainerViewLayout, navigationBarHeight: CGFloat, transition: ContainedViewLayoutTransition) {
let hadValidLayout = self.validLayout != nil
self.validLayout = layout
if !hadValidLayout {
self.updateBackground()
}
self.updateBackground()
if layout.size.width == 320.0 {
self.iconNode.alpha = 0.0