Swiftgram/TelegramUI/EmojiUtils.swift
2019-05-06 01:37:51 +02:00

119 lines
3.3 KiB
Swift

import Foundation
import CoreText
extension UnicodeScalar {
var isEmoji: Bool {
switch self.value {
case 0x1F600...0x1F64F, // Emoticons
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
}
}
var isZeroWidthJoiner: Bool {
return self.value == 8205
}
}
extension String {
func trimmingTrailingSpaces() -> String {
var t = self
while t.hasSuffix(" ") {
t = "" + t.dropLast()
}
return t
}
var isSingleEmoji: Bool {
return self.emojis.count == 1 && self.containsEmoji
}
var containsEmoji: Bool {
return self.unicodeScalars.contains { $0.isEmoji }
}
var containsOnlyEmoji: Bool {
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
}
var emojiString: String {
return self.emojiScalars.map { String($0) }.reduce("", +)
}
var firstEmoji: String {
if let first = self.emojiScalars.first {
return String(first)
} else {
return ""
}
}
var emojis: [String] {
var emojis: [String] = []
self.enumerateSubstrings(in: self.startIndex ..< self.endIndex, options: .byComposedCharacterSequences) { substring, _, _, _ in
if let substring = substring {
emojis.append(substring)
}
}
return emojis
}
fileprivate var emojiScalars: [UnicodeScalar] {
var chars: [UnicodeScalar] = []
var previous: UnicodeScalar?
for cur in self.unicodeScalars {
if let previous = previous, previous.isZeroWidthJoiner && cur.isEmoji {
chars.append(previous)
chars.append(cur)
} else if cur.isEmoji {
chars.append(cur)
}
previous = cur
}
return chars
}
}