// // SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors // SPDX-License-Identifier: GPL-3.0-or-later // import Foundation // based on https://stackoverflow.com/a/39425959/2512312 extension Character { /// A simple emoji is one scalar and presented to the user as an Emoji var isSimpleEmoji: Bool { guard let firstScalar = unicodeScalars.first else { return false } return firstScalar.properties.isEmoji && firstScalar.value > 0x238C } /// Checks if the scalars will be merged into an emoji var isCombinedIntoEmoji: Bool { unicodeScalars.count > 1 && unicodeScalars.first?.properties.isEmoji ?? false } var isEmoji: Bool { isSimpleEmoji || isCombinedIntoEmoji } } extension String { var isSingleEmoji: Bool { count == 1 && containsEmoji } var containsEmoji: Bool { contains { $0.isEmoji } } var containsOnlyEmoji: Bool { !isEmpty && !contains { !$0.isEmoji } } var emojiString: String { emojis.map { String($0) }.reduce("", +) } var emojis: [Character] { filter { $0.isEmoji } } var emojiScalars: [UnicodeScalar] { filter { $0.isEmoji }.flatMap { $0.unicodeScalars } } } extension UIView { // https://stackoverflow.com/a/41288197 // Using a function since `var image` might conflict with an existing variable // (like on `UIImageView`) func asImage() -> UIImage { let renderer = UIGraphicsImageRenderer(bounds: bounds) return renderer.image { rendererContext in layer.render(in: rendererContext.cgContext) } } } @objc extension NSString { public var containsOnlyEmoji: Bool { let str = self as String return str.containsOnlyEmoji } public var isSingleEmoji: Bool { let str = self as String return str.isSingleEmoji } public var emojiCount: Int { let str = self as String return str.emojis.count } }