[WIP] Animated emoji

This commit is contained in:
Ali
2022-07-08 19:53:20 +02:00
parent 1ac654e8b2
commit ed59ead31e
108 changed files with 1005 additions and 678 deletions

View File

@@ -247,7 +247,8 @@ private class AdMessagesHistoryContextImpl {
media: self.media,
peers: messagePeers,
associatedMessages: SimpleDictionary<MessageId, Message>(),
associatedMessageIds: []
associatedMessageIds: [],
associatedMedia: [:]
)
}
}

View File

@@ -16,6 +16,16 @@ public final class EngineChatList {
case later(than: EngineChatList.Item.Index?)
case earlier(than: EngineChatList.Item.Index?)
}
public struct Draft {
public var text: String
public var entities: [MessageTextEntity]
public init(text: String, entities: [MessageTextEntity]) {
self.text = text
self.entities = entities
}
}
public final class Item {
public typealias Index = ChatListIndex
@@ -24,7 +34,7 @@ public final class EngineChatList {
public let messages: [EngineMessage]
public let readCounters: EnginePeerReadCounters?
public let isMuted: Bool
public let draftText: String?
public let draft: Draft?
public let renderedPeer: EngineRenderedPeer
public let presence: EnginePeer.Presence?
public let hasUnseenMentions: Bool
@@ -37,7 +47,7 @@ public final class EngineChatList {
messages: [EngineMessage],
readCounters: EnginePeerReadCounters?,
isMuted: Bool,
draftText: String?,
draft: Draft?,
renderedPeer: EngineRenderedPeer,
presence: EnginePeer.Presence?,
hasUnseenMentions: Bool,
@@ -49,7 +59,7 @@ public final class EngineChatList {
self.messages = messages
self.readCounters = readCounters
self.isMuted = isMuted
self.draftText = draftText
self.draft = draft
self.renderedPeer = renderedPeer
self.presence = presence
self.hasUnseenMentions = hasUnseenMentions
@@ -209,11 +219,11 @@ extension EngineChatList.Item {
convenience init?(_ entry: ChatListEntry) {
switch entry {
case let .MessageEntry(index, messages, readState, isRemovedFromTotalUnreadCount, embeddedState, renderedPeer, presence, tagSummaryInfo, hasFailed, isContact):
var draftText: String?
var draft: EngineChatList.Draft?
if let embeddedState = embeddedState, let _ = embeddedState.overrideChatTimestamp {
if let opaqueState = _internal_decodeStoredChatInterfaceState(state: embeddedState) {
if let text = opaqueState.synchronizeableInputState?.text {
draftText = text
draft = EngineChatList.Draft(text: text, entities: opaqueState.synchronizeableInputState?.entities ?? [])
}
}
}
@@ -239,7 +249,7 @@ extension EngineChatList.Item {
messages: messages.map(EngineMessage.init),
readCounters: readState.flatMap(EnginePeerReadCounters.init),
isMuted: isRemovedFromTotalUnreadCount,
draftText: draftText,
draft: draft,
renderedPeer: EngineRenderedPeer(renderedPeer),
presence: presence.flatMap(EnginePeer.Presence.init),
hasUnseenMentions: hasUnseenMentions,

View File

@@ -75,6 +75,9 @@ public final class EngineMessage {
public var associatedMessageIds: [EngineMessage.Id] {
return self.impl.associatedMessageIds
}
public var associatedMedia: [MediaId: Media] {
return self.impl.associatedMedia
}
public var index: MessageIndex {
return self.impl.index
@@ -100,7 +103,8 @@ public final class EngineMessage {
media: [EngineMedia],
peers: [EnginePeer.Id: EnginePeer],
associatedMessages: [EngineMessage.Id: EngineMessage],
associatedMessageIds: [EngineMessage.Id]
associatedMessageIds: [EngineMessage.Id],
associatedMedia: [MediaId: Media]
) {
var mappedPeers: [PeerId: Peer] = [:]
for (id, peer) in peers {
@@ -132,7 +136,8 @@ public final class EngineMessage {
media: media.map { $0._asMedia() },
peers: SimpleDictionary(mappedPeers),
associatedMessages: SimpleDictionary(mappedAssociatedMessages),
associatedMessageIds: associatedMessageIds
associatedMessageIds: associatedMessageIds,
associatedMedia: associatedMedia
)
}

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, 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)
} else {
return .message(text: caption, attributes: filteredAttributes, mediaReference: nil, replyToMessageId: replyToMessageId, localGroupingKey: nil, correlationId: correlationId)
return .message(text: caption, attributes: filteredAttributes, inlineStickers: [:], mediaReference: nil, replyToMessageId: replyToMessageId, localGroupingKey: nil, correlationId: correlationId)
}
} else {
return .message(text: "", attributes: attributes, 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)
}
} else if let file = internalReference.file, internalReference.type == "gif" {
return .message(text: caption, attributes: attributes, 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)
} else if let image = internalReference.image {
return .message(text: caption, attributes: attributes, 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)
} else if let file = internalReference.file {
return .message(text: caption, attributes: attributes, 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)
} 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, 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)
} else {
return .message(text: caption, attributes: attributes, mediaReference: nil, replyToMessageId: replyToMessageId, localGroupingKey: nil, correlationId: correlationId)
return .message(text: caption, attributes: attributes, inlineStickers: [:], mediaReference: nil, replyToMessageId: replyToMessageId, localGroupingKey: nil, correlationId: correlationId)
}
} 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, 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)
} else {
return .message(text: caption, attributes: attributes, mediaReference: nil, replyToMessageId: replyToMessageId, localGroupingKey: nil, correlationId: correlationId)
return .message(text: caption, attributes: attributes, inlineStickers: [:], mediaReference: nil, replyToMessageId: replyToMessageId, localGroupingKey: nil, correlationId: correlationId)
}
}
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, mediaReference: nil, replyToMessageId: replyToMessageId, localGroupingKey: nil, correlationId: correlationId)
return .message(text: text, attributes: attributes, inlineStickers: [:], mediaReference: nil, replyToMessageId: replyToMessageId, localGroupingKey: nil, correlationId: correlationId)
case let .mapLocation(media, replyMarkup):
if let replyMarkup = replyMarkup {
attributes.append(replyMarkup)
}
return .message(text: "", attributes: attributes, 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)
case let .contact(media, replyMarkup):
if let replyMarkup = replyMarkup {
attributes.append(replyMarkup)
}
return .message(text: "", attributes: attributes, 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)
case let .invoice(media, replyMarkup):
if let replyMarkup = replyMarkup {
attributes.append(replyMarkup)
}
return .message(text: "", attributes: attributes, 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)
}
}

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: [], 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)]) |> mapToSignal { _ -> Signal<Void, NoError> in
return .complete()
}
}

