Emoji improvements

This commit is contained in:
Ali 2022-09-01 03:12:43 +04:00
parent 79ffa2d2f0
commit 93cb743468
73 changed files with 532 additions and 430 deletions

View File

@ -369,7 +369,7 @@ public struct ChatTextInputStateText: Codable, Equatable {
} else if key == ChatTextInputAttributes.textUrl, let value = value as? ChatTextInputTextUrlAttribute {
parsedAttributes.append(ChatTextInputStateTextAttribute(type: .textUrl(value.url), range: range.location ..< (range.location + range.length)))
} else if key == ChatTextInputAttributes.customEmoji, let value = value as? ChatTextInputTextCustomEmojiAttribute {
parsedAttributes.append(ChatTextInputStateTextAttribute(type: .customEmoji(stickerPack: value.stickerPack, fileId: value.fileId), range: range.location ..< (range.location + range.length)))
parsedAttributes.append(ChatTextInputStateTextAttribute(type: .customEmoji(stickerPack: nil, fileId: value.fileId), range: range.location ..< (range.location + range.length)))
}
}
})
@ -406,8 +406,8 @@ public struct ChatTextInputStateText: Codable, Equatable {
result.addAttribute(ChatTextInputAttributes.textMention, value: ChatTextInputTextMentionAttribute(peerId: id), range: NSRange(location: attribute.range.lowerBound, length: attribute.range.count))
case let .textUrl(url):
result.addAttribute(ChatTextInputAttributes.textUrl, value: ChatTextInputTextUrlAttribute(url: url), range: NSRange(location: attribute.range.lowerBound, length: attribute.range.count))
case let .customEmoji(stickerPack, fileId):
result.addAttribute(ChatTextInputAttributes.customEmoji, value: ChatTextInputTextCustomEmojiAttribute(stickerPack: stickerPack, fileId: fileId, file: nil), range: NSRange(location: attribute.range.lowerBound, length: attribute.range.count))
case let .customEmoji(_, fileId):
result.addAttribute(ChatTextInputAttributes.customEmoji, value: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: fileId, file: nil), range: NSRange(location: attribute.range.lowerBound, length: attribute.range.count))
}
}
return result

View File

@ -603,7 +603,7 @@ final class AttachmentPanel: ASDisplayNode, UIScrollViewDelegate {
}, displayVideoUnmuteTip: { _ in
}, switchMediaRecordingMode: {
}, setupMessageAutoremoveTimeout: {
}, sendSticker: { _, _, _, _, _ in
}, sendSticker: { _, _, _, _, _, _ in
return false
}, unblockPeer: {
}, pinMessage: { _, _ in

View File

@ -1214,7 +1214,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
if !entities.isEmpty {
attributes.append(TextEntitiesMessageAttribute(entities: entities))
}
result.append(.message(text: text.string, attributes: attributes, inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil))
result.append(.message(text: text.string, attributes: attributes, inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []))
}
}
}

View File

@ -384,7 +384,7 @@ final class ChatListTitleView: UIView, NavigationBarTitleView, NavigationBarTitl
containerSize: CGSize(width: 22.0, height: 22.0)
)
titleCredibilityIconTransition.setFrame(view: titleCredibilityIconView, frame: CGRect(origin: CGPoint(x: titleFrame.maxX + 2.0, y: floorToScreenPixels(titleFrame.midY - titleIconSize.height / 2.0)), size: titleIconSize))
titleCredibilityIconView.isHidden = self.title.activity
titleCredibilityIconView.alpha = self.title.activity ? 0.0 : 1.0
} else {
if let titleCredibilityIconView = self.titleCredibilityIconView {
self.titleCredibilityIconView = nil

View File

@ -99,7 +99,7 @@ public final class ChatPanelInterfaceInteraction {
public let displayVideoUnmuteTip: (CGPoint?) -> Void
public let switchMediaRecordingMode: () -> Void
public let setupMessageAutoremoveTimeout: () -> Void
public let sendSticker: (FileMediaReference, Bool, UIView, CGRect, CALayer?) -> Bool
public let sendSticker: (FileMediaReference, Bool, UIView, CGRect, CALayer?, [ItemCollectionId]) -> Bool
public let unblockPeer: () -> Void
public let pinMessage: (MessageId, ContextControllerProtocol?) -> Void
public let unpinMessage: (MessageId, Bool, ContextControllerProtocol?) -> Void
@ -195,7 +195,7 @@ public final class ChatPanelInterfaceInteraction {
displayVideoUnmuteTip: @escaping (CGPoint?) -> Void,
switchMediaRecordingMode: @escaping () -> Void,
setupMessageAutoremoveTimeout: @escaping () -> Void,
sendSticker: @escaping (FileMediaReference, Bool, UIView, CGRect, CALayer?) -> Bool,
sendSticker: @escaping (FileMediaReference, Bool, UIView, CGRect, CALayer?, [ItemCollectionId]) -> Bool,
unblockPeer: @escaping () -> Void,
pinMessage: @escaping (MessageId, ContextControllerProtocol?) -> Void,
unpinMessage: @escaping (MessageId, Bool, ContextControllerProtocol?) -> Void,
@ -392,7 +392,7 @@ public final class ChatPanelInterfaceInteraction {
}, displayVideoUnmuteTip: { _ in
}, switchMediaRecordingMode: {
}, setupMessageAutoremoveTimeout: {
}, sendSticker: { _, _, _, _, _ in
}, sendSticker: { _, _, _, _, _, _ in
return false
}, unblockPeer: {
}, pinMessage: { _, _ in

View File

@ -141,7 +141,7 @@ public final class ReactionIconView: PortalSourceView {
context: context,
attemptSynchronousLoad: false,
emoji: ChatTextInputTextCustomEmojiAttribute(
stickerPack: nil,
interactivelySelectedFromPackId: nil,
fileId: file.fileId.id,
file: file
),

View File

@ -195,7 +195,7 @@ public final class ReactionListContextMenuContent: ContextControllerItemsContent
let reactionLayer = InlineStickerItemLayer(
context: context,
attemptSynchronousLoad: false,
emoji: ChatTextInputTextCustomEmojiAttribute(stickerPack: nil, fileId: file.fileId.id, file: file),
emoji: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: file.fileId.id, file: file),
file: file,
cache: self.animationCache,
renderer: self.animationRenderer,
@ -437,7 +437,7 @@ public final class ReactionListContextMenuContent: ContextControllerItemsContent
let reactionLayer = InlineStickerItemLayer(
context: context,
attemptSynchronousLoad: false,
emoji: ChatTextInputTextCustomEmojiAttribute(stickerPack: nil, fileId: file.fileId.id, file: file),
emoji: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: file.fileId.id, file: file),
file: file,
cache: self.animationCache,
renderer: self.animationRenderer,

View File

@ -518,7 +518,7 @@ final class InnerTextSelectionTipContainerNode: ASDisplayNode {
if let file = self.file {
let range = (attributedText.string as NSString).range(of: "#")
if range.location != NSNotFound {
attributedText.addAttribute(ChatTextInputAttributes.customEmoji, value: ChatTextInputTextCustomEmojiAttribute(stickerPack: nil, fileId: file.fileId.id, file: file), range: range)
attributedText.addAttribute(ChatTextInputAttributes.customEmoji, value: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: file.fileId.id, file: file), range: range)
}
}

View File

@ -291,7 +291,7 @@ private enum DebugControllerEntry: ItemListNodeEntry {
context.account.postbox.mediaBox.storeResourceData(fileResource.id, data: gzippedData)
let file = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: id), partialReference: nil, resource: fileResource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "application/text", size: Int64(gzippedData.count), attributes: [.FileName(fileName: "Log-iOS-Full.txt.zip")])
let message: EnqueueMessage = .message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: file), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil)
let message: EnqueueMessage = .message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: file), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])
let _ = enqueueMessages(account: context.account, peerId: peerId, messages: [message]).start()
}
@ -371,7 +371,7 @@ private enum DebugControllerEntry: ItemListNodeEntry {
context.account.postbox.mediaBox.storeResourceData(fileResource.id, data: logData)
let file = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: id), partialReference: nil, resource: fileResource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "application/text", size: Int64(logData.count), attributes: [.FileName(fileName: "Log-iOS-Short.txt")])
let message: EnqueueMessage = .message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: file), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil)
let message: EnqueueMessage = .message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: file), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])
let _ = enqueueMessages(account: context.account, peerId: peerId, messages: [message]).start()
}
@ -457,7 +457,7 @@ private enum DebugControllerEntry: ItemListNodeEntry {
context.account.postbox.mediaBox.storeResourceData(fileResource.id, data: gzippedData)
let file = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: id), partialReference: nil, resource: fileResource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "application/text", size: Int64(gzippedData.count), attributes: [.FileName(fileName: "Log-iOS-Full.txt.zip")])
let message: EnqueueMessage = .message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: file), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil)
let message: EnqueueMessage = .message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: file), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])
let _ = enqueueMessages(account: context.account, peerId: peerId, messages: [message]).start()
}
@ -541,7 +541,7 @@ private enum DebugControllerEntry: ItemListNodeEntry {
context.account.postbox.mediaBox.storeResourceData(fileResource.id, data: gzippedData)
let file = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: id), partialReference: nil, resource: fileResource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "application/text", size: Int64(gzippedData.count), attributes: [.FileName(fileName: "Log-iOS-Full.txt.zip")])
let message: EnqueueMessage = .message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: file), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil)
let message: EnqueueMessage = .message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: file), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])
let _ = enqueueMessages(account: context.account, peerId: peerId, messages: [message]).start()
}
@ -625,7 +625,7 @@ private enum DebugControllerEntry: ItemListNodeEntry {
context.account.postbox.mediaBox.storeResourceData(fileResource.id, data: gzippedData)
let file = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: id), partialReference: nil, resource: fileResource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "application/text", size: Int64(gzippedData.count), attributes: [.FileName(fileName: "Log-iOS-Full.txt.zip")])
let message: EnqueueMessage = .message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: file), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil)
let message: EnqueueMessage = .message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: file), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])
let _ = enqueueMessages(account: context.account, peerId: peerId, messages: [message]).start()
}
@ -678,7 +678,7 @@ private enum DebugControllerEntry: ItemListNodeEntry {
let messages = logs.map { (name, path) -> EnqueueMessage in
let id = Int64.random(in: Int64.min ... Int64.max)
let file = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: id), partialReference: nil, resource: LocalFileReferenceMediaResource(localFilePath: path, randomId: id), previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "application/text", size: nil, attributes: [.FileName(fileName: name)])
return .message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: file), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil)
return .message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: file), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])
}
let _ = enqueueMessages(account: context.account, peerId: peerId, messages: messages).start()
}
@ -786,7 +786,7 @@ private enum DebugControllerEntry: ItemListNodeEntry {
context.account.postbox.mediaBox.storeResourceData(fileResource.id, data: gzippedData)
let file = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: id), partialReference: nil, resource: fileResource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "application/zip", size: Int64(gzippedData.count), attributes: [.FileName(fileName: "Log-iOS-All.txt.zip")])
let message: EnqueueMessage = .message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: file), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil)
let message: EnqueueMessage = .message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: file), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])
let _ = enqueueMessages(account: context.account, peerId: peerId, messages: [message]).start()
}
@ -1388,7 +1388,7 @@ public func triggerDebugSendLogsUI(context: AccountContext, additionalInfo: Stri
context.account.postbox.mediaBox.storeResourceData(fileResource.id, data: gzippedData)
let file = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: id), partialReference: nil, resource: fileResource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "application/text", size: Int64(gzippedData.count), attributes: [.FileName(fileName: "Log-iOS-Full.txt.zip")])
let message: EnqueueMessage = .message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: file), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil)
let message: EnqueueMessage = .message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: file), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])
let _ = enqueueMessages(account: context.account, peerId: peerId, messages: [message]).start()
}

View File

@ -340,7 +340,7 @@ public final class SecretMediaPreviewController: ViewController {
|> deliverOnMainQueue).start(next: { [weak self] _ in
if let strongSelf = self, strongSelf.traceVisibility() {
if strongSelf.messageId.peerId.namespace == Namespaces.Peer.CloudUser {
let _ = enqueueMessages(account: strongSelf.context.account, peerId: strongSelf.messageId.peerId, messages: [.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: TelegramMediaAction(action: TelegramMediaActionType.historyScreenshot)), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil)]).start()
let _ = enqueueMessages(account: strongSelf.context.account, peerId: strongSelf.messageId.peerId, messages: [.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: TelegramMediaAction(action: TelegramMediaActionType.historyScreenshot)), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])]).start()
} else if strongSelf.messageId.peerId.namespace == Namespaces.Peer.SecretChat {
let _ = strongSelf.context.engine.messages.addSecretChatMessageScreenshot(peerId: strongSelf.messageId.peerId).start()
}

View File

@ -347,7 +347,7 @@ public func legacyEnqueueGifMessage(account: Account, data: Data, correlationId:
fileAttributes.append(.Animated)
let media = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: Int64.random(in: Int64.min ... Int64.max)), partialReference: nil, resource: resource, previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: "video/mp4", size: nil, attributes: fileAttributes)
subscriber.putNext(.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: nil, localGroupingKey: nil, correlationId: correlationId))
subscriber.putNext(.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: nil, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: []))
subscriber.putCompletion()
} else {
subscriber.putError(Void())
@ -389,7 +389,7 @@ public func legacyEnqueueVideoMessage(account: Account, data: Data, correlationI
fileAttributes.append(.Animated)
let media = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: Int64.random(in: Int64.min ... Int64.max)), partialReference: nil, resource: resource, previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: "video/mp4", size: nil, attributes: fileAttributes)
subscriber.putNext(.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: nil, localGroupingKey: nil, correlationId: correlationId))
subscriber.putNext(.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: nil, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: []))
subscriber.putCompletion()
} else {
subscriber.putError(Void())
@ -463,7 +463,7 @@ public func legacyAssetPickerEnqueueMessages(account: Account, signals: [Any]) -
attributes.append(TextEntitiesMessageAttribute(entities: entities))
}
messages.append(LegacyAssetPickerEnqueueMessage(message: .message(text: text.string, attributes: attributes, inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: nil, localGroupingKey: item.groupedId, correlationId: nil), uniqueId: item.uniqueId, isFile: false))
messages.append(LegacyAssetPickerEnqueueMessage(message: .message(text: text.string, attributes: attributes, inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: nil, localGroupingKey: item.groupedId, correlationId: nil, bubbleUpEmojiOrStickersets: []), uniqueId: item.uniqueId, isFile: false))
}
}
case let .asset(asset):
@ -486,7 +486,7 @@ public func legacyAssetPickerEnqueueMessages(account: Account, signals: [Any]) -
attributes.append(TextEntitiesMessageAttribute(entities: entities))
}
messages.append(LegacyAssetPickerEnqueueMessage(message: .message(text: text.string, attributes: attributes, inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: nil, localGroupingKey: item.groupedId, correlationId: nil), uniqueId: item.uniqueId, isFile: false))
messages.append(LegacyAssetPickerEnqueueMessage(message: .message(text: text.string, attributes: attributes, inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: nil, localGroupingKey: item.groupedId, correlationId: nil, bubbleUpEmojiOrStickersets: []), uniqueId: item.uniqueId, isFile: false))
case .tempFile:
break
}
@ -516,7 +516,7 @@ public func legacyAssetPickerEnqueueMessages(account: Account, signals: [Any]) -
attributes.append(TextEntitiesMessageAttribute(entities: entities))
}
messages.append(LegacyAssetPickerEnqueueMessage(message: .message(text: text.string, attributes: attributes, inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: nil, localGroupingKey: item.groupedId, correlationId: nil), uniqueId: item.uniqueId, isFile: true))
messages.append(LegacyAssetPickerEnqueueMessage(message: .message(text: text.string, attributes: attributes, inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: nil, localGroupingKey: item.groupedId, correlationId: nil, bubbleUpEmojiOrStickersets: []), uniqueId: item.uniqueId, isFile: true))
case let .asset(asset):
var randomId: Int64 = 0
arc4random_buf(&randomId, 8)
@ -530,7 +530,7 @@ public func legacyAssetPickerEnqueueMessages(account: Account, signals: [Any]) -
attributes.append(TextEntitiesMessageAttribute(entities: entities))
}
messages.append(LegacyAssetPickerEnqueueMessage(message: .message(text: text.string, attributes: attributes, inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: nil, localGroupingKey: item.groupedId, correlationId: nil), uniqueId: item.uniqueId, isFile: true))
messages.append(LegacyAssetPickerEnqueueMessage(message: .message(text: text.string, attributes: attributes, inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: nil, localGroupingKey: item.groupedId, correlationId: nil, bubbleUpEmojiOrStickersets: []), uniqueId: item.uniqueId, isFile: true))
default:
break
}
@ -665,7 +665,7 @@ public func legacyAssetPickerEnqueueMessages(account: Account, signals: [Any]) -
attributes.append(TextEntitiesMessageAttribute(entities: entities))
}
messages.append(LegacyAssetPickerEnqueueMessage(message: .message(text: text.string, attributes: attributes, inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: nil, localGroupingKey: item.groupedId, correlationId: nil), uniqueId: item.uniqueId, isFile: asFile))
messages.append(LegacyAssetPickerEnqueueMessage(message: .message(text: text.string, attributes: attributes, inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: nil, localGroupingKey: item.groupedId, correlationId: nil, bubbleUpEmojiOrStickersets: []), uniqueId: item.uniqueId, isFile: asFile))
}
}
}

View File

@ -83,7 +83,7 @@ public func chatInputStateStringFromRTF(_ data: Data, type: NSAttributedString.D
}
if let emojiId = emojiId {
updatedString.removeAttribute(NSAttributedString.Key.link, range: range)
updatedString.addAttribute(ChatTextInputAttributes.customEmoji, value: ChatTextInputTextCustomEmojiAttribute(stickerPack: nil, fileId: emojiId, file: nil), range: range)
updatedString.addAttribute(ChatTextInputAttributes.customEmoji, value: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: emojiId, file: nil), range: range)
}
}
})

View File

@ -2151,7 +2151,7 @@ private final class PremiumIntroScreenComponent: CombinedComponent {
if let emojiFile = state.emojiFile {
let range = (secondaryAttributedText.string as NSString).range(of: "#")
if range.location != NSNotFound {
secondaryAttributedText.addAttribute(ChatTextInputAttributes.customEmoji, value: ChatTextInputTextCustomEmojiAttribute(stickerPack: nil, fileId: emojiFile.fileId.id, file: emojiFile), range: range)
secondaryAttributedText.addAttribute(ChatTextInputAttributes.customEmoji, value: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: emojiFile.fileId.id, file: emojiFile), range: range)
}
}
let accountContext = context.component.context

View File

@ -1443,7 +1443,7 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
let baseItemLayer = InlineStickerItemLayer(
context: itemNode.context,
attemptSynchronousLoad: false,
emoji: ChatTextInputTextCustomEmojiAttribute(stickerPack: nil, fileId: itemNode.item.listAnimation.fileId.id, file: itemNode.item.listAnimation),
emoji: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: itemNode.item.listAnimation.fileId.id, file: itemNode.item.listAnimation),
file: itemNode.item.listAnimation,
cache: animationCache,
renderer: animationRenderer,
@ -1918,9 +1918,12 @@ public final class StandaloneReactionAnimation: ASDisplayNode {
itemNode.isExtracted = true
var selfTargetBounds = targetView.bounds
if case .builtin = itemNode.item.reaction.rawValue {
selfTargetBounds = selfTargetBounds.insetBy(dx: -selfTargetBounds.width * 0.5, dy: -selfTargetBounds.height * 0.5)
if let targetView = targetView as? ReactionIconView, let iconFrame = targetView.iconFrame {
selfTargetBounds = iconFrame
}
/*if case .builtin = itemNode.item.reaction.rawValue {
selfTargetBounds = selfTargetBounds.insetBy(dx: -selfTargetBounds.width * 0.5, dy: -selfTargetBounds.height * 0.5)
}*/
let selfTargetRect = self.view.convert(selfTargetBounds, from: targetView)
@ -2027,7 +2030,7 @@ public final class StandaloneReactionAnimation: ASDisplayNode {
let baseItemLayer = InlineStickerItemLayer(
context: itemNode.context,
attemptSynchronousLoad: false,
emoji: ChatTextInputTextCustomEmojiAttribute(stickerPack: nil, fileId: itemNode.item.listAnimation.fileId.id, file: itemNode.item.listAnimation),
emoji: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: itemNode.item.listAnimation.fileId.id, file: itemNode.item.listAnimation),
file: itemNode.item.listAnimation,
cache: animationCache,
renderer: animationRenderer,

View File

@ -537,7 +537,7 @@ public func editThemeController(context: AccountContext, mode: EditThemeControll
|> take(1)).start(next: { previewTheme, settings in
let saveThemeTemplateFile: (String, LocalFileMediaResource, @escaping () -> Void) -> Void = { title, resource, completion in
let file = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: resource.fileId), partialReference: nil, resource: resource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "application/x-tgtheme-ios", size: nil, attributes: [.FileName(fileName: "\(title).tgios-theme")])
let message = EnqueueMessage.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: file), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil)
let message = EnqueueMessage.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: file), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])
let _ = enqueueMessages(account: context.account, peerId: context.account.peerId, messages: [message]).start()

