mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios
This commit is contained in:
commit
27b412e351
@ -4,8 +4,8 @@ set -e
|
||||
|
||||
BUILD_TELEGRAM_VERSION="1"
|
||||
|
||||
MACOS_VERSION="11"
|
||||
XCODE_VERSION="13.2.1"
|
||||
MACOS_VERSION="12"
|
||||
XCODE_VERSION="13.4.1"
|
||||
GUEST_SHELL="bash"
|
||||
|
||||
VM_BASE_NAME="macos$(echo $MACOS_VERSION | sed -e 's/\.'/_/g)_Xcode$(echo $XCODE_VERSION | sed -e 's/\.'/_/g)"
|
||||
|
@ -6,7 +6,11 @@ set -x
|
||||
IPA_PATH="build/artifacts/Telegram.ipa"
|
||||
DSYM_PATH="build/artifacts/Telegram.DSYMs.zip"
|
||||
|
||||
APPCENTER="/usr/local/bin/appcenter"
|
||||
if [ `which appcenter` ]; then
|
||||
APPCENTER="$(which appcenter)"
|
||||
else
|
||||
APPCENTER="/usr/local/bin/appcenter"
|
||||
fi
|
||||
|
||||
$APPCENTER login --token "$API_TOKEN"
|
||||
|
||||
|
@ -375,6 +375,11 @@ public final class AnimatedStickerNode: ASDisplayNode {
|
||||
}
|
||||
|
||||
private var isSetUpForPlayback = false
|
||||
|
||||
public func playOnce() {
|
||||
self.playbackMode = .once
|
||||
self.play()
|
||||
}
|
||||
|
||||
public func play(firstFrame: Bool = false, fromIndex: Int? = nil) {
|
||||
if !firstFrame {
|
||||
|
@ -936,6 +936,7 @@ public final class MessageHistoryView {
|
||||
public let entries: [MessageHistoryEntry]
|
||||
public let maxReadIndex: MessageIndex?
|
||||
public let fixedReadStates: MessageHistoryViewReadState?
|
||||
public let transientReadStates: MessageHistoryViewReadState?
|
||||
public let topTaggedMessages: [Message]
|
||||
public let additionalData: [AdditionalMessageHistoryViewDataEntry]
|
||||
public let isLoading: Bool
|
||||
@ -952,6 +953,7 @@ public final class MessageHistoryView {
|
||||
self.entries = entries
|
||||
self.maxReadIndex = nil
|
||||
self.fixedReadStates = nil
|
||||
self.transientReadStates = nil
|
||||
self.topTaggedMessages = []
|
||||
self.additionalData = []
|
||||
self.isLoading = isLoading
|
||||
@ -1053,6 +1055,7 @@ public final class MessageHistoryView {
|
||||
self.additionalData = mutableView.additionalDatas
|
||||
|
||||
self.fixedReadStates = mutableView.combinedReadStates
|
||||
self.transientReadStates = mutableView.transientReadStates
|
||||
|
||||
switch mutableView.peerIds {
|
||||
case .single, .associated:
|
||||
|
@ -52,6 +52,11 @@ public enum ChatControllerInteractionReaction {
|
||||
case reaction(String)
|
||||
}
|
||||
|
||||
struct UnreadMessageRangeKey: Hashable {
|
||||
var peerId: PeerId
|
||||
var namespace: MessageId.Namespace
|
||||
}
|
||||
|
||||
public final class ChatControllerInteraction {
|
||||
let openMessage: (Message, ChatControllerInteractionOpenMessageMode) -> Bool
|
||||
let openPeer: (PeerId?, ChatControllerInteractionNavigateToPeer, MessageReference?, Peer?) -> Void
|
||||
@ -149,6 +154,7 @@ public final class ChatControllerInteraction {
|
||||
var currentPsaMessageWithTooltip: MessageId?
|
||||
var stickerSettings: ChatInterfaceStickerSettings
|
||||
var searchTextHighightState: (String, [MessageIndex])?
|
||||
var unreadMessageRange: [UnreadMessageRangeKey: Range<MessageId.Id>] = [:]
|
||||
var seenOneTimeAnimatedMedia = Set<MessageId>()
|
||||
var currentMessageWithLoadingReplyThread: MessageId?
|
||||
var updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?
|
||||
|
@ -2435,7 +2435,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
for text in breakChatInputText(trimChatInputText(inputText)) {
|
||||
if text.length != 0 {
|
||||
var attributes: [MessageAttribute] = []
|
||||
let entities = generateTextEntities(text.string, enabledTypes: .all, currentEntities: generateChatInputTextEntities(text, maxAnimatedEmojisInText: Int(self.context.userLimits.maxAnimatedEmojisInText)))
|
||||
let entities = generateTextEntities(text.string, enabledTypes: .all, currentEntities: generateChatInputTextEntities(text, maxAnimatedEmojisInText: 0/*Int(self.context.userLimits.maxAnimatedEmojisInText)*/))
|
||||
if !entities.isEmpty {
|
||||
attributes.append(TextEntitiesMessageAttribute(entities: entities))
|
||||
}
|
||||
|
@ -1309,31 +1309,35 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
|
||||
let previousMaxIncomingMessageIndexByNamespace = Atomic<[MessageId.Namespace: MessageIndex]>(value: [:])
|
||||
let readHistory = combineLatest(self.maxVisibleIncomingMessageIndex.get(), self.canReadHistory.get())
|
||||
|> map { messageIndex, canRead in
|
||||
if canRead {
|
||||
var apply = false
|
||||
let _ = previousMaxIncomingMessageIndexByNamespace.modify { dict in
|
||||
let previousIndex = dict[messageIndex.id.namespace]
|
||||
if previousIndex == nil || previousIndex! < messageIndex {
|
||||
apply = true
|
||||
var dict = dict
|
||||
dict[messageIndex.id.namespace] = messageIndex
|
||||
return dict
|
||||
}
|
||||
|
||||
self.readHistoryDisposable.set((readHistory |> deliverOnMainQueue).start(next: { [weak self] messageIndex, canRead in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
if !canRead {
|
||||
return
|
||||
}
|
||||
|
||||
var apply = false
|
||||
let _ = previousMaxIncomingMessageIndexByNamespace.modify { dict in
|
||||
let previousIndex = dict[messageIndex.id.namespace]
|
||||
if previousIndex == nil || previousIndex! < messageIndex {
|
||||
apply = true
|
||||
var dict = dict
|
||||
dict[messageIndex.id.namespace] = messageIndex
|
||||
return dict
|
||||
}
|
||||
if apply {
|
||||
switch chatLocation {
|
||||
case .peer, .replyThread, .feed:
|
||||
if !context.sharedContext.immediateExperimentalUISettings.skipReadHistory {
|
||||
context.applyMaxReadIndex(for: chatLocation, contextHolder: chatLocationContextHolder, messageIndex: messageIndex)
|
||||
}
|
||||
return dict
|
||||
}
|
||||
if apply {
|
||||
switch chatLocation {
|
||||
case .peer, .replyThread, .feed:
|
||||
if !strongSelf.context.sharedContext.immediateExperimentalUISettings.skipReadHistory {
|
||||
strongSelf.context.applyMaxReadIndex(for: chatLocation, contextHolder: chatLocationContextHolder, messageIndex: messageIndex)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.readHistoryDisposable.set(readHistory.start())
|
||||
}))
|
||||
|
||||
self.canReadHistoryDisposable = (self.canReadHistory.get() |> deliverOnMainQueue).start(next: { [weak self, weak context] value in
|
||||
if let strongSelf = self {
|
||||
@ -2157,6 +2161,14 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
return result
|
||||
}
|
||||
|
||||
public func forEachVisibleMessageItemNode(_ f: (ChatMessageItemView) -> Void) {
|
||||
self.forEachVisibleItemNode { itemNode in
|
||||
if let itemNode = itemNode as? ChatMessageItemView {
|
||||
f(itemNode)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func latestMessageInCurrentHistoryView() -> Message? {
|
||||
if let historyView = self.historyView {
|
||||
if historyView.originalView.laterId == nil, let firstEntry = historyView.filteredEntries.last {
|
||||
@ -2369,6 +2381,42 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
}
|
||||
}
|
||||
|
||||
var unreadMessageRangeUpdated = false
|
||||
|
||||
if case let .peer(peerId) = strongSelf.chatLocation, let previousReadStatesValue = strongSelf.historyView?.originalView.transientReadStates, case let .peer(previousReadStates) = previousReadStatesValue, case let .peer(updatedReadStates) = transition.historyView.originalView.transientReadStates {
|
||||
if let previousPeerReadState = previousReadStates[peerId], let updatedPeerReadState = updatedReadStates[peerId] {
|
||||
if previousPeerReadState != updatedPeerReadState {
|
||||
for (namespace, state) in previousPeerReadState.states {
|
||||
inner: for (updatedNamespace, updatedState) in updatedPeerReadState.states {
|
||||
if namespace == updatedNamespace {
|
||||
switch state {
|
||||
case let .idBased(previousIncomingId, _, _, _, _):
|
||||
if case let .idBased(updatedIncomingId, _, _, _, _) = updatedState, previousIncomingId <= updatedIncomingId {
|
||||
let rangeKey = UnreadMessageRangeKey(peerId: peerId, namespace: namespace)
|
||||
|
||||
if let currentRange = strongSelf.controllerInteraction.unreadMessageRange[rangeKey] {
|
||||
if currentRange.upperBound < (updatedIncomingId + 1) {
|
||||
strongSelf.controllerInteraction.unreadMessageRange[UnreadMessageRangeKey(peerId: peerId, namespace: namespace)] = currentRange.lowerBound ..< (updatedIncomingId + 1)
|
||||
unreadMessageRangeUpdated = true
|
||||
}
|
||||
} else {
|
||||
strongSelf.controllerInteraction.unreadMessageRange[rangeKey] = (previousIncomingId + 1) ..< (updatedIncomingId + 1)
|
||||
unreadMessageRangeUpdated = true
|
||||
}
|
||||
}
|
||||
case .indexBased:
|
||||
break
|
||||
}
|
||||
|
||||
break inner
|
||||
}
|
||||
}
|
||||
}
|
||||
//print("Read from \(previousPeerReadState) up to \(updatedPeerReadState)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
strongSelf.historyView = transition.historyView
|
||||
|
||||
let loadState: ChatHistoryNodeLoadState
|
||||
@ -2541,6 +2589,12 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
}
|
||||
}
|
||||
|
||||
if unreadMessageRangeUpdated {
|
||||
strongSelf.forEachVisibleMessageItemNode { itemNode in
|
||||
itemNode.unreadMessageRangeUpdated()
|
||||
}
|
||||
}
|
||||
|
||||
strongSelf.hasActiveTransition = false
|
||||
strongSelf.dequeueHistoryViewTransitions()
|
||||
}
|
||||
|
@ -218,6 +218,9 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
|
||||
private var currentSwipeAction: ChatControllerInteractionSwipeAction?
|
||||
|
||||
private var wasPending: Bool = false
|
||||
private var didChangeFromPendingToSent: Bool = false
|
||||
|
||||
required init() {
|
||||
self.contextSourceNode = ContextExtractedContentContainingNode()
|
||||
self.containerNode = ContextControllerSourceNode()
|
||||
@ -470,6 +473,13 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
|
||||
override func setupItem(_ item: ChatMessageItem, synchronousLoad: Bool) {
|
||||
super.setupItem(item, synchronousLoad: synchronousLoad)
|
||||
|
||||
if item.message.id.namespace == Namespaces.Message.Local {
|
||||
self.wasPending = true
|
||||
}
|
||||
if self.wasPending && item.message.id.namespace != Namespaces.Message.Local {
|
||||
self.didChangeFromPendingToSent = true
|
||||
}
|
||||
|
||||
for media in item.message.media {
|
||||
if let telegramFile = media as? TelegramMediaFile {
|
||||
@ -526,7 +536,6 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
self.imageNode.setSignal(chatMessageAnimatedSticker(postbox: item.context.account.postbox, file: emojiFile, small: false, size: dimensions.cgSize.aspectFilled(CGSize(width: 384.0, height: 384.0)), fitzModifier: fitzModifier, thumbnail: false, synchronousLoad: synchronousLoad), attemptSynchronously: synchronousLoad)
|
||||
self.disposable.set(freeMediaFileInteractiveFetched(account: item.context.account, fileReference: .standalone(media: emojiFile)).start())
|
||||
}
|
||||
self.updateVisibility()
|
||||
|
||||
let textEmoji = item.message.text.strippedEmoji
|
||||
var additionalTextEmoji = textEmoji
|
||||
@ -551,6 +560,8 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.updateVisibility()
|
||||
}
|
||||
|
||||
private func updateVisibility() {
|
||||
@ -558,6 +569,30 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
return
|
||||
}
|
||||
|
||||
var file: TelegramMediaFile?
|
||||
var playbackMode: AnimatedStickerPlaybackMode = .loop
|
||||
var isEmoji = false
|
||||
var fitzModifier: EmojiFitzModifier?
|
||||
|
||||
if let telegramFile = self.telegramFile {
|
||||
file = telegramFile
|
||||
if !item.controllerInteraction.stickerSettings.loopAnimatedStickers {
|
||||
playbackMode = .once
|
||||
}
|
||||
} else if let emojiFile = self.emojiFile {
|
||||
isEmoji = true
|
||||
file = emojiFile
|
||||
//if alreadySeen && emojiFile.resource is LocalFileReferenceMediaResource {
|
||||
playbackMode = .still(.end)
|
||||
//} else {
|
||||
// playbackMode = .once
|
||||
//}
|
||||
let (_, fitz) = item.message.text.basicEmoji
|
||||
if let fitz = fitz {
|
||||
fitzModifier = EmojiFitzModifier(emoji: fitz)
|
||||
}
|
||||
}
|
||||
|
||||
let isPlaying = self.visibilityStatus && !self.forceStopAnimations
|
||||
if let animationNode = self.animationNode as? AnimatedStickerNode {
|
||||
if !isPlaying {
|
||||
@ -583,51 +618,20 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
if self.isPlaying != isPlaying {
|
||||
self.isPlaying = isPlaying
|
||||
|
||||
var alreadySeen = false
|
||||
if isPlaying, let _ = self.emojiFile {
|
||||
if item.controllerInteraction.seenOneTimeAnimatedMedia.contains(item.message.id) {
|
||||
alreadySeen = true
|
||||
}
|
||||
}
|
||||
|
||||
if isPlaying && self.setupTimestamp == nil {
|
||||
self.setupTimestamp = CACurrentMediaTime()
|
||||
}
|
||||
animationNode.visibility = isPlaying
|
||||
|
||||
if self.didSetUpAnimationNode && alreadySeen {
|
||||
/*if self.didSetUpAnimationNode && alreadySeen {
|
||||
if let emojiFile = self.emojiFile, emojiFile.resource is LocalFileReferenceMediaResource {
|
||||
} else {
|
||||
animationNode.seekTo(.start)
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
if self.isPlaying && !self.didSetUpAnimationNode {
|
||||
self.didSetUpAnimationNode = true
|
||||
|
||||
var file: TelegramMediaFile?
|
||||
var playbackMode: AnimatedStickerPlaybackMode = .loop
|
||||
var isEmoji = false
|
||||
var fitzModifier: EmojiFitzModifier?
|
||||
|
||||
if let telegramFile = self.telegramFile {
|
||||
file = telegramFile
|
||||
if !item.controllerInteraction.stickerSettings.loopAnimatedStickers {
|
||||
playbackMode = .once
|
||||
}
|
||||
} else if let emojiFile = self.emojiFile {
|
||||
isEmoji = true
|
||||
file = emojiFile
|
||||
if alreadySeen && emojiFile.resource is LocalFileReferenceMediaResource {
|
||||
playbackMode = .still(.end)
|
||||
} else {
|
||||
playbackMode = .once
|
||||
}
|
||||
let (_, fitz) = item.message.text.basicEmoji
|
||||
if let fitz = fitz {
|
||||
fitzModifier = EmojiFitzModifier(emoji: fitz)
|
||||
}
|
||||
}
|
||||
|
||||
if let file = file {
|
||||
let dimensions = file.dimensions ?? PixelDimensions(width: 512, height: 512)
|
||||
@ -637,15 +641,39 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
let mode: AnimatedStickerMode = .direct(cachePathPrefix: pathPrefix)
|
||||
self.animationSize = fittedSize
|
||||
animationNode.setup(source: AnimatedStickerResourceSource(account: item.context.account, resource: file.resource, fitzModifier: fitzModifier, isVideo: file.isVideoSticker), width: Int(fittedSize.width), height: Int(fittedSize.height), playbackMode: playbackMode, mode: mode)
|
||||
|
||||
if file.isPremiumSticker && !alreadySeen {
|
||||
item.controllerInteraction.seenOneTimeAnimatedMedia.insert(item.message.id)
|
||||
Queue.mainQueue().after(0.1) {
|
||||
self.playPremiumStickerAnimation()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if isPlaying, let animationNode = self.animationNode as? AnimatedStickerNode {
|
||||
var alreadySeen = true
|
||||
if item.message.flags.contains(.Incoming) {
|
||||
if let unreadRange = item.controllerInteraction.unreadMessageRange[UnreadMessageRangeKey(peerId: item.message.id.peerId, namespace: item.message.id.namespace)] {
|
||||
if unreadRange.contains(item.message.id.id) {
|
||||
if !item.controllerInteraction.seenOneTimeAnimatedMedia.contains(item.message.id) {
|
||||
alreadySeen = false
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if self.didChangeFromPendingToSent {
|
||||
if !item.controllerInteraction.seenOneTimeAnimatedMedia.contains(item.message.id) {
|
||||
alreadySeen = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !alreadySeen {
|
||||
item.controllerInteraction.seenOneTimeAnimatedMedia.insert(item.message.id)
|
||||
if let file = file, file.isPremiumSticker {
|
||||
Queue.mainQueue().after(0.1) {
|
||||
self.playPremiumStickerAnimation()
|
||||
}
|
||||
} else if isEmoji {
|
||||
animationNode.seekTo(.start)
|
||||
animationNode.playOnce()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -655,7 +683,6 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
self.updateVisibility()
|
||||
}
|
||||
|
||||
|
||||
private var absoluteRect: (CGRect, CGSize)?
|
||||
override func updateAbsoluteRect(_ rect: CGRect, within containerSize: CGSize) {
|
||||
self.absoluteRect = (rect, containerSize)
|
||||
@ -2382,6 +2409,10 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
override func unreadMessageRangeUpdated() {
|
||||
self.updateVisibility()
|
||||
}
|
||||
}
|
||||
|
||||
struct AnimatedEmojiSoundsConfiguration {
|
||||
|
@ -898,4 +898,7 @@ public class ChatMessageItemView: ListViewItemNode, ChatMessageItemNodeProtocol
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func unreadMessageRangeUpdated() {
|
||||
}
|
||||
}
|
||||
|
@ -341,7 +341,7 @@ class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode {
|
||||
attributedText = NSAttributedString(string: " ", font: textFont, textColor: messageTheme.primaryTextColor)
|
||||
}
|
||||
|
||||
if let entities = entities {
|
||||
/*if let entities = entities {
|
||||
let updatedString = NSMutableAttributedString(attributedString: attributedText)
|
||||
|
||||
for entity in entities.sorted(by: { $0.range.lowerBound > $1.range.lowerBound }) {
|
||||
@ -368,48 +368,11 @@ class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode {
|
||||
updatedAttributes[NSAttributedString.Key("Attribute__EmbeddedItem")] = InlineStickerItem(file: emojiFile)
|
||||
|
||||
let insertString = NSAttributedString(string: "[\u{00a0}\u{00a0}]", attributes: updatedAttributes)
|
||||
//updatedString.insert(insertString, at: NSRange(substringRange, in: updatedString.string).upperBound)
|
||||
updatedString.replaceCharacters(in: range, with: insertString)
|
||||
}
|
||||
|
||||
/*var currentCount = 0
|
||||
let updatedString = NSMutableAttributedString(attributedString: attributedText)
|
||||
var startIndex = updatedString.string.startIndex
|
||||
while true {
|
||||
var hadUpdates = false
|
||||
updatedString.string.enumerateSubstrings(in: startIndex ..< updatedString.string.endIndex, options: [.byComposedCharacterSequences]) { substring, substringRange, _, stop in
|
||||
if let substring = substring {
|
||||
let emoji = substring.basicEmoji.0
|
||||
|
||||
var emojiFile: TelegramMediaFile?
|
||||
emojiFile = item.associatedData.animatedEmojiStickers[emoji]?.first?.file
|
||||
if emojiFile == nil {
|
||||
emojiFile = item.associatedData.animatedEmojiStickers[emoji.strippedEmoji]?.first?.file
|
||||
}
|
||||
|
||||
if let emojiFile = emojiFile {
|
||||
let currentDict = updatedString.attributes(at: NSRange(substringRange, in: updatedString.string).lowerBound, effectiveRange: nil)
|
||||
var updatedAttributes: [NSAttributedString.Key: Any] = currentDict
|
||||
updatedAttributes[NSAttributedString.Key.foregroundColor] = UIColor.clear.cgColor
|
||||
updatedAttributes[NSAttributedString.Key("Attribute__EmbeddedItem")] = InlineStickerItem(file: emojiFile)
|
||||
|
||||
let insertString = NSAttributedString(string: "[\u{00a0}\u{00a0}\u{00a0}]", attributes: updatedAttributes)
|
||||
//updatedString.insert(insertString, at: NSRange(substringRange, in: updatedString.string).upperBound)
|
||||
updatedString.replaceCharacters(in: NSRange(substringRange, in: updatedString.string), with: insertString)
|
||||
startIndex = substringRange.lowerBound
|
||||
currentCount += 1
|
||||
hadUpdates = true
|
||||
stop = true
|
||||
}
|
||||
}
|
||||
}
|
||||
if !hadUpdates || currentCount >= 10 {
|
||||
break
|
||||
}
|
||||
}*/
|
||||
}
|
||||
attributedText = updatedString
|
||||
}
|
||||
}*/
|
||||
|
||||
let cutout: TextNodeCutout? = nil
|
||||
|
||||
|
@ -146,7 +146,7 @@ private func commitEntity(_ utf16: String.UTF16View, _ type: CurrentEntityType,
|
||||
public func generateChatInputTextEntities(_ text: NSAttributedString, maxAnimatedEmojisInText: Int? = nil) -> [MessageTextEntity] {
|
||||
var entities: [MessageTextEntity] = []
|
||||
|
||||
if let maxAnimatedEmojisInText = maxAnimatedEmojisInText {
|
||||
if let maxAnimatedEmojisInText = maxAnimatedEmojisInText, maxAnimatedEmojisInText != 0 {
|
||||
var count = 0
|
||||
text.string.enumerateSubstrings(in: text.string.startIndex ..< text.string.endIndex, options: [.byComposedCharacterSequences], { substring, substringRange, _, stop in
|
||||
if let substring = substring {
|
||||
@ -159,10 +159,7 @@ public func generateChatInputTextEntities(_ text: NSAttributedString, maxAnimate
|
||||
|
||||
count += 1
|
||||
if count >= maxAnimatedEmojisInText {
|
||||
#if DEBUG
|
||||
#else
|
||||
stop = true
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"app": "8.7.2",
|
||||
"bazel": "5.1.0",
|
||||
"xcode": "13.2.1"
|
||||
"xcode": "13.4.1"
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user