View File

@@ -0,0 +1,5 @@
import Foundation
import Postbox
import TelegramApi
import SwiftSignalKit

View File

@@ -1,5 +1,6 @@
import SwiftSignalKit
import Postbox
import TelegramApi
public extension TelegramEngine {
final class Stickers {
@@ -155,5 +156,36 @@ public extension TelegramEngine {
}
|> ignoreValues
}
public func resolveInlineSticker(fileId: Int64) -> Signal<TelegramMediaFile?, NoError> {
return self.account.postbox.transaction { transaction -> TelegramMediaFile? in
return transaction.getMedia(MediaId(namespace: Namespaces.Media.CloudFile, id: fileId)) as? TelegramMediaFile
}
|> mapToSignal { cachedFile -> Signal<TelegramMediaFile?, NoError> in
if let cachedFile = cachedFile {
return .single(cachedFile)
}
return self.account.network.request(Api.functions.messages.getCustomEmojiDocuments(documentId: [fileId]))
|> map(Optional.init)
|> `catch` { _ -> Signal<[Api.Document]?, NoError> in
return .single(nil)
}
|> mapToSignal { result -> Signal<TelegramMediaFile?, NoError> in
guard let result = result else {
return .single(nil)
}
return self.account.postbox.transaction { transaction -> TelegramMediaFile? in
for document in result {
if let file = telegramMediaFileFromApiDocument(document) {
transaction.storeMediaIfNotPresent(media: file)
}
}
return transaction.getMedia(MediaId(namespace: Namespaces.Media.CloudFile, id: fileId)) as? TelegramMediaFile
}
}
}
}
}
}