View File

@ -583,9 +583,9 @@ public final class ShareController: ViewController {
for peerId in peerIds {
var messages: [EnqueueMessage] = []
if !text.isEmpty {
messages.append(.message(text: url + "\n\n" + text, attributes: [], inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil))
messages.append(.message(text: url + "\n\n" + text, attributes: [], inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []))
} else {
messages.append(.message(text: url, attributes: [], inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil))
messages.append(.message(text: url, attributes: [], inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []))
}
messages = transformMessages(messages, showNames: showNames, silently: silently)
shareSignals.append(enqueueMessages(account: strongSelf.currentAccount, peerId: peerId, messages: messages))
@ -594,9 +594,9 @@ public final class ShareController: ViewController {
for peerId in peerIds {
var messages: [EnqueueMessage] = []
if !text.isEmpty {
messages.append(.message(text: text, attributes: [], inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil))
messages.append(.message(text: text, attributes: [], inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []))
}
messages.append(.message(text: string, attributes: [], inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil))
messages.append(.message(text: string, attributes: [], inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []))
messages = transformMessages(messages, showNames: showNames, silently: silently)
shareSignals.append(enqueueMessages(account: strongSelf.currentAccount, peerId: peerId, messages: messages))
}
@ -604,19 +604,19 @@ public final class ShareController: ViewController {
for peerId in peerIds {
var messages: [EnqueueMessage] = []
if !text.isEmpty {
messages.append(.message(text: text, attributes: [], inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil))
messages.append(.message(text: text, attributes: [], inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []))
}
let attributedText = NSMutableAttributedString(string: string, attributes: [ChatTextInputAttributes.italic: true as NSNumber])
attributedText.append(NSAttributedString(string: "\n\n\(url)"))
let entities = generateChatInputTextEntities(attributedText)
messages.append(.message(text: attributedText.string, attributes: [TextEntitiesMessageAttribute(entities: entities)], inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil))
messages.append(.message(text: attributedText.string, attributes: [TextEntitiesMessageAttribute(entities: entities)], inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []))
messages = transformMessages(messages, showNames: showNames, silently: silently)
shareSignals.append(enqueueMessages(account: strongSelf.currentAccount, peerId: peerId, messages: messages))
}
case let .image(representations):
for peerId in peerIds {
var messages: [EnqueueMessage] = []
messages.append(.message(text: text, attributes: [], inlineStickers: [:], mediaReference: .standalone(media: TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.LocalImage, id: Int64.random(in: Int64.min ... Int64.max)), representations: representations.map({ $0.representation }), immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: [])), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil))
messages.append(.message(text: text, attributes: [], inlineStickers: [:], mediaReference: .standalone(media: TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.LocalImage, id: Int64.random(in: Int64.min ... Int64.max)), representations: representations.map({ $0.representation }), immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: [])), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []))
messages = transformMessages(messages, showNames: showNames, silently: silently)
shareSignals.append(enqueueMessages(account: strongSelf.currentAccount, peerId: peerId, messages: messages))
}
@ -629,9 +629,9 @@ public final class ShareController: ViewController {
for peerId in peerIds {
var messages: [EnqueueMessage] = []
if !text.isEmpty && !sendTextAsCaption {
messages.append(.message(text: text, attributes: [], inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil))
messages.append(.message(text: text, attributes: [], inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []))
}
messages.append(.message(text: sendTextAsCaption ? text : "", attributes: [], inlineStickers: [:], mediaReference: mediaReference, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil))
messages.append(.message(text: sendTextAsCaption ? text : "", attributes: [], inlineStickers: [:], mediaReference: mediaReference, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []))
messages = transformMessages(messages, showNames: showNames, silently: silently)
shareSignals.append(enqueueMessages(account: strongSelf.currentAccount, peerId: peerId, messages: messages))
}
@ -639,9 +639,9 @@ public final class ShareController: ViewController {
for peerId in peerIds {
var messages: [EnqueueMessage] = []
if !text.isEmpty {
messages.append(.message(text: text, attributes: [], inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil))
messages.append(.message(text: text, attributes: [], inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []))
}
messages.append(.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil))
messages.append(.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []))
messages = transformMessages(messages, showNames: showNames, silently: silently)
shareSignals.append(enqueueMessages(account: strongSelf.currentAccount, peerId: peerId, messages: messages))
}
@ -649,7 +649,7 @@ public final class ShareController: ViewController {
for peerId in peerIds {
var messagesToEnqueue: [EnqueueMessage] = []
if !text.isEmpty {
messagesToEnqueue.append(.message(text: text, attributes: [], inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil))
messagesToEnqueue.append(.message(text: text, attributes: [], inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []))
}
for message in messages {
messagesToEnqueue.append(.forward(source: message.id, grouping: .auto, attributes: [], correlationId: nil))

View File

@ -459,11 +459,11 @@ public func sentShareItems(account: Account, to peerIds: [PeerId], items: [Prepa
for item in items {
switch item {
case let .text(text):
messages.append(.message(text: text, attributes: attributes, inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil))
messages.append(.message(text: text, attributes: attributes, inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []))
case let .media(media):
switch media {
case let .media(reference):
let message: EnqueueMessage = .message(text: "", attributes: attributes, inlineStickers: [:], mediaReference: reference, replyToMessageId: nil, localGroupingKey: groupingKey, correlationId: nil)
let message: EnqueueMessage = .message(text: "", attributes: attributes, inlineStickers: [:], mediaReference: reference, replyToMessageId: nil, localGroupingKey: groupingKey, correlationId: nil, bubbleUpEmojiOrStickersets: [])
messages.append(message)
mediaMessages.append(message)

View File

@ -203,9 +203,9 @@ final class StickerPackEmojisItemNode: GridItemNode {
var emojiAttribute: ChatTextInputTextCustomEmojiAttribute?
loop: for attribute in file.attributes {
switch attribute {
case let .CustomEmoji(_, displayText, packReference):
case let .CustomEmoji(_, displayText, _):
text = displayText
emojiAttribute = ChatTextInputTextCustomEmojiAttribute(stickerPack: packReference, fileId: file.fileId.id, file: file)
emojiAttribute = ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: file.fileId.id, file: file)
break loop
default:
break
@ -229,9 +229,9 @@ final class StickerPackEmojisItemNode: GridItemNode {
var emojiAttribute: ChatTextInputTextCustomEmojiAttribute?
loop: for attribute in file.attributes {
switch attribute {
case let .CustomEmoji(_, displayText, packReference):
case let .CustomEmoji(_, displayText, _):
text = displayText
emojiAttribute = ChatTextInputTextCustomEmojiAttribute(stickerPack: packReference, fileId: file.fileId.id, file: file)
emojiAttribute = ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: file.fileId.id, file: file)
break loop
default:
break

View File

@ -1669,7 +1669,7 @@ public final class StickerPackScreenImpl: ViewController {
MessageTextEntity(
range: 0 ..< (text as NSString).length,
type: .CustomEmoji(
stickerPack: attribute.stickerPack,
stickerPack: nil,
fileId: attribute.fileId
)
)

View File

@ -292,7 +292,7 @@ func rateCallAndSendLogs(engine: TelegramEngine, callId: CallId, starsCount: Int
let name = "\(callId.id)_\(callId.accessHash).log.json"
let path = callLogsPath(account: engine.account) + "/" + name
let file = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: id), partialReference: nil, resource: LocalFileReferenceMediaResource(localFilePath: path, randomId: id), previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "application/text", size: nil, attributes: [.FileName(fileName: name)])
let message = EnqueueMessage.message(text: comment, attributes: [], inlineStickers: [:], mediaReference: .standalone(media: file), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil)
let message = EnqueueMessage.message(text: comment, attributes: [], inlineStickers: [:], mediaReference: .standalone(media: file), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])
return rate
|> then(enqueueMessages(account: engine.account, peerId: peerId, messages: [message])
|> mapToSignal({ _ -> Signal<Void, NoError> in
@ -300,7 +300,7 @@ func rateCallAndSendLogs(engine: TelegramEngine, callId: CallId, starsCount: Int
}))
} else if !comment.isEmpty {
return rate
|> then(enqueueMessages(account: engine.account, peerId: peerId, messages: [.message(text: comment, attributes: [], inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil)])
|> then(enqueueMessages(account: engine.account, peerId: peerId, messages: [.message(text: comment, attributes: [], inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])])
|> mapToSignal({ _ -> Signal<Void, NoError> in
return .single(Void())
}))

View File

@ -1264,7 +1264,7 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController
dismissController?()
if let strongSelf = self {
let _ = (enqueueMessages(account: strongSelf.context.account, peerId: peer.id, messages: [.message(text: listenerLink, attributes: [], inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil)])
let _ = (enqueueMessages(account: strongSelf.context.account, peerId: peer.id, messages: [.message(text: listenerLink, attributes: [], inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])])
|> deliverOnMainQueue).start(next: { [weak self] _ in
if let strongSelf = self {
strongSelf.presentUndoOverlay(content: .forward(savedMessages: false, text: strongSelf.presentationData.strings.UserInfo_LinkForwardTooltip_Chat_One(peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string), action: { _ in return true })

View File

@ -9,13 +9,13 @@ public enum EnqueueMessageGrouping {
}
public enum EnqueueMessage {
case message(text: String, attributes: [MessageAttribute], inlineStickers: [MediaId: Media], mediaReference: AnyMediaReference?, replyToMessageId: MessageId?, localGroupingKey: Int64?, correlationId: Int64?)
case message(text: String, attributes: [MessageAttribute], inlineStickers: [MediaId: Media], mediaReference: AnyMediaReference?, replyToMessageId: MessageId?, localGroupingKey: Int64?, correlationId: Int64?, bubbleUpEmojiOrStickersets: [ItemCollectionId])
case forward(source: MessageId, grouping: EnqueueMessageGrouping, attributes: [MessageAttribute], correlationId: Int64?)
public func withUpdatedReplyToMessageId(_ replyToMessageId: MessageId?) -> EnqueueMessage {
switch self {
case let .message(text, attributes, inlineStickers, mediaReference, _, localGroupingKey, correlationId):
return .message(text: text, attributes: attributes, inlineStickers: inlineStickers, mediaReference: mediaReference, replyToMessageId: replyToMessageId, localGroupingKey: localGroupingKey, correlationId: correlationId)
case let .message(text, attributes, inlineStickers, mediaReference, _, localGroupingKey, correlationId, bubbleUpEmojiOrStickersets):
return .message(text: text, attributes: attributes, inlineStickers: inlineStickers, mediaReference: mediaReference, replyToMessageId: replyToMessageId, localGroupingKey: localGroupingKey, correlationId: correlationId, bubbleUpEmojiOrStickersets: bubbleUpEmojiOrStickersets)
case .forward:
return self
}
@ -23,8 +23,8 @@ public enum EnqueueMessage {
public func withUpdatedAttributes(_ f: ([MessageAttribute]) -> [MessageAttribute]) -> EnqueueMessage {
switch self {
case let .message(text, attributes, inlineStickers, mediaReference, replyToMessageId, localGroupingKey, correlationId):
return .message(text: text, attributes: f(attributes), inlineStickers: inlineStickers, mediaReference: mediaReference, replyToMessageId: replyToMessageId, localGroupingKey: localGroupingKey, correlationId: correlationId)
case let .message(text, attributes, inlineStickers, mediaReference, replyToMessageId, localGroupingKey, correlationId, bubbleUpEmojiOrStickersets):
return .message(text: text, attributes: f(attributes), inlineStickers: inlineStickers, mediaReference: mediaReference, replyToMessageId: replyToMessageId, localGroupingKey: localGroupingKey, correlationId: correlationId, bubbleUpEmojiOrStickersets: bubbleUpEmojiOrStickersets)
case let .forward(source, grouping, attributes, correlationId):
return .forward(source: source, grouping: grouping, attributes: f(attributes), correlationId: correlationId)
}
@ -32,8 +32,8 @@ public enum EnqueueMessage {
public func withUpdatedGroupingKey(_ f: (Int64?) -> Int64?) -> EnqueueMessage {
switch self {
case let .message(text, attributes, inlineStickers, mediaReference, replyToMessageId, localGroupingKey, correlationId):
return .message(text: text, attributes: attributes, inlineStickers: inlineStickers, mediaReference: mediaReference, replyToMessageId: replyToMessageId, localGroupingKey: f(localGroupingKey), correlationId: correlationId)
case let .message(text, attributes, inlineStickers, mediaReference, replyToMessageId, localGroupingKey, correlationId, bubbleUpEmojiOrStickersets):
return .message(text: text, attributes: attributes, inlineStickers: inlineStickers, mediaReference: mediaReference, replyToMessageId: replyToMessageId, localGroupingKey: f(localGroupingKey), correlationId: correlationId, bubbleUpEmojiOrStickersets: bubbleUpEmojiOrStickersets)
case .forward:
return self
}
@ -41,15 +41,15 @@ public enum EnqueueMessage {
public func withUpdatedCorrelationId(_ value: Int64?) -> EnqueueMessage {
switch self {
case let .message(text, attributes, inlineStickers, mediaReference, replyToMessageId, localGroupingKey, _):
return .message(text: text, attributes: attributes, inlineStickers: inlineStickers, mediaReference: mediaReference, replyToMessageId: replyToMessageId, localGroupingKey: localGroupingKey, correlationId: value)
case let .message(text, attributes, inlineStickers, mediaReference, replyToMessageId, localGroupingKey, _, bubbleUpEmojiOrStickersets):
return .message(text: text, attributes: attributes, inlineStickers: inlineStickers, mediaReference: mediaReference, replyToMessageId: replyToMessageId, localGroupingKey: localGroupingKey, correlationId: value, bubbleUpEmojiOrStickersets: bubbleUpEmojiOrStickersets)
case let .forward(source, grouping, attributes, _):
return .forward(source: source, grouping: grouping, attributes: attributes, correlationId: value)
}
}
public var groupingKey: Int64? {
if case let .message(_, _, _, _, _, localGroupingKey, _) = self {
if case let .message(_, _, _, _, _, localGroupingKey, _, _) = self {
return localGroupingKey
} else {
return nil
@ -60,12 +60,21 @@ public enum EnqueueMessage {
private extension EnqueueMessage {
var correlationId: Int64? {
switch self {
case let .message(_, _, _, _, _, _, correlationId):
case let .message(_, _, _, _, _, _, correlationId, _):
return correlationId
case let .forward(_, _, _, correlationId):
return correlationId
}
}
var bubbleUpEmojiOrStickersets: [ItemCollectionId] {
switch self {
case let .message(_, _, _, _, _, _, _, bubbleUpEmojiOrStickersets):
return bubbleUpEmojiOrStickersets
case .forward:
return []
}
}
}
func augmentMediaWithReference(_ mediaReference: AnyMediaReference) -> Media {
@ -179,7 +188,7 @@ private func opportunisticallyTransformOutgoingMedia(network: Network, postbox:
var hasMedia = false
loop: for message in messages {
switch message {
case let .message(_, _, _, mediaReference, _, _, _):
case let .message(_, _, _, mediaReference, _, _, _, _):
if mediaReference != nil {
hasMedia = true
break loop
@ -196,14 +205,14 @@ private func opportunisticallyTransformOutgoingMedia(network: Network, postbox:
var signals: [Signal<(Bool, EnqueueMessage), NoError>] = []
for message in messages {
switch message {
case let .message(text, attributes, inlineStickers, mediaReference, replyToMessageId, localGroupingKey, correlationId):
case let .message(text, attributes, inlineStickers, mediaReference, replyToMessageId, localGroupingKey, correlationId, bubbleUpEmojiOrStickersets):
if let mediaReference = mediaReference {
signals.append(opportunisticallyTransformMessageWithMedia(network: network, postbox: postbox, transformOutgoingMessageMedia: transformOutgoingMessageMedia, mediaReference: mediaReference, userInteractive: userInteractive)
|> map { result -> (Bool, EnqueueMessage) in
if let result = result {
return (true, .message(text: text, attributes: attributes, inlineStickers: inlineStickers, mediaReference: .standalone(media: result.media), replyToMessageId: replyToMessageId, localGroupingKey: localGroupingKey, correlationId: correlationId))
return (true, .message(text: text, attributes: attributes, inlineStickers: inlineStickers, mediaReference: .standalone(media: result.media), replyToMessageId: replyToMessageId, localGroupingKey: localGroupingKey, correlationId: correlationId, bubbleUpEmojiOrStickersets: bubbleUpEmojiOrStickersets))
} else {
return (false, .message(text: text, attributes: attributes, inlineStickers: inlineStickers, mediaReference: mediaReference, replyToMessageId: replyToMessageId, localGroupingKey: localGroupingKey, correlationId: correlationId))
return (false, .message(text: text, attributes: attributes, inlineStickers: inlineStickers, mediaReference: mediaReference, replyToMessageId: replyToMessageId, localGroupingKey: localGroupingKey, correlationId: correlationId, bubbleUpEmojiOrStickersets: bubbleUpEmojiOrStickersets))
}
})
} else {
@ -265,17 +274,19 @@ public func resendMessages(account: Account, messageIds: [MessageId]) -> Signal<
var filteredAttributes: [MessageAttribute] = []
var replyToMessageId: MessageId?
var bubbleUpEmojiOrStickersets: [ItemCollectionId] = []
inner: for attribute in message.attributes {
if let attribute = attribute as? ReplyMessageAttribute {
replyToMessageId = attribute.messageId
} else if attribute is OutgoingMessageInfoAttribute {
} else if let attribute = attribute as? OutgoingMessageInfoAttribute {
bubbleUpEmojiOrStickersets = attribute.bubbleUpEmojiOrStickersets
continue inner
} else {
filteredAttributes.append(attribute)
}
}
messages.append(.message(text: message.text, attributes: filteredAttributes, inlineStickers: [:], mediaReference: message.media.first.flatMap(AnyMediaReference.standalone), replyToMessageId: replyToMessageId, localGroupingKey: message.groupingKey, correlationId: nil))
messages.append(.message(text: message.text, attributes: filteredAttributes, inlineStickers: [:], mediaReference: message.media.first.flatMap(AnyMediaReference.standalone), replyToMessageId: replyToMessageId, localGroupingKey: message.groupingKey, correlationId: nil, bubbleUpEmojiOrStickersets: bubbleUpEmojiOrStickersets))
}
}
let _ = enqueueMessages(transaction: transaction, account: account, peerId: peerId, messages: messages.map { (false, $0) })
@ -305,7 +316,7 @@ func enqueueMessages(transaction: Transaction, account: Account, peerId: PeerId,
}
}
switch message {
case let .message(_, attributes, _, _, replyToMessageId, _, _):
case let .message(_, attributes, _, _, replyToMessageId, _, _, _):
if let replyToMessageId = replyToMessageId, replyToMessageId.peerId != peerId, let replyMessage = transaction.getMessage(replyToMessageId) {
var canBeForwarded = true
if replyMessage.id.namespace != Namespaces.Message.Cloud {
@ -329,7 +340,7 @@ func enqueueMessages(transaction: Transaction, account: Account, peerId: PeerId,
mediaReference = .standalone(media: media)
}
}
updatedMessages.append((transformedMedia, .message(text: sourceMessage.text, attributes: sourceMessage.attributes, inlineStickers: [:], mediaReference: mediaReference, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil)))
updatedMessages.append((transformedMedia, .message(text: sourceMessage.text, attributes: sourceMessage.attributes, inlineStickers: [:], mediaReference: mediaReference, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])))
continue outer
}
}
@ -367,11 +378,11 @@ func enqueueMessages(transaction: Transaction, account: Account, peerId: PeerId,
if transformedMedia {
infoFlags.insert(.transformedMedia)
}
attributes.append(OutgoingMessageInfoAttribute(uniqueId: randomId, flags: infoFlags, acknowledged: false, correlationId: message.correlationId))
attributes.append(OutgoingMessageInfoAttribute(uniqueId: randomId, flags: infoFlags, acknowledged: false, correlationId: message.correlationId, bubbleUpEmojiOrStickersets: message.bubbleUpEmojiOrStickersets))
globallyUniqueIds.append(randomId)
switch message {
case let .message(text, requestedAttributes, inlineStickers, mediaReference, replyToMessageId, localGroupingKey, _):
case let .message(text, requestedAttributes, inlineStickers, mediaReference, replyToMessageId, localGroupingKey, _, _):
for (_, file) in inlineStickers {
transaction.storeMediaIfNotPresent(media: file)
}

View File

@ -375,7 +375,7 @@ private func uploadedMediaImageContent(network: Network, postbox: Postbox, trans
let attribute = updatedAttributes[index] as! OutgoingMessageInfoAttribute
updatedAttributes[index] = attribute.withUpdatedFlags(attribute.flags.union([.transformedMedia]))
} else {
updatedAttributes.append(OutgoingMessageInfoAttribute(uniqueId: Int64.random(in: Int64.min ... Int64.max), flags: [.transformedMedia], acknowledged: false, correlationId: nil))
updatedAttributes.append(OutgoingMessageInfoAttribute(uniqueId: Int64.random(in: Int64.min ... Int64.max), flags: [.transformedMedia], acknowledged: false, correlationId: nil, bubbleUpEmojiOrStickersets: []))
}
return .update(StoreMessage(id: currentMessage.id, globallyUniqueId: currentMessage.globallyUniqueId, groupingKey: currentMessage.groupingKey, threadId: currentMessage.threadId, timestamp: currentMessage.timestamp, flags: StoreMessageFlags(currentMessage.flags), tags: currentMessage.tags, globalTags: currentMessage.globalTags, localTags: currentMessage.localTags, forwardInfo: storeForwardInfo, authorId: currentMessage.author?.id, text: currentMessage.text, attributes: updatedAttributes, media: currentMessage.media))
})
@ -668,7 +668,7 @@ private func uploadedMediaFileContent(network: Network, postbox: Postbox, auxili
let attribute = updatedAttributes[index] as! OutgoingMessageInfoAttribute
updatedAttributes[index] = attribute.withUpdatedFlags(attribute.flags.union([.transformedMedia]))
} else {
updatedAttributes.append(OutgoingMessageInfoAttribute(uniqueId: Int64.random(in: Int64.min ... Int64.max), flags: [.transformedMedia], acknowledged: false, correlationId: nil))
updatedAttributes.append(OutgoingMessageInfoAttribute(uniqueId: Int64.random(in: Int64.min ... Int64.max), flags: [.transformedMedia], acknowledged: false, correlationId: nil, bubbleUpEmojiOrStickersets: []))
}
return .update(StoreMessage(id: currentMessage.id, globallyUniqueId: currentMessage.globallyUniqueId, groupingKey: currentMessage.groupingKey, threadId: currentMessage.threadId, timestamp: currentMessage.timestamp, flags: StoreMessageFlags(currentMessage.flags), tags: currentMessage.tags, globalTags: currentMessage.globalTags, localTags: currentMessage.localTags, forwardInfo: storeForwardInfo, authorId: currentMessage.author?.id, text: currentMessage.text, attributes: updatedAttributes, media: currentMessage.media))
})

View File

@ -2,7 +2,6 @@ import Foundation
import Postbox
import SwiftSignalKit
func _internal_setSecretChatMessageAutoremoveTimeoutInteractively(account: Account, peerId: PeerId, timeout: Int32?) -> Signal<Void, NoError> {
return account.postbox.transaction { transaction -> Void in
if let peer = transaction.getPeer(peerId) as? TelegramSecretChat, let state = transaction.getPeerChatState(peerId) as? SecretChatState {
@ -16,7 +15,7 @@ func _internal_setSecretChatMessageAutoremoveTimeoutInteractively(account: Accou
transaction.setPeerChatState(peerId, state: updatedState)
}
let _ = enqueueMessages(transaction: transaction, account: account, peerId: peerId, messages: [(true, .message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: TelegramMediaAction(action: TelegramMediaActionType.messageAutoremoveTimeoutUpdated(timeout == nil ? 0 : timeout!))), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil))])
let _ = enqueueMessages(transaction: transaction, account: account, peerId: peerId, messages: [(true, .message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: TelegramMediaAction(action: TelegramMediaActionType.messageAutoremoveTimeoutUpdated(timeout == nil ? 0 : timeout!))), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []))])
}
}
}
@ -31,7 +30,7 @@ func _internal_addSecretChatMessageScreenshot(account: Account, peerId: PeerId)
default:
break
}
let _ = enqueueMessages(transaction: transaction, account: account, peerId: peerId, messages: [(true, .message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: TelegramMediaAction(action: TelegramMediaActionType.historyScreenshot)), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil))])
let _ = enqueueMessages(transaction: transaction, account: account, peerId: peerId, messages: [(true, .message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: TelegramMediaAction(action: TelegramMediaActionType.historyScreenshot)), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []))])
}
}
}

View File

@ -91,6 +91,8 @@ func applyUpdateMessage(postbox: Postbox, stateManager: AccountStateManager, mes
var updatedMessage: StoreMessage?
var bubbleUpEmojiOrStickersets: [ItemCollectionId] = []
transaction.updateMessage(message.id, update: { currentMessage in
let updatedId: MessageId
if let messageId = messageId {
@ -107,6 +109,12 @@ func applyUpdateMessage(postbox: Postbox, stateManager: AccountStateManager, mes
updatedId = currentMessage.id
}
for attribute in currentMessage.attributes {
if let attribute = attribute as? OutgoingMessageInfoAttribute {
bubbleUpEmojiOrStickersets = attribute.bubbleUpEmojiOrStickersets
}
}
let media: [Media]
var attributes: [MessageAttribute]
let text: String
@ -262,6 +270,9 @@ func applyUpdateMessage(postbox: Postbox, stateManager: AccountStateManager, mes
}
}
}
if !bubbleUpEmojiOrStickersets.isEmpty {
applyBubbleUpEmojiOrStickersets(transaction: transaction, ids: bubbleUpEmojiOrStickersets)
}
stateManager.addUpdates(result)
stateManager.addUpdateGroups([.ensurePeerHasLocalState(id: message.id.peerId)])
@ -335,6 +346,8 @@ func applyUpdateGroupMessages(postbox: Postbox, stateManager: AccountStateManage
transaction.updateMessageGroupingKeysAtomically(ids, groupingKey: key)
}
var bubbleUpEmojiOrStickersets: [ItemCollectionId] = []
for (message, _, updatedMessage) in mapping {
transaction.updateMessage(message.id, update: { currentMessage in
let updatedId: MessageId
@ -344,6 +357,16 @@ func applyUpdateGroupMessages(postbox: Postbox, stateManager: AccountStateManage
updatedId = currentMessage.id
}
for attribute in currentMessage.attributes {
if let attribute = attribute as? OutgoingMessageInfoAttribute {
for id in attribute.bubbleUpEmojiOrStickersets {
if !bubbleUpEmojiOrStickersets.contains(id) {
bubbleUpEmojiOrStickersets.append(id)
}
}
}
}
let media: [Media]
let attributes: [MessageAttribute]
let text: String
@ -409,7 +432,36 @@ func applyUpdateGroupMessages(postbox: Postbox, stateManager: AccountStateManage
}
}
}
if !bubbleUpEmojiOrStickersets.isEmpty {
applyBubbleUpEmojiOrStickersets(transaction: transaction, ids: bubbleUpEmojiOrStickersets)
}
stateManager.addUpdates(result)
stateManager.addUpdateGroups([.ensurePeerHasLocalState(id: messages[0].id.peerId)])
}
}
private func applyBubbleUpEmojiOrStickersets(transaction: Transaction, ids: [ItemCollectionId]) {
let namespaces: [ItemCollectionId.Namespace] = [Namespaces.ItemCollection.CloudStickerPacks, Namespaces.ItemCollection.CloudEmojiPacks]
for namespace in namespaces {
let namespaceIds = ids.filter { $0.namespace == namespace }
if !namespaceIds.isEmpty {
let infos = transaction.getItemCollectionsInfos(namespace: namespace)
var packDict: [ItemCollectionId: Int] = [:]
for i in 0 ..< infos.count {
packDict[infos[i].0] = i
}
var topSortedPacks: [(ItemCollectionId, ItemCollectionInfo)] = []
var processedPacks = Set<ItemCollectionId>()
for id in namespaceIds {
if let index = packDict[id] {
topSortedPacks.append(infos[index])
processedPacks.insert(id)
}
}
let restPacks = infos.filter { !processedPacks.contains($0.0) }
let sortedPacks = topSortedPacks + restPacks
transaction.replaceItemCollectionInfos(namespace: namespace, itemCollectionInfos: sortedPacks)
}
}
}

View File

@ -798,12 +798,17 @@ public final class PendingMessageManager {
flags |= (1 << 13)
}
var bubbleUpEmojiOrStickersets = false
var singleMedias: [Api.InputSingleMedia] = []
for (message, content) in messages {
var uniqueId: Int64?
inner: for attribute in message.attributes {
if let outgoingInfo = attribute as? OutgoingMessageInfoAttribute {
uniqueId = outgoingInfo.uniqueId
if !outgoingInfo.bubbleUpEmojiOrStickersets.isEmpty {
bubbleUpEmojiOrStickersets = true
}
break inner
}
}
@ -831,6 +836,10 @@ public final class PendingMessageManager {
}
}
if bubbleUpEmojiOrStickersets {
flags |= Int32(1 << 15)
}
sendMessageRequest = network.request(Api.functions.messages.sendMultiMedia(flags: flags, peer: inputPeer, replyToMsgId: replyMessageId, multiMedia: singleMedias, scheduleDate: scheduleTime, sendAs: sendAsInputPeer))
}
@ -1002,6 +1011,7 @@ public final class PendingMessageManager {
var replyMessageId: Int32?
var scheduleTime: Int32?
var sendAsPeerId: PeerId?
var bubbleUpEmojiOrStickersets = false
var flags: Int32 = 0
@ -1010,6 +1020,7 @@ public final class PendingMessageManager {
replyMessageId = replyAttribute.messageId.id
} else if let outgoingInfo = attribute as? OutgoingMessageInfoAttribute {
uniqueId = outgoingInfo.uniqueId
bubbleUpEmojiOrStickersets = !outgoingInfo.bubbleUpEmojiOrStickersets.isEmpty
} else if let attribute = attribute as? ForwardSourceInfoAttribute {
forwardSourceInfoAttribute = attribute
} else if let attribute = attribute as? TextEntitiesMessageAttribute {
@ -1053,8 +1064,16 @@ public final class PendingMessageManager {
let sendMessageRequest: Signal<NetworkRequestResult<Api.Updates>, MTRpcError>
switch content.content {
case .text:
if bubbleUpEmojiOrStickersets {
flags |= Int32(1 << 15)
}
sendMessageRequest = network.requestWithAdditionalInfo(Api.functions.messages.sendMessage(flags: flags, peer: inputPeer, replyToMsgId: replyMessageId, message: message.text, randomId: uniqueId, replyMarkup: nil, entities: messageEntities, scheduleDate: scheduleTime, sendAs: sendAsInputPeer), info: .acknowledgement, tag: dependencyTag)
case let .media(inputMedia, text):
if bubbleUpEmojiOrStickersets {
flags |= Int32(1 << 15)
}
sendMessageRequest = network.request(Api.functions.messages.sendMedia(flags: flags, peer: inputPeer, replyToMsgId: replyMessageId, media: inputMedia, message: text, randomId: uniqueId, replyMarkup: nil, entities: messageEntities, scheduleDate: scheduleTime, sendAs: sendAsInputPeer), tag: dependencyTag)
|> map(NetworkRequestResult.result)
case let .forward(sourceInfo):

View File

@ -20,12 +20,14 @@ public class OutgoingMessageInfoAttribute: MessageAttribute {
public let flags: OutgoingMessageInfoFlags
public let acknowledged: Bool
public let correlationId: Int64?
public let bubbleUpEmojiOrStickersets: [ItemCollectionId]
public init(uniqueId: Int64, flags: OutgoingMessageInfoFlags, acknowledged: Bool, correlationId: Int64?) {
public init(uniqueId: Int64, flags: OutgoingMessageInfoFlags, acknowledged: Bool, correlationId: Int64?, bubbleUpEmojiOrStickersets: [ItemCollectionId]) {
self.uniqueId = uniqueId
self.flags = flags
self.acknowledged = acknowledged
self.correlationId = correlationId
self.bubbleUpEmojiOrStickersets = bubbleUpEmojiOrStickersets
}
required public init(decoder: PostboxDecoder) {
@ -33,6 +35,11 @@ public class OutgoingMessageInfoAttribute: MessageAttribute {
self.flags = OutgoingMessageInfoFlags(rawValue: decoder.decodeInt32ForKey("f", orElse: 0))
self.acknowledged = decoder.decodeInt32ForKey("ack", orElse: 0) != 0
self.correlationId = decoder.decodeOptionalInt64ForKey("cid")
if let data = decoder.decodeDataForKey("bubbleUpEmojiOrStickersets") {
self.bubbleUpEmojiOrStickersets = ItemCollectionId.decodeArrayFromBuffer(ReadBuffer(data: data))
} else {
self.bubbleUpEmojiOrStickersets = []
}
}
public func encode(_ encoder: PostboxEncoder) {
@ -44,13 +51,16 @@ public class OutgoingMessageInfoAttribute: MessageAttribute {
} else {
encoder.encodeNil(forKey: "cid")
}
let bubbleUpEmojiOrStickersetsBuffer = WriteBuffer()
ItemCollectionId.encodeArrayToBuffer(self.bubbleUpEmojiOrStickersets, buffer: bubbleUpEmojiOrStickersetsBuffer)
encoder.encodeData(bubbleUpEmojiOrStickersetsBuffer.makeData(), forKey: "bubbleUpEmojiOrStickersets")
}
public func withUpdatedFlags(_ flags: OutgoingMessageInfoFlags) -> OutgoingMessageInfoAttribute {
return OutgoingMessageInfoAttribute(uniqueId: self.uniqueId, flags: flags, acknowledged: self.acknowledged, correlationId: self.correlationId)
return OutgoingMessageInfoAttribute(uniqueId: self.uniqueId, flags: flags, acknowledged: self.acknowledged, correlationId: self.correlationId, bubbleUpEmojiOrStickersets: self.bubbleUpEmojiOrStickersets)
}
public func withUpdatedAcknowledged(_ acknowledged: Bool) -> OutgoingMessageInfoAttribute {
return OutgoingMessageInfoAttribute(uniqueId: self.uniqueId, flags: self.flags, acknowledged: acknowledged, correlationId: self.correlationId)
return OutgoingMessageInfoAttribute(uniqueId: self.uniqueId, flags: self.flags, acknowledged: acknowledged, correlationId: self.correlationId, bubbleUpEmojiOrStickersets: self.bubbleUpEmojiOrStickersets)
}
}

View File

@ -41,19 +41,19 @@ func _internal_outgoingMessageWithChatContextResult(to peerId: PeerId, botId: Pe
return true
}
if let media: Media = internalReference.file ?? internalReference.image {
return .message(text: caption, attributes: filteredAttributes, inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: replyToMessageId, localGroupingKey: nil, correlationId: correlationId)
return .message(text: caption, attributes: filteredAttributes, inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: replyToMessageId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: [])
} else {
return .message(text: caption, attributes: filteredAttributes, inlineStickers: [:], mediaReference: nil, replyToMessageId: replyToMessageId, localGroupingKey: nil, correlationId: correlationId)
return .message(text: caption, attributes: filteredAttributes, inlineStickers: [:], mediaReference: nil, replyToMessageId: replyToMessageId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: [])
}
} else {
return .message(text: "", attributes: attributes, inlineStickers: [:], mediaReference: .standalone(media: TelegramMediaGame(gameId: 0, accessHash: 0, name: "", title: internalReference.title ?? "", description: internalReference.description ?? "", image: internalReference.image, file: internalReference.file)), replyToMessageId: replyToMessageId, localGroupingKey: nil, correlationId: correlationId)
return .message(text: "", attributes: attributes, inlineStickers: [:], mediaReference: .standalone(media: TelegramMediaGame(gameId: 0, accessHash: 0, name: "", title: internalReference.title ?? "", description: internalReference.description ?? "", image: internalReference.image, file: internalReference.file)), replyToMessageId: replyToMessageId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: [])
}
} else if let file = internalReference.file, internalReference.type == "gif" {
return .message(text: caption, attributes: attributes, inlineStickers: [:], mediaReference: .standalone(media: file), replyToMessageId: replyToMessageId, localGroupingKey: nil, correlationId: correlationId)
return .message(text: caption, attributes: attributes, inlineStickers: [:], mediaReference: .standalone(media: file), replyToMessageId: replyToMessageId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: [])
} else if let image = internalReference.image {
return .message(text: caption, attributes: attributes, inlineStickers: [:], mediaReference: .standalone(media: image), replyToMessageId: replyToMessageId, localGroupingKey: nil, correlationId: correlationId)
return .message(text: caption, attributes: attributes, inlineStickers: [:], mediaReference: .standalone(media: image), replyToMessageId: replyToMessageId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: [])
} else if let file = internalReference.file {
return .message(text: caption, attributes: attributes, inlineStickers: [:], mediaReference: .standalone(media: file), replyToMessageId: replyToMessageId, localGroupingKey: nil, correlationId: correlationId)
return .message(text: caption, attributes: attributes, inlineStickers: [:], mediaReference: .standalone(media: file), replyToMessageId: replyToMessageId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: [])
} else {
return nil
}
@ -65,9 +65,9 @@ func _internal_outgoingMessageWithChatContextResult(to peerId: PeerId, botId: Pe
let thumbnailResource = thumbnail.resource
let imageDimensions = thumbnail.dimensions ?? PixelDimensions(width: 128, height: 128)
let tmpImage = TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.LocalImage, id: randomId), representations: [TelegramMediaImageRepresentation(dimensions: imageDimensions, resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil)], immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: [])
return .message(text: caption, attributes: attributes, inlineStickers: [:], mediaReference: .standalone(media: tmpImage), replyToMessageId: replyToMessageId, localGroupingKey: nil, correlationId: correlationId)
return .message(text: caption, attributes: attributes, inlineStickers: [:], mediaReference: .standalone(media: tmpImage), replyToMessageId: replyToMessageId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: [])
} else {
return .message(text: caption, attributes: attributes, inlineStickers: [:], mediaReference: nil, replyToMessageId: replyToMessageId, localGroupingKey: nil, correlationId: correlationId)
return .message(text: caption, attributes: attributes, inlineStickers: [:], mediaReference: nil, replyToMessageId: replyToMessageId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: [])
}
} else if externalReference.type == "document" || externalReference.type == "gif" || externalReference.type == "audio" || externalReference.type == "voice" {
var videoThumbnails: [TelegramMediaFile.VideoThumbnail] = []
@ -127,9 +127,9 @@ func _internal_outgoingMessageWithChatContextResult(to peerId: PeerId, botId: Pe
}
let file = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: randomId), partialReference: nil, resource: resource, previewRepresentations: previewRepresentations, videoThumbnails: videoThumbnails, immediateThumbnailData: nil, mimeType: externalReference.content?.mimeType ?? "application/binary", size: nil, attributes: fileAttributes)
return .message(text: caption, attributes: attributes, inlineStickers: [:], mediaReference: .standalone(media: file), replyToMessageId: replyToMessageId, localGroupingKey: nil, correlationId: correlationId)
return .message(text: caption, attributes: attributes, inlineStickers: [:], mediaReference: .standalone(media: file), replyToMessageId: replyToMessageId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: [])
} else {
return .message(text: caption, attributes: attributes, inlineStickers: [:], mediaReference: nil, replyToMessageId: replyToMessageId, localGroupingKey: nil, correlationId: correlationId)
return .message(text: caption, attributes: attributes, inlineStickers: [:], mediaReference: nil, replyToMessageId: replyToMessageId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: [])
}
}
case let .text(text, entities, _, replyMarkup):
@ -139,21 +139,21 @@ func _internal_outgoingMessageWithChatContextResult(to peerId: PeerId, botId: Pe
if let replyMarkup = replyMarkup {
attributes.append(replyMarkup)
}
return .message(text: text, attributes: attributes, inlineStickers: [:], mediaReference: nil, replyToMessageId: replyToMessageId, localGroupingKey: nil, correlationId: correlationId)
return .message(text: text, attributes: attributes, inlineStickers: [:], mediaReference: nil, replyToMessageId: replyToMessageId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: [])
case let .mapLocation(media, replyMarkup):
if let replyMarkup = replyMarkup {
attributes.append(replyMarkup)
}
return .message(text: "", attributes: attributes, inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: replyToMessageId, localGroupingKey: nil, correlationId: correlationId)
return .message(text: "", attributes: attributes, inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: replyToMessageId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: [])
case let .contact(media, replyMarkup):
if let replyMarkup = replyMarkup {
attributes.append(replyMarkup)
}
return .message(text: "", attributes: attributes, inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: replyToMessageId, localGroupingKey: nil, correlationId: correlationId)
return .message(text: "", attributes: attributes, inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: replyToMessageId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: [])
case let .invoice(media, replyMarkup):
if let replyMarkup = replyMarkup {
attributes.append(replyMarkup)
}
return .message(text: "", attributes: attributes, inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: replyToMessageId, localGroupingKey: nil, correlationId: correlationId)
return .message(text: "", attributes: attributes, inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: replyToMessageId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: [])
}
}

View File

@ -25,7 +25,7 @@ func _internal_requestStartBot(account: Account, botPeerId: PeerId, payload: Str
}
}
} else {
return enqueueMessages(account: account, peerId: botPeerId, messages: [.message(text: "/start", attributes: [], inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil)]) |> mapToSignal { _ -> Signal<Void, NoError> in
return enqueueMessages(account: account, peerId: botPeerId, messages: [.message(text: "/start", attributes: [], inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])]) |> mapToSignal { _ -> Signal<Void, NoError> in
return .complete()
}
}

View File

@ -103,7 +103,7 @@ public func messageTextWithAttributes(message: EngineMessage) -> NSAttributedStr
let updatedString = NSMutableAttributedString(attributedString: attributedText)
for entity in entities.sorted(by: { $0.range.lowerBound > $1.range.lowerBound }) {
guard case let .CustomEmoji(stickerPack, fileId) = entity.type else {
guard case let .CustomEmoji(_, fileId) = entity.type else {
continue
}
@ -111,8 +111,7 @@ public func messageTextWithAttributes(message: EngineMessage) -> NSAttributedStr
let currentDict = updatedString.attributes(at: range.lowerBound, effectiveRange: nil)
var updatedAttributes: [NSAttributedString.Key: Any] = currentDict
//updatedAttributes[NSAttributedString.Key.foregroundColor] = UIColor.clear.cgColor
updatedAttributes[ChatTextInputAttributes.customEmoji] = ChatTextInputTextCustomEmojiAttribute(stickerPack: stickerPack, fileId: fileId, file: message.associatedMedia[MediaId(namespace: Namespaces.Media.CloudFile, id: fileId)] as? TelegramMediaFile)
updatedAttributes[ChatTextInputAttributes.customEmoji] = ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: fileId, file: message.associatedMedia[MediaId(namespace: Namespaces.Media.CloudFile, id: fileId)] as? TelegramMediaFile)
let insertString = NSAttributedString(string: updatedString.attributedSubstring(from: range).string, attributes: updatedAttributes)
updatedString.replaceCharacters(in: range, with: insertString)

View File

@ -278,10 +278,10 @@ public func universalServiceMessageString(presentationData: (PresentationTheme,
let index = ranges.count
ranges.append((ranges.count, NSRange(location: location, length: length)))
attributes[index] = spoilerAttributes(primaryTextColor: primaryTextColor)
case let .CustomEmoji(stickerPack, fileId):
case let .CustomEmoji(_, fileId):
let index = ranges.count
ranges.append((ranges.count, NSRange(location: location, length: length)))
attributes[index] = customEmojiAttributes(primaryTextColor: primaryTextColor, emoji: ChatTextInputTextCustomEmojiAttribute(stickerPack: stickerPack, fileId: fileId, file: message.associatedMedia[MediaId(namespace: Namespaces.Media.CloudFile, id: fileId)] as? TelegramMediaFile))
attributes[index] = customEmojiAttributes(primaryTextColor: primaryTextColor, emoji: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: fileId, file: message.associatedMedia[MediaId(namespace: Namespaces.Media.CloudFile, id: fileId)] as? TelegramMediaFile))
default:
break
}

View File

@ -404,7 +404,7 @@ public final class EmojiStatusComponent: Component {
animationLayer = InlineStickerItemLayer(
context: component.context,
attemptSynchronousLoad: false,
emoji: ChatTextInputTextCustomEmojiAttribute(stickerPack: nil, fileId: emojiFile.fileId.id, file: emojiFile),
emoji: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: emojiFile.fileId.id, file: emojiFile),
file: emojiFile,
cache: component.animationCache,
renderer: component.animationRenderer,

View File

@ -159,6 +159,7 @@ public final class EmojiStatusSelectionComponent: Component {
hideInputUpdated: { _, _, _ in },
switchToTextInput: {},
switchToGifSubject: { _ in },
reorderItems: { _, _ in },
makeSearchContainerNode: { _ in return nil },
deviceMetrics: component.deviceMetrics,
hiddenInputHeight: 0.0,
@ -397,6 +398,7 @@ public final class EmojiStatusSelectionController: ViewController {
}
self.isUserInteractionEnabled = false
destinationView.isHidden = true
let hapticFeedback: HapticFeedback
if let current = self.hapticFeedback {
@ -470,7 +472,7 @@ public final class EmojiStatusSelectionController: ViewController {
let baseItemLayer = InlineStickerItemLayer(
context: self.context,
attemptSynchronousLoad: false,
emoji: ChatTextInputTextCustomEmojiAttribute(stickerPack: nil, fileId: itemFile.fileId.id, file: itemFile),
emoji: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: itemFile.fileId.id, file: itemFile),
file: item.itemFile,
cache: animationCache,
renderer: animationRenderer,
@ -501,7 +503,6 @@ public final class EmojiStatusSelectionController: ViewController {
self.layer.addSublayer(sourceCopyLayer)
sourceCopyLayer.frame = sourceLayer.convert(sourceLayer.bounds, to: self.layer)
sourceLayer.isHidden = true
destinationView.isHidden = true
let previousSourceCopyFrame = sourceCopyLayer.frame
@ -512,7 +513,15 @@ public final class EmojiStatusSelectionController: ViewController {
let transition: ContainedViewLayoutTransition = .animated(duration: 0.2, curve: .linear)
sourceCopyLayer.position = localDestinationFrame.center
transition.animatePositionWithKeyframes(layer: sourceCopyLayer, keyframes: generateParabollicMotionKeyframes(from: previousSourceCopyFrame.center, to: localDestinationFrame.center, elevation: -(localDestinationFrame.center.y - previousSourceCopyFrame.center.y) + 30.0), completion: { [weak self, weak sourceCopyLayer, weak destinationView] _ in
var midPointY: CGFloat = localDestinationFrame.center.y - 30.0
if let layout = self.validLayout {
if midPointY < layout.safeInsets.top + 8.0 {
midPointY = max(localDestinationFrame.center.y, layout.safeInsets.top + 8.0)
}
}
transition.animatePositionWithKeyframes(layer: sourceCopyLayer, keyframes: generateParabollicMotionKeyframes(from: previousSourceCopyFrame.center, to: localDestinationFrame.center, midPointY: midPointY), completion: { [weak self, weak sourceCopyLayer, weak destinationView] _ in
guard let strongSelf = self else {
return
}
@ -549,6 +558,7 @@ public final class EmojiStatusSelectionController: ViewController {
sourceCopyLayer.animateKeyframes(values: scaleKeyframes.map({ $0 as NSNumber }), duration: 0.2, keyPath: "transform.scale", timingFunction: CAMediaTimingFunctionName.linear.rawValue)
} else {
itemCompleted = true
destinationView.isHidden = false
}
self.animateOut(completion: {
@ -877,8 +887,8 @@ public final class EmojiStatusSelectionController: ViewController {
}
}
private func generateParabollicMotionKeyframes(from sourcePoint: CGPoint, to targetPosition: CGPoint, elevation: CGFloat) -> [CGPoint] {
let midPoint = CGPoint(x: (sourcePoint.x + targetPosition.x) / 2.0, y: sourcePoint.y - elevation)
private func generateParabollicMotionKeyframes(from sourcePoint: CGPoint, to targetPosition: CGPoint, midPointY: CGFloat) -> [CGPoint] {
let midPoint = CGPoint(x: (sourcePoint.x + targetPosition.x) / 2.0, y: midPointY)
let x1 = sourcePoint.x
let y1 = sourcePoint.y

View File

@ -284,7 +284,7 @@ public final class EmojiSuggestionsComponent: Component {
itemLayer = InlineStickerItemLayer(
context: component.context,
attemptSynchronousLoad: synchronousLoad,
emoji: ChatTextInputTextCustomEmojiAttribute(stickerPack: nil, fileId: item.fileId.id, file: item),
emoji: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: item.fileId.id, file: item),
file: item,
cache: component.animationCache,
renderer: component.animationRenderer,

View File

@ -1496,7 +1496,7 @@ private final class GroupExpandActionButton: UIButton {
}
public protocol EmojiContentPeekBehavior: AnyObject {
func setGestureRecognizerEnabled(view: UIView, isEnabled: Bool, itemAtPoint: @escaping (CGPoint) -> (EmojiPagerContentComponent.View.ItemLayer, TelegramMediaFile)?)
func setGestureRecognizerEnabled(view: UIView, isEnabled: Bool, itemAtPoint: @escaping (CGPoint) -> (AnyHashable, EmojiPagerContentComponent.View.ItemLayer, TelegramMediaFile)?)
}
public final class EmojiPagerContentComponent: Component {
@ -1571,7 +1571,7 @@ public final class EmojiPagerContentComponent: Component {
public let presentController: (ViewController) -> Void
public let presentGlobalOverlayController: (ViewController) -> Void
public let navigationController: () -> NavigationController?
public let sendSticker: ((FileMediaReference, Bool, Bool, String?, Bool, UIView, CGRect, CALayer?) -> Void)?
public let sendSticker: ((FileMediaReference, Bool, Bool, String?, Bool, UIView, CGRect, CALayer?, [ItemCollectionId]) -> Void)?
public let chatPeerId: PeerId?
public let peekBehavior: EmojiContentPeekBehavior?
public let customLayout: CustomLayout?
@ -1588,7 +1588,7 @@ public final class EmojiPagerContentComponent: Component {
presentController: @escaping (ViewController) -> Void,
presentGlobalOverlayController: @escaping (ViewController) -> Void,
navigationController: @escaping () -> NavigationController?,
sendSticker: ((FileMediaReference, Bool, Bool, String?, Bool, UIView, CGRect, CALayer?) -> Void)?,
sendSticker: ((FileMediaReference, Bool, Bool, String?, Bool, UIView, CGRect, CALayer?, [ItemCollectionId]) -> Void)?,
chatPeerId: PeerId?,
peekBehavior: EmojiContentPeekBehavior?,
customLayout: CustomLayout?,
@ -1842,6 +1842,22 @@ public final class EmojiPagerContentComponent: Component {
self.selectedItems = selectedItems
}
public func withUpdatedItemGroups(_ itemGroups: [ItemGroup]) -> EmojiPagerContentComponent {
return EmojiPagerContentComponent(
id: self.id,
context: self.context,
avatarPeer: self.avatarPeer,
animationCache: self.animationCache,
animationRenderer: self.animationRenderer,
inputInteractionHolder: self.inputInteractionHolder,
itemGroups: itemGroups,
itemLayoutType: self.itemLayoutType,
warpContentsOnEdges: self.warpContentsOnEdges,
enableLongPress: self.enableLongPress,
selectedItems: self.selectedItems
)
}
public static func ==(lhs: EmojiPagerContentComponent, rhs: EmojiPagerContentComponent) -> Bool {
if lhs === rhs {
return true
@ -4399,7 +4415,7 @@ public final class EmojiPagerContentComponent: Component {
if itemLayer.displayPlaceholder {
return nil
}
return (itemLayer, file)
return (item.1.groupId, itemLayer, file)
})
let keyboardChildEnvironment = environment[EntityKeyboardChildEnvironment.self].value

View File

@ -49,7 +49,7 @@ public final class EntityKeyboardComponent: Component {
}
}
private enum ReorderCategory {
public enum ReorderCategory {
case stickers
case emoji
}
@ -94,6 +94,7 @@ public final class EntityKeyboardComponent: Component {
public let hideInputUpdated: (Bool, Bool, Transition) -> Void
public let switchToTextInput: () -> Void
public let switchToGifSubject: (GifPagerContentComponent.Subject) -> Void
public let reorderItems: (ReorderCategory, [EntityKeyboardTopPanelComponent.Item]) -> Void
public let makeSearchContainerNode: (EntitySearchContentType) -> EntitySearchContainerNode?
public let deviceMetrics: DeviceMetrics
public let hiddenInputHeight: CGFloat
@ -116,6 +117,7 @@ public final class EntityKeyboardComponent: Component {
hideInputUpdated: @escaping (Bool, Bool, Transition) -> Void,
switchToTextInput: @escaping () -> Void,
switchToGifSubject: @escaping (GifPagerContentComponent.Subject) -> Void,
reorderItems: @escaping (ReorderCategory, [EntityKeyboardTopPanelComponent.Item]) -> Void,
makeSearchContainerNode: @escaping (EntitySearchContentType) -> EntitySearchContainerNode?,
deviceMetrics: DeviceMetrics,
hiddenInputHeight: CGFloat,
@ -137,6 +139,7 @@ public final class EntityKeyboardComponent: Component {
self.hideInputUpdated = hideInputUpdated
self.switchToTextInput = switchToTextInput
self.switchToGifSubject = switchToGifSubject
self.reorderItems = reorderItems
self.makeSearchContainerNode = makeSearchContainerNode
self.deviceMetrics = deviceMetrics
self.hiddenInputHeight = hiddenInputHeight
@ -766,31 +769,7 @@ public final class EntityKeyboardComponent: Component {
}
private func reorderPacks(category: ReorderCategory, items: [EntityKeyboardTopPanelComponent.Item]) {
guard let component = self.component else {
return
}
var currentIds: [ItemCollectionId] = []
for item in items {
guard let id = item.id.base as? ItemCollectionId else {
continue
}
currentIds.append(id)
}
let namespace: ItemCollectionId.Namespace
switch category {
case .stickers:
namespace = Namespaces.ItemCollection.CloudStickerPacks
case .emoji:
namespace = Namespaces.ItemCollection.CloudEmojiPacks
}
let _ = (component.emojiContent.context.engine.stickers.reorderStickerPacks(namespace: namespace, itemIds: currentIds)
|> deliverOnMainQueue).start(completed: { [weak self] in
guard let strongSelf = self else {
return
}
strongSelf.state?.updated(transition: Transition(animation: .curve(duration: 0.4, curve: .spring)))
})
self.component?.reorderItems(category, items)
}
}

View File

@ -913,18 +913,18 @@ final class EntityKeyboardStaticStickersPanelComponent: Component {
}
}
final class EntityKeyboardTopPanelItemEnvironment: Equatable {
let isExpanded: Bool
let isHighlighted: Bool
let highlightedSubgroupId: AnyHashable?
public final class EntityKeyboardTopPanelItemEnvironment: Equatable {
public let isExpanded: Bool
public let isHighlighted: Bool
public let highlightedSubgroupId: AnyHashable?
init(isExpanded: Bool, isHighlighted: Bool, highlightedSubgroupId: AnyHashable?) {
public init(isExpanded: Bool, isHighlighted: Bool, highlightedSubgroupId: AnyHashable?) {
self.isExpanded = isExpanded
self.isHighlighted = isHighlighted
self.highlightedSubgroupId = highlightedSubgroupId
}
static func ==(lhs: EntityKeyboardTopPanelItemEnvironment, rhs: EntityKeyboardTopPanelItemEnvironment) -> Bool {
public static func ==(lhs: EntityKeyboardTopPanelItemEnvironment, rhs: EntityKeyboardTopPanelItemEnvironment) -> Bool {
if lhs.isExpanded != rhs.isExpanded {
return false
}
@ -1137,18 +1137,18 @@ private final class ReorderGestureRecognizer: UIGestureRecognizer {
public final class EntityKeyboardTopPanelComponent: Component {
public typealias EnvironmentType = EntityKeyboardTopContainerPanelEnvironment
final class Item: Equatable {
let id: AnyHashable
let isReorderable: Bool
let content: AnyComponent<EntityKeyboardTopPanelItemEnvironment>
public final class Item: Equatable {
public let id: AnyHashable
public let isReorderable: Bool
public let content: AnyComponent<EntityKeyboardTopPanelItemEnvironment>
init(id: AnyHashable, isReorderable: Bool, content: AnyComponent<EntityKeyboardTopPanelItemEnvironment>) {
public init(id: AnyHashable, isReorderable: Bool, content: AnyComponent<EntityKeyboardTopPanelItemEnvironment>) {
self.id = id
self.isReorderable = isReorderable
self.content = content
}
static func ==(lhs: Item, rhs: Item) -> Bool {
public static func ==(lhs: Item, rhs: Item) -> Bool {
if lhs.id != rhs.id {
return false
}

View File

@ -2002,7 +2002,7 @@ private func extractAccountManagerState(records: AccountRecordsView<TelegramAcco
if let messageId = messageIdFromNotification(peerId: peerId, notification: response.notification) {
let _ = TelegramEngine(account: account).messages.applyMaxReadIndexInteractively(index: MessageIndex(id: messageId, timestamp: 0)).start()
}
return enqueueMessages(account: account, peerId: peerId, messages: [EnqueueMessage.message(text: text, attributes: [], inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil)])
return enqueueMessages(account: account, peerId: peerId, messages: [EnqueueMessage.message(text: text, attributes: [], inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])])
|> map { messageIds -> MessageId? in
if messageIds.isEmpty {
return nil

View File

@ -828,7 +828,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}, enqueueMessage: { message in
self?.sendMessages([message])
}, sendSticker: canSendMessagesToChat(strongSelf.presentationInterfaceState) ? { fileReference, sourceNode, sourceRect in
return self?.controllerInteraction?.sendSticker(fileReference, false, false, nil, false, sourceNode, sourceRect, nil) ?? false
return self?.controllerInteraction?.sendSticker(fileReference, false, false, nil, false, sourceNode, sourceRect, nil, []) ?? false
} : nil, sendEmoji: canSendMessagesToChat(strongSelf.presentationInterfaceState) ? { text, attribute in
self?.controllerInteraction?.sendEmoji(text, attribute)
} : nil, setupTemporaryHiddenMedia: { signal, centralIndex, galleryMedia in
@ -1822,8 +1822,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
if !entities.isEmpty {
attributes.append(TextEntitiesMessageAttribute(entities: entities))
}
strongSelf.sendMessages([.message(text: text, attributes: attributes, inlineStickers: [:], mediaReference: nil, replyToMessageId: strongSelf.presentationInterfaceState.interfaceState.replyMessageId, localGroupingKey: nil, correlationId: nil)])
}, sendSticker: { [weak self] fileReference, silentPosting, schedule, query, clearInput, sourceView, sourceRect, sourceLayer in
strongSelf.sendMessages([.message(text: text, attributes: attributes, inlineStickers: [:], mediaReference: nil, replyToMessageId: strongSelf.presentationInterfaceState.interfaceState.replyMessageId, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])])
}, sendSticker: { [weak self] fileReference, silentPosting, schedule, query, clearInput, sourceView, sourceRect, sourceLayer, bubbleUpEmojiOrStickersets in
guard let strongSelf = self else {
return false
}
@ -1919,7 +1919,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
}
let messages: [EnqueueMessage] = [.message(text: "", attributes: attributes, inlineStickers: [:], mediaReference: fileReference.abstract, replyToMessageId: strongSelf.presentationInterfaceState.interfaceState.replyMessageId, localGroupingKey: nil, correlationId: correlationId)]
let messages: [EnqueueMessage] = [.message(text: "", attributes: attributes, inlineStickers: [:], mediaReference: fileReference.abstract, replyToMessageId: strongSelf.presentationInterfaceState.interfaceState.replyMessageId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: bubbleUpEmojiOrStickersets)]
if silentPosting {
let transformedMessages = strongSelf.transformEnqueueMessages(messages, silentPosting: silentPosting)
strongSelf.sendMessages(transformedMessages)
@ -1980,7 +1980,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
}, nil)
var messages = [EnqueueMessage.message(text: "", attributes: [], inlineStickers: [:], mediaReference: fileReference.abstract, replyToMessageId: strongSelf.presentationInterfaceState.interfaceState.replyMessageId, localGroupingKey: nil, correlationId: nil)]
var messages = [EnqueueMessage.message(text: "", attributes: [], inlineStickers: [:], mediaReference: fileReference.abstract, replyToMessageId: strongSelf.presentationInterfaceState.interfaceState.replyMessageId, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])]
if silentPosting {
messages = strongSelf.transformEnqueueMessages(messages, silentPosting: true)
strongSelf.sendMessages(messages)
@ -2314,7 +2314,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|> deliverOnMainQueue).start(next: { coordinate in
if let strongSelf = self {
if let coordinate = coordinate {
strongSelf.sendMessages([.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: TelegramMediaMap(latitude: coordinate.latitude, longitude: coordinate.longitude, heading: nil, accuracyRadius: nil, geoPlace: nil, venue: nil, liveBroadcastingTimeout: nil, liveProximityNotificationRadius: nil)), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil)])
strongSelf.sendMessages([.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: TelegramMediaMap(latitude: coordinate.latitude, longitude: coordinate.longitude, heading: nil, accuracyRadius: nil, geoPlace: nil, venue: nil, liveBroadcastingTimeout: nil, liveProximityNotificationRadius: nil)), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])])
} else {
strongSelf.present(textAlertController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, title: nil, text: strongSelf.presentationData.strings.Login_UnknownError, actions: [TextAlertAction(type: .genericAction, title: strongSelf.presentationData.strings.Common_Cancel, action: {})]), in: .window(.root))
}
@ -2338,7 +2338,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
let _ = (strongSelf.context.account.postbox.loadedPeerWithId(strongSelf.context.account.peerId)
|> deliverOnMainQueue).start(next: { peer in
if let peer = peer as? TelegramUser, let phone = peer.phone, !phone.isEmpty {
strongSelf.sendMessages([.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: TelegramMediaContact(firstName: peer.firstName ?? "", lastName: peer.lastName ?? "", phoneNumber: phone, peerId: peer.id, vCardData: nil)), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil)])
strongSelf.sendMessages([.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: TelegramMediaContact(firstName: peer.firstName ?? "", lastName: peer.lastName ?? "", phoneNumber: phone, peerId: peer.id, vCardData: nil)), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])])
}
})
}
@ -2382,7 +2382,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
if !entities.isEmpty {
attributes.append(TextEntitiesMessageAttribute(entities: entities))
}
strongSelf.sendMessages([.message(text: command, attributes: attributes, inlineStickers: [:], mediaReference: nil, replyToMessageId: (postAsReply && messageId != nil) ? messageId! : nil, localGroupingKey: nil, correlationId: nil)])
strongSelf.sendMessages([.message(text: command, attributes: attributes, inlineStickers: [:], mediaReference: nil, replyToMessageId: (postAsReply && messageId != nil) ? messageId! : nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])])
}
}, openInstantPage: { [weak self] message, associatedData in
if let strongSelf = self, strongSelf.isNodeLoaded, let navigationController = strongSelf.effectiveNavigationController, let message = strongSelf.chatDisplayNode.historyNode.messageInCurrentHistoryView(message.id) {
@ -2685,7 +2685,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
items.append(ActionSheetButtonItem(title: strongSelf.presentationData.strings.ShareMenu_Send, color: .accent, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
if let strongSelf = self {
strongSelf.sendMessages([.message(text: command, attributes: [], inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil)])
strongSelf.sendMessages([.message(text: command, attributes: [], inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])])
}
}))
}
@ -6421,7 +6421,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
var correlationIds: [Int64] = []
for message in messages {
switch message {
case let .message(_, _, _, _, _, _, correlationId):
case let .message(_, _, _, _, _, _, correlationId, _):
if let correlationId = correlationId {
correlationIds.append(correlationId)
}
@ -7674,7 +7674,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
if !entities.isEmpty {
attributes.append(TextEntitiesMessageAttribute(entities: entities))
}
strongSelf.sendMessages([.message(text: messageText, attributes: attributes, inlineStickers: [:], mediaReference: nil, replyToMessageId: replyMessageId, localGroupingKey: nil, correlationId: nil)])
strongSelf.sendMessages([.message(text: messageText, attributes: attributes, inlineStickers: [:], mediaReference: nil, replyToMessageId: replyMessageId, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])])
strongSelf.interfaceInteraction?.updateShowCommands { _ in
return false
}
@ -8059,9 +8059,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
}
}
}, sendSticker: { [weak self] file, clearInput, sourceView, sourceRect, sourceLayer in
}, sendSticker: { [weak self] file, clearInput, sourceView, sourceRect, sourceLayer, bubbleUpEmojiOrStickersets in
if let strongSelf = self, canSendMessagesToChat(strongSelf.presentationInterfaceState) {
return strongSelf.controllerInteraction?.sendSticker(file, false, false, nil, clearInput, sourceView, sourceRect, sourceLayer) ?? false
return strongSelf.controllerInteraction?.sendSticker(file, false, false, nil, clearInput, sourceView, sourceRect, sourceLayer, bubbleUpEmojiOrStickersets) ?? false
} else {
return false
}
@ -11129,7 +11129,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
private func editMessageMediaWithMessages(_ messages: [EnqueueMessage]) {
if let message = messages.first, case let .message(text, attributes, _, maybeMediaReference, _, _, _) = message, let mediaReference = maybeMediaReference {
if let message = messages.first, case let .message(text, attributes, _, maybeMediaReference, _, _, _, _) = message, let mediaReference = maybeMediaReference {
self.updateChatPresentationInterfaceState(animated: true, interactive: true, { state in
var entities: [MessageTextEntity] = []
for attribute in attributes {
@ -11543,7 +11543,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
guard let strongSelf = self, let peerId = strongSelf.chatLocation.peerId else {
return
}
let message: EnqueueMessage = .message(text: "", attributes: [], inlineStickers: [:], mediaReference: mediaReference, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil)
let message: EnqueueMessage = .message(text: "", attributes: [], inlineStickers: [:], mediaReference: mediaReference, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])
let _ = (enqueueMessages(account: strongSelf.context.account, peerId: peerId, messages: strongSelf.transformEnqueueMessages([message]))
|> deliverOnMainQueue).start(next: { [weak self] _ in
if let strongSelf = self, strongSelf.presentationInterfaceState.subject != .scheduledMessages {
@ -11580,7 +11580,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
return
}
let replyMessageId = strongSelf.presentationInterfaceState.interfaceState.replyMessageId
let message: EnqueueMessage = .message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: location), replyToMessageId: replyMessageId, localGroupingKey: nil, correlationId: nil)
let message: EnqueueMessage = .message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: location), replyToMessageId: replyMessageId, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])
strongSelf.chatDisplayNode.setupSendActionOnViewUpdate({
if let strongSelf = self {
strongSelf.chatDisplayNode.collapseInput()
@ -11615,7 +11615,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
if !entities.isEmpty {
attributes.append(TextEntitiesMessageAttribute(entities: entities))
}
textEnqueueMessage = .message(text: text.string, attributes: attributes, inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil)
textEnqueueMessage = .message(text: text.string, attributes: attributes, inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])
}
if peers.count > 1 {
var enqueueMessages: [EnqueueMessage] = []
@ -11654,7 +11654,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
})
}
}, nil)
let message = EnqueueMessage.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: replyMessageId, localGroupingKey: nil, correlationId: nil)
let message = EnqueueMessage.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: replyMessageId, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])
enqueueMessages.append(message)
}
}
@ -11720,7 +11720,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
if let textEnqueueMessage = textEnqueueMessage {
enqueueMessages.append(textEnqueueMessage)
}
enqueueMessages.append(.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: replyMessageId, localGroupingKey: nil, correlationId: nil))
enqueueMessages.append(.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: replyMessageId, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []))
strongSelf.sendMessages(strongSelf.transformEnqueueMessages(enqueueMessages, silentPosting: silent, scheduleTime: scheduleTime))
} else {
let contactController = strongSelf.context.sharedContext.makeDeviceContactInfoController(context: strongSelf.context, subject: .filter(peer: peerAndContactData.0, contactId: nil, contactData: contactData, completion: { peer, contactData in
@ -11745,7 +11745,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
if let textEnqueueMessage = textEnqueueMessage {
enqueueMessages.append(textEnqueueMessage)
}
enqueueMessages.append(.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: replyMessageId, localGroupingKey: nil, correlationId: nil))
enqueueMessages.append(.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: replyMessageId, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []))
strongSelf.sendMessages(strongSelf.transformEnqueueMessages(enqueueMessages, silentPosting: silent, scheduleTime: scheduleTime))
}
}), completed: nil, cancelled: nil)
@ -12177,7 +12177,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
let file = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: fileId), partialReference: nil, resource: ICloudFileResource(urlData: item.urlData, thumbnail: false), previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int64(item.fileSize), attributes: attributes)
let message: EnqueueMessage = .message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: file), replyToMessageId: replyMessageId, localGroupingKey: groupingKey, correlationId: nil)
let message: EnqueueMessage = .message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: file), replyToMessageId: replyMessageId, localGroupingKey: groupingKey, correlationId: nil, bubbleUpEmojiOrStickersets: [])
messages.append(message)
}
if let _ = groupingKey, messages.count % 10 == 0 {
@ -12505,7 +12505,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
return
}
let replyMessageId = strongSelf.presentationInterfaceState.interfaceState.replyMessageId
let message: EnqueueMessage = .message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: location), replyToMessageId: replyMessageId, localGroupingKey: nil, correlationId: nil)
let message: EnqueueMessage = .message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: location), replyToMessageId: replyMessageId, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])
strongSelf.chatDisplayNode.setupSendActionOnViewUpdate({
if let strongSelf = self {
strongSelf.chatDisplayNode.collapseInput()
@ -12564,7 +12564,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
})
}
}, nil)
let message = EnqueueMessage.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: replyMessageId, localGroupingKey: nil, correlationId: nil)
let message = EnqueueMessage.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: replyMessageId, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])
enqueueMessages.append(message)
}
}
@ -12625,7 +12625,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
})
}
}, nil)
let message = EnqueueMessage.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: replyMessageId, localGroupingKey: nil, correlationId: nil)
let message = EnqueueMessage.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: replyMessageId, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])
strongSelf.sendMessages([message])
} else {
let contactController = strongSelf.context.sharedContext.makeDeviceContactInfoController(context: strongSelf.context, subject: .filter(peer: peerAndContactData.0, contactId: nil, contactData: contactData, completion: { peer, contactData in
@ -12645,7 +12645,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
})
}
}, nil)
let message = EnqueueMessage.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: replyMessageId, localGroupingKey: nil, correlationId: nil)
let message = EnqueueMessage.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: replyMessageId, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])
strongSelf.sendMessages([message])
}
}), completed: nil, cancelled: nil)
@ -12986,7 +12986,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
)),
replyToMessageId: nil,
localGroupingKey: nil,
correlationId: nil
correlationId: nil,
bubbleUpEmojiOrStickersets: []
)
strongSelf.sendMessages([message.withUpdatedReplyToMessageId(replyMessageId)])
})
@ -13092,7 +13093,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
if let value = value {
self.present(UndoOverlayController(presentationData: self.presentationData, content: .dice(dice: dice, context: self.context, text: value, action: canSendMessagesToChat(self.presentationInterfaceState) ? self.presentationData.strings.Conversation_SendDice : nil), elevatedLayout: false, action: { [weak self] action in
if let strongSelf = self, canSendMessagesToChat(strongSelf.presentationInterfaceState), action == .undo {
strongSelf.sendMessages([.message(text: "", attributes: [], inlineStickers: [:], mediaReference: AnyMediaReference.standalone(media: TelegramMediaDice(emoji: dice.emoji)), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil)])
strongSelf.sendMessages([.message(text: "", attributes: [], inlineStickers: [:], mediaReference: AnyMediaReference.standalone(media: TelegramMediaDice(emoji: dice.emoji)), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])])
}
return false
}), in: .current)
@ -13115,9 +13116,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
if let defaultReplyMessageId = defaultReplyMessageId {
switch message {
case let .message(text, attributes, inlineStickers, mediaReference, replyToMessageId, localGroupingKey, correlationId):
case let .message(text, attributes, inlineStickers, mediaReference, replyToMessageId, localGroupingKey, correlationId, bubbleUpEmojiOrStickersets):
if replyToMessageId == nil {
message = .message(text: text, attributes: attributes, inlineStickers: inlineStickers, mediaReference: mediaReference, replyToMessageId: defaultReplyMessageId, localGroupingKey: localGroupingKey, correlationId: correlationId)
message = .message(text: text, attributes: attributes, inlineStickers: inlineStickers, mediaReference: mediaReference, replyToMessageId: defaultReplyMessageId, localGroupingKey: localGroupingKey, correlationId: correlationId, bubbleUpEmojiOrStickersets: bubbleUpEmojiOrStickersets)
}
case .forward:
break
@ -13396,7 +13397,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
fileAttributes.append(.ImageSize(size: PixelDimensions(size)))
let media = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: Int64.random(in: Int64.min ... Int64.max)), partialReference: nil, resource: resource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "image/webp", size: Int64(data.count), attributes: fileAttributes)
let message = EnqueueMessage.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil)
let message = EnqueueMessage.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])
let replyMessageId = strongSelf.presentationInterfaceState.interfaceState.replyMessageId
strongSelf.chatDisplayNode.setupSendActionOnViewUpdate({
@ -13667,7 +13668,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
}, usedCorrelationId ? correlationId : nil)
strongSelf.sendMessages([.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: randomId), partialReference: nil, resource: resource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "audio/ogg", size: Int64(data.compressedData.count), attributes: [.Audio(isVoice: true, duration: Int(data.duration), title: nil, performer: nil, waveform: waveformBuffer)])), replyToMessageId: strongSelf.presentationInterfaceState.interfaceState.replyMessageId, localGroupingKey: nil, correlationId: correlationId)])
strongSelf.sendMessages([.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: randomId), partialReference: nil, resource: resource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "audio/ogg", size: Int64(data.compressedData.count), attributes: [.Audio(isVoice: true, duration: Int(data.duration), title: nil, performer: nil, waveform: waveformBuffer)])), replyToMessageId: strongSelf.presentationInterfaceState.interfaceState.replyMessageId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: [])])
strongSelf.recorderFeedback?.tap()
strongSelf.recorderFeedback = nil
@ -13764,7 +13765,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
}, nil)
let messages: [EnqueueMessage] = [.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: Int64.random(in: Int64.min ... Int64.max)), partialReference: nil, resource: recordedMediaPreview.resource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "audio/ogg", size: Int64(recordedMediaPreview.fileSize), attributes: [.Audio(isVoice: true, duration: Int(recordedMediaPreview.duration), title: nil, performer: nil, waveform: waveformBuffer)])), replyToMessageId: self.presentationInterfaceState.interfaceState.replyMessageId, localGroupingKey: nil, correlationId: nil)]
let messages: [EnqueueMessage] = [.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: Int64.random(in: Int64.min ... Int64.max)), partialReference: nil, resource: recordedMediaPreview.resource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "audio/ogg", size: Int64(recordedMediaPreview.fileSize), attributes: [.Audio(isVoice: true, duration: Int(recordedMediaPreview.duration), title: nil, performer: nil, waveform: waveformBuffer)])), replyToMessageId: self.presentationInterfaceState.interfaceState.replyMessageId, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])]
let transformedMessages: [EnqueueMessage]
if let silentPosting = silentPosting {
@ -14667,7 +14668,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
if !entities.isEmpty {
attributes.append(TextEntitiesMessageAttribute(entities: entities))
}
result.append(.message(text: text.string, attributes: attributes, inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil))
result.append(.message(text: text.string, attributes: attributes, inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []))
}
}
}
@ -15161,7 +15162,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
Queue.mainQueue().async {
unblockingPeer.set(false)
if let strongSelf = self, restartBot {
let _ = enqueueMessages(account: strongSelf.context.account, peerId: peerId, messages: [.message(text: "/start", attributes: [], inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil)]).start()
let _ = enqueueMessages(account: strongSelf.context.account, peerId: peerId, messages: [.message(text: "/start", attributes: [], inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])]).start()
}
}
})).start())
@ -15443,7 +15444,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
break
}
}, sendFile: nil, sendSticker: { [weak self] f, sourceView, sourceRect in
return self?.interfaceInteraction?.sendSticker(f, true, sourceView, sourceRect, nil) ?? false
return self?.interfaceInteraction?.sendSticker(f, true, sourceView, sourceRect, nil, []) ?? false
}, requestMessageActionUrlAuth: { [weak self] subject in
if case let .url(url) = subject {
self?.controllerInteraction?.requestMessageActionUrlAuth(url, subject)

View File

@ -4,6 +4,7 @@ import Postbox
import SwiftSignalKit
import AsyncDisplayKit
import TelegramCore
import Postbox
import Display
import TelegramUIPreferences
import AccountContext
@ -74,7 +75,7 @@ public final class ChatControllerInteraction {
let toggleMessagesSelection: ([MessageId], Bool) -> Void
let sendCurrentMessage: (Bool) -> Void
let sendMessage: (String) -> Void
let sendSticker: (FileMediaReference, Bool, Bool, String?, Bool, UIView, CGRect, CALayer?) -> Bool
let sendSticker: (FileMediaReference, Bool, Bool, String?, Bool, UIView, CGRect, CALayer?, [ItemCollectionId]) -> Bool
let sendEmoji: (String, ChatTextInputTextCustomEmojiAttribute) -> Void
let sendGif: (FileMediaReference, UIView, CGRect, Bool, Bool) -> Bool
let sendBotContextResultAsGif: (ChatContextResultCollection, ChatContextResult, UIView, CGRect, Bool) -> Bool
@ -180,7 +181,7 @@ public final class ChatControllerInteraction {
toggleMessagesSelection: @escaping ([MessageId], Bool) -> Void,
sendCurrentMessage: @escaping (Bool) -> Void,
sendMessage: @escaping (String) -> Void,
sendSticker: @escaping (FileMediaReference, Bool, Bool, String?, Bool, UIView, CGRect, CALayer?) -> Bool,
sendSticker: @escaping (FileMediaReference, Bool, Bool, String?, Bool, UIView, CGRect, CALayer?, [ItemCollectionId]) -> Bool,
sendEmoji: @escaping (String, ChatTextInputTextCustomEmojiAttribute) -> Void,
sendGif: @escaping (FileMediaReference, UIView, CGRect, Bool, Bool) -> Bool,
sendBotContextResultAsGif: @escaping (ChatContextResultCollection, ChatContextResult, UIView, CGRect, Bool) -> Bool,

View File

@ -2970,10 +2970,14 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
var inlineStickers: [MediaId: Media] = [:]
var firstLockedPremiumEmoji: TelegramMediaFile?
var bubbleUpEmojiOrStickersetsById: [Int64: ItemCollectionId] = [:]
effectiveInputText.enumerateAttribute(ChatTextInputAttributes.customEmoji, in: NSRange(location: 0, length: effectiveInputText.length), using: { value, _, _ in
if let value = value as? ChatTextInputTextCustomEmojiAttribute {
if let file = value.file {
inlineStickers[file.fileId] = file
if let packId = value.interactivelySelectedFromPackId {
bubbleUpEmojiOrStickersetsById[file.fileId.id] = packId
}
if file.isPremiumEmoji && !self.chatPresentationInterfaceState.isPremium && self.chatPresentationInterfaceState.chatLocation.peerId != self.context.account.peerId {
if firstLockedPremiumEmoji == nil {
firstLockedPremiumEmoji = file
@ -3016,7 +3020,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
let trimmedInputText = effectiveInputText.string.trimmingCharacters(in: .whitespacesAndNewlines)
let peerId = effectivePresentationInterfaceState.chatLocation.peerId
if peerId?.namespace != Namespaces.Peer.SecretChat, let interactiveEmojis = self.interactiveEmojis, interactiveEmojis.emojis.contains(trimmedInputText) {
messages.append(.message(text: "", attributes: [], inlineStickers: [:], mediaReference: AnyMediaReference.standalone(media: TelegramMediaDice(emoji: trimmedInputText)), replyToMessageId: self.chatPresentationInterfaceState.interfaceState.replyMessageId, localGroupingKey: nil, correlationId: nil))
messages.append(.message(text: "", attributes: [], inlineStickers: [:], mediaReference: AnyMediaReference.standalone(media: TelegramMediaDice(emoji: trimmedInputText)), replyToMessageId: self.chatPresentationInterfaceState.interfaceState.replyMessageId, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []))
} else {
let inputText = convertMarkdownToAttributes(effectiveInputText)
@ -3033,8 +3037,23 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
} else {
webpage = self.chatPresentationInterfaceState.urlPreview?.1
}
var bubbleUpEmojiOrStickersets: [ItemCollectionId] = []
for entity in entities {
if case let .CustomEmoji(_, fileId) = entity.type {
if let packId = bubbleUpEmojiOrStickersetsById[fileId] {
if !bubbleUpEmojiOrStickersets.contains(packId) {
bubbleUpEmojiOrStickersets.append(packId)
}
}
}
}
if bubbleUpEmojiOrStickersets.count > 1 {
bubbleUpEmojiOrStickersets.removeAll()
}
messages.append(.message(text: text.string, attributes: attributes, inlineStickers: inlineStickers, mediaReference: webpage.flatMap(AnyMediaReference.standalone), replyToMessageId: self.chatPresentationInterfaceState.interfaceState.replyMessageId, localGroupingKey: nil, correlationId: nil))
messages.append(.message(text: text.string, attributes: attributes, inlineStickers: inlineStickers, mediaReference: webpage.flatMap(AnyMediaReference.standalone), replyToMessageId: self.chatPresentationInterfaceState.interfaceState.replyMessageId, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: bubbleUpEmojiOrStickersets))
}
}

View File

@ -134,7 +134,7 @@ final class ChatEmptyNodeGreetingChatContent: ASDisplayNode, ChatEmptyNodeSticke
guard let stickerItem = self.stickerItem else {
return
}
let _ = self.interaction?.sendSticker(.standalone(media: stickerItem.stickerItem.file), false, self.view, self.stickerNode.bounds, nil)
let _ = self.interaction?.sendSticker(.standalone(media: stickerItem.stickerItem.file), false, self.view, self.stickerNode.bounds, nil, [])
}
func updateLayout(interfaceState: ChatPresentationInterfaceState, size: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
@ -303,7 +303,7 @@ final class ChatEmptyNodeNearbyChatContent: ASDisplayNode, ChatEmptyNodeStickerC
guard let stickerItem = self.stickerItem else {
return
}
let _ = self.interaction?.sendSticker(.standalone(media: stickerItem.stickerItem.file), false, self.view, self.stickerNode.bounds, nil)
let _ = self.interaction?.sendSticker(.standalone(media: stickerItem.stickerItem.file), false, self.view, self.stickerNode.bounds, nil, [])
}
func updateLayout(interfaceState: ChatPresentationInterfaceState, size: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {

View File

@ -633,6 +633,7 @@ final class ChatEntityKeyboardInputNode: ChatInputNode {
private let entityKeyboardView: ComponentHostView<Empty>
private let defaultToEmojiTab: Bool
private var stableReorderableGroupOrder: [EntityKeyboardComponent.ReorderCategory: [ItemCollectionId]] = [:]
private var currentInputData: InputData
private var inputDataDisposable: Disposable?
private var hasRecentGifsDisposable: Disposable?
@ -902,6 +903,8 @@ final class ChatEntityKeyboardInputNode: ChatInputNode {
super.init()
self.currentInputData = self.processInputData(inputData: self.currentInputData)
self.topBackgroundExtension = 34.0
self.followsDefaultHeight = true
@ -911,7 +914,7 @@ final class ChatEntityKeyboardInputNode: ChatInputNode {
var premiumToastCounter = 0
self.emojiInputInteraction = EmojiPagerContentComponent.InputInteraction(
performItemAction: { [weak self, weak interfaceInteraction, weak controllerInteraction] _, item, _, _, _, _ in
performItemAction: { [weak self, weak interfaceInteraction, weak controllerInteraction] groupId, item, _, _, _, _ in
let _ = (ChatEntityKeyboardInputNode.hasPremium(context: context, chatPeerId: chatPeerId, premiumIfSavedMessages: true) |> take(1) |> deliverOnMainQueue).start(next: { hasPremium in
guard let strongSelf = self, let controllerInteraction = controllerInteraction, let interfaceInteraction = interfaceInteraction else {
return
@ -922,9 +925,14 @@ final class ChatEntityKeyboardInputNode: ChatInputNode {
var emojiAttribute: ChatTextInputTextCustomEmojiAttribute?
loop: for attribute in file.attributes {
switch attribute {
case let .CustomEmoji(_, displayText, packReference):
case let .CustomEmoji(_, displayText, _):
text = displayText
emojiAttribute = ChatTextInputTextCustomEmojiAttribute(stickerPack: packReference, fileId: file.fileId.id, file: file)
var packId: ItemCollectionId?
if let id = groupId.base as? ItemCollectionId {
packId = id
}
emojiAttribute = ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: packId, fileId: file.fileId.id, file: file)
break loop
default:
break
@ -1087,11 +1095,11 @@ final class ChatEntityKeyboardInputNode: ChatInputNode {
navigationController: { [weak controllerInteraction] in
return controllerInteraction?.navigationController()
},
sendSticker: { [weak controllerInteraction] fileReference, silentPosting, schedule, query, clearInput, sourceView, sourceRect, sourceLayer in
sendSticker: { [weak controllerInteraction] fileReference, silentPosting, schedule, query, clearInput, sourceView, sourceRect, sourceLayer, bubbleUpEmojiOrStickersets in
guard let controllerInteraction = controllerInteraction else {
return
}
let _ = controllerInteraction.sendSticker(fileReference, silentPosting, schedule, query, clearInput, sourceView, sourceRect, sourceLayer)
let _ = controllerInteraction.sendSticker(fileReference, silentPosting, schedule, query, clearInput, sourceView, sourceRect, sourceLayer, bubbleUpEmojiOrStickersets)
},
chatPeerId: chatPeerId,
peekBehavior: nil,
@ -1137,7 +1145,7 @@ final class ChatEntityKeyboardInputNode: ChatInputNode {
guard let controllerInteraction = controllerInteraction else {
return false
}
return controllerInteraction.sendSticker(fileReference, false, false, nil, false, sourceNode, sourceRect, nil)
return controllerInteraction.sendSticker(fileReference, false, false, nil, false, sourceNode, sourceRect, nil, [])
}
))
@ -1152,7 +1160,11 @@ final class ChatEntityKeyboardInputNode: ChatInputNode {
return
}
let _ = interfaceInteraction.sendSticker(.standalone(media: file), false, view, rect, layer)
var bubbleUpEmojiOrStickersets: [ItemCollectionId] = []
if let id = groupId.base as? ItemCollectionId {
bubbleUpEmojiOrStickersets.append(id)
}
let _ = interfaceInteraction.sendSticker(.standalone(media: file), false, view, rect, layer, bubbleUpEmojiOrStickersets)
}
})
},
@ -1182,7 +1194,7 @@ final class ChatEntityKeyboardInputNode: ChatInputNode {
guard let controllerInteraction = controllerInteraction else {
return false
}
return controllerInteraction.sendSticker(fileReference, false, false, nil, false, sourceNode, sourceRect, nil)
return controllerInteraction.sendSticker(fileReference, false, false, nil, false, sourceNode, sourceRect, nil, [])
}
))
},
@ -1287,11 +1299,11 @@ final class ChatEntityKeyboardInputNode: ChatInputNode {
navigationController: { [weak controllerInteraction] in
return controllerInteraction?.navigationController()
},
sendSticker: { [weak controllerInteraction] fileReference, silentPosting, schedule, query, clearInput, sourceView, sourceRect, sourceLayer in
sendSticker: { [weak controllerInteraction] fileReference, silentPosting, schedule, query, clearInput, sourceView, sourceRect, sourceLayer, bubbleUpEmojiOrStickersets in
guard let controllerInteraction = controllerInteraction else {
return
}
let _ = controllerInteraction.sendSticker(fileReference, silentPosting, schedule, query, clearInput, sourceView, sourceRect, sourceLayer)
let _ = controllerInteraction.sendSticker(fileReference, silentPosting, schedule, query, clearInput, sourceView, sourceRect, sourceLayer, bubbleUpEmojiOrStickersets)
},
chatPeerId: chatPeerId,
peekBehavior: stickerPeekBehavior,
@ -1331,7 +1343,7 @@ final class ChatEntityKeyboardInputNode: ChatInputNode {
}
transition = Transition(animation: .curve(duration: 0.4, curve: .spring)).withUserData(contentAnimation)
}
strongSelf.currentInputData = inputData
strongSelf.currentInputData = strongSelf.processInputData(inputData: inputData)
strongSelf.performLayout(transition: transition)
})
@ -1547,6 +1559,12 @@ final class ChatEntityKeyboardInputNode: ChatInputNode {
}
strongSelf.gifMode = subject
},
reorderItems: { [weak self] category, items in
guard let strongSelf = self else {
return
}
strongSelf.reorderItems(category: category, items: items)
},
makeSearchContainerNode: { [weak controllerInteraction] content in
guard let controllerInteraction = controllerInteraction else {
return nil
@ -1593,6 +1611,108 @@ final class ChatEntityKeyboardInputNode: ChatInputNode {
return (expandedHeight, 0.0)
}
private func processStableItemGroupList(category: EntityKeyboardComponent.ReorderCategory, itemGroups: [EmojiPagerContentComponent.ItemGroup]) -> [EmojiPagerContentComponent.ItemGroup] {
let nextIds: [ItemCollectionId] = itemGroups.compactMap { group -> ItemCollectionId? in
if group.isEmbedded {
return nil
}
if group.isFeatured {
return nil
}
if let collectionId = group.groupId.base as? ItemCollectionId {
return collectionId
} else {
return nil
}
}
let stableOrder = self.stableReorderableGroupOrder[category] ?? nextIds
var updatedGroups: [EmojiPagerContentComponent.ItemGroup] = []
for group in itemGroups {
if !(group.groupId.base is ItemCollectionId) {
updatedGroups.append(group)
} else {
if group.isEmbedded {
continue
}
if group.isFeatured {
continue
}
if !stableOrder.contains(where: { AnyHashable($0) == group.groupId }) {
updatedGroups.append(group)
}
}
}
for id in stableOrder {
if let group = itemGroups.first(where: { $0.groupId == AnyHashable(id) }) {
updatedGroups.append(group)
}
}
for group in itemGroups {
if !updatedGroups.contains(where: { $0.groupId == group.groupId }) {
updatedGroups.append(group)
}
}
let updatedIds = updatedGroups.compactMap { group -> ItemCollectionId? in
if group.isEmbedded {
return nil
}
if group.isFeatured {
return nil
}
if let collectionId = group.groupId.base as? ItemCollectionId {
return collectionId
} else {
return nil
}
}
self.stableReorderableGroupOrder[category] = updatedIds
return updatedGroups
}
private func processInputData(inputData: InputData) -> InputData {
return InputData(
emoji: inputData.emoji.withUpdatedItemGroups(self.processStableItemGroupList(category: .emoji, itemGroups: inputData.emoji.itemGroups)),
stickers: inputData.stickers.flatMap { stickers in
return stickers.withUpdatedItemGroups(self.processStableItemGroupList(category: .stickers, itemGroups: stickers.itemGroups))
},
gifs: inputData.gifs,
availableGifSearchEmojies: inputData.availableGifSearchEmojies
)
}
private func reorderItems(category: EntityKeyboardComponent.ReorderCategory, items: [EntityKeyboardTopPanelComponent.Item]) {
var currentIds: [ItemCollectionId] = []
for item in items {
guard let id = item.id.base as? ItemCollectionId else {
continue
}
currentIds.append(id)
}
let namespace: ItemCollectionId.Namespace
switch category {
case .stickers:
namespace = Namespaces.ItemCollection.CloudStickerPacks
case .emoji:
namespace = Namespaces.ItemCollection.CloudEmojiPacks
}
self.stableReorderableGroupOrder.removeValue(forKey: category)
let _ = (self.context.engine.stickers.reorderStickerPacks(namespace: namespace, itemIds: currentIds)
|> deliverOnMainQueue).start(completed: { [weak self] in
guard let strongSelf = self else {
return
}
strongSelf.performLayout(transition: Transition(animation: .curve(duration: 0.4, curve: .spring)))
})
}
private func openGifContextMenu(item: GifPagerContentComponent.Item, sourceView: UIView, sourceRect: CGRect, gesture: ContextGesture, isSaved: Bool) {
let file = item
@ -1726,133 +1846,6 @@ final class ChatEntityKeyboardInputNode: ChatInputNode {
let contextController = ContextController(account: strongSelf.context.account, presentationData: presentationData, source: .controller(ContextControllerContentSourceImpl(controller: gallery, sourceView: sourceView, sourceRect: sourceRect)), items: .single(ContextController.Items(content: .list(items))), gesture: gesture)
strongSelf.controllerInteraction?.presentGlobalOverlayController(contextController, nil)
})
/*let canSaveGif: Bool
if item.file.fileId.namespace == Namespaces.Media.CloudFile {
canSaveGif = true
} else {
canSaveGif = false
}
let _ = (self.context.engine.stickers.isGifSaved(id: file.fileId)
|> deliverOnMainQueue).start(next: { [weak self] isGifSaved in
guard let strongSelf = self else {
return
}
var isGifSaved = isGifSaved
if !canSaveGif {
isGifSaved = false
}
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }
let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: PeerId(0), namespace: Namespaces.Message.Local, id: 0), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 0, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: nil, text: "", attributes: [], media: [file], peers: SimpleDictionary(), associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:])
let gallery = GalleryController(context: strongSelf.context, source: .standaloneMessage(message), streamSingleVideo: true, replaceRootController: { _, _ in
}, baseNavigationController: nil)
gallery.setHintWillBePresentedInPreviewingContext(true)
var items: [ContextMenuItem] = []
items.append(.action(ContextMenuActionItem(text: presentationData.strings.MediaPicker_Send, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Resend"), color: theme.actionSheet.primaryTextColor)
}, action: { _, f in
f(.default)
if isSaved {
let _ = self?.controllerInteraction?.sendGif(FileMediaReference.savedGif(media: file), sourceView, sourceRect, false, false)
}/* else if let (collection, result) = file.contextResult {
let _ = self?.controllerInteraction.sendBotContextResultAsGif(collection, result, sourceNode, sourceRect, false)
}*/
})))
if let currentState = strongSelf.currentState {
let interfaceState = currentState.interfaceState
var isScheduledMessages = false
if case .scheduledMessages = interfaceState.subject {
isScheduledMessages = true
}
if !isScheduledMessages {
if case let .peer(peerId) = interfaceState.chatLocation {
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
if peerId != self?.context.account.peerId && peerId.namespace != Namespaces.Peer.SecretChat {
items.append(.action(ContextMenuActionItem(text: presentationData.strings.Conversation_SendMessage_SendSilently, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Menu/SilentIcon"), color: theme.actionSheet.primaryTextColor)
}, action: { _, f in
f(.default)
if isSaved {
let _ = self?.controllerInteraction.sendGif(file.file, sourceNode.view, sourceRect, true, false)
} else if let (collection, result) = file.contextResult {
let _ = self?.controllerInteraction.sendBotContextResultAsGif(collection, result, sourceNode, sourceRect, true)
}
})))
}
if isSaved {
items.append(.action(ContextMenuActionItem(text: presentationData.strings.Conversation_SendMessage_ScheduleMessage, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Menu/ScheduleIcon"), color: theme.actionSheet.primaryTextColor)
}, action: { _, f in
f(.default)
let _ = self?.controllerInteraction.sendGif(file.file, sourceNode.view, sourceRect, false, true)
})))
}
}
}
}
if isSaved || isGifSaved {
items.append(.action(ContextMenuActionItem(text: presentationData.strings.Conversation_ContextMenuDelete, textColor: .destructive, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: theme.actionSheet.destructiveActionTextColor)
}, action: { _, f in
f(.dismissWithoutContent)
guard let strongSelf = self else {
return
}
let _ = removeSavedGif(postbox: strongSelf.context.account.postbox, mediaId: file.fileId).start()
})))
} else if canSaveGif && !isGifSaved {
items.append(.action(ContextMenuActionItem(text: presentationData.strings.Preview_SaveGif, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Save"), color: theme.actionSheet.primaryTextColor)
}, action: { _, f in
f(.dismissWithoutContent)
guard let strongSelf = self else {
return
}
let context = strongSelf.context
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let controllerInteraction = strongSelf.controllerInteraction
let _ = (toggleGifSaved(account: context.account, fileReference: FileMediaReference.savedGif(media: file), saved: true)
|> deliverOnMainQueue).start(next: { result in
switch result {
case .generic:
controllerInteraction?.presentController(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_gif", scale: 0.075, colors: [:], title: nil, text: presentationData.strings.Gallery_GifSaved), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), nil)
case let .limitExceeded(limit, premiumLimit):
let premiumConfiguration = PremiumConfiguration.with(appConfiguration: context.currentAppConfiguration.with { $0 })
let text: String
if limit == premiumLimit || premiumConfiguration.isPremiumDisabled {
text = presentationData.strings.Premium_MaxSavedGifsFinalText
} else {
text = presentationData.strings.Premium_MaxSavedGifsText("\(premiumLimit)").string
}
controllerInteraction?.presentController(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_gif", scale: 0.075, colors: [:], title: presentationData.strings.Premium_MaxSavedGifsTitle("\(limit)").string, text: text), elevatedLayout: false, animateInAsReplacement: false, action: { action in
if case .info = action {
let controller = PremiumIntroScreen(context: context, source: .savedGifs)
controllerInteraction?.navigationController()?.pushViewController(controller)
return true
}
return false
}), nil)
}
})
})))
}
let contextController = ContextController(account: strongSelf.context.account, presentationData: presentationData, source: .controller(ContextControllerContentSourceImpl(controller: gallery, sourceView: sourceView, sourceRect: sourceRect)), items: .single(ContextController.Items(content: .list(items))), gesture: gesture)
strongSelf.controllerInteraction?.presentGlobalOverlayController(contextController, nil)
})*/
}
}
@ -1925,7 +1918,7 @@ final class EntityInputView: UIView, AttachmentTextInputPanelInputView, UIInputV
self.clipsToBounds = true
let inputInteraction = EmojiPagerContentComponent.InputInteraction(
performItemAction: { [weak self] _, item, _, _, _, _ in
performItemAction: { [weak self] groupId, item, _, _, _, _ in
let _ = (ChatEntityKeyboardInputNode.hasPremium(context: context, chatPeerId: nil, premiumIfSavedMessages: false) |> take(1) |> deliverOnMainQueue).start(next: { hasPremium in
guard let strongSelf = self else {
return
@ -1936,9 +1929,13 @@ final class EntityInputView: UIView, AttachmentTextInputPanelInputView, UIInputV
var emojiAttribute: ChatTextInputTextCustomEmojiAttribute?
loop: for attribute in file.attributes {
switch attribute {
case let .CustomEmoji(_, displayText, packReference):
case let .CustomEmoji(_, displayText, _):
text = displayText
emojiAttribute = ChatTextInputTextCustomEmojiAttribute(stickerPack: packReference, fileId: file.fileId.id, file: file)
var packId: ItemCollectionId?
if let id = groupId.base as? ItemCollectionId {
packId = id
}
emojiAttribute = ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: packId, fileId: file.fileId.id, file: file)
break loop
default:
break
@ -2141,16 +2138,21 @@ private final class EmojiContentPeekBehaviorImpl: EmojiContentPeekBehavior {
self.chatPeerId = chatPeerId
}
func setGestureRecognizerEnabled(view: UIView, isEnabled: Bool, itemAtPoint: @escaping (CGPoint) -> (EmojiPagerContentComponent.View.ItemLayer, TelegramMediaFile)?) {
func setGestureRecognizerEnabled(view: UIView, isEnabled: Bool, itemAtPoint: @escaping (CGPoint) -> (AnyHashable, EmojiPagerContentComponent.View.ItemLayer, TelegramMediaFile)?) {
if self.peekRecognizer == nil {
let peekRecognizer = PeekControllerGestureRecognizer(contentAtPoint: { [weak self, weak view] point in
guard let strongSelf = self else {
return nil
}
guard let (itemLayer, file) = itemAtPoint(point) else {
guard let (groupId, itemLayer, file) = itemAtPoint(point) else {
return nil
}
var bubbleUpEmojiOrStickersets: [ItemCollectionId] = []
if let id = groupId.base as? ItemCollectionId {
bubbleUpEmojiOrStickersets.append(id)
}
let context = strongSelf.context
let accountPeerId = context.account.peerId
return combineLatest(
@ -2176,7 +2178,7 @@ private final class EmojiContentPeekBehaviorImpl: EmojiContentPeekBehavior {
guard let strongSelf = self else {
return
}
let _ = strongSelf.controllerInteraction.sendSticker(fileReference, silentPosting, schedule, query, clearInput, sourceView, sourceRect, sourceLayer)
let _ = strongSelf.controllerInteraction.sendSticker(fileReference, silentPosting, schedule, query, clearInput, sourceView, sourceRect, sourceLayer, bubbleUpEmojiOrStickersets)
}
if let chatPeerId = strongSelf.chatPeerId {

View File

@ -212,7 +212,7 @@ func serviceTasksForChatPresentationIntefaceState(context: AccountContext, chatP
if let value = value as? ChatTextInputTextCustomEmojiAttribute {
if value.fileId == id {
text.removeAttribute(ChatTextInputAttributes.customEmoji, range: range)
text.addAttribute(ChatTextInputAttributes.customEmoji, value: ChatTextInputTextCustomEmojiAttribute(stickerPack: nil, fileId: file.fileId.id, file: file), range: range)
text.addAttribute(ChatTextInputAttributes.customEmoji, value: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: file.fileId.id, file: file), range: range)
}
}
})

View File

@ -694,7 +694,7 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
let id = Int64.random(in: Int64.min ... Int64.max)
let file = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: id), partialReference: nil, resource: LocalFileReferenceMediaResource(localFilePath: logPath, randomId: id), previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "application/text", size: nil, attributes: [.FileName(fileName: "CallStats.log")])
let message: EnqueueMessage = .message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: file), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil)
let message: EnqueueMessage = .message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: file), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])
let _ = enqueueMessages(account: context.account, peerId: peerId, messages: [message]).start()
}

View File

@ -797,7 +797,7 @@ final class ChatMediaInputNode: ChatInputNode {
sendSticker: {
fileReference, sourceNode, sourceRect in
if let strongSelf = self {
return strongSelf.controllerInteraction.sendSticker(fileReference, false, false, nil, false, sourceNode, sourceRect, nil)
return strongSelf.controllerInteraction.sendSticker(fileReference, false, false, nil, false, sourceNode, sourceRect, nil, [])
} else {
return false
}
@ -865,7 +865,7 @@ final class ChatMediaInputNode: ChatInputNode {
sendSticker: {
fileReference, sourceNode, sourceRect in
if let strongSelf = self {
return strongSelf.controllerInteraction.sendSticker(fileReference, false, false, nil, false, sourceNode, sourceRect, nil)
return strongSelf.controllerInteraction.sendSticker(fileReference, false, false, nil, false, sourceNode, sourceRect, nil, [])
} else {
return false
}
@ -1097,7 +1097,7 @@ final class ChatMediaInputNode: ChatInputNode {
let packReference: StickerPackReference = .id(id: info.id.id, accessHash: info.accessHash)
let controller = StickerPackScreen(context: strongSelf.context, updatedPresentationData: strongSelf.controllerInteraction.updatedPresentationData, mainStickerPack: packReference, stickerPacks: [packReference], parentNavigationController: strongSelf.controllerInteraction.navigationController(), sendSticker: { fileReference, sourceNode, sourceRect in
if let strongSelf = self {
return strongSelf.controllerInteraction.sendSticker(fileReference, false, false, nil, false, sourceNode, sourceRect, nil)
return strongSelf.controllerInteraction.sendSticker(fileReference, false, false, nil, false, sourceNode, sourceRect, nil, [])
} else {
return false
}
@ -1609,9 +1609,9 @@ final class ChatMediaInputNode: ChatInputNode {
}, action: { _, f in
if let strongSelf = self, let peekController = strongSelf.peekController {
if let animationNode = (peekController.contentNode as? StickerPreviewPeekContentNode)?.animationNode {
let _ = strongSelf.controllerInteraction.sendSticker(.standalone(media: item.file), true, false, nil, false, animationNode.view, animationNode.bounds, nil)
let _ = strongSelf.controllerInteraction.sendSticker(.standalone(media: item.file), true, false, nil, false, animationNode.view, animationNode.bounds, nil, [])
} else if let imageNode = (peekController.contentNode as? StickerPreviewPeekContentNode)?.imageNode {
let _ = strongSelf.controllerInteraction.sendSticker(.standalone(media: item.file), true, false, nil, false, imageNode.view, imageNode.bounds, nil)
let _ = strongSelf.controllerInteraction.sendSticker(.standalone(media: item.file), true, false, nil, false, imageNode.view, imageNode.bounds, nil, [])
}
}
f(.default)
@ -1623,9 +1623,9 @@ final class ChatMediaInputNode: ChatInputNode {
}, action: { _, f in
if let strongSelf = self, let peekController = strongSelf.peekController {
if let animationNode = (peekController.contentNode as? StickerPreviewPeekContentNode)?.animationNode {
let _ = strongSelf.controllerInteraction.sendSticker(.standalone(media: item.file), false, true, nil, false, animationNode.view, animationNode.bounds, nil)
let _ = strongSelf.controllerInteraction.sendSticker(.standalone(media: item.file), false, true, nil, false, animationNode.view, animationNode.bounds, nil, [])
} else if let imageNode = (peekController.contentNode as? StickerPreviewPeekContentNode)?.imageNode {
let _ = strongSelf.controllerInteraction.sendSticker(.standalone(media: item.file), false, true, nil, false, imageNode.view, imageNode.bounds, nil)
let _ = strongSelf.controllerInteraction.sendSticker(.standalone(media: item.file), false, true, nil, false, imageNode.view, imageNode.bounds, nil, [])
}
}
f(.default)
@ -1679,7 +1679,7 @@ final class ChatMediaInputNode: ChatInputNode {
if let packReference = packReference {
let controller = StickerPackScreen(context: strongSelf.context, updatedPresentationData: strongSelf.controllerInteraction.updatedPresentationData, mainStickerPack: packReference, stickerPacks: [packReference], parentNavigationController: strongSelf.controllerInteraction.navigationController(), sendSticker: { file, sourceNode, sourceRect in
if let strongSelf = self {
return strongSelf.controllerInteraction.sendSticker(file, false, false, nil, false, sourceNode, sourceRect, nil)
return strongSelf.controllerInteraction.sendSticker(file, false, false, nil, false, sourceNode, sourceRect, nil, [])
} else {
return false
}
@ -1761,9 +1761,9 @@ final class ChatMediaInputNode: ChatInputNode {
}, action: { _, f in
if let strongSelf = self, let peekController = strongSelf.peekController {
if let animationNode = (peekController.contentNode as? StickerPreviewPeekContentNode)?.animationNode {
let _ = strongSelf.controllerInteraction.sendSticker(.standalone(media: item.file), true, false, nil, false, animationNode.view, animationNode.bounds, nil)
let _ = strongSelf.controllerInteraction.sendSticker(.standalone(media: item.file), true, false, nil, false, animationNode.view, animationNode.bounds, nil, [])
} else if let imageNode = (peekController.contentNode as? StickerPreviewPeekContentNode)?.imageNode {
let _ = strongSelf.controllerInteraction.sendSticker(.standalone(media: item.file), true, false, nil, false, imageNode.view, imageNode.bounds, nil)
let _ = strongSelf.controllerInteraction.sendSticker(.standalone(media: item.file), true, false, nil, false, imageNode.view, imageNode.bounds, nil, [])
}
}
f(.default)
@ -1775,9 +1775,9 @@ final class ChatMediaInputNode: ChatInputNode {
}, action: { _, f in
if let strongSelf = self, let peekController = strongSelf.peekController {
if let animationNode = (peekController.contentNode as? StickerPreviewPeekContentNode)?.animationNode {
let _ = strongSelf.controllerInteraction.sendSticker(.standalone(media: item.file), false, true, nil, false, animationNode.view, animationNode.bounds, nil)
let _ = strongSelf.controllerInteraction.sendSticker(.standalone(media: item.file), false, true, nil, false, animationNode.view, animationNode.bounds, nil, [])
} else if let imageNode = (peekController.contentNode as? StickerPreviewPeekContentNode)?.imageNode {
let _ = strongSelf.controllerInteraction.sendSticker(.standalone(media: item.file), false, true, nil, false, imageNode.view, imageNode.bounds, nil)
let _ = strongSelf.controllerInteraction.sendSticker(.standalone(media: item.file), false, true, nil, false, imageNode.view, imageNode.bounds, nil, [])
}
}
f(.default)
@ -1833,7 +1833,7 @@ final class ChatMediaInputNode: ChatInputNode {
if let packReference = packReference {
let controller = StickerPackScreen(context: strongSelf.context, updatedPresentationData: strongSelf.controllerInteraction.updatedPresentationData, mainStickerPack: packReference, stickerPacks: [packReference], parentNavigationController: strongSelf.controllerInteraction.navigationController(), sendSticker: { file, sourceNode, sourceRect in
if let strongSelf = self {
return strongSelf.controllerInteraction.sendSticker(file, false, false, nil, false, sourceNode, sourceRect, nil)
return strongSelf.controllerInteraction.sendSticker(file, false, false, nil, false, sourceNode, sourceRect, nil, [])
} else {
return false
}

View File

@ -412,7 +412,7 @@ final class ChatMediaInputStickerGridItemNode: GridItemNode {
if let interfaceInteraction = self.interfaceInteraction, let (_, item, _) = self.currentState, case .ended = recognizer.state {
if let isLocked = self.isLocked, isLocked {
} else {
let _ = interfaceInteraction.sendSticker(.standalone(media: item.file), false, false, nil, false, self.view, self.bounds, nil)
let _ = interfaceInteraction.sendSticker(.standalone(media: item.file), false, false, nil, false, self.view, self.bounds, nil, [])
self.imageNode.layer.animateAlpha(from: 0.5, to: 1.0, duration: 1.0)
}
}

View File

@ -326,7 +326,7 @@ final class ChatMediaInputTrendingPane: ChatMediaInputPane {
let packReference: StickerPackReference = .id(id: info.id.id, accessHash: info.accessHash)
let controller = StickerPackScreen(context: strongSelf.context, mainStickerPack: packReference, stickerPacks: [packReference], parentNavigationController: strongSelf.controllerInteraction.navigationController(), sendSticker: { fileReference, sourceNode, sourceRect in
if let strongSelf = self {
return strongSelf.controllerInteraction.sendSticker(fileReference, false, false, nil, false, sourceNode, sourceRect, nil)
return strongSelf.controllerInteraction.sendSticker(fileReference, false, false, nil, false, sourceNode, sourceRect, nil, [])
} else {
return false
}

View File

@ -395,7 +395,6 @@ final class ChatMessageAvatarHeaderNode: ListViewItemHeaderNode {
private let containerNode: ContextControllerSourceNode
private let avatarNode: AvatarNode
private var videoNode: UniversalVideoNode?
private var credibilityIconNode: ASImageNode?
private var videoContent: NativeVideoContent?
private let playbackStartDisposable = MetaDisposable()
@ -520,25 +519,7 @@ final class ChatMessageAvatarHeaderNode: ListViewItemHeaderNode {
let _ = context.engine.peers.fetchAndUpdateCachedPeerData(peerId: peer.id).start()
}
}))
let premiumConfiguration = PremiumConfiguration.with(appConfiguration: context.currentAppConfiguration.with { $0 })
if !premiumConfiguration.isPremiumDisabled {
let credibilityIconNode: ASImageNode
if let current = self.credibilityIconNode {
credibilityIconNode = current
} else {
credibilityIconNode = ASImageNode()
credibilityIconNode.displaysAsynchronously = false
credibilityIconNode.displayWithoutProcessing = true
credibilityIconNode.image = generateTintedImage(image: UIImage(bundleImageName: "Chat List/PeerPremiumIcon"), color: .white)
self.containerNode.addSubnode(credibilityIconNode)
}
credibilityIconNode.frame = CGRect(origin: CGPoint(x: 29.0 - UIScreenPixel, y: 29.0 - UIScreenPixel), size: CGSize(width: 10.0, height: 10.0))
}
} else {
self.credibilityIconNode?.removeFromSupernode()
self.credibilityIconNode = nil
} else {
self.cachedDataDisposable.set(nil)
self.videoContent = nil

View File

@ -318,7 +318,7 @@ class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode {
let updatedString = NSMutableAttributedString(attributedString: attributedText)
for entity in entities.sorted(by: { $0.range.lowerBound > $1.range.lowerBound }) {
guard case let .CustomEmoji(stickerPack, fileId) = entity.type else {
guard case let .CustomEmoji(_, fileId) = entity.type else {
continue
}
@ -327,7 +327,7 @@ class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode {
let currentDict = updatedString.attributes(at: range.lowerBound, effectiveRange: nil)
var updatedAttributes: [NSAttributedString.Key: Any] = currentDict
updatedAttributes[NSAttributedString.Key.foregroundColor] = UIColor.clear.cgColor
updatedAttributes[ChatTextInputAttributes.customEmoji] = ChatTextInputTextCustomEmojiAttribute(stickerPack: stickerPack, fileId: fileId, file: item.message.associatedMedia[MediaId(namespace: Namespaces.Media.CloudFile, id: fileId)] as? TelegramMediaFile)
updatedAttributes[ChatTextInputAttributes.customEmoji] = ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: fileId, file: item.message.associatedMedia[MediaId(namespace: Namespaces.Media.CloudFile, id: fileId)] as? TelegramMediaFile)
let insertString = NSAttributedString(string: updatedString.attributedSubstring(from: range).string, attributes: updatedAttributes)
updatedString.replaceCharacters(in: range, with: insertString)

View File

@ -105,7 +105,7 @@ final class ChatRecentActionsController: TelegramBaseController {
}, displayVideoUnmuteTip: { _ in
}, switchMediaRecordingMode: {
}, setupMessageAutoremoveTimeout: {
}, sendSticker: { _, _, _, _, _ in
}, sendSticker: { _, _, _, _, _, _ in
return false
}, unblockPeer: {
}, pinMessage: { _, _ in

View File

@ -261,7 +261,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
}, activateMessagePinch: { _ in
}, openMessageContextActions: { _, _, _, _ in
}, navigateToMessage: { _, _ in }, navigateToMessageStandalone: { _ in
}, tapMessage: nil, clickThroughMessage: { }, toggleMessagesSelection: { _, _ in }, sendCurrentMessage: { _ in }, sendMessage: { _ in }, sendSticker: { _, _, _, _, _, _, _, _ in return false }, sendEmoji: { _, _ in }, sendGif: { _, _, _, _, _ in return false }, sendBotContextResultAsGif: { _, _, _, _, _ in return false }, requestMessageActionCallback: { _, _, _, _ in }, requestMessageActionUrlAuth: { _, _ in }, activateSwitchInline: { _, _ in }, openUrl: { [weak self] url, _, _, _ in
}, tapMessage: nil, clickThroughMessage: { }, toggleMessagesSelection: { _, _ in }, sendCurrentMessage: { _ in }, sendMessage: { _ in }, sendSticker: { _, _, _, _, _, _, _, _, _ in return false }, sendEmoji: { _, _ in }, sendGif: { _, _, _, _, _ in return false }, sendBotContextResultAsGif: { _, _, _, _, _ in return false }, requestMessageActionCallback: { _, _, _, _ in }, requestMessageActionUrlAuth: { _, _ in }, activateSwitchInline: { _, _ in }, openUrl: { [weak self] url, _, _, _ in
self?.openUrl(url)
}, shareCurrentLocation: {}, shareAccountContact: {}, sendBotCommand: { _, _ in }, openInstantPage: { [weak self] message, associatedData in
if let strongSelf = self, let navigationController = strongSelf.getNavigationController() {

View File

@ -2587,9 +2587,9 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
var emojiAttribute: ChatTextInputTextCustomEmojiAttribute?
loop: for attribute in file.attributes {
switch attribute {
case let .CustomEmoji(_, displayText, packReference):
case let .CustomEmoji(_, displayText, _):
text = displayText
emojiAttribute = ChatTextInputTextCustomEmojiAttribute(stickerPack: packReference, fileId: file.fileId.id, file: file)
emojiAttribute = ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: file.fileId.id, file: file)
break loop
default:
break
@ -2614,7 +2614,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
if adjacentString.string != previousText.string || adjacentString.attribute(ChatTextInputAttributes.customEmoji, at: 0, effectiveRange: nil) != nil {
break
}
inputText.replaceCharacters(in: replaceRange, with: NSAttributedString(string: text, attributes: [ChatTextInputAttributes.customEmoji: ChatTextInputTextCustomEmojiAttribute(stickerPack: emojiAttribute.stickerPack, fileId: emojiAttribute.fileId, file: emojiAttribute.file)]))
inputText.replaceCharacters(in: replaceRange, with: NSAttributedString(string: text, attributes: [ChatTextInputAttributes.customEmoji: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: emojiAttribute.interactivelySelectedFromPackId, fileId: emojiAttribute.fileId, file: emojiAttribute.file)]))
replacedUpperBound = replaceRange.lowerBound
} else {
break

View File

@ -112,7 +112,7 @@ private final class DrawingStickersScreenNode: ViewControllerTracingNode {
return false }, openPeer: { _, _, _, _, _ in }, openPeerMention: { _ in }, openMessageContextMenu: { _, _, _, _, _, _ in }, openMessageReactionContextMenu: { _, _, _, _ in
}, updateMessageReaction: { _, _ in }, activateMessagePinch: { _ in
}, openMessageContextActions: { _, _, _, _ in }, navigateToMessage: { _, _ in }, navigateToMessageStandalone: { _ in
}, tapMessage: nil, clickThroughMessage: { }, toggleMessagesSelection: { _, _ in }, sendCurrentMessage: { _ in }, sendMessage: { _ in }, sendSticker: { fileReference, _, _, _, _, node, rect, _ in return selectStickerImpl?(fileReference, node, rect) ?? false }, sendEmoji: { _, _ in }, sendGif: { _, _, _, _, _ in return false }, sendBotContextResultAsGif: { _, _, _, _, _ in return false }, requestMessageActionCallback: { _, _, _, _ in }, requestMessageActionUrlAuth: { _, _ in }, activateSwitchInline: { _, _ in }, openUrl: { _, _, _, _ in }, shareCurrentLocation: {}, shareAccountContact: {}, sendBotCommand: { _, _ in }, openInstantPage: { _, _ in }, openWallpaper: { _ in }, openTheme: { _ in }, openHashtag: { _, _ in }, updateInputState: { _ in }, updateInputMode: { _ in }, openMessageShareMenu: { _ in
}, tapMessage: nil, clickThroughMessage: { }, toggleMessagesSelection: { _, _ in }, sendCurrentMessage: { _ in }, sendMessage: { _ in }, sendSticker: { fileReference, _, _, _, _, node, rect, _, _ in return selectStickerImpl?(fileReference, node, rect) ?? false }, sendEmoji: { _, _ in }, sendGif: { _, _, _, _, _ in return false }, sendBotContextResultAsGif: { _, _, _, _, _ in return false }, requestMessageActionCallback: { _, _, _, _ in }, requestMessageActionUrlAuth: { _, _ in }, activateSwitchInline: { _, _ in }, openUrl: { _, _, _, _ in }, shareCurrentLocation: {}, shareAccountContact: {}, sendBotCommand: { _, _ in }, openInstantPage: { _, _ in }, openWallpaper: { _ in }, openTheme: { _ in }, openHashtag: { _, _ in }, updateInputState: { _ in }, updateInputMode: { _ in }, openMessageShareMenu: { _ in
}, presentController: { _, _ in
}, presentControllerInCurrent: { _, _ in
}, navigationController: {
@ -237,7 +237,7 @@ private final class DrawingStickersScreenNode: ViewControllerTracingNode {
sendSticker: {
fileReference, sourceNode, sourceRect in
if let strongSelf = self {
return strongSelf.controllerInteraction.sendSticker(fileReference, false, false, nil, false, sourceNode, sourceRect, nil)
return strongSelf.controllerInteraction.sendSticker(fileReference, false, false, nil, false, sourceNode, sourceRect, nil, [])
} else {
return false
}
@ -350,7 +350,7 @@ private final class DrawingStickersScreenNode: ViewControllerTracingNode {
sendSticker: {
fileReference, sourceNode, sourceRect in
if let strongSelf = self {
return strongSelf.controllerInteraction.sendSticker(fileReference, false, false, nil, false, sourceNode, sourceRect, nil)
return strongSelf.controllerInteraction.sendSticker(fileReference, false, false, nil, false, sourceNode, sourceRect, nil, [])
} else {
return false
}

View File

@ -206,9 +206,9 @@ final class EmojisChatInputContextPanelNode: ChatInputContextPanelNode {
if let file = file {
loop: for attribute in file.attributes {
switch attribute {
case let .CustomEmoji(_, displayText, packReference):
case let .CustomEmoji(_, displayText, _):
text = displayText
emojiAttribute = ChatTextInputTextCustomEmojiAttribute(stickerPack: packReference, fileId: file.fileId.id, file: file)
emojiAttribute = ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: file.fileId.id, file: file)
break loop
default:
break

View File

@ -136,7 +136,7 @@ final class EmojisChatInputPanelItemNode: ListViewItemNode {
emojiView = EmojiTextAttachmentView(
context: item.context,
emoji: ChatTextInputTextCustomEmojiAttribute(
stickerPack: nil,
interactivelySelectedFromPackId: nil,
fileId: file.fileId.id,
file: file
),

View File

@ -202,7 +202,7 @@ final class ForwardAccessoryPanelNode: AccessoryPanelNode {
case let .CustomEmoji(_, fileId):
let range = NSRange(location: entity.range.lowerBound, length: entity.range.upperBound - entity.range.lowerBound)
if range.lowerBound >= 0 && range.upperBound <= additionalText.length {
additionalText.addAttribute(ChatTextInputAttributes.customEmoji, value: ChatTextInputTextCustomEmojiAttribute(stickerPack: nil, fileId: fileId, file: messages[0].associatedMedia[MediaId(namespace: Namespaces.Media.CloudFile, id: fileId)] as? TelegramMediaFile), range: range)
additionalText.addAttribute(ChatTextInputAttributes.customEmoji, value: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: fileId, file: messages[0].associatedMedia[MediaId(namespace: Namespaces.Media.CloudFile, id: fileId)] as? TelegramMediaFile), range: range)
}
default:
break

View File

@ -165,7 +165,7 @@ final class HorizontalListContextResultsChatInputContextPanelNode: ChatInputCont
if let strongSelf = self {
let controller = StickerPackScreen(context: strongSelf.context, mainStickerPack: packReference, stickerPacks: [packReference], parentNavigationController: strongSelf.interfaceInteraction?.getNavigationController(), sendSticker: { file, sourceView, sourceRect in
if let strongSelf = self {
return strongSelf.interfaceInteraction?.sendSticker(file, false, sourceView, sourceRect, nil) ?? false
return strongSelf.interfaceInteraction?.sendSticker(file, false, sourceView, sourceRect, nil, []) ?? false
} else {
return false
}

View File

@ -73,7 +73,7 @@ private struct StickerEntry: Identifiable, Comparable {
return HorizontalStickerGridItem(account: account, file: self.file, theme: theme, isPreviewed: { item in
return false//stickersInteraction.previewedStickerItem == item
}, sendSticker: { file, node, rect in
let _ = interfaceInteraction.sendSticker(file, true, node, rect, nil)
let _ = interfaceInteraction.sendSticker(file, true, node, rect, nil, [])
})
}
}
@ -181,7 +181,7 @@ final class HorizontalStickersChatContextPanelNode: ChatInputContextPanelNode {
.action(ContextMenuActionItem(text: strongSelf.strings.StickerPack_Send, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Resend"), color: theme.contextMenu.primaryColor) }, action: { _, f in
f(.default)
let _ = controllerInteraction.sendSticker(.standalone(media: item.file), false, false, nil, true, itemNode.view, itemNode.bounds, nil)
let _ = controllerInteraction.sendSticker(.standalone(media: item.file), false, false, nil, true, itemNode.view, itemNode.bounds, nil, [])
})),
.action(ContextMenuActionItem(text: isStarred ? strongSelf.strings.Stickers_RemoveFromFavorites : strongSelf.strings.Stickers_AddToFavorites, icon: { theme in generateTintedImage(image: isStarred ? UIImage(bundleImageName: "Chat/Context Menu/Unfave") : UIImage(bundleImageName: "Chat/Context Menu/Fave"), color: theme.contextMenu.primaryColor) }, action: { [weak self] _, f in
f(.default)
@ -225,7 +225,7 @@ final class HorizontalStickersChatContextPanelNode: ChatInputContextPanelNode {
if let packReference = packReference {
let controller = StickerPackScreen(context: strongSelf.context, mainStickerPack: packReference, stickerPacks: [packReference], parentNavigationController: controllerInteraction.navigationController(), sendSticker: { file, sourceNode, sourceRect in
if let strongSelf = self, let controllerInteraction = strongSelf.controllerInteraction {
return controllerInteraction.sendSticker(file, false, false, nil, true, sourceNode, sourceRect, nil)
return controllerInteraction.sendSticker(file, false, false, nil, true, sourceNode, sourceRect, nil, [])
} else {
return false
}

View File

@ -112,9 +112,9 @@ private final class InlineReactionSearchStickersNode: ASDisplayNode, UIScrollVie
}, action: { _, f in
if let strongSelf = self, let peekController = strongSelf.peekController {
if let animationNode = (peekController.contentNode as? StickerPreviewPeekContentNode)?.animationNode {
let _ = controllerInteraction.sendSticker(.standalone(media: item.file), true, false, nil, true, animationNode.view, animationNode.bounds, nil)
let _ = controllerInteraction.sendSticker(.standalone(media: item.file), true, false, nil, true, animationNode.view, animationNode.bounds, nil, [])
} else if let imageNode = (peekController.contentNode as? StickerPreviewPeekContentNode)?.imageNode {
let _ = controllerInteraction.sendSticker(.standalone(media: item.file), true, false, nil, true, imageNode.view, imageNode.bounds, nil)
let _ = controllerInteraction.sendSticker(.standalone(media: item.file), true, false, nil, true, imageNode.view, imageNode.bounds, nil, [])
}
}
f(.default)
@ -126,9 +126,9 @@ private final class InlineReactionSearchStickersNode: ASDisplayNode, UIScrollVie
}, action: { _, f in
if let strongSelf = self, let peekController = strongSelf.peekController {
if let animationNode = (peekController.contentNode as? StickerPreviewPeekContentNode)?.animationNode {
let _ = controllerInteraction.sendSticker(.standalone(media: item.file), false, true, nil, true, animationNode.view, animationNode.bounds, nil)
let _ = controllerInteraction.sendSticker(.standalone(media: item.file), false, true, nil, true, animationNode.view, animationNode.bounds, nil, [])
} else if let imageNode = (peekController.contentNode as? StickerPreviewPeekContentNode)?.imageNode {
let _ = controllerInteraction.sendSticker(.standalone(media: item.file), false, true, nil, true, imageNode.view, imageNode.bounds, nil)
let _ = controllerInteraction.sendSticker(.standalone(media: item.file), false, true, nil, true, imageNode.view, imageNode.bounds, nil, [])
}
}
f(.default)
@ -180,7 +180,7 @@ private final class InlineReactionSearchStickersNode: ASDisplayNode, UIScrollVie
if let packReference = packReference {
let controller = StickerPackScreen(context: strongSelf.context, mainStickerPack: packReference, stickerPacks: [packReference], parentNavigationController: controllerInteraction.navigationController(), sendSticker: { file, sourceNode, sourceRect in
if let strongSelf = self, let controllerInteraction = strongSelf.getControllerInteraction?() {
return controllerInteraction.sendSticker(file, false, false, nil, true, sourceNode, sourceRect, nil)
return controllerInteraction.sendSticker(file, false, false, nil, true, sourceNode, sourceRect, nil, [])
} else {
return false
}
@ -577,7 +577,7 @@ final class InlineReactionSearchPanel: ChatInputContextPanelNode {
guard let strongSelf = self else {
return
}
let _ = strongSelf.controllerInteraction?.sendSticker(file, false, false, strongSelf.query, true, node, rect, nil)
let _ = strongSelf.controllerInteraction?.sendSticker(file, false, false, strongSelf.query, true, node, rect, nil, [])
}
self.view.disablesInteractiveTransitionGestureRecognizer = true

View File

@ -212,7 +212,7 @@ func legacyInstantVideoController(theme: PresentationTheme, panelFrame: CGRect,
}
let media = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: Int64.random(in: Int64.min ... Int64.max)), partialReference: nil, resource: resource, previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: "video/mp4", size: nil, attributes: [.FileName(fileName: "video.mp4"), .Video(duration: Int(finalDuration), size: PixelDimensions(finalDimensions), flags: [.instantRoundVideo])])
var message: EnqueueMessage = .message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil)
var message: EnqueueMessage = .message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])
let scheduleTime: Int32? = scheduleTimestamp > 0 ? scheduleTimestamp : nil

View File

@ -66,7 +66,7 @@ func openChatMessageImpl(_ params: OpenChatMessageParams) -> Bool {
params.dismissInput()
let controllerParams = LocationViewParams(sendLiveLocation: { location in
let outMessage: EnqueueMessage = .message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: location), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil)
let outMessage: EnqueueMessage = .message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: location), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])
params.enqueueMessage(outMessage)
}, stopLiveLocation: { messageId in
params.context.liveLocationManager?.cancelLiveLocation(peerId: messageId?.peerId ?? params.message.id.peerId)

View File

@ -80,7 +80,7 @@ final class OverlayAudioPlayerControllerNode: ViewControllerTracingNode, UIGestu
}, toggleMessagesSelection: { _, _ in
}, sendCurrentMessage: { _ in
}, sendMessage: { _ in
}, sendSticker: { _, _, _, _, _, _, _, _ in
}, sendSticker: { _, _, _, _, _, _, _, _, _ in
return false
}, sendEmoji: { _, _ in
}, sendGif: { _, _, _, _, _ in

View File

@ -314,7 +314,7 @@ final class PeerInfoSelectionPanelNode: ASDisplayNode {
}, displayVideoUnmuteTip: { _ in
}, switchMediaRecordingMode: {
}, setupMessageAutoremoveTimeout: {
}, sendSticker: { _, _, _, _, _ in
}, sendSticker: { _, _, _, _, _, _ in
return false
}, unblockPeer: {
}, pinMessage: { _, _ in
@ -2273,7 +2273,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
strongSelf.paneContainerNode.updateSelectedMessageIds(strongSelf.state.selectedMessageIds, animated: true)
}, sendCurrentMessage: { _ in
}, sendMessage: { _ in
}, sendSticker: { _, _, _, _, _, _, _, _ in
}, sendSticker: { _, _, _, _, _, _, _, _, _ in
return false
}, sendEmoji: { _, _ in
}, sendGif: { _, _, _, _, _ in
@ -5107,7 +5107,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
if case let .user(peer) = peer, let _ = peer.botInfo {
strongSelf.activeActionDisposable.set(strongSelf.context.engine.privacy.requestUpdatePeerIsBlocked(peerId: peer.id, isBlocked: block).start())
if !block {
let _ = enqueueMessages(account: strongSelf.context.account, peerId: peer.id, messages: [.message(text: "/start", attributes: [], inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil)]).start()
let _ = enqueueMessages(account: strongSelf.context.account, peerId: peer.id, messages: [.message(text: "/start", attributes: [], inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])]).start()
if let navigationController = strongSelf.controller?.navigationController as? NavigationController {
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(id: peer.id)))
}
@ -5532,7 +5532,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
case .help:
text = "/help"
}
let _ = enqueueMessages(account: strongSelf.context.account, peerId: peer.id, messages: [.message(text: text, attributes: [], inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil)]).start()
let _ = enqueueMessages(account: strongSelf.context.account, peerId: peer.id, messages: [.message(text: text, attributes: [], inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])]).start()
if let navigationController = strongSelf.controller?.navigationController as? NavigationController {
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(id: strongSelf.peerId)))
@ -6741,7 +6741,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
if !entities.isEmpty {
attributes.append(TextEntitiesMessageAttribute(entities: entities))
}
result.append(.message(text: text.string, attributes: attributes, inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil))
result.append(.message(text: text.string, attributes: attributes, inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []))
}
}
}

View File

@ -260,7 +260,7 @@ final class PeerSelectionControllerNode: ASDisplayNode {
}, displayVideoUnmuteTip: { _ in
}, switchMediaRecordingMode: {
}, setupMessageAutoremoveTimeout: {
}, sendSticker: { _, _, _, _, _ in
}, sendSticker: { _, _, _, _, _, _ in
return false
}, unblockPeer: {
}, pinMessage: { _, _ in

View File

@ -1281,7 +1281,7 @@ public final class SharedAccountContextImpl: SharedAccountContext {
tapMessage?(message)
}, clickThroughMessage: {
clickThroughMessage?()
}, toggleMessagesSelection: { _, _ in }, sendCurrentMessage: { _ in }, sendMessage: { _ in }, sendSticker: { _, _, _, _, _, _, _, _ in return false }, sendEmoji: { _, _ in }, sendGif: { _, _, _, _, _ in return false }, sendBotContextResultAsGif: { _, _, _, _, _ in
}, toggleMessagesSelection: { _, _ in }, sendCurrentMessage: { _ in }, sendMessage: { _ in }, sendSticker: { _, _, _, _, _, _, _, _, _ in return false }, sendEmoji: { _, _ in }, sendGif: { _, _, _, _, _ in return false }, sendBotContextResultAsGif: { _, _, _, _, _ in
return false
}, requestMessageActionCallback: { _, _, _, _ in }, requestMessageActionUrlAuth: { _, _ in }, activateSwitchInline: { _, _ in }, openUrl: { _, _, _, _ in }, shareCurrentLocation: {}, shareAccountContact: {}, sendBotCommand: { _, _ in }, openInstantPage: { _, _ in }, openWallpaper: { _ in }, openTheme: { _ in }, openHashtag: { _, _ in }, updateInputState: { _ in }, updateInputMode: { _ in }, openMessageShareMenu: { _ in
}, presentController: { _, _ in

View File

@ -227,7 +227,7 @@ final class StickerPaneSearchContentNode: ASDisplayNode, PaneSearchContentNode {
let packReference: StickerPackReference = .id(id: info.id.id, accessHash: info.accessHash)
let controller = StickerPackScreen(context: strongSelf.context, mainStickerPack: packReference, stickerPacks: [packReference], parentNavigationController: strongSelf.controllerInteraction.navigationController(), sendSticker: { [weak self] fileReference, sourceNode, sourceRect in
if let strongSelf = self {
return strongSelf.controllerInteraction.sendSticker(fileReference, false, false, nil, false, sourceNode, sourceRect, nil)
return strongSelf.controllerInteraction.sendSticker(fileReference, false, false, nil, false, sourceNode, sourceRect, nil, [])
} else {
return false
}
@ -322,7 +322,7 @@ final class StickerPaneSearchContentNode: ASDisplayNode, PaneSearchContentNode {
}
}, sendSticker: { [weak self] file, sourceView, sourceRect in
if let strongSelf = self {
let _ = strongSelf.controllerInteraction.sendSticker(file, false, false, nil, false, sourceView, sourceRect, nil)
let _ = strongSelf.controllerInteraction.sendSticker(file, false, false, nil, false, sourceView, sourceRect, nil, [])
}
}, getItemIsPreviewed: { item in
return inputNodeInteraction.previewedStickerPackItem == .pack(item.file)

View File

@ -126,7 +126,7 @@ final class StickersChatInputContextPanelItemNode: ListViewItemNode {
for i in 0 ..< self.nodes.count {
if self.nodes[i].frame.contains(location) {
let file = item.files[i]
let _ = item.interfaceInteraction.sendSticker(.standalone(media: file), true, self.nodes[i].view, self.nodes[i].bounds, nil)
let _ = item.interfaceInteraction.sendSticker(.standalone(media: file), true, self.nodes[i].view, self.nodes[i].bounds, nil, [])
break
}
}

View File

@ -137,7 +137,7 @@ final class StickersChatInputContextPanelNode: ChatInputContextPanelNode {
.action(ContextMenuActionItem(text: strongSelf.strings.StickerPack_Send, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Resend"), color: theme.contextMenu.primaryColor) }, action: { _, f in
f(.default)
let _ = controllerInteraction.sendSticker(.standalone(media: item.file), false, false, nil, true, itemNode.view, itemNode.bounds, nil)
let _ = controllerInteraction.sendSticker(.standalone(media: item.file), false, false, nil, true, itemNode.view, itemNode.bounds, nil, [])
})),
.action(ContextMenuActionItem(text: isStarred ? strongSelf.strings.Stickers_RemoveFromFavorites : strongSelf.strings.Stickers_AddToFavorites, icon: { theme in generateTintedImage(image: isStarred ? UIImage(bundleImageName: "Chat/Context Menu/Unfave") : UIImage(bundleImageName: "Chat/Context Menu/Fave"), color: theme.contextMenu.primaryColor) }, action: { [weak self] _, f in
f(.default)
@ -181,7 +181,7 @@ final class StickersChatInputContextPanelNode: ChatInputContextPanelNode {
if let packReference = packReference {
let controller = StickerPackScreen(context: strongSelf.context, mainStickerPack: packReference, stickerPacks: [packReference], parentNavigationController: controllerInteraction.navigationController(), sendSticker: { file, sourceNode, sourceRect in
if let strongSelf = self, let controllerInteraction = strongSelf.controllerInteraction {
return controllerInteraction.sendSticker(file, false, false, nil, true, sourceNode, sourceRect, nil)
return controllerInteraction.sendSticker(file, false, false, nil, true, sourceNode, sourceRect, nil, [])
} else {
return false
}

View File

@ -193,12 +193,12 @@ public final class ChatTextInputTextUrlAttribute: NSObject {
}
public final class ChatTextInputTextCustomEmojiAttribute: NSObject {
public let stickerPack: StickerPackReference?
public let interactivelySelectedFromPackId: ItemCollectionId?
public let fileId: Int64
public let file: TelegramMediaFile?
public init(stickerPack: StickerPackReference?, fileId: Int64, file: TelegramMediaFile?) {
self.stickerPack = stickerPack
public init(interactivelySelectedFromPackId: ItemCollectionId?, fileId: Int64, file: TelegramMediaFile?) {
self.interactivelySelectedFromPackId = interactivelySelectedFromPackId
self.fileId = fileId
self.file = file

View File

@ -165,7 +165,7 @@ public func generateChatInputTextEntities(_ text: NSAttributedString, maxAnimate
} else if key == ChatTextInputAttributes.spoiler {
entities.append(MessageTextEntity(range: range.lowerBound ..< range.upperBound, type: .Spoiler))
} else if key == ChatTextInputAttributes.customEmoji, let value = value as? ChatTextInputTextCustomEmojiAttribute {
entities.append(MessageTextEntity(range: range.lowerBound ..< range.upperBound, type: .CustomEmoji(stickerPack: value.stickerPack, fileId: value.fileId)))
entities.append(MessageTextEntity(range: range.lowerBound ..< range.upperBound, type: .CustomEmoji(stickerPack: nil, fileId: value.fileId)))
}
}
})

View File

@ -41,8 +41,8 @@ public func chatInputStateStringWithAppliedEntities(_ text: String, entities: [M
string.addAttribute(ChatTextInputAttributes.underline, value: true as NSNumber, range: range)
case .Spoiler:
string.addAttribute(ChatTextInputAttributes.spoiler, value: true as NSNumber, range: range)
case let .CustomEmoji(stickerPack, fileId):
string.addAttribute(ChatTextInputAttributes.customEmoji, value: ChatTextInputTextCustomEmojiAttribute(stickerPack: stickerPack, fileId: fileId, file: nil), range: range)
case let .CustomEmoji(_, fileId):
string.addAttribute(ChatTextInputAttributes.customEmoji, value: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: fileId, file: nil), range: range)
default:
break
}
@ -250,8 +250,8 @@ public func stringWithAppliedEntities(_ text: String, entities: [MessageTextEnti
string.addAttribute(NSAttributedString.Key(rawValue: TelegramTextAttributes.Timecode), value: TelegramTimecode(time: time, text: text), range: range)
}
}
case let .CustomEmoji(stickerPack, fileId):
string.addAttribute(ChatTextInputAttributes.customEmoji, value: ChatTextInputTextCustomEmojiAttribute(stickerPack: stickerPack, fileId: fileId, file: message?.associatedMedia[MediaId(namespace: Namespaces.Media.CloudFile, id: fileId)] as? TelegramMediaFile), range: range)
case let .CustomEmoji(_, fileId):
string.addAttribute(ChatTextInputAttributes.customEmoji, value: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: fileId, file: message?.associatedMedia[MediaId(namespace: Namespaces.Media.CloudFile, id: fileId)] as? TelegramMediaFile), range: range)
default:
break
}

View File

@ -199,17 +199,17 @@ final class WatchSendMessageHandler: WatchRequestHandler {
if args.replyToMid != 0, let peerId = peerId {
replyMessageId = MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: args.replyToMid)
}
messageSignal = .single((.message(text: args.text, attributes: [], inlineStickers: [:], mediaReference: nil, replyToMessageId: replyMessageId, localGroupingKey: nil, correlationId: nil), peerId))
messageSignal = .single((.message(text: args.text, attributes: [], inlineStickers: [:], mediaReference: nil, replyToMessageId: replyMessageId, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []), peerId))
} else if let args = subscription as? TGBridgeSendLocationMessageSubscription, let location = args.location {
let peerId = makePeerIdFromBridgeIdentifier(args.peerId)
let map = TelegramMediaMap(latitude: location.latitude, longitude: location.longitude, heading: nil, accuracyRadius: nil, geoPlace: nil, venue: makeVenue(from: location.venue), liveBroadcastingTimeout: nil, liveProximityNotificationRadius: nil)
messageSignal = .single((.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: map), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil), peerId))
messageSignal = .single((.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: map), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []), peerId))
} else if let args = subscription as? TGBridgeSendStickerMessageSubscription {
let peerId = makePeerIdFromBridgeIdentifier(args.peerId)
messageSignal = mediaForSticker(documentId: args.document.documentId, account: context.account)
|> map({ media -> (EnqueueMessage?, PeerId?) in
if let media = media {
return (.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil), peerId)
return (.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []), peerId)
} else {
return (nil, nil)
}
@ -720,7 +720,7 @@ final class WatchAudioHandler: WatchRequestHandler {
replyMessageId = MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: replyToMid)
}
let _ = enqueueMessages(account: context.account, peerId: peerId, messages: [.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: randomId), partialReference: nil, resource: resource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "audio/ogg", size: Int64(data.count), attributes: [.Audio(isVoice: true, duration: Int(duration), title: nil, performer: nil, waveform: nil)])), replyToMessageId: replyMessageId, localGroupingKey: nil, correlationId: nil)]).start()
let _ = enqueueMessages(account: context.account, peerId: peerId, messages: [.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: randomId), partialReference: nil, resource: resource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "audio/ogg", size: Int64(data.count), attributes: [.Audio(isVoice: true, duration: Int(duration), title: nil, performer: nil, waveform: nil)])), replyToMessageId: replyMessageId, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])]).start()
}
})
} else {