mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-10-09 03:20:48 +00:00
[WIP] Serialization
This commit is contained in:
parent
c178023779
commit
8918f70173
@ -42,9 +42,19 @@ public struct ItemCollectionViewEntry {
|
||||
}
|
||||
}
|
||||
|
||||
private func fetchLowerEntries(namespaces: [ItemCollectionId.Namespace], collectionId: ItemCollectionId, collectionIndex: Int32, itemIndex: ItemCollectionItemIndex, count: Int, lowerCollectionId: (_ namespaceList: [ItemCollectionId.Namespace], _ collectionId: ItemCollectionId, _ collectionIndex: Int32) -> (ItemCollectionId, Int32)?, lowerItems: (_ collectionId: ItemCollectionId, _ itemIndex: ItemCollectionItemIndex, _ count: Int) -> [ItemCollectionItem]) -> [ItemCollectionViewEntry] {
|
||||
public struct RawItemCollectionViewEntry {
|
||||
public let index: ItemCollectionViewEntryIndex
|
||||
public let data: Data
|
||||
|
||||
var entries: [ItemCollectionViewEntry] = []
|
||||
public init(index: ItemCollectionViewEntryIndex, data: Data) {
|
||||
self.index = index
|
||||
self.data = data
|
||||
}
|
||||
}
|
||||
|
||||
private func fetchLowerEntries(namespaces: [ItemCollectionId.Namespace], collectionId: ItemCollectionId, collectionIndex: Int32, itemIndex: ItemCollectionItemIndex, count: Int, lowerCollectionId: (_ namespaceList: [ItemCollectionId.Namespace], _ collectionId: ItemCollectionId, _ collectionIndex: Int32) -> (ItemCollectionId, Int32)?, lowerItems: (_ collectionId: ItemCollectionId, _ itemIndex: ItemCollectionItemIndex, _ count: Int) -> [ItemCollectionItem]) -> [RawItemCollectionViewEntry] {
|
||||
|
||||
var entries: [RawItemCollectionViewEntry] = []
|
||||
|
||||
var currentCollectionIndex = collectionIndex
|
||||
var currentCollectionId = collectionId
|
||||
@ -75,9 +85,9 @@ private func fetchLowerEntries(namespaces: [ItemCollectionId.Namespace], collect
|
||||
return entries
|
||||
}
|
||||
|
||||
private func fetchHigherEntries(namespaces: [ItemCollectionId.Namespace], collectionId: ItemCollectionId, collectionIndex: Int32, itemIndex: ItemCollectionItemIndex, count: Int, higherCollectionId: (_ namespaceList: [ItemCollectionId.Namespace], _ collectionId: ItemCollectionId, _ collectionIndex: Int32) -> (ItemCollectionId, Int32)?, higherItems: (_ collectionId: ItemCollectionId, _ itemIndex: ItemCollectionItemIndex, _ count: Int) -> [ItemCollectionItem]) -> [ItemCollectionViewEntry] {
|
||||
private func fetchHigherEntries(namespaces: [ItemCollectionId.Namespace], collectionId: ItemCollectionId, collectionIndex: Int32, itemIndex: ItemCollectionItemIndex, count: Int, higherCollectionId: (_ namespaceList: [ItemCollectionId.Namespace], _ collectionId: ItemCollectionId, _ collectionIndex: Int32) -> (ItemCollectionId, Int32)?, higherItems: (_ collectionId: ItemCollectionId, _ itemIndex: ItemCollectionItemIndex, _ count: Int) -> [ItemCollectionItem]) -> [RawItemCollectionViewEntry] {
|
||||
|
||||
var entries: [ItemCollectionViewEntry] = []
|
||||
var entries: [RawItemCollectionViewEntry] = []
|
||||
|
||||
var currentCollectionIndex = collectionIndex
|
||||
var currentCollectionId = collectionId
|
||||
@ -115,11 +125,11 @@ private func aroundEntries(namespaces: [ItemCollectionId.Namespace],
|
||||
lowerCollectionId: (_ namespaceList: [ItemCollectionId.Namespace], _ collectionId: ItemCollectionId, _ collectionIndex: Int32) -> (ItemCollectionId, Int32)?,
|
||||
fetchLowerItems: (_ collectionId: ItemCollectionId, _ itemIndex: ItemCollectionItemIndex, _ count: Int) -> [ItemCollectionItem],
|
||||
higherCollectionId: (_ namespaceList: [ItemCollectionId.Namespace], _ collectionId: ItemCollectionId, _ collectionIndex: Int32) -> (ItemCollectionId, Int32)?,
|
||||
fetchHigherItems: (_ collectionId: ItemCollectionId, _ itemIndex: ItemCollectionItemIndex, _ count: Int) -> [ItemCollectionItem]) -> ([ItemCollectionViewEntry], ItemCollectionViewEntry?, ItemCollectionViewEntry?) {
|
||||
var lowerEntries: [ItemCollectionViewEntry] = []
|
||||
var upperEntries: [ItemCollectionViewEntry] = []
|
||||
var lower: ItemCollectionViewEntry?
|
||||
var upper: ItemCollectionViewEntry?
|
||||
fetchHigherItems: (_ collectionId: ItemCollectionId, _ itemIndex: ItemCollectionItemIndex, _ count: Int) -> [ItemCollectionItem]) -> ([RawItemCollectionViewEntry], RawItemCollectionViewEntry?, RawItemCollectionViewEntry?) {
|
||||
var lowerEntries: [RawItemCollectionViewEntry] = []
|
||||
var upperEntries: [RawItemCollectionViewEntry] = []
|
||||
var lower: RawItemCollectionViewEntry?
|
||||
var upper: RawItemCollectionViewEntry?
|
||||
|
||||
let selectedAroundIndex: ItemCollectionViewEntryIndex
|
||||
if let aroundIndex = aroundIndex, let aroundCollectionIndex = collectionIndexById(aroundIndex.collectionId) {
|
||||
@ -153,7 +163,7 @@ private func aroundEntries(namespaces: [ItemCollectionId.Namespace],
|
||||
}
|
||||
|
||||
if lowerEntries.count != 0 && lowerEntries.count + upperEntries.count < count {
|
||||
var additionalLowerEntries: [ItemCollectionViewEntry] = fetchLowerEntries(namespaces: namespaces, collectionId: lowerEntries.last!.index.collectionId, collectionIndex: lowerEntries.last!.index.collectionIndex, itemIndex: lowerEntries.last!.index.itemIndex, count: count - lowerEntries.count - upperEntries.count + 1, lowerCollectionId: lowerCollectionId, lowerItems: fetchLowerItems)
|
||||
var additionalLowerEntries: [RawItemCollectionViewEntry] = fetchLowerEntries(namespaces: namespaces, collectionId: lowerEntries.last!.index.collectionId, collectionIndex: lowerEntries.last!.index.collectionIndex, itemIndex: lowerEntries.last!.index.itemIndex, count: count - lowerEntries.count - upperEntries.count + 1, lowerCollectionId: lowerCollectionId, lowerItems: fetchLowerItems)
|
||||
|
||||
if additionalLowerEntries.count >= count - lowerEntries.count + upperEntries.count + 1 {
|
||||
lower = additionalLowerEntries.last
|
||||
@ -162,7 +172,7 @@ private func aroundEntries(namespaces: [ItemCollectionId.Namespace],
|
||||
lowerEntries.append(contentsOf: additionalLowerEntries)
|
||||
}
|
||||
|
||||
var entries: [ItemCollectionViewEntry] = []
|
||||
var entries: [RawItemCollectionViewEntry] = []
|
||||
entries.append(contentsOf: lowerEntries.reversed())
|
||||
entries.append(contentsOf: upperEntries)
|
||||
return (entries: entries, lower: lower, upper: upper)
|
||||
|
@ -23,6 +23,7 @@ swift_library(
|
||||
"//submodules/Utils/RangeSet:RangeSet",
|
||||
"//submodules/Utils/DarwinDirStat",
|
||||
"//submodules/Emoji",
|
||||
"//submodules/TelegramCore/FlatBuffers",
|
||||
"//submodules/TelegramCore/FlatSerialization",
|
||||
],
|
||||
visibility = [
|
||||
|
@ -26,7 +26,7 @@ genrule(
|
||||
rm -rf "$$BUILD_DIR"
|
||||
mkdir -p "$$BUILD_DIR"
|
||||
|
||||
"$$FLATC" --swift -o "$$BUILD_DIR" {flatc_input}
|
||||
"$$FLATC" --require-explicit-ids --swift -o "$$BUILD_DIR" {flatc_input}
|
||||
""".format(
|
||||
flatc_input=flatc_input
|
||||
) + "\n" + "\n".join([
|
||||
|
@ -0,0 +1,9 @@
|
||||
include "PeerId.fbs";
|
||||
|
||||
namespace TelegramCore;
|
||||
|
||||
struct MessageId {
|
||||
peerId: PeerId (id: 0);
|
||||
namespace: int32 (id: 1);
|
||||
id: int32 (id: 2);
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
include "MessageId.fbs";
|
||||
include "PeerId.fbs";
|
||||
include "PeerReference.fbs";
|
||||
include "StickerPackReference.fbs";
|
||||
|
||||
namespace TelegramCore;
|
||||
|
||||
table MessageReference {
|
||||
peer:PeerReference (id: 0, required);
|
||||
author:PeerReference (id: 1);
|
||||
messageId:MessageId (id: 2, required);
|
||||
timestamp:int32 (id: 3);
|
||||
incoming:bool (id: 4);
|
||||
secret:bool (id: 5);
|
||||
threadId:int64 (id: 6);
|
||||
}
|
||||
|
||||
table WebpageReference {
|
||||
webpageId:int64 (id: 0);
|
||||
url:string (id: 1, required);
|
||||
}
|
||||
|
||||
table PartialMediaReference_Message {
|
||||
message:MessageReference (id: 0);
|
||||
}
|
||||
|
||||
table PartialMediaReference_WebPage {
|
||||
webPage:WebpageReference (id: 0);
|
||||
}
|
||||
|
||||
table PartialMediaReference_StickerPack {
|
||||
stickerPack:StickerPackReference (id: 0, required);
|
||||
}
|
||||
|
||||
table PartialMediaReference_SavedGif {
|
||||
}
|
||||
|
||||
table PartialMediaReference_SavedSticker {
|
||||
}
|
||||
|
||||
table PartialMediaReference_RecentSticker {
|
||||
}
|
||||
|
||||
union PartialMediaReference_Value {
|
||||
PartialMediaReference_Message,
|
||||
PartialMediaReference_WebPage,
|
||||
PartialMediaReference_StickerPack,
|
||||
PartialMediaReference_SavedGif,
|
||||
PartialMediaReference_SavedSticker,
|
||||
PartialMediaReference_RecentSticker
|
||||
}
|
||||
|
||||
table PartialMediaReference {
|
||||
value:PartialMediaReference_Value (id: 1, required);
|
||||
}
|
||||
|
||||
root_type PartialMediaReference;
|
@ -0,0 +1,6 @@
|
||||
namespace TelegramCore;
|
||||
|
||||
struct PeerId {
|
||||
namespace: int32 (id: 0);
|
||||
id: int64 (id: 1);
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
namespace TelegramCore;
|
||||
|
||||
table PeerReference_User {
|
||||
id:int64 (id: 0);
|
||||
accessHash:int64 (id: 1);
|
||||
}
|
||||
|
||||
table PeerReference_Group {
|
||||
id:int64 (id: 0);
|
||||
}
|
||||
|
||||
table PeerReference_Channel {
|
||||
id:int64 (id: 0);
|
||||
accessHash:int64 (id: 1);
|
||||
}
|
||||
|
||||
union PeerReference_Value {
|
||||
PeerReference_User,
|
||||
PeerReference_Group,
|
||||
PeerReference_Channel
|
||||
}
|
||||
|
||||
table PeerReference {
|
||||
value:PeerReference_Value (id: 1, required);
|
||||
}
|
||||
|
||||
root_type PeerReference;
|
@ -0,0 +1,54 @@
|
||||
namespace TelegramCore;
|
||||
|
||||
table StickerPackReference_Id {
|
||||
id:int64 (id: 0);
|
||||
accessHash:int64 (id: 1);
|
||||
}
|
||||
|
||||
table StickerPackReference_Name {
|
||||
name:string (id: 0, required);
|
||||
}
|
||||
|
||||
table StickerPackReference_AnimatedEmoji {
|
||||
}
|
||||
|
||||
table StickerPackReference_Dice {
|
||||
emoji:string (id: 0, required);
|
||||
}
|
||||
|
||||
table StickerPackReference_AnimatedEmojiAnimations {
|
||||
}
|
||||
|
||||
table StickerPackReference_PremiumGifts {
|
||||
}
|
||||
|
||||
table StickerPackReference_EmojiGenericAnimations {
|
||||
}
|
||||
|
||||
table StickerPackReference_IconStatusEmoji {
|
||||
}
|
||||
|
||||
table StickerPackReference_IconTopicEmoji {
|
||||
}
|
||||
|
||||
table StickerPackReference_IconChannelStatusEmoji {
|
||||
}
|
||||
|
||||
union StickerPackReference_Value {
|
||||
StickerPackReference_Id,
|
||||
StickerPackReference_Name,
|
||||
StickerPackReference_AnimatedEmoji,
|
||||
StickerPackReference_Dice,
|
||||
StickerPackReference_AnimatedEmojiAnimations,
|
||||
StickerPackReference_PremiumGifts,
|
||||
StickerPackReference_EmojiGenericAnimations,
|
||||
StickerPackReference_IconStatusEmoji,
|
||||
StickerPackReference_IconTopicEmoji,
|
||||
StickerPackReference_IconChannelStatusEmoji
|
||||
}
|
||||
|
||||
table StickerPackReference {
|
||||
value:StickerPackReference_Value (id: 1, required);
|
||||
}
|
||||
|
||||
root_type StickerPackReference;
|
@ -1,11 +1,25 @@
|
||||
include "MediaId.fbs";
|
||||
include "TelegramMediaResource.fbs";
|
||||
include "TelegramMediaFileAttribute.fbs";
|
||||
include "TelegramMediaImageRepresentation.fbs";
|
||||
include "VideoThumbnail.fbs";
|
||||
include "TelegramMediaImage.fbs";
|
||||
include "PartialMediaReference.fbs";
|
||||
|
||||
namespace TelegramCore;
|
||||
|
||||
table TelegramMediaFile {
|
||||
id: MediaId;
|
||||
videoThumbnails: [VideoThumbnail];
|
||||
fileId:MediaId (id: 0, required);
|
||||
partialReference:PartialMediaReference (id: 1);
|
||||
resource:TelegramMediaResource (id: 2, required);
|
||||
previewRepresentations:[TelegramMediaImageRepresentation] (id: 3);
|
||||
videoThumbnails:[VideoThumbnail] (id: 4);
|
||||
videoCover:TelegramMediaImage (id: 5);
|
||||
immediateThumbnailData:[ubyte] (id: 6);
|
||||
mimeType:string (id: 7, required);
|
||||
size:int64 (id: 8);
|
||||
attributes:[TelegramMediaFileAttribute] (id: 9);
|
||||
alternativeRepresentations:[TelegramMediaFile] (id: 10);
|
||||
}
|
||||
|
||||
root_type TelegramMediaFile;
|
||||
|
@ -0,0 +1,85 @@
|
||||
include "StickerPackReference.fbs";
|
||||
|
||||
namespace TelegramCore;
|
||||
|
||||
table TelegramMediaFileAttribute_FileName {
|
||||
fileName:string (id: 0, required);
|
||||
}
|
||||
|
||||
table StickerMaskCoords {
|
||||
n:int32 (id: 0);
|
||||
x:float32 (id: 1);
|
||||
y:float32 (id: 2);
|
||||
zoom:float32 (id: 3);
|
||||
}
|
||||
|
||||
table TelegramMediaFileAttribute_Sticker {
|
||||
displayText:string (id: 0, required);
|
||||
packReference:StickerPackReference (id: 1);
|
||||
maskData:StickerMaskCoords (id: 2);
|
||||
}
|
||||
|
||||
table TelegramMediaFileAttribute_ImageSize {
|
||||
width:int32 (id: 0);
|
||||
height:int32 (id: 1);
|
||||
}
|
||||
|
||||
table TelegramMediaFileAttribute_Animated {
|
||||
}
|
||||
|
||||
table TelegramMediaFileAttribute_Video {
|
||||
duration:float32 (id: 0);
|
||||
width:int32 (id: 1);
|
||||
height:int32 (id: 2);
|
||||
flags:int32 (id: 3);
|
||||
preloadSize:int32 (id: 4);
|
||||
coverTime:float32 (id: 5);
|
||||
videoCodec:string (id: 6);
|
||||
}
|
||||
|
||||
table TelegramMediaFileAttribute_Audio {
|
||||
isVoice:bool (id: 0);
|
||||
duration:int32 (id: 1);
|
||||
title:string (id: 2);
|
||||
performer:string (id: 3);
|
||||
waveform:[ubyte] (id: 4);
|
||||
}
|
||||
|
||||
table TelegramMediaFileAttribute_HasLinkedStickers {
|
||||
}
|
||||
|
||||
table TelegramMediaFileAttribute_HintFileIsLarge {
|
||||
}
|
||||
|
||||
table TelegramMediaFileAttribute_HintIsValidated {
|
||||
}
|
||||
|
||||
table TelegramMediaFileAttribute_NoPremium {
|
||||
}
|
||||
|
||||
table TelegramMediaFileAttribute_CustomEmoji {
|
||||
isPremium:bool (id: 0);
|
||||
isSingleColor:bool (id: 1);
|
||||
alt:string (id: 2, required);
|
||||
packReference:StickerPackReference (id: 3);
|
||||
}
|
||||
|
||||
union TelegramMediaFileAttribute_Value {
|
||||
TelegramMediaFileAttribute_FileName,
|
||||
TelegramMediaFileAttribute_Sticker,
|
||||
TelegramMediaFileAttribute_ImageSize,
|
||||
TelegramMediaFileAttribute_Animated,
|
||||
TelegramMediaFileAttribute_Video,
|
||||
TelegramMediaFileAttribute_Audio,
|
||||
TelegramMediaFileAttribute_HasLinkedStickers,
|
||||
TelegramMediaFileAttribute_HintFileIsLarge,
|
||||
TelegramMediaFileAttribute_HintIsValidated,
|
||||
TelegramMediaFileAttribute_NoPremium,
|
||||
TelegramMediaFileAttribute_CustomEmoji
|
||||
}
|
||||
|
||||
table TelegramMediaFileAttribute {
|
||||
value:TelegramMediaFileAttribute_Value (id: 1, required);
|
||||
}
|
||||
|
||||
root_type TelegramMediaFileAttribute;
|
@ -0,0 +1,51 @@
|
||||
include "MediaId.fbs";
|
||||
include "TelegramMediaImageRepresentation.fbs";
|
||||
include "StickerPackReference.fbs";
|
||||
include "PartialMediaReference.fbs";
|
||||
|
||||
namespace TelegramCore;
|
||||
|
||||
table TelegramMediaImageReference {
|
||||
imageId:int64 (id: 0);
|
||||
accessHash:int64 (id: 1);
|
||||
fileReference:[ubyte] (id: 2);
|
||||
}
|
||||
|
||||
table VideoRepresentation {
|
||||
width:int32 (id: 0);
|
||||
height:int32 (id: 1);
|
||||
resource:TelegramMediaResource (id: 2, required);
|
||||
startTimestamp:float32 (id: 3);
|
||||
}
|
||||
|
||||
table EmojiMarkup_Content_Emoji {
|
||||
fileId:int64 (id: 0);
|
||||
}
|
||||
|
||||
table EmojiMarkup_Content_Sticker {
|
||||
packReference:StickerPackReference (id: 0, required);
|
||||
fileId:int64 (id: 1);
|
||||
}
|
||||
|
||||
union EmojiMarkup_Content {
|
||||
EmojiMarkup_Content_Emoji,
|
||||
EmojiMarkup_Content_Sticker
|
||||
}
|
||||
|
||||
table EmojiMarkup {
|
||||
content:EmojiMarkup_Content (id: 1, required);
|
||||
backgroundColors:[int32] (id: 2);
|
||||
}
|
||||
|
||||
table TelegramMediaImage {
|
||||
imageId:MediaId (id: 0, required);
|
||||
representations:[TelegramMediaImageRepresentation] (id: 1);
|
||||
videoRepresentations:[VideoRepresentation] (id: 2);
|
||||
immediateThumbnailData:[ubyte] (id: 3);
|
||||
emojiMarkup:EmojiMarkup (id: 4);
|
||||
reference:TelegramMediaImageReference (id: 5);
|
||||
partialReference:PartialMediaReference (id: 6);
|
||||
flags:int32 (id: 7);
|
||||
}
|
||||
|
||||
root_type TelegramMediaImage;
|
@ -0,0 +1,22 @@
|
||||
include "TelegramMediaResource.fbs";
|
||||
|
||||
namespace TelegramCore;
|
||||
|
||||
enum TelegramMediaImageRepresentation_TypeHint:int32 {
|
||||
generic = 0,
|
||||
animated = 1,
|
||||
video = 2
|
||||
}
|
||||
|
||||
table TelegramMediaImageRepresentation {
|
||||
width:int32 (id: 0);
|
||||
height:int32 (id: 1);
|
||||
resource:TelegramMediaResource (id: 2, required);
|
||||
progressiveSizes:[int32] (id: 3);
|
||||
immediateThumbnailData:[ubyte] (id: 4);
|
||||
hasVideo:bool (id: 5);
|
||||
isPersonal:bool (id: 6);
|
||||
typeHint:TelegramMediaImageRepresentation_TypeHint (id: 7);
|
||||
}
|
||||
|
||||
root_type TelegramMediaImageRepresentation;
|
@ -0,0 +1,78 @@
|
||||
namespace TelegramCore;
|
||||
|
||||
table TelegramMediaResource_CloudFileMediaResource {
|
||||
datacenterId:int32 (id: 0);
|
||||
volumeId:int64 (id: 1);
|
||||
localId:int32 (id: 2);
|
||||
secret:int64 (id: 3);
|
||||
size:int64 (id: 4);
|
||||
fileReference:[ubyte] (id: 5);
|
||||
}
|
||||
|
||||
table TelegramMediaResource_CloudDocumentSizeMediaResource {
|
||||
datacenterId:int32 (id: 0);
|
||||
documentId:int64 (id: 1);
|
||||
accessHash:int64 (id: 2);
|
||||
sizeSpec:string (id: 3, required);
|
||||
fileReference:[ubyte] (id: 4);
|
||||
}
|
||||
|
||||
table TelegramMediaResource_CloudPhotoSizeMediaResource {
|
||||
datacenterId:int32 (id: 0);
|
||||
photoId:int64 (id: 1);
|
||||
accessHash:int64 (id: 2);
|
||||
sizeSpec:string (id: 3, required);
|
||||
size:int64 (id: 4);
|
||||
fileReference:[ubyte] (id: 5);
|
||||
}
|
||||
|
||||
enum CloudPeerPhotoSizeSpec:int32 {
|
||||
small = 0,
|
||||
fullSize = 1
|
||||
}
|
||||
|
||||
table TelegramMediaResource_CloudPeerPhotoSizeMediaResource {
|
||||
datacenterId:int32 (id: 0);
|
||||
photoId:int64 (id: 1);
|
||||
sizeSpec:CloudPeerPhotoSizeSpec (id: 2);
|
||||
volumeId:int64 (id: 3);
|
||||
localId:int32 (id: 4);
|
||||
}
|
||||
|
||||
table TelegramMediaResource_CloudStickerPackThumbnailMediaResource {
|
||||
datacenterId:int32 (id: 0);
|
||||
thumbVersion:int32 (id: 1);
|
||||
volumeId:int64 (id: 2);
|
||||
localId:int32 (id: 3);
|
||||
}
|
||||
|
||||
table TelegramMediaResource_CloudDocumentMediaResource {
|
||||
datacenterId:int32 (id: 0);
|
||||
fileId:int64 (id: 1);
|
||||
accessHash:int64 (id: 2);
|
||||
size:int64 (id: 3);
|
||||
fileReference:[ubyte] (id: 4);
|
||||
fileName:string (id: 5);
|
||||
}
|
||||
|
||||
table TelegramMediaResource_LocalFileMediaResource {
|
||||
fileId:int64 (id: 0);
|
||||
size:int64 (id: 1);
|
||||
isSecretRelated:bool (id: 2);
|
||||
}
|
||||
|
||||
union TelegramMediaResource_Value {
|
||||
TelegramMediaResource_CloudFileMediaResource,
|
||||
TelegramMediaResource_CloudDocumentSizeMediaResource,
|
||||
TelegramMediaResource_CloudPhotoSizeMediaResource,
|
||||
TelegramMediaResource_CloudPeerPhotoSizeMediaResource,
|
||||
TelegramMediaResource_CloudStickerPackThumbnailMediaResource,
|
||||
TelegramMediaResource_CloudDocumentMediaResource,
|
||||
TelegramMediaResource_LocalFileMediaResource
|
||||
}
|
||||
|
||||
table TelegramMediaResource {
|
||||
value:TelegramMediaResource_Value (id: 1, required);
|
||||
}
|
||||
|
||||
root_type TelegramMediaResource;
|
@ -1,7 +1,11 @@
|
||||
include "PixelDimensions.fbs";
|
||||
include "TelegramMediaResource.fbs";
|
||||
|
||||
namespace TelegramCore;
|
||||
|
||||
struct VideoThumbnail {
|
||||
dimensions: PixelDimensions;
|
||||
table VideoThumbnail {
|
||||
width:int32 (id: 0);
|
||||
height:int32 (id: 1);
|
||||
resource:TelegramMediaResource (id: 2, required);
|
||||
}
|
||||
|
||||
root_type VideoThumbnail;
|
||||
|
@ -2,7 +2,6 @@ import Foundation
|
||||
import Postbox
|
||||
import TelegramApi
|
||||
|
||||
|
||||
func dimensionsForFileAttributes(_ attributes: [TelegramMediaFileAttribute]) -> PixelDimensions? {
|
||||
for attribute in attributes {
|
||||
switch attribute {
|
||||
@ -183,7 +182,7 @@ func telegramMediaFileFromApiDocument(_ document: Api.Document, altDocuments: [A
|
||||
}
|
||||
}
|
||||
|
||||
var alternativeRepresentations: [Media] = []
|
||||
var alternativeRepresentations: [TelegramMediaFile] = []
|
||||
if let altDocuments {
|
||||
alternativeRepresentations = altDocuments.compactMap { telegramMediaFileFromApiDocument($0, altDocuments: []) }
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
import Foundation
|
||||
import Postbox
|
||||
import TelegramApi
|
||||
import FlatBuffers
|
||||
import FlatSerialization
|
||||
|
||||
public struct CloudFileMediaResourceId: Hashable, Equatable {
|
||||
let datacenterId: Int
|
||||
@ -956,3 +958,215 @@ public final class WallpaperDataResource: TelegramMediaResource {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
public func TelegramMediaResource_parse(flatBuffersData data: Data) throws -> TelegramMediaResource {
|
||||
var byteBuffer = ByteBuffer(data: data)
|
||||
let flatBuffersObject: TelegramCore_TelegramMediaResource = try getCheckedRoot(byteBuffer: &byteBuffer)
|
||||
|
||||
return try TelegramMediaResource_parse(flatBuffersObject: flatBuffersObject)
|
||||
}
|
||||
|
||||
public func TelegramMediaResource_parse(flatBuffersObject: TelegramCore_TelegramMediaResource) throws -> TelegramMediaResource {
|
||||
switch flatBuffersObject.valueType {
|
||||
case .telegrammediaresourceCloudfilemediaresource:
|
||||
guard let value = flatBuffersObject.value(type: TelegramCore_TelegramMediaResource_CloudFileMediaResource.self) else {
|
||||
throw FlatBuffersError.missingRequiredField
|
||||
}
|
||||
return CloudFileMediaResource(
|
||||
datacenterId: Int(value.datacenterId),
|
||||
volumeId: value.volumeId,
|
||||
localId: value.localId,
|
||||
secret: value.secret,
|
||||
size: value.size == 0 ? nil : value.size,
|
||||
fileReference: value.fileReference.isEmpty ? nil : Data(value.fileReference)
|
||||
)
|
||||
case .telegrammediaresourceClouddocumentsizemediaresource:
|
||||
guard let value = flatBuffersObject.value(type: TelegramCore_TelegramMediaResource_CloudDocumentSizeMediaResource.self) else {
|
||||
throw FlatBuffersError.missingRequiredField
|
||||
}
|
||||
return CloudDocumentSizeMediaResource(
|
||||
datacenterId: value.datacenterId,
|
||||
documentId: value.documentId,
|
||||
accessHash: value.accessHash,
|
||||
sizeSpec: value.sizeSpec,
|
||||
fileReference: value.fileReference.isEmpty ? nil : Data(value.fileReference)
|
||||
)
|
||||
case .telegrammediaresourceCloudphotosizemediaresource:
|
||||
guard let value = flatBuffersObject.value(type: TelegramCore_TelegramMediaResource_CloudPhotoSizeMediaResource.self) else {
|
||||
throw FlatBuffersError.missingRequiredField
|
||||
}
|
||||
return CloudPhotoSizeMediaResource(
|
||||
datacenterId: value.datacenterId,
|
||||
photoId: value.photoId,
|
||||
accessHash: value.accessHash,
|
||||
sizeSpec: value.sizeSpec,
|
||||
size: value.size == 0 ? nil : value.size,
|
||||
fileReference: value.fileReference.isEmpty ? nil : Data(value.fileReference)
|
||||
)
|
||||
case .telegrammediaresourceCloudpeerphotosizemediaresource:
|
||||
guard let value = flatBuffersObject.value(type: TelegramCore_TelegramMediaResource_CloudPeerPhotoSizeMediaResource.self) else {
|
||||
throw FlatBuffersError.missingRequiredField
|
||||
}
|
||||
let sizeSpec: CloudPeerPhotoSizeSpec
|
||||
switch value.sizeSpec {
|
||||
case .small:
|
||||
sizeSpec = .small
|
||||
case .fullSize:
|
||||
sizeSpec = .fullSize
|
||||
}
|
||||
return CloudPeerPhotoSizeMediaResource(
|
||||
datacenterId: value.datacenterId,
|
||||
photoId: value.photoId == Int64.min ? nil : value.photoId,
|
||||
sizeSpec: sizeSpec,
|
||||
volumeId: value.volumeId == Int64.min ? nil : value.volumeId,
|
||||
localId: value.localId == Int32.min ? nil : value.localId
|
||||
)
|
||||
case .telegrammediaresourceCloudstickerpackthumbnailmediaresource:
|
||||
guard let value = flatBuffersObject.value(type: TelegramCore_TelegramMediaResource_CloudStickerPackThumbnailMediaResource.self) else {
|
||||
throw FlatBuffersError.missingRequiredField
|
||||
}
|
||||
return CloudStickerPackThumbnailMediaResource(
|
||||
datacenterId: value.datacenterId,
|
||||
thumbVersion: value.thumbVersion == Int32.min ? nil : value.thumbVersion,
|
||||
volumeId: value.volumeId == Int64.min ? nil : value.volumeId,
|
||||
localId: value.localId == Int32.min ? nil : value.localId
|
||||
)
|
||||
case .telegrammediaresourceClouddocumentmediaresource:
|
||||
guard let value = flatBuffersObject.value(type: TelegramCore_TelegramMediaResource_CloudDocumentMediaResource.self) else {
|
||||
throw FlatBuffersError.missingRequiredField
|
||||
}
|
||||
return CloudDocumentMediaResource(
|
||||
datacenterId: Int(value.datacenterId),
|
||||
fileId: value.fileId,
|
||||
accessHash: value.accessHash,
|
||||
size: value.size == 0 ? nil : value.size,
|
||||
fileReference: value.fileReference.isEmpty ? nil : Data(value.fileReference),
|
||||
fileName: value.fileName
|
||||
)
|
||||
case .telegrammediaresourceLocalfilemediaresource:
|
||||
guard let value = flatBuffersObject.value(type: TelegramCore_TelegramMediaResource_LocalFileMediaResource.self) else {
|
||||
throw FlatBuffersError.missingRequiredField
|
||||
}
|
||||
return LocalFileMediaResource(
|
||||
fileId: value.fileId,
|
||||
size: value.size == Int64.min ? nil : value.size,
|
||||
isSecretRelated: value.isSecretRelated
|
||||
)
|
||||
case .none_:
|
||||
throw FlatBuffersError.missingRequiredField
|
||||
}
|
||||
}
|
||||
|
||||
public func TelegramMediaResource_serialize(resource: TelegramMediaResource, flatBuffersBuilder builder: inout FlatBufferBuilder) -> Offset? {
|
||||
switch resource {
|
||||
case let resource as CloudFileMediaResource:
|
||||
let fileReferenceOffset = resource.fileReference.flatMap { builder.createVector(bytes: $0) }
|
||||
|
||||
let start = TelegramCore_TelegramMediaResource_CloudFileMediaResource.startTelegramMediaResource_CloudFileMediaResource(&builder)
|
||||
|
||||
TelegramCore_TelegramMediaResource_CloudFileMediaResource.add(datacenterId: Int32(resource.datacenterId), &builder)
|
||||
TelegramCore_TelegramMediaResource_CloudFileMediaResource.add(volumeId: resource.volumeId, &builder)
|
||||
TelegramCore_TelegramMediaResource_CloudFileMediaResource.add(localId: resource.localId, &builder)
|
||||
TelegramCore_TelegramMediaResource_CloudFileMediaResource.add(secret: resource.secret, &builder)
|
||||
TelegramCore_TelegramMediaResource_CloudFileMediaResource.add(size: resource.size ?? 0, &builder)
|
||||
|
||||
if let fileReferenceOffset {
|
||||
TelegramCore_TelegramMediaResource_CloudFileMediaResource.addVectorOf(fileReference: fileReferenceOffset, &builder)
|
||||
}
|
||||
|
||||
let offset = TelegramCore_TelegramMediaResource_CloudFileMediaResource.endTelegramMediaResource_CloudFileMediaResource(&builder, start: start)
|
||||
return TelegramCore_TelegramMediaResource.createTelegramMediaResource(&builder, valueType: .telegrammediaresourceCloudfilemediaresource, valueOffset: offset)
|
||||
case let resource as CloudDocumentSizeMediaResource:
|
||||
let sizeSpecOffset = builder.create(string: resource.sizeSpec)
|
||||
let fileReferenceOffset = resource.fileReference.flatMap { builder.createVector(bytes: $0) }
|
||||
|
||||
let start = TelegramCore_TelegramMediaResource_CloudDocumentSizeMediaResource.startTelegramMediaResource_CloudDocumentSizeMediaResource(&builder)
|
||||
|
||||
TelegramCore_TelegramMediaResource_CloudDocumentSizeMediaResource.add(datacenterId: Int32(resource.datacenterId), &builder)
|
||||
TelegramCore_TelegramMediaResource_CloudDocumentSizeMediaResource.add(documentId: resource.documentId, &builder)
|
||||
TelegramCore_TelegramMediaResource_CloudDocumentSizeMediaResource.add(accessHash: resource.accessHash, &builder)
|
||||
TelegramCore_TelegramMediaResource_CloudDocumentSizeMediaResource.add(sizeSpec: sizeSpecOffset, &builder)
|
||||
if let fileReferenceOffset {
|
||||
TelegramCore_TelegramMediaResource_CloudDocumentSizeMediaResource.addVectorOf(fileReference: fileReferenceOffset, &builder)
|
||||
}
|
||||
|
||||
let offset = TelegramCore_TelegramMediaResource_CloudDocumentSizeMediaResource.endTelegramMediaResource_CloudDocumentSizeMediaResource(&builder, start: start)
|
||||
return TelegramCore_TelegramMediaResource.createTelegramMediaResource(&builder, valueType: .telegrammediaresourceClouddocumentsizemediaresource, valueOffset: offset)
|
||||
case let resource as CloudPhotoSizeMediaResource:
|
||||
let sizeSpecOffset = builder.create(string: resource.sizeSpec)
|
||||
let start = TelegramCore_TelegramMediaResource_CloudPhotoSizeMediaResource.startTelegramMediaResource_CloudPhotoSizeMediaResource(&builder)
|
||||
let fileReferenceOffset = resource.fileReference.flatMap { builder.createVector(bytes: $0) }
|
||||
|
||||
TelegramCore_TelegramMediaResource_CloudPhotoSizeMediaResource.add(datacenterId: Int32(resource.datacenterId), &builder)
|
||||
TelegramCore_TelegramMediaResource_CloudPhotoSizeMediaResource.add(photoId: resource.photoId, &builder)
|
||||
TelegramCore_TelegramMediaResource_CloudPhotoSizeMediaResource.add(accessHash: resource.accessHash, &builder)
|
||||
TelegramCore_TelegramMediaResource_CloudPhotoSizeMediaResource.add(sizeSpec: sizeSpecOffset, &builder)
|
||||
TelegramCore_TelegramMediaResource_CloudPhotoSizeMediaResource.add(size: resource.size ?? 0, &builder)
|
||||
if let fileReferenceOffset {
|
||||
TelegramCore_TelegramMediaResource_CloudPhotoSizeMediaResource.addVectorOf(fileReference: fileReferenceOffset, &builder)
|
||||
}
|
||||
|
||||
let offset = TelegramCore_TelegramMediaResource_CloudPhotoSizeMediaResource.endTelegramMediaResource_CloudPhotoSizeMediaResource(&builder, start: start)
|
||||
return TelegramCore_TelegramMediaResource.createTelegramMediaResource(&builder, valueType: .telegrammediaresourceCloudphotosizemediaresource, valueOffset: offset)
|
||||
case let resource as CloudPeerPhotoSizeMediaResource:
|
||||
let start = TelegramCore_TelegramMediaResource_CloudPeerPhotoSizeMediaResource.startTelegramMediaResource_CloudPeerPhotoSizeMediaResource(&builder)
|
||||
|
||||
let sizeSpec: TelegramCore_CloudPeerPhotoSizeSpec
|
||||
switch resource.sizeSpec {
|
||||
case .small:
|
||||
sizeSpec = .small
|
||||
case .fullSize:
|
||||
sizeSpec = .fullSize
|
||||
}
|
||||
|
||||
TelegramCore_TelegramMediaResource_CloudPeerPhotoSizeMediaResource.add(datacenterId: Int32(resource.datacenterId), &builder)
|
||||
TelegramCore_TelegramMediaResource_CloudPeerPhotoSizeMediaResource.add(photoId: resource.photoId ?? Int64.min, &builder)
|
||||
TelegramCore_TelegramMediaResource_CloudPeerPhotoSizeMediaResource.add(sizeSpec: sizeSpec, &builder)
|
||||
TelegramCore_TelegramMediaResource_CloudPeerPhotoSizeMediaResource.add(volumeId: resource.volumeId ?? Int64.min, &builder)
|
||||
TelegramCore_TelegramMediaResource_CloudPeerPhotoSizeMediaResource.add(localId: resource.localId ?? Int32.min, &builder)
|
||||
|
||||
let offset = TelegramCore_TelegramMediaResource_CloudPeerPhotoSizeMediaResource.endTelegramMediaResource_CloudPeerPhotoSizeMediaResource(&builder, start: start)
|
||||
return TelegramCore_TelegramMediaResource.createTelegramMediaResource(&builder, valueType: .telegrammediaresourceCloudpeerphotosizemediaresource, valueOffset: offset)
|
||||
case let resource as CloudStickerPackThumbnailMediaResource:
|
||||
let start = TelegramCore_TelegramMediaResource_CloudStickerPackThumbnailMediaResource.startTelegramMediaResource_CloudStickerPackThumbnailMediaResource(&builder)
|
||||
|
||||
TelegramCore_TelegramMediaResource_CloudStickerPackThumbnailMediaResource.add(datacenterId: Int32(resource.datacenterId), &builder)
|
||||
TelegramCore_TelegramMediaResource_CloudStickerPackThumbnailMediaResource.add(thumbVersion: resource.thumbVersion ?? Int32.min, &builder)
|
||||
TelegramCore_TelegramMediaResource_CloudStickerPackThumbnailMediaResource.add(volumeId: resource.volumeId ?? Int64.min, &builder)
|
||||
TelegramCore_TelegramMediaResource_CloudStickerPackThumbnailMediaResource.add(localId: resource.localId ?? Int32.min, &builder)
|
||||
|
||||
let offset = TelegramCore_TelegramMediaResource_CloudStickerPackThumbnailMediaResource.endTelegramMediaResource_CloudStickerPackThumbnailMediaResource(&builder, start: start)
|
||||
return TelegramCore_TelegramMediaResource.createTelegramMediaResource(&builder, valueType: .telegrammediaresourceCloudstickerpackthumbnailmediaresource, valueOffset: offset)
|
||||
case let resource as CloudDocumentMediaResource:
|
||||
let fileNameOffset = resource.fileName.flatMap { builder.create(string: $0) }
|
||||
let fileReferenceOffset = resource.fileReference.flatMap { builder.createVector(bytes: $0) }
|
||||
|
||||
let start = TelegramCore_TelegramMediaResource_CloudDocumentMediaResource.startTelegramMediaResource_CloudDocumentMediaResource(&builder)
|
||||
|
||||
TelegramCore_TelegramMediaResource_CloudDocumentMediaResource.add(datacenterId: Int32(resource.datacenterId), &builder)
|
||||
TelegramCore_TelegramMediaResource_CloudDocumentMediaResource.add(fileId: resource.fileId, &builder)
|
||||
TelegramCore_TelegramMediaResource_CloudDocumentMediaResource.add(accessHash: resource.accessHash, &builder)
|
||||
TelegramCore_TelegramMediaResource_CloudDocumentMediaResource.add(size: resource.size ?? 0, &builder)
|
||||
if let fileReferenceOffset {
|
||||
TelegramCore_TelegramMediaResource_CloudDocumentMediaResource.addVectorOf(fileReference: fileReferenceOffset, &builder)
|
||||
}
|
||||
if let fileNameOffset {
|
||||
TelegramCore_TelegramMediaResource_CloudDocumentMediaResource.add(fileName: fileNameOffset, &builder)
|
||||
}
|
||||
|
||||
let offset = TelegramCore_TelegramMediaResource_CloudDocumentMediaResource.endTelegramMediaResource_CloudDocumentMediaResource(&builder, start: start)
|
||||
return TelegramCore_TelegramMediaResource.createTelegramMediaResource(&builder, valueType: .telegrammediaresourceClouddocumentmediaresource, valueOffset: offset)
|
||||
case let resource as LocalFileMediaResource:
|
||||
let start = TelegramCore_TelegramMediaResource_LocalFileMediaResource.startTelegramMediaResource_LocalFileMediaResource(&builder)
|
||||
|
||||
TelegramCore_TelegramMediaResource_LocalFileMediaResource.add(fileId: resource.fileId, &builder)
|
||||
TelegramCore_TelegramMediaResource_LocalFileMediaResource.add(size: resource.size ?? Int64.min, &builder)
|
||||
TelegramCore_TelegramMediaResource_LocalFileMediaResource.add(isSecretRelated: resource.isSecretRelated, &builder)
|
||||
|
||||
let offset = TelegramCore_TelegramMediaResource_LocalFileMediaResource.endTelegramMediaResource_LocalFileMediaResource(&builder, start: start)
|
||||
return TelegramCore_TelegramMediaResource.createTelegramMediaResource(&builder, valueType: .telegrammediaresourceLocalfilemediaresource, valueOffset: offset)
|
||||
default:
|
||||
assertionFailure()
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
@ -65,6 +65,10 @@ public struct MessageReference: PostboxCoding, Hashable, Equatable {
|
||||
}
|
||||
}
|
||||
|
||||
init(content: MessageReferenceContent) {
|
||||
self.content = content
|
||||
}
|
||||
|
||||
public init(_ message: Message) {
|
||||
if message.id.namespace != Namespaces.Message.Local, let peer = message.peers[message.id.peerId], let inputPeer = PeerReference(peer) {
|
||||
let author: PeerReference?
|
||||
@ -145,6 +149,10 @@ public enum MessageReferenceContent: PostboxCoding, Hashable, Equatable {
|
||||
public struct WebpageReference: PostboxCoding, Hashable, Equatable {
|
||||
public let content: WebpageReferenceContent
|
||||
|
||||
init(content: WebpageReferenceContent) {
|
||||
self.content = content
|
||||
}
|
||||
|
||||
public init(_ webPage: TelegramMediaWebpage) {
|
||||
if case let .Loaded(content) = webPage.content {
|
||||
self.content = .webPage(id: webPage.webpageId.id, url: content.url)
|
||||
|
@ -0,0 +1,146 @@
|
||||
import Postbox
|
||||
import FlatBuffers
|
||||
import FlatSerialization
|
||||
|
||||
public extension PeerId {
|
||||
init(flatBuffersObject: TelegramCore_PeerId) {
|
||||
self.init(namespace: PeerId.Namespace._internalFromInt32Value(flatBuffersObject.namespace), id: PeerId.Id._internalFromInt64Value(flatBuffersObject.id))
|
||||
}
|
||||
}
|
||||
|
||||
public extension MessageId {
|
||||
init(flatBuffersObject: TelegramCore_MessageId) {
|
||||
self.init(peerId: PeerId(flatBuffersObject: flatBuffersObject.peerId), namespace: flatBuffersObject.namespace, id: flatBuffersObject.id)
|
||||
}
|
||||
}
|
||||
|
||||
public extension MessageReference {
|
||||
init(flatBuffersObject: TelegramCore_MessageReference) throws {
|
||||
self.init(content: .message(
|
||||
peer: try PeerReference(flatBuffersObject: flatBuffersObject.peer),
|
||||
author: try flatBuffersObject.author.flatMap { try PeerReference(flatBuffersObject: $0) },
|
||||
id: MessageId(flatBuffersObject: flatBuffersObject.messageId),
|
||||
timestamp: flatBuffersObject.timestamp,
|
||||
incoming: flatBuffersObject.incoming,
|
||||
secret: flatBuffersObject.secret,
|
||||
threadId: flatBuffersObject.threadId == Int64.min ? nil : flatBuffersObject.threadId)
|
||||
)
|
||||
}
|
||||
|
||||
func encodeToFlatBuffers(builder: inout FlatBufferBuilder) -> Offset? {
|
||||
switch self.content {
|
||||
case let .message(peer, author, id, timestamp, incoming, secret, threadId):
|
||||
let peerOffset = peer.encodeToFlatBuffers(builder: &builder)
|
||||
let authorOffset = author.flatMap { $0.encodeToFlatBuffers(builder: &builder) }
|
||||
|
||||
let start = TelegramCore_MessageReference.startMessageReference(&builder)
|
||||
|
||||
TelegramCore_MessageReference.add(peer: peerOffset, &builder)
|
||||
if let authorOffset {
|
||||
TelegramCore_MessageReference.add(author: authorOffset, &builder)
|
||||
}
|
||||
TelegramCore_MessageReference.add(messageId: TelegramCore_MessageId(peerId: TelegramCore_PeerId(namespace: id.peerId.namespace._internalGetInt32Value(), id: id.peerId.id._internalGetInt64Value()), namespace: id.namespace, id: id.id), &builder)
|
||||
TelegramCore_MessageReference.add(timestamp: timestamp, &builder)
|
||||
TelegramCore_MessageReference.add(incoming: incoming, &builder)
|
||||
TelegramCore_MessageReference.add(secret: secret, &builder)
|
||||
TelegramCore_MessageReference.add(threadId: threadId ?? Int64.min, &builder)
|
||||
|
||||
return TelegramCore_MessageReference.endMessageReference(&builder, start: start)
|
||||
case .none:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public extension WebpageReference {
|
||||
init(flatBuffersObject: TelegramCore_WebpageReference) throws {
|
||||
self.init(content: .webPage(id: flatBuffersObject.webpageId, url: flatBuffersObject.url))
|
||||
}
|
||||
|
||||
func encodeToFlatBuffers(builder: inout FlatBufferBuilder) -> Offset? {
|
||||
switch self.content {
|
||||
case let .webPage(id, url):
|
||||
let urlOffset = builder.create(string: url)
|
||||
|
||||
let start = TelegramCore_WebpageReference.startWebpageReference(&builder)
|
||||
|
||||
TelegramCore_WebpageReference.add(webpageId: id, &builder)
|
||||
TelegramCore_WebpageReference.add(url: urlOffset, &builder)
|
||||
|
||||
return TelegramCore_WebpageReference.endWebpageReference(&builder, start: start)
|
||||
case .none:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public extension PartialMediaReference {
|
||||
init(flatBuffersObject: TelegramCore_PartialMediaReference) throws {
|
||||
switch flatBuffersObject.valueType {
|
||||
case .partialmediareferenceMessage:
|
||||
guard let value = flatBuffersObject.value(type: TelegramCore_PartialMediaReference_Message.self) else {
|
||||
throw FlatBuffersError.missingRequiredField
|
||||
}
|
||||
if let message = value.message {
|
||||
self = .message(message: try MessageReference(flatBuffersObject: message))
|
||||
} else {
|
||||
self = .message(message: MessageReference(content: .none))
|
||||
}
|
||||
case .partialmediareferenceWebpage:
|
||||
guard let value = flatBuffersObject.value(type: TelegramCore_PartialMediaReference_WebPage.self) else {
|
||||
throw FlatBuffersError.missingRequiredField
|
||||
}
|
||||
if let webPage = value.webPage {
|
||||
self = .webPage(webPage: try WebpageReference(flatBuffersObject: webPage))
|
||||
} else {
|
||||
self = .webPage(webPage: WebpageReference(content: .none))
|
||||
}
|
||||
case .partialmediareferenceStickerpack:
|
||||
guard let value = flatBuffersObject.value(type: TelegramCore_PartialMediaReference_StickerPack.self) else {
|
||||
throw FlatBuffersError.missingRequiredField
|
||||
}
|
||||
self = .stickerPack(stickerPack: try StickerPackReference(flatBuffersObject: value.stickerPack))
|
||||
case .partialmediareferenceSavedgif:
|
||||
self = .savedGif
|
||||
case .partialmediareferenceSavedsticker:
|
||||
self = .savedSticker
|
||||
case .partialmediareferenceRecentsticker:
|
||||
self = .recentSticker
|
||||
case .none_:
|
||||
throw FlatBuffersError.missingRequiredField
|
||||
}
|
||||
}
|
||||
|
||||
func encodeToFlatBuffers(builder: inout FlatBufferBuilder) -> Offset {
|
||||
switch self {
|
||||
case let .message(message):
|
||||
let messageOffset = message.encodeToFlatBuffers(builder: &builder)
|
||||
let start = TelegramCore_PartialMediaReference_Message.startPartialMediaReference_Message(&builder)
|
||||
if let messageOffset {
|
||||
TelegramCore_PartialMediaReference_Message.add(message: messageOffset, &builder)
|
||||
}
|
||||
return TelegramCore_PartialMediaReference_Message.endPartialMediaReference_Message(&builder, start: start)
|
||||
case let .webPage(webPage):
|
||||
let webpageOffset = webPage.encodeToFlatBuffers(builder: &builder)
|
||||
let start = TelegramCore_PartialMediaReference_WebPage.startPartialMediaReference_WebPage(&builder)
|
||||
if let webpageOffset {
|
||||
TelegramCore_PartialMediaReference_WebPage.add(webPage: webpageOffset, &builder)
|
||||
}
|
||||
return TelegramCore_PartialMediaReference_WebPage.endPartialMediaReference_WebPage(&builder, start: start)
|
||||
case let .stickerPack(stickerPack):
|
||||
let stickerPackOffset = stickerPack.encodeToFlatBuffers(builder: &builder)
|
||||
let start = TelegramCore_PartialMediaReference_StickerPack.startPartialMediaReference_StickerPack(&builder)
|
||||
TelegramCore_PartialMediaReference_StickerPack.add(stickerPack: stickerPackOffset, &builder)
|
||||
return TelegramCore_PartialMediaReference_StickerPack.endPartialMediaReference_StickerPack(&builder, start: start)
|
||||
case .savedGif:
|
||||
let start = TelegramCore_PartialMediaReference_SavedGif.startPartialMediaReference_SavedGif(&builder)
|
||||
return TelegramCore_PartialMediaReference_SavedGif.endPartialMediaReference_SavedGif(&builder, start: start)
|
||||
case .savedSticker:
|
||||
let start = TelegramCore_PartialMediaReference_SavedSticker.startPartialMediaReference_SavedSticker(&builder)
|
||||
return TelegramCore_PartialMediaReference_SavedSticker.endPartialMediaReference_SavedSticker(&builder, start: start)
|
||||
case .recentSticker:
|
||||
let start = TelegramCore_PartialMediaReference_RecentSticker.startPartialMediaReference_RecentSticker(&builder)
|
||||
return TelegramCore_PartialMediaReference_RecentSticker.endPartialMediaReference_RecentSticker(&builder, start: start)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,6 @@
|
||||
import Postbox
|
||||
import FlatBuffers
|
||||
import FlatSerialization
|
||||
|
||||
public enum PeerReference: PostboxCoding, Hashable, Equatable {
|
||||
case user(id: Int64, accessHash: Int64)
|
||||
@ -73,4 +75,48 @@ public enum PeerReference: PostboxCoding, Hashable, Equatable {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
public init(flatBuffersObject: TelegramCore_PeerReference) throws {
|
||||
switch flatBuffersObject.valueType {
|
||||
case .peerreferenceUser:
|
||||
guard let value = flatBuffersObject.value(type: TelegramCore_PeerReference_User.self) else {
|
||||
throw FlatBuffersError.missingRequiredField
|
||||
}
|
||||
self = .user(id: value.id, accessHash: value.accessHash)
|
||||
case .peerreferenceGroup:
|
||||
guard let value = flatBuffersObject.value(type: TelegramCore_PeerReference_Group.self) else {
|
||||
throw FlatBuffersError.missingRequiredField
|
||||
}
|
||||
self = .group(id: value.id)
|
||||
case .peerreferenceChannel:
|
||||
guard let value = flatBuffersObject.value(type: TelegramCore_PeerReference_Channel.self) else {
|
||||
throw FlatBuffersError.missingRequiredField
|
||||
}
|
||||
self = .channel(id: value.id, accessHash: value.accessHash)
|
||||
case .none_:
|
||||
throw FlatBuffersError.missingRequiredField
|
||||
}
|
||||
}
|
||||
|
||||
public func encodeToFlatBuffers(builder: inout FlatBufferBuilder) -> Offset {
|
||||
switch self {
|
||||
case let .user(id, accessHash):
|
||||
let start = TelegramCore_PeerReference.startPeerReference(&builder)
|
||||
TelegramCore_PeerReference_User.add(id: id, &builder)
|
||||
TelegramCore_PeerReference_User.add(accessHash: accessHash, &builder)
|
||||
let offset = TelegramCore_PeerReference_User.endPeerReference_User(&builder, start: start)
|
||||
return TelegramCore_PeerReference.createPeerReference(&builder, valueType: .peerreferenceUser, valueOffset: offset)
|
||||
case let .group(id):
|
||||
let start = TelegramCore_PeerReference.startPeerReference(&builder)
|
||||
TelegramCore_PeerReference_Group.add(id: id, &builder)
|
||||
let offset = TelegramCore_PeerReference_Group.endPeerReference_Group(&builder, start: start)
|
||||
return TelegramCore_PeerReference.createPeerReference(&builder, valueType: .peerreferenceUser, valueOffset: offset)
|
||||
case let .channel(id, accessHash):
|
||||
let start = TelegramCore_PeerReference.startPeerReference(&builder)
|
||||
TelegramCore_PeerReference_Channel.add(id: id, &builder)
|
||||
TelegramCore_PeerReference_Channel.add(accessHash: accessHash, &builder)
|
||||
let offset = TelegramCore_PeerReference_Channel.endPeerReference_Channel(&builder, start: start)
|
||||
return TelegramCore_PeerReference.createPeerReference(&builder, valueType: .peerreferenceUser, valueOffset: offset)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +1,25 @@
|
||||
import Foundation
|
||||
import Postbox
|
||||
import FlatBuffers
|
||||
import FlatSerialization
|
||||
|
||||
public final class StickerPackItem: ItemCollectionItem, Equatable {
|
||||
public let index: ItemCollectionItemIndex
|
||||
public let file: TelegramMediaFile
|
||||
public let serializedFile: Data
|
||||
public let indexKeys: [MemoryBuffer]
|
||||
|
||||
public init(index: ItemCollectionItemIndex, file: TelegramMediaFile, indexKeys: [MemoryBuffer]) {
|
||||
self.index = index
|
||||
self.file = file
|
||||
self.serializedFile = file.encodeToFlatBuffersData()
|
||||
self.indexKeys = indexKeys
|
||||
}
|
||||
|
||||
public init(decoder: PostboxDecoder) {
|
||||
self.index = ItemCollectionItemIndex(index: decoder.decodeInt32ForKey("i.n", orElse: 0), id: decoder.decodeInt64ForKey("i.i", orElse: 0))
|
||||
self.file = decoder.decodeObjectForKey("f") as! TelegramMediaFile
|
||||
self.serializedFile = decoder.decodeDataForKey("fd") ?? self.file.encodeToFlatBuffersData()
|
||||
self.indexKeys = decoder.decodeBytesArrayForKey("s")
|
||||
}
|
||||
|
||||
@ -21,6 +27,7 @@ public final class StickerPackItem: ItemCollectionItem, Equatable {
|
||||
encoder.encodeInt32(self.index.index, forKey: "i.n")
|
||||
encoder.encodeInt64(self.index.id, forKey: "i.i")
|
||||
encoder.encodeObject(self.file, forKey: "f")
|
||||
encoder.encodeData(self.serializedFile, forKey: "fd")
|
||||
encoder.encodeBytesArray(self.indexKeys, forKey: "s")
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
import Foundation
|
||||
import Postbox
|
||||
import FlatBuffers
|
||||
import FlatSerialization
|
||||
|
||||
private let typeFileName: Int32 = 0
|
||||
private let typeSticker: Int32 = 1
|
||||
@ -13,6 +15,11 @@ private let typeHintIsValidated: Int32 = 8
|
||||
private let typeNoPremium: Int32 = 9
|
||||
private let typeCustomEmoji: Int32 = 10
|
||||
|
||||
enum FlatBuffersError: Error {
|
||||
case missingRequiredField
|
||||
case invalidUnionType
|
||||
}
|
||||
|
||||
public enum StickerPackReference: PostboxCoding, Hashable, Equatable, Codable {
|
||||
case id(id: Int64, accessHash: Int64)
|
||||
case name(String)
|
||||
@ -120,6 +127,96 @@ public enum StickerPackReference: PostboxCoding, Hashable, Equatable, Codable {
|
||||
}
|
||||
}
|
||||
|
||||
init(flatBuffersObject: TelegramCore_StickerPackReference) throws {
|
||||
switch flatBuffersObject.valueType {
|
||||
case .stickerpackreferenceId:
|
||||
guard let value = flatBuffersObject.value(type: TelegramCore_StickerPackReference_Id.self) else {
|
||||
throw FlatBuffersError.missingRequiredField
|
||||
}
|
||||
self = .id(id: value.id, accessHash: value.accessHash)
|
||||
case .stickerpackreferenceName:
|
||||
guard let value = flatBuffersObject.value(type: TelegramCore_StickerPackReference_Name.self) else {
|
||||
throw FlatBuffersError.missingRequiredField
|
||||
}
|
||||
self = .name(value.name)
|
||||
case .stickerpackreferenceAnimatedemoji:
|
||||
self = .animatedEmoji
|
||||
case .stickerpackreferenceDice:
|
||||
guard let value = flatBuffersObject.value(type: TelegramCore_StickerPackReference_Dice.self) else {
|
||||
throw FlatBuffersError.missingRequiredField
|
||||
}
|
||||
self = .dice(value.emoji)
|
||||
case .stickerpackreferenceAnimatedemojianimations:
|
||||
self = .animatedEmojiAnimations
|
||||
case .stickerpackreferencePremiumgifts:
|
||||
self = .premiumGifts
|
||||
case .stickerpackreferenceEmojigenericanimations:
|
||||
self = .emojiGenericAnimations
|
||||
case .stickerpackreferenceIconstatusemoji:
|
||||
self = .iconStatusEmoji
|
||||
case .stickerpackreferenceIcontopicemoji:
|
||||
self = .iconTopicEmoji
|
||||
case .stickerpackreferenceIconchannelstatusemoji:
|
||||
self = .iconChannelStatusEmoji
|
||||
case .none_:
|
||||
throw FlatBuffersError.missingRequiredField
|
||||
}
|
||||
}
|
||||
|
||||
func encodeToFlatBuffers(builder: inout FlatBufferBuilder) -> Offset {
|
||||
let valueType: TelegramCore_StickerPackReference_Value
|
||||
let offset: Offset
|
||||
switch self {
|
||||
case let .id(id, accessHash):
|
||||
valueType = .stickerpackreferenceId
|
||||
let start = TelegramCore_StickerPackReference_Id.startStickerPackReference_Id(&builder)
|
||||
TelegramCore_StickerPackReference_Id.add(id: id, &builder)
|
||||
TelegramCore_StickerPackReference_Id.add(accessHash: accessHash, &builder)
|
||||
offset = TelegramCore_StickerPackReference_Id.endStickerPackReference_Id(&builder, start: start)
|
||||
case let .name(name):
|
||||
valueType = .stickerpackreferenceName
|
||||
let nameOffset = builder.create(string: name)
|
||||
let start = TelegramCore_StickerPackReference_Name.startStickerPackReference_Name(&builder)
|
||||
TelegramCore_StickerPackReference_Name.add(name: nameOffset, &builder)
|
||||
offset = TelegramCore_StickerPackReference_Name.endStickerPackReference_Name(&builder, start: start)
|
||||
case .animatedEmoji:
|
||||
valueType = .stickerpackreferenceAnimatedemoji
|
||||
let start = TelegramCore_StickerPackReference_AnimatedEmoji.startStickerPackReference_AnimatedEmoji(&builder)
|
||||
offset = TelegramCore_StickerPackReference_AnimatedEmoji.endStickerPackReference_AnimatedEmoji(&builder, start: start)
|
||||
case let .dice(emoji):
|
||||
valueType = .stickerpackreferenceDice
|
||||
let emojiOffset = builder.create(string: emoji)
|
||||
let start = TelegramCore_StickerPackReference_Dice.startStickerPackReference_Dice(&builder)
|
||||
TelegramCore_StickerPackReference_Dice.add(emoji: emojiOffset, &builder)
|
||||
offset = TelegramCore_StickerPackReference_Dice.endStickerPackReference_Dice(&builder, start: start)
|
||||
case .animatedEmojiAnimations:
|
||||
valueType = .stickerpackreferenceAnimatedemojianimations
|
||||
let start = TelegramCore_StickerPackReference_AnimatedEmojiAnimations.startStickerPackReference_AnimatedEmojiAnimations(&builder)
|
||||
offset = TelegramCore_StickerPackReference_AnimatedEmojiAnimations.endStickerPackReference_AnimatedEmojiAnimations(&builder, start: start)
|
||||
case .premiumGifts:
|
||||
valueType = .stickerpackreferencePremiumgifts
|
||||
let start = TelegramCore_StickerPackReference_PremiumGifts.startStickerPackReference_PremiumGifts(&builder)
|
||||
offset = TelegramCore_StickerPackReference_PremiumGifts.endStickerPackReference_PremiumGifts(&builder, start: start)
|
||||
case .emojiGenericAnimations:
|
||||
valueType = .stickerpackreferenceEmojigenericanimations
|
||||
let start = TelegramCore_StickerPackReference_EmojiGenericAnimations.startStickerPackReference_EmojiGenericAnimations(&builder)
|
||||
offset = TelegramCore_StickerPackReference_EmojiGenericAnimations.endStickerPackReference_EmojiGenericAnimations(&builder, start: start)
|
||||
case .iconStatusEmoji:
|
||||
valueType = .stickerpackreferenceIconstatusemoji
|
||||
let start = TelegramCore_StickerPackReference_IconStatusEmoji.startStickerPackReference_IconStatusEmoji(&builder)
|
||||
offset = TelegramCore_StickerPackReference_IconStatusEmoji.endStickerPackReference_IconStatusEmoji(&builder, start: start)
|
||||
case .iconTopicEmoji:
|
||||
valueType = .stickerpackreferenceIcontopicemoji
|
||||
let start = TelegramCore_StickerPackReference_IconTopicEmoji.startStickerPackReference_IconTopicEmoji(&builder)
|
||||
offset = TelegramCore_StickerPackReference_IconTopicEmoji.endStickerPackReference_IconTopicEmoji(&builder, start: start)
|
||||
case .iconChannelStatusEmoji:
|
||||
valueType = .stickerpackreferenceIconchannelstatusemoji
|
||||
let start = TelegramCore_StickerPackReference_IconChannelStatusEmoji.startStickerPackReference_IconChannelStatusEmoji(&builder)
|
||||
offset = TelegramCore_StickerPackReference_IconChannelStatusEmoji.endStickerPackReference_IconChannelStatusEmoji(&builder, start: start)
|
||||
}
|
||||
return TelegramCore_StickerPackReference.createStickerPackReference(&builder, valueType: valueType, valueOffset: offset)
|
||||
}
|
||||
|
||||
public static func ==(lhs: StickerPackReference, rhs: StickerPackReference) -> Bool {
|
||||
switch lhs {
|
||||
case let .id(id, accessHash):
|
||||
@ -217,9 +314,9 @@ public struct StickerMaskCoords: PostboxCoding, Equatable {
|
||||
|
||||
public init(decoder: PostboxDecoder) {
|
||||
self.n = decoder.decodeInt32ForKey("n", orElse: 0)
|
||||
self.x = decoder.decodeDoubleForKey("x", orElse: 0.0)
|
||||
self.y = decoder.decodeDoubleForKey("y", orElse: 0.0)
|
||||
self.zoom = decoder.decodeDoubleForKey("z", orElse: 0.0)
|
||||
self.x = Double(Float32(decoder.decodeDoubleForKey("x", orElse: 0.0)))
|
||||
self.y = Double(Float32(decoder.decodeDoubleForKey("y", orElse: 0.0)))
|
||||
self.zoom = Double(Float32(decoder.decodeDoubleForKey("z", orElse: 0.0)))
|
||||
}
|
||||
|
||||
public func encode(_ encoder: PostboxEncoder) {
|
||||
@ -228,6 +325,13 @@ public struct StickerMaskCoords: PostboxCoding, Equatable {
|
||||
encoder.encodeDouble(self.y, forKey: "y")
|
||||
encoder.encodeDouble(self.zoom, forKey: "z")
|
||||
}
|
||||
|
||||
init(flatBuffersObject: TelegramCore_StickerMaskCoords) {
|
||||
self.n = flatBuffersObject.n
|
||||
self.x = Double(flatBuffersObject.x)
|
||||
self.y = Double(flatBuffersObject.y)
|
||||
self.zoom = Double(flatBuffersObject.zoom)
|
||||
}
|
||||
}
|
||||
|
||||
public enum TelegramMediaFileAttribute: PostboxCoding, Equatable {
|
||||
@ -262,7 +366,12 @@ public enum TelegramMediaFileAttribute: PostboxCoding, Equatable {
|
||||
duration = Double(decoder.decodeInt32ForKey("du", orElse: 0))
|
||||
}
|
||||
|
||||
self = .Video(duration: duration, size: PixelDimensions(width: decoder.decodeInt32ForKey("w", orElse: 0), height: decoder.decodeInt32ForKey("h", orElse: 0)), flags: TelegramMediaVideoFlags(rawValue: decoder.decodeInt32ForKey("f", orElse: 0)), preloadSize: decoder.decodeOptionalInt32ForKey("prs"), coverTime: decoder.decodeOptionalDoubleForKey("ct"), videoCodec: decoder.decodeOptionalStringForKey("vc"))
|
||||
var coverTime: Double?
|
||||
if let coverTimeValue = decoder.decodeOptionalDoubleForKey("ct") {
|
||||
coverTime = Double(Float32(coverTimeValue))
|
||||
}
|
||||
|
||||
self = .Video(duration: Double(Float32(duration)), size: PixelDimensions(width: decoder.decodeInt32ForKey("w", orElse: 0), height: decoder.decodeInt32ForKey("h", orElse: 0)), flags: TelegramMediaVideoFlags(rawValue: decoder.decodeInt32ForKey("f", orElse: 0)), preloadSize: decoder.decodeOptionalInt32ForKey("prs"), coverTime: coverTime, videoCodec: decoder.decodeOptionalStringForKey("vc"))
|
||||
case typeAudio:
|
||||
let waveformBuffer = decoder.decodeBytesForKeyNoCopy("wf")
|
||||
var waveform: Data?
|
||||
@ -363,6 +472,171 @@ public enum TelegramMediaFileAttribute: PostboxCoding, Equatable {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
init(flatBuffersData data: Data) throws {
|
||||
var byteBuffer = ByteBuffer(data: data)
|
||||
let flatBuffersObject: TelegramCore_TelegramMediaFileAttribute = try getCheckedRoot(byteBuffer: &byteBuffer)
|
||||
try self.init(flatBuffersObject: flatBuffersObject)
|
||||
}
|
||||
|
||||
init(flatBuffersObject: TelegramCore_TelegramMediaFileAttribute) throws {
|
||||
switch flatBuffersObject.valueType {
|
||||
case .telegrammediafileattributeFilename:
|
||||
guard let value = flatBuffersObject.value(type: TelegramCore_TelegramMediaFileAttribute_FileName.self) else {
|
||||
throw FlatBuffersError.missingRequiredField
|
||||
}
|
||||
self = .FileName(fileName: value.fileName)
|
||||
case .telegrammediafileattributeSticker:
|
||||
guard let value = flatBuffersObject.value(type: TelegramCore_TelegramMediaFileAttribute_Sticker.self) else {
|
||||
throw FlatBuffersError.missingRequiredField
|
||||
}
|
||||
self = .Sticker(displayText: value.displayText, packReference: try value.packReference.flatMap({ try StickerPackReference(flatBuffersObject: $0) }), maskData: value.maskData.flatMap({ StickerMaskCoords(flatBuffersObject: $0) }))
|
||||
case .telegrammediafileattributeImagesize:
|
||||
guard let value = flatBuffersObject.value(type: TelegramCore_TelegramMediaFileAttribute_ImageSize.self) else {
|
||||
throw FlatBuffersError.missingRequiredField
|
||||
}
|
||||
self = .ImageSize(size: PixelDimensions(width: value.width, height: value.height))
|
||||
case .telegrammediafileattributeAnimated:
|
||||
self = .Animated
|
||||
case .telegrammediafileattributeVideo:
|
||||
guard let value = flatBuffersObject.value(type: TelegramCore_TelegramMediaFileAttribute_Video.self) else {
|
||||
throw FlatBuffersError.missingRequiredField
|
||||
}
|
||||
self = .Video(duration: Double(value.duration), size: PixelDimensions(width: value.width, height: value.height), flags: TelegramMediaVideoFlags(rawValue: value.flags), preloadSize: value.preloadSize == 0 ? nil : value.preloadSize, coverTime: value.coverTime == 0.0 ? nil : Double(value.coverTime), videoCodec: value.videoCodec)
|
||||
case .telegrammediafileattributeAudio:
|
||||
guard let value = flatBuffersObject.value(type: TelegramCore_TelegramMediaFileAttribute_Audio.self) else {
|
||||
throw FlatBuffersError.missingRequiredField
|
||||
}
|
||||
self = .Audio(isVoice: value.isVoice, duration: Int(value.duration), title: value.title, performer: value.performer, waveform: value.waveform.isEmpty ? nil : Data(value.waveform))
|
||||
case .telegrammediafileattributeHaslinkedstickers:
|
||||
self = .HasLinkedStickers
|
||||
case .telegrammediafileattributeHintfileislarge:
|
||||
self = .hintFileIsLarge
|
||||
case .telegrammediafileattributeHintisvalidated:
|
||||
self = .hintIsValidated
|
||||
case .telegrammediafileattributeNopremium:
|
||||
self = .NoPremium
|
||||
case .none_:
|
||||
throw FlatBuffersError.missingRequiredField
|
||||
case .telegrammediafileattributeCustomemoji:
|
||||
guard let value = flatBuffersObject.value(type: TelegramCore_TelegramMediaFileAttribute_CustomEmoji.self) else {
|
||||
throw FlatBuffersError.missingRequiredField
|
||||
}
|
||||
self = .CustomEmoji(isPremium: value.isPremium, isSingleColor: value.isSingleColor, alt: value.alt, packReference: try value.packReference.flatMap({ try StickerPackReference(flatBuffersObject: $0) }))
|
||||
}
|
||||
}
|
||||
|
||||
func encodeToFlatBuffers(builder: inout FlatBufferBuilder) -> Offset {
|
||||
let valueType: TelegramCore_TelegramMediaFileAttribute_Value
|
||||
let offset: Offset
|
||||
|
||||
switch self {
|
||||
case let .FileName(fileName):
|
||||
valueType = .telegrammediafileattributeFilename
|
||||
let fileNameOffset = builder.create(string: fileName)
|
||||
let start = TelegramCore_TelegramMediaFileAttribute_FileName.startTelegramMediaFileAttribute_FileName(&builder)
|
||||
TelegramCore_TelegramMediaFileAttribute_FileName.add(fileName: fileNameOffset, &builder)
|
||||
offset = TelegramCore_TelegramMediaFileAttribute_FileName.endTelegramMediaFileAttribute_FileName(&builder, start: start)
|
||||
case let .Sticker(displayText, packReference, maskData):
|
||||
valueType = .telegrammediafileattributeSticker
|
||||
let displayTextOffset = builder.create(string: displayText)
|
||||
|
||||
let packReferenceOffset = packReference.flatMap {
|
||||
return $0.encodeToFlatBuffers(builder: &builder)
|
||||
}
|
||||
let maskDataOffset = maskData.flatMap { maskData -> Offset in
|
||||
let start = TelegramCore_StickerMaskCoords.startStickerMaskCoords(&builder)
|
||||
TelegramCore_StickerMaskCoords.add(n: maskData.n, &builder)
|
||||
TelegramCore_StickerMaskCoords.add(x: Float32(maskData.x), &builder)
|
||||
TelegramCore_StickerMaskCoords.add(y: Float32(maskData.y), &builder)
|
||||
TelegramCore_StickerMaskCoords.add(zoom: Float32(maskData.zoom), &builder)
|
||||
return TelegramCore_StickerMaskCoords.endStickerMaskCoords(&builder, start: start)
|
||||
}
|
||||
let start = TelegramCore_TelegramMediaFileAttribute_Sticker.startTelegramMediaFileAttribute_Sticker(&builder)
|
||||
TelegramCore_TelegramMediaFileAttribute_Sticker.add(displayText: displayTextOffset, &builder)
|
||||
if let packReferenceOffset {
|
||||
TelegramCore_TelegramMediaFileAttribute_Sticker.add(packReference: packReferenceOffset, &builder)
|
||||
}
|
||||
if let maskDataOffset {
|
||||
TelegramCore_TelegramMediaFileAttribute_Sticker.add(maskData: maskDataOffset, &builder)
|
||||
}
|
||||
offset = TelegramCore_TelegramMediaFileAttribute_Sticker.endTelegramMediaFileAttribute_Sticker(&builder, start: start)
|
||||
case let .ImageSize(size):
|
||||
valueType = .telegrammediafileattributeImagesize
|
||||
let start = TelegramCore_TelegramMediaFileAttribute_ImageSize.startTelegramMediaFileAttribute_ImageSize(&builder)
|
||||
TelegramCore_TelegramMediaFileAttribute_ImageSize.add(width: size.width, &builder)
|
||||
TelegramCore_TelegramMediaFileAttribute_ImageSize.add(height: size.height, &builder)
|
||||
offset = TelegramCore_TelegramMediaFileAttribute_ImageSize.endTelegramMediaFileAttribute_ImageSize(&builder, start: start)
|
||||
case .Animated:
|
||||
valueType = .telegrammediafileattributeAnimated
|
||||
let start = TelegramCore_TelegramMediaFileAttribute_Animated.startTelegramMediaFileAttribute_Animated(&builder)
|
||||
offset = TelegramCore_TelegramMediaFileAttribute_Animated.endTelegramMediaFileAttribute_Animated(&builder, start: start)
|
||||
case let .Video(duration, size, flags, preloadSize, coverTime, videoCodec):
|
||||
valueType = .telegrammediafileattributeVideo
|
||||
let videoCodecOffset = videoCodec.flatMap { builder.create(string: $0) }
|
||||
let start = TelegramCore_TelegramMediaFileAttribute_Video.startTelegramMediaFileAttribute_Video(&builder)
|
||||
|
||||
TelegramCore_TelegramMediaFileAttribute_Video.add(duration: Float32(duration), &builder)
|
||||
TelegramCore_TelegramMediaFileAttribute_Video.add(width: size.width, &builder)
|
||||
TelegramCore_TelegramMediaFileAttribute_Video.add(height: size.height, &builder)
|
||||
TelegramCore_TelegramMediaFileAttribute_Video.add(flags: flags.rawValue, &builder)
|
||||
TelegramCore_TelegramMediaFileAttribute_Video.add(preloadSize: preloadSize ?? 0, &builder)
|
||||
TelegramCore_TelegramMediaFileAttribute_Video.add(coverTime: Float32(coverTime ?? 0.0), &builder)
|
||||
if let videoCodecOffset {
|
||||
TelegramCore_TelegramMediaFileAttribute_Video.add(videoCodec: videoCodecOffset, &builder)}
|
||||
offset = TelegramCore_TelegramMediaFileAttribute_Video.endTelegramMediaFileAttribute_Video(&builder, start: start)
|
||||
case let .Audio(isVoice, duration, title, performer, waveform):
|
||||
valueType = .telegrammediafileattributeAudio
|
||||
let titleOffset = title.flatMap { builder.create(string: $0) }
|
||||
let performerOffset = performer.flatMap { builder.create(string: $0) }
|
||||
let waveformOffset = waveform.flatMap { builder.createVector(bytes: $0) }
|
||||
let start = TelegramCore_TelegramMediaFileAttribute_Audio.startTelegramMediaFileAttribute_Audio(&builder)
|
||||
TelegramCore_TelegramMediaFileAttribute_Audio.add(isVoice: isVoice, &builder)
|
||||
TelegramCore_TelegramMediaFileAttribute_Audio.add(duration: Int32(duration), &builder)
|
||||
if let titleOffset {
|
||||
TelegramCore_TelegramMediaFileAttribute_Audio.add(title: titleOffset, &builder)
|
||||
}
|
||||
if let performerOffset {
|
||||
TelegramCore_TelegramMediaFileAttribute_Audio.add(performer: performerOffset, &builder)
|
||||
}
|
||||
if let waveformOffset {
|
||||
TelegramCore_TelegramMediaFileAttribute_Audio.addVectorOf(waveform: waveformOffset, &builder)
|
||||
}
|
||||
offset = TelegramCore_TelegramMediaFileAttribute_Audio.endTelegramMediaFileAttribute_Audio(&builder, start: start)
|
||||
case .HasLinkedStickers:
|
||||
valueType = .telegrammediafileattributeHaslinkedstickers
|
||||
let start = TelegramCore_TelegramMediaFileAttribute_HasLinkedStickers.startTelegramMediaFileAttribute_HasLinkedStickers(&builder)
|
||||
offset = TelegramCore_TelegramMediaFileAttribute_HasLinkedStickers.endTelegramMediaFileAttribute_HasLinkedStickers(&builder, start: start)
|
||||
case .hintFileIsLarge:
|
||||
valueType = .telegrammediafileattributeHintfileislarge
|
||||
let start = TelegramCore_TelegramMediaFileAttribute_HintFileIsLarge.startTelegramMediaFileAttribute_HintFileIsLarge(&builder)
|
||||
offset = TelegramCore_TelegramMediaFileAttribute_HintFileIsLarge.endTelegramMediaFileAttribute_HintFileIsLarge(&builder, start: start)
|
||||
case .hintIsValidated:
|
||||
valueType = .telegrammediafileattributeHintisvalidated
|
||||
let start = TelegramCore_TelegramMediaFileAttribute_HintIsValidated.startTelegramMediaFileAttribute_HintIsValidated(&builder)
|
||||
offset = TelegramCore_TelegramMediaFileAttribute_HintIsValidated.endTelegramMediaFileAttribute_HintIsValidated(&builder, start: start)
|
||||
case .NoPremium:
|
||||
valueType = .telegrammediafileattributeNopremium
|
||||
let start = TelegramCore_TelegramMediaFileAttribute_NoPremium.startTelegramMediaFileAttribute_NoPremium(&builder)
|
||||
offset = TelegramCore_TelegramMediaFileAttribute_NoPremium.endTelegramMediaFileAttribute_NoPremium(&builder, start: start)
|
||||
case let .CustomEmoji(isPremium, isSingleColor, alt, packReference):
|
||||
valueType = .telegrammediafileattributeCustomemoji
|
||||
let altOffset = builder.create(string: alt)
|
||||
let packReferenceOffset = packReference.flatMap {
|
||||
return $0.encodeToFlatBuffers(builder: &builder)
|
||||
}
|
||||
let start = TelegramCore_TelegramMediaFileAttribute_CustomEmoji.startTelegramMediaFileAttribute_CustomEmoji(&builder)
|
||||
TelegramCore_TelegramMediaFileAttribute_CustomEmoji.add(isPremium: isPremium, &builder)
|
||||
TelegramCore_TelegramMediaFileAttribute_CustomEmoji.add(isSingleColor: isSingleColor, &builder)
|
||||
TelegramCore_TelegramMediaFileAttribute_CustomEmoji.add(alt: altOffset, &builder)
|
||||
if let packReferenceOffset {
|
||||
TelegramCore_TelegramMediaFileAttribute_CustomEmoji.add(packReference: packReferenceOffset, &builder)
|
||||
}
|
||||
offset = TelegramCore_TelegramMediaFileAttribute_CustomEmoji.endTelegramMediaFileAttribute_CustomEmoji(&builder, start: start)
|
||||
}
|
||||
|
||||
return TelegramCore_TelegramMediaFileAttribute.createTelegramMediaFileAttribute(&builder, valueType: valueType, valueOffset: offset)
|
||||
}
|
||||
}
|
||||
|
||||
public enum TelegramMediaFileReference: PostboxCoding, Equatable {
|
||||
@ -422,6 +696,23 @@ public final class TelegramMediaFile: Media, Equatable, Codable {
|
||||
encoder.encodeObject(self.resource, forKey: "r")
|
||||
}
|
||||
|
||||
public init(flatBuffersObject: TelegramCore_VideoThumbnail) throws {
|
||||
self.dimensions = PixelDimensions(width: flatBuffersObject.width, height: flatBuffersObject.height)
|
||||
self.resource = try TelegramMediaResource_parse(flatBuffersObject: flatBuffersObject.resource)
|
||||
}
|
||||
|
||||
public func encodeToFlatBuffers(builder: inout FlatBufferBuilder) -> Offset {
|
||||
let resourceOffset = TelegramMediaResource_serialize(resource: self.resource, flatBuffersBuilder: &builder)!
|
||||
|
||||
let start = TelegramCore_VideoThumbnail.startVideoThumbnail(&builder)
|
||||
|
||||
TelegramCore_VideoThumbnail.add(width: self.dimensions.width, &builder)
|
||||
TelegramCore_VideoThumbnail.add(height: self.dimensions.height, &builder)
|
||||
TelegramCore_VideoThumbnail.add(resource: resourceOffset, &builder)
|
||||
|
||||
return TelegramCore_VideoThumbnail.endVideoThumbnail(&builder, start: start)
|
||||
}
|
||||
|
||||
public static func ==(lhs: VideoThumbnail, rhs: VideoThumbnail) -> Bool {
|
||||
if lhs === rhs {
|
||||
return true
|
||||
@ -446,7 +737,7 @@ public final class TelegramMediaFile: Media, Equatable, Codable {
|
||||
public let mimeType: String
|
||||
public let size: Int64?
|
||||
public let attributes: [TelegramMediaFileAttribute]
|
||||
public let alternativeRepresentations: [Media]
|
||||
public let alternativeRepresentations: [TelegramMediaFile]
|
||||
public let peerIds: [PeerId] = []
|
||||
|
||||
public var id: MediaId? {
|
||||
@ -477,7 +768,7 @@ public final class TelegramMediaFile: Media, Equatable, Codable {
|
||||
mimeType: String,
|
||||
size: Int64?,
|
||||
attributes: [TelegramMediaFileAttribute],
|
||||
alternativeRepresentations: [Media]
|
||||
alternativeRepresentations: [TelegramMediaFile]
|
||||
) {
|
||||
self.fileId = fileId
|
||||
self.partialReference = partialReference
|
||||
@ -510,12 +801,20 @@ public final class TelegramMediaFile: Media, Equatable, Codable {
|
||||
}
|
||||
self.attributes = decoder.decodeObjectArrayForKey("at")
|
||||
if let altMedia = try? decoder.decodeObjectArrayWithCustomDecoderForKey("arep", decoder: { d in
|
||||
return d.decodeRootObject() as! Media
|
||||
return d.decodeRootObject()
|
||||
}) {
|
||||
self.alternativeRepresentations = altMedia
|
||||
self.alternativeRepresentations = altMedia.compactMap { $0 as? TelegramMediaFile }
|
||||
} else {
|
||||
self.alternativeRepresentations = []
|
||||
}
|
||||
|
||||
/*#if DEBUG
|
||||
let fbData = self.encodeToFlatBuffersData()
|
||||
var byteBuffer = ByteBuffer(data: fbData)
|
||||
let flatBuffersObject: TelegramCore_TelegramMediaFile = try! getCheckedRoot(byteBuffer: &byteBuffer)
|
||||
let fbObject = try! TelegramMediaFile(flatBuffersObject: flatBuffersObject)
|
||||
assert(self == fbObject)
|
||||
#endif*/
|
||||
}
|
||||
|
||||
public func encode(_ encoder: PostboxEncoder) {
|
||||
@ -580,6 +879,89 @@ public final class TelegramMediaFile: Media, Equatable, Codable {
|
||||
try container.encode(postboxEncoder.makeData(), forKey: .data)
|
||||
}
|
||||
|
||||
public func encodeToFlatBuffersData() -> Data {
|
||||
var builder = FlatBufferBuilder(initialSize: 1024)
|
||||
let value = self.encodeToFlatBuffers(builder: &builder)
|
||||
builder.finish(offset: value)
|
||||
return builder.data
|
||||
}
|
||||
|
||||
public init(flatBuffersObject: TelegramCore_TelegramMediaFile) throws {
|
||||
self.fileId = MediaId(namespace: flatBuffersObject.fileId.namespace, id: flatBuffersObject.fileId.id)
|
||||
self.partialReference = try flatBuffersObject.partialReference.flatMap { try PartialMediaReference(flatBuffersObject: $0 ) }
|
||||
self.resource = try TelegramMediaResource_parse(flatBuffersObject: flatBuffersObject.resource)
|
||||
self.previewRepresentations = try (0 ..< flatBuffersObject.previewRepresentationsCount).map { i in
|
||||
return try TelegramMediaImageRepresentation(flatBuffersObject: flatBuffersObject.previewRepresentations(at: i)!)
|
||||
}
|
||||
self.videoThumbnails = try (0 ..< flatBuffersObject.videoThumbnailsCount).map { i in
|
||||
return try VideoThumbnail(flatBuffersObject: flatBuffersObject.videoThumbnails(at: i)!)
|
||||
}
|
||||
self.videoCover = try flatBuffersObject.videoCover.flatMap { try TelegramMediaImage(flatBuffersObject: $0) }
|
||||
self.immediateThumbnailData = flatBuffersObject.immediateThumbnailData.isEmpty ? nil : Data(flatBuffersObject.immediateThumbnailData)
|
||||
self.mimeType = flatBuffersObject.mimeType
|
||||
self.size = flatBuffersObject.size == Int64.min ? nil : flatBuffersObject.size
|
||||
self.attributes = try (0 ..< flatBuffersObject.attributesCount).map { i in
|
||||
return try TelegramMediaFileAttribute(flatBuffersObject: flatBuffersObject.attributes(at: i)!)
|
||||
}
|
||||
self.alternativeRepresentations = try (0 ..< flatBuffersObject.alternativeRepresentationsCount).map { i in
|
||||
return try TelegramMediaFile(flatBuffersObject: flatBuffersObject.alternativeRepresentations(at: i)!)
|
||||
}
|
||||
}
|
||||
|
||||
func encodeToFlatBuffers(builder: inout FlatBufferBuilder) -> Offset {
|
||||
let partialReferenceOffset = self.partialReference.flatMap { $0.encodeToFlatBuffers(builder: &builder) }
|
||||
|
||||
let resourceOffset = TelegramMediaResource_serialize(resource: self.resource, flatBuffersBuilder: &builder)!
|
||||
|
||||
let previewRepresentationsOffsets = self.previewRepresentations.map { attribute in
|
||||
return attribute.encodeToFlatBuffers(builder: &builder)
|
||||
}
|
||||
let previewRepresentationsOffset = builder.createVector(ofOffsets: previewRepresentationsOffsets, len: previewRepresentationsOffsets.count)
|
||||
|
||||
let videoThumbnailsOffsets = self.videoThumbnails.map { videoThumbnail in
|
||||
return videoThumbnail.encodeToFlatBuffers(builder: &builder)
|
||||
}
|
||||
let videoThumbnailsOffset = builder.createVector(ofOffsets: videoThumbnailsOffsets, len: videoThumbnailsOffsets.count)
|
||||
|
||||
let videoCoverOffset = self.videoCover.flatMap { $0.encodeToFlatBuffers(builder: &builder) }
|
||||
|
||||
let immediateThumbnailDataOffset = self.immediateThumbnailData.flatMap { builder.createVector(bytes: $0) }
|
||||
|
||||
let mimeTypeOffset = builder.create(string: self.mimeType)
|
||||
|
||||
let attributesOffsets = self.attributes.map { attribute in
|
||||
return attribute.encodeToFlatBuffers(builder: &builder)
|
||||
}
|
||||
let attributesOffset = builder.createVector(ofOffsets: attributesOffsets, len: attributesOffsets.count)
|
||||
|
||||
let alternativeRepresentationsOffsets = self.alternativeRepresentations.map { alternativeRepresentation in
|
||||
return alternativeRepresentation.encodeToFlatBuffers(builder: &builder)
|
||||
}
|
||||
let alternativeRepresentationsOffset = builder.createVector(ofOffsets: alternativeRepresentationsOffsets, len: alternativeRepresentationsOffsets.count)
|
||||
|
||||
let start = TelegramCore_TelegramMediaFile.startTelegramMediaFile(&builder)
|
||||
|
||||
TelegramCore_TelegramMediaFile.add(fileId: TelegramCore_MediaId(namespace: self.fileId.namespace, id: self.fileId.id), &builder)
|
||||
if let partialReferenceOffset {
|
||||
TelegramCore_TelegramMediaFile.add(partialReference: partialReferenceOffset, &builder)
|
||||
}
|
||||
TelegramCore_TelegramMediaFile.add(resource: resourceOffset, &builder)
|
||||
TelegramCore_TelegramMediaFile.addVectorOf(previewRepresentations: previewRepresentationsOffset, &builder)
|
||||
TelegramCore_TelegramMediaFile.addVectorOf(videoThumbnails: videoThumbnailsOffset, &builder)
|
||||
if let immediateThumbnailDataOffset {
|
||||
TelegramCore_TelegramMediaFile.addVectorOf(immediateThumbnailData: immediateThumbnailDataOffset, &builder)
|
||||
}
|
||||
if let videoCoverOffset {
|
||||
TelegramCore_TelegramMediaFile.add(videoCover: videoCoverOffset, &builder)
|
||||
}
|
||||
TelegramCore_TelegramMediaFile.add(mimeType: mimeTypeOffset, &builder)
|
||||
TelegramCore_TelegramMediaFile.add(size: self.size ?? Int64.min, &builder)
|
||||
TelegramCore_TelegramMediaFile.addVectorOf(attributes: attributesOffset, &builder)
|
||||
TelegramCore_TelegramMediaFile.addVectorOf(alternativeRepresentations: alternativeRepresentationsOffset, &builder)
|
||||
|
||||
return TelegramCore_TelegramMediaFile.endTelegramMediaFile(&builder, start: start)
|
||||
}
|
||||
|
||||
public var fileName: String? {
|
||||
get {
|
||||
for attribute in self.attributes {
|
||||
|
@ -1,5 +1,7 @@
|
||||
import Foundation
|
||||
import Postbox
|
||||
import FlatBuffers
|
||||
import FlatSerialization
|
||||
|
||||
public enum TelegramMediaImageReferenceDecodingError: Error {
|
||||
case generic
|
||||
@ -54,6 +56,31 @@ public enum TelegramMediaImageReference: PostboxCoding, Equatable {
|
||||
try container.encode(postboxEncoder.makeData(), forKey: .data)
|
||||
}
|
||||
|
||||
public init(flatBuffersObject: TelegramCore_TelegramMediaImageReference) throws {
|
||||
self = .cloud(
|
||||
imageId: flatBuffersObject.imageId,
|
||||
accessHash: flatBuffersObject.accessHash,
|
||||
fileReference: flatBuffersObject.fileReference.isEmpty ? nil : Data(flatBuffersObject.fileReference)
|
||||
)
|
||||
}
|
||||
|
||||
public func encodeToFlatBuffers(builder: inout FlatBufferBuilder) -> Offset {
|
||||
switch self {
|
||||
case let .cloud(imageId, accessHash, fileReference):
|
||||
let fileReferenceOffset = fileReference.flatMap { builder.createVector(bytes: $0) }
|
||||
|
||||
let start = TelegramCore_TelegramMediaImageReference.startTelegramMediaImageReference(&builder)
|
||||
|
||||
TelegramCore_TelegramMediaImageReference.add(imageId: imageId, &builder)
|
||||
TelegramCore_TelegramMediaImageReference.add(accessHash: accessHash, &builder)
|
||||
if let fileReferenceOffset {
|
||||
TelegramCore_TelegramMediaImageReference.addVectorOf(fileReference: fileReferenceOffset, &builder)
|
||||
}
|
||||
|
||||
return TelegramCore_TelegramMediaImageReference.endTelegramMediaImageReference(&builder, start: start)
|
||||
}
|
||||
}
|
||||
|
||||
public static func ==(lhs: TelegramMediaImageReference, rhs: TelegramMediaImageReference) -> Bool {
|
||||
switch lhs {
|
||||
case let .cloud(imageId, accessHash, fileReference):
|
||||
@ -99,7 +126,7 @@ public final class TelegramMediaImage: Media, Equatable, Codable {
|
||||
public init(decoder: PostboxDecoder) {
|
||||
self.dimensions = PixelDimensions(width: decoder.decodeInt32ForKey("w", orElse: 0), height: decoder.decodeInt32ForKey("h", orElse: 0))
|
||||
self.resource = decoder.decodeObjectForKey("r") as! TelegramMediaResource
|
||||
self.startTimestamp = decoder.decodeOptionalDoubleForKey("s")
|
||||
self.startTimestamp = decoder.decodeOptionalDoubleForKey("s").flatMap({ Double(Float32($0)) })
|
||||
}
|
||||
|
||||
public func encode(_ encoder: PostboxEncoder) {
|
||||
@ -113,6 +140,29 @@ public final class TelegramMediaImage: Media, Equatable, Codable {
|
||||
}
|
||||
}
|
||||
|
||||
public init(flatBuffersObject: TelegramCore_VideoRepresentation) throws {
|
||||
self.dimensions = PixelDimensions(width: flatBuffersObject.width, height: flatBuffersObject.height)
|
||||
self.resource = try TelegramMediaResource_parse(flatBuffersObject: flatBuffersObject.resource)
|
||||
if flatBuffersObject.startTimestamp != -1.0 {
|
||||
self.startTimestamp = Double(flatBuffersObject.startTimestamp)
|
||||
} else {
|
||||
self.startTimestamp = nil
|
||||
}
|
||||
}
|
||||
|
||||
public func encodeToFlatBuffers(builder: inout FlatBufferBuilder) -> Offset {
|
||||
let resourceOffset = TelegramMediaResource_serialize(resource: self.resource, flatBuffersBuilder: &builder)!
|
||||
|
||||
let start = TelegramCore_VideoRepresentation.startVideoRepresentation(&builder)
|
||||
|
||||
TelegramCore_VideoRepresentation.add(width: self.dimensions.width, &builder)
|
||||
TelegramCore_VideoRepresentation.add(height: self.dimensions.height, &builder)
|
||||
TelegramCore_VideoRepresentation.add(resource: resourceOffset, &builder)
|
||||
TelegramCore_VideoRepresentation.add(startTimestamp: Float32(self.startTimestamp ?? -1.0), &builder)
|
||||
|
||||
return TelegramCore_VideoRepresentation.endVideoRepresentation(&builder, start: start)
|
||||
}
|
||||
|
||||
public static func ==(lhs: VideoRepresentation, rhs: VideoRepresentation) -> Bool {
|
||||
if lhs === rhs {
|
||||
return true
|
||||
@ -165,6 +215,52 @@ public final class TelegramMediaImage: Media, Equatable, Codable {
|
||||
encoder.encodeInt32Array(self.backgroundColors, forKey: "b")
|
||||
}
|
||||
|
||||
init(flatBuffersObject: TelegramCore_EmojiMarkup) throws {
|
||||
switch flatBuffersObject.contentType {
|
||||
case .emojimarkupContentEmoji:
|
||||
guard let value = flatBuffersObject.content(type: TelegramCore_EmojiMarkup_Content_Emoji.self) else {
|
||||
throw FlatBuffersError.missingRequiredField
|
||||
}
|
||||
self.content = .emoji(fileId: value.fileId)
|
||||
case .emojimarkupContentSticker:
|
||||
guard let value = flatBuffersObject.content(type: TelegramCore_EmojiMarkup_Content_Sticker.self) else {
|
||||
throw FlatBuffersError.missingRequiredField
|
||||
}
|
||||
self.content = .sticker(packReference: try StickerPackReference(flatBuffersObject: value.packReference), fileId: value.fileId)
|
||||
case .none_:
|
||||
throw FlatBuffersError.missingRequiredField
|
||||
}
|
||||
|
||||
self.backgroundColors = flatBuffersObject.backgroundColors
|
||||
}
|
||||
|
||||
func encodeToFlatBuffers(builder: inout FlatBufferBuilder) -> Offset {
|
||||
let contentOffset: Offset
|
||||
let contentType: TelegramCore_EmojiMarkup_Content
|
||||
switch self.content {
|
||||
case let .emoji(fileId):
|
||||
contentType = .emojimarkupContentEmoji
|
||||
let start = TelegramCore_EmojiMarkup_Content_Emoji.startEmojiMarkup_Content_Emoji(&builder)
|
||||
TelegramCore_EmojiMarkup_Content_Emoji.add(fileId: fileId, &builder)
|
||||
contentOffset = TelegramCore_EmojiMarkup_Content_Emoji.endEmojiMarkup_Content_Emoji(&builder, start: start)
|
||||
case let .sticker(packReference, fileId):
|
||||
contentType = .emojimarkupContentSticker
|
||||
let packReferenceOffset = packReference.encodeToFlatBuffers(builder: &builder)
|
||||
let start = TelegramCore_EmojiMarkup_Content_Sticker.startEmojiMarkup_Content_Sticker(&builder)
|
||||
TelegramCore_EmojiMarkup_Content_Sticker.add(packReference: packReferenceOffset, &builder)
|
||||
TelegramCore_EmojiMarkup_Content_Sticker.add(fileId: fileId, &builder)
|
||||
contentOffset = TelegramCore_EmojiMarkup_Content_Sticker.endEmojiMarkup_Content_Sticker(&builder, start: start)
|
||||
}
|
||||
|
||||
let backgroundColorsOffset = builder.createVector(self.backgroundColors)
|
||||
|
||||
let start = TelegramCore_EmojiMarkup.startEmojiMarkup(&builder)
|
||||
TelegramCore_EmojiMarkup.add(contentType: contentType, &builder)
|
||||
TelegramCore_EmojiMarkup.add(content: contentOffset, &builder)
|
||||
TelegramCore_EmojiMarkup.addVectorOf(backgroundColors: backgroundColorsOffset, &builder)
|
||||
return TelegramCore_EmojiMarkup.endEmojiMarkup(&builder, start: start)
|
||||
}
|
||||
|
||||
public static func ==(lhs: EmojiMarkup, rhs: EmojiMarkup) -> Bool {
|
||||
if lhs.content != rhs.content {
|
||||
return false
|
||||
@ -267,6 +363,59 @@ public final class TelegramMediaImage: Media, Equatable, Codable {
|
||||
try container.encode(postboxEncoder.makeData(), forKey: .data)
|
||||
}
|
||||
|
||||
public init(flatBuffersObject: TelegramCore_TelegramMediaImage) throws {
|
||||
self.imageId = MediaId(namespace: flatBuffersObject.imageId.namespace, id: flatBuffersObject.imageId.id)
|
||||
self.representations = try (0 ..< flatBuffersObject.representationsCount).map { i in
|
||||
return try TelegramMediaImageRepresentation(flatBuffersObject: flatBuffersObject.representations(at: i)!)
|
||||
}
|
||||
self.videoRepresentations = try (0 ..< flatBuffersObject.videoRepresentationsCount).map { i in
|
||||
return try TelegramMediaImage.VideoRepresentation(flatBuffersObject: flatBuffersObject.videoRepresentations(at: i)!)
|
||||
}
|
||||
self.immediateThumbnailData = flatBuffersObject.immediateThumbnailData.isEmpty ? nil : Data(flatBuffersObject.immediateThumbnailData)
|
||||
self.emojiMarkup = try flatBuffersObject.emojiMarkup.map { try EmojiMarkup(flatBuffersObject: $0) }
|
||||
self.reference = try flatBuffersObject.reference.map { try TelegramMediaImageReference(flatBuffersObject: $0) }
|
||||
self.partialReference = try flatBuffersObject.partialReference.map { try PartialMediaReference(flatBuffersObject: $0) }
|
||||
self.flags = TelegramMediaImageFlags(rawValue: flatBuffersObject.flags)
|
||||
}
|
||||
|
||||
public func encodeToFlatBuffers(builder: inout FlatBufferBuilder) -> Offset {
|
||||
let representationsOffsets = self.representations.map { item in
|
||||
return item.encodeToFlatBuffers(builder: &builder)
|
||||
}
|
||||
let representationsOffset = builder.createVector(ofOffsets: representationsOffsets, len: representationsOffsets.count)
|
||||
|
||||
let videoRepresentationsOffsets = self.videoRepresentations.map { item in
|
||||
return item.encodeToFlatBuffers(builder: &builder)
|
||||
}
|
||||
let videoRepresentationsOffset = builder.createVector(ofOffsets: videoRepresentationsOffsets, len: videoRepresentationsOffsets.count)
|
||||
|
||||
let immediateThumbnailDataOffset = self.immediateThumbnailData.flatMap { builder.createVector(bytes: $0) }
|
||||
let emojiMarkupOffset = self.emojiMarkup.flatMap { $0.encodeToFlatBuffers(builder: &builder) }
|
||||
let referenceOffset = self.reference.flatMap { $0.encodeToFlatBuffers(builder: &builder) }
|
||||
let partialReferenceOffset = self.partialReference.flatMap { $0.encodeToFlatBuffers(builder: &builder) }
|
||||
|
||||
let start = TelegramCore_TelegramMediaImage.startTelegramMediaImage(&builder)
|
||||
|
||||
TelegramCore_TelegramMediaImage.add(imageId: TelegramCore_MediaId(namespace: self.imageId.namespace, id: self.imageId.id), &builder)
|
||||
TelegramCore_TelegramMediaImage.addVectorOf(representations: representationsOffset, &builder)
|
||||
TelegramCore_TelegramMediaImage.addVectorOf(videoRepresentations: videoRepresentationsOffset, &builder)
|
||||
if let immediateThumbnailDataOffset {
|
||||
TelegramCore_TelegramMediaImage.addVectorOf(immediateThumbnailData: immediateThumbnailDataOffset, &builder)
|
||||
}
|
||||
if let emojiMarkupOffset {
|
||||
TelegramCore_TelegramMediaImage.add(emojiMarkup: emojiMarkupOffset, &builder)
|
||||
}
|
||||
if let referenceOffset {
|
||||
TelegramCore_TelegramMediaImage.add(reference: referenceOffset, &builder)
|
||||
}
|
||||
if let partialReferenceOffset {
|
||||
TelegramCore_TelegramMediaImage.add(partialReference: partialReferenceOffset, &builder)
|
||||
}
|
||||
TelegramCore_TelegramMediaImage.add(flags: self.flags.rawValue, &builder)
|
||||
|
||||
return TelegramCore_TelegramMediaImage.endTelegramMediaImage(&builder, start: start)
|
||||
}
|
||||
|
||||
public func representationForDisplayAtSize(_ size: PixelDimensions) -> TelegramMediaImageRepresentation? {
|
||||
if self.representations.count == 0 {
|
||||
return nil
|
||||
@ -417,6 +566,44 @@ public final class TelegramMediaImageRepresentation: PostboxCoding, Equatable, C
|
||||
encoder.encodeInt32(self.typeHint.rawValue, forKey: "th")
|
||||
}
|
||||
|
||||
public init(flatBuffersObject: TelegramCore_TelegramMediaImageRepresentation) throws {
|
||||
self.dimensions = PixelDimensions(width: flatBuffersObject.width, height: flatBuffersObject.height)
|
||||
self.resource = try TelegramMediaResource_parse(flatBuffersObject: flatBuffersObject.resource)
|
||||
self.progressiveSizes = flatBuffersObject.progressiveSizes
|
||||
self.immediateThumbnailData = flatBuffersObject.immediateThumbnailData.isEmpty ? nil : Data(flatBuffersObject.immediateThumbnailData)
|
||||
self.hasVideo = flatBuffersObject.hasVideo
|
||||
self.isPersonal = flatBuffersObject.isPersonal
|
||||
|
||||
switch flatBuffersObject.typeHint {
|
||||
case .generic:
|
||||
self.typeHint = .generic
|
||||
case .animated:
|
||||
self.typeHint = .animated
|
||||
case .video:
|
||||
self.typeHint = .video
|
||||
}
|
||||
}
|
||||
|
||||
func encodeToFlatBuffers(builder: inout FlatBufferBuilder) -> Offset {
|
||||
let resourceOffset = TelegramMediaResource_serialize(resource: self.resource, flatBuffersBuilder: &builder)!
|
||||
let progressiveSizesOffset = builder.createVector(self.progressiveSizes)
|
||||
let immediateThumbnailDataOffset = self.immediateThumbnailData.flatMap { builder.createVector(bytes: $0) }
|
||||
|
||||
let start = TelegramCore_TelegramMediaImageRepresentation.startTelegramMediaImageRepresentation(&builder)
|
||||
|
||||
TelegramCore_TelegramMediaImageRepresentation.add(width: self.dimensions.width, &builder)
|
||||
TelegramCore_TelegramMediaImageRepresentation.add(height: self.dimensions.height, &builder)
|
||||
TelegramCore_TelegramMediaImageRepresentation.add(resource: resourceOffset, &builder)
|
||||
TelegramCore_TelegramMediaImageRepresentation.addVectorOf(progressiveSizes: progressiveSizesOffset, &builder)
|
||||
if let immediateThumbnailDataOffset {
|
||||
TelegramCore_TelegramMediaImageRepresentation.addVectorOf(immediateThumbnailData: immediateThumbnailDataOffset, &builder)
|
||||
}
|
||||
TelegramCore_TelegramMediaImageRepresentation.add(hasVideo: self.hasVideo, &builder)
|
||||
TelegramCore_TelegramMediaImageRepresentation.add(isPersonal: self.isPersonal, &builder)
|
||||
|
||||
return TelegramCore_TelegramMediaImageRepresentation.endTelegramMediaImageRepresentation(&builder, start: start)
|
||||
}
|
||||
|
||||
public var description: String {
|
||||
return "(\(Int(dimensions.width))x\(Int(dimensions.height)))"
|
||||
}
|
||||
|
@ -583,12 +583,10 @@ func _internal_reindexCacheInBackground(account: Account, lowImpact: Bool) -> Si
|
||||
}
|
||||
processResource(mediaMessages, file.resource, MediaResourceUserContentType(file: file))
|
||||
for alternativeRepresentation in file.alternativeRepresentations {
|
||||
if let alternativeRepresentation = alternativeRepresentation as? TelegramMediaFile {
|
||||
for representation in alternativeRepresentation.previewRepresentations {
|
||||
processResource(mediaMessages, representation.resource, MediaResourceUserContentType(file: file))
|
||||
}
|
||||
processResource(mediaMessages, alternativeRepresentation.resource, MediaResourceUserContentType(file: file))
|
||||
for representation in alternativeRepresentation.previewRepresentations {
|
||||
processResource(mediaMessages, representation.resource, MediaResourceUserContentType(file: file))
|
||||
}
|
||||
processResource(mediaMessages, alternativeRepresentation.resource, MediaResourceUserContentType(file: file))
|
||||
}
|
||||
} else if let webpage = media as? TelegramMediaWebpage {
|
||||
if case let .Loaded(content) = webpage.content {
|
||||
|
@ -48,6 +48,8 @@ swift_library(
|
||||
"//submodules/lottie-ios:Lottie",
|
||||
"//submodules/TelegramUI/Components/Utils/GenerateStickerPlaceholderImage",
|
||||
"//submodules/TelegramUIPreferences",
|
||||
"//submodules/TelegramCore/FlatBuffers",
|
||||
"//submodules/TelegramCore/FlatSerialization",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
@ -7,6 +7,8 @@ import SwiftSignalKit
|
||||
import AnimationCache
|
||||
import MultiAnimationRenderer
|
||||
import TelegramNotices
|
||||
import FlatBuffers
|
||||
import FlatSerialization
|
||||
|
||||
public extension EmojiPagerContentComponent {
|
||||
private static func hasPremium(context: AccountContext, chatPeerId: EnginePeer.Id?, premiumIfSavedMessages: Bool) -> Signal<Bool, NoError> {
|
||||
@ -1366,6 +1368,14 @@ public extension EmojiPagerContentComponent {
|
||||
continue
|
||||
}
|
||||
|
||||
#if DEBUG && false
|
||||
let fbData = item.file.encodeToFlatBuffersData()
|
||||
var byteBuffer = ByteBuffer(data: fbData)
|
||||
let flatBuffersObject: TelegramCore_TelegramMediaFile = try! getCheckedRoot(byteBuffer: &byteBuffer)
|
||||
let fbObject = try! TelegramMediaFile(flatBuffersObject: flatBuffersObject)
|
||||
assert(item.file == fbObject)
|
||||
#endif
|
||||
|
||||
var icon: EmojiPagerContentComponent.Item.Icon = .none
|
||||
if [.reaction(onlyTop: false), .quickReaction].contains(subject), !hasPremium {
|
||||
icon = .locked
|
||||
|
@ -986,6 +986,8 @@ extension ChatControllerImpl {
|
||||
//effectiveCachedDataReady = .single(true)
|
||||
effectiveCachedDataReady = self.cachedDataReady.get()
|
||||
}
|
||||
var measure_isFirstTime = true
|
||||
let initTimestamp = self.initTimestamp
|
||||
self.ready.set(combineLatest(queue: .mainQueue(),
|
||||
self.chatDisplayNode.historyNode.historyState.get(),
|
||||
self._chatLocationInfoReady.get(),
|
||||
@ -997,7 +999,16 @@ extension ChatControllerImpl {
|
||||
|> map { _, chatLocationInfoReady, cachedDataReady, _, wallpaperReady, presentationReady in
|
||||
return chatLocationInfoReady && cachedDataReady && wallpaperReady && presentationReady
|
||||
}
|
||||
|> distinctUntilChanged)
|
||||
|> distinctUntilChanged
|
||||
|> beforeNext { value in
|
||||
if measure_isFirstTime {
|
||||
measure_isFirstTime = false
|
||||
#if DEBUG
|
||||
let deltaTime = (CFAbsoluteTimeGetCurrent() - initTimestamp) * 1000.0
|
||||
print("Chat controller init to ready: \(deltaTime) ms")
|
||||
#endif
|
||||
}
|
||||
})
|
||||
|
||||
if self.context.sharedContext.immediateExperimentalUISettings.crashOnLongQueries {
|
||||
let _ = (self.ready.get()
|
||||
|
@ -627,6 +627,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
var currentSendStarsUndoMessageId: EngineMessage.Id?
|
||||
var currentSendStarsUndoCount: Int = 0
|
||||
|
||||
let initTimestamp: Double
|
||||
|
||||
public var alwaysShowSearchResultsAsList: Bool = false {
|
||||
didSet {
|
||||
self.presentationInterfaceState = self.presentationInterfaceState.updatedDisplayHistoryFilterAsList(self.alwaysShowSearchResultsAsList)
|
||||
@ -675,6 +677,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
customChatNavigationStack: [EnginePeer.Id]? = nil,
|
||||
params: ChatControllerParams? = nil
|
||||
) {
|
||||
self.initTimestamp = CFAbsoluteTimeGetCurrent()
|
||||
|
||||
let _ = ChatControllerCount.modify { value in
|
||||
return value + 1
|
||||
}
|
||||
|
@ -733,8 +733,13 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto
|
||||
public var isReady: Signal<Bool, NoError> {
|
||||
return self._isReady.get()
|
||||
}
|
||||
private var didSetReady: Bool = false
|
||||
|
||||
private let initTimestamp: Double
|
||||
|
||||
public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>), chatLocation: ChatLocation, chatLocationContextHolder: Atomic<ChatLocationContextHolder?>, tag: HistoryViewInputTag?, source: ChatHistoryListSource, subject: ChatControllerSubject?, controllerInteraction: ChatControllerInteraction, selectedMessages: Signal<Set<MessageId>?, NoError>, mode: ChatHistoryListMode = .bubbles, rotated: Bool = false, isChatPreview: Bool, messageTransitionNode: @escaping () -> ChatMessageTransitionNodeImpl?) {
|
||||
self.initTimestamp = CFAbsoluteTimeGetCurrent()
|
||||
|
||||
var tag = tag
|
||||
if case .pinnedMessages = subject {
|
||||
tag = .tag(.pinned)
|
||||
@ -1698,6 +1703,8 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto
|
||||
}
|
||||
|> distinctUntilChanged
|
||||
|
||||
let startTime = CFAbsoluteTimeGetCurrent()
|
||||
var measure_isFirstTime = true
|
||||
let messageViewQueue = Queue.mainQueue()
|
||||
let historyViewTransitionDisposable = combineLatest(queue: messageViewQueue,
|
||||
historyViewUpdate,
|
||||
@ -1728,6 +1735,14 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto
|
||||
).startStrict(next: { [weak self] update, chatPresentationData, selectedMessages, updatingMedia, networkType, preferredStoryHighQuality, animatedEmojiStickers, additionalAnimatedEmojiStickers, customChannelDiscussionReadState, customThreadOutgoingReadState, availableReactions, availableMessageEffects, savedMessageTags, defaultReaction, accountPeer, suggestAudioTranscription, promises, topicAuthorId, translationState, maxReadStoryId, recommendedChannels, audioTranscriptionTrial, chatThemes, deviceContactsNumbers, contentSettings in
|
||||
let (historyAppearsCleared, pendingUnpinnedAllMessages, pendingRemovedMessages, currentlyPlayingMessageIdAndType, scrollToMessageId, chatHasBots, allAdMessages) = promises
|
||||
|
||||
if measure_isFirstTime {
|
||||
measure_isFirstTime = false
|
||||
#if DEBUG
|
||||
let deltaTime = (CFAbsoluteTimeGetCurrent() - startTime) * 1000.0
|
||||
print("Chat load time: \(deltaTime) ms")
|
||||
#endif
|
||||
}
|
||||
|
||||
func applyHole() {
|
||||
Queue.mainQueue().async {
|
||||
if let strongSelf = self {
|
||||
@ -4051,6 +4066,14 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto
|
||||
strongSelf.dequeueHistoryViewTransitions()
|
||||
|
||||
strongSelf._isReady.set(true)
|
||||
|
||||
if !strongSelf.didSetReady {
|
||||
strongSelf.didSetReady = true
|
||||
#if DEBUG
|
||||
let deltaTime = (CFAbsoluteTimeGetCurrent() - strongSelf.initTimestamp) * 1000.0
|
||||
print("Chat init to dequeue time: \(deltaTime) ms")
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,25 +55,24 @@ public final class HLSQualitySet {
|
||||
public init?(baseFile: FileMediaReference, codecConfiguration: HLSCodecConfiguration) {
|
||||
var qualityFiles: [Int: FileMediaReference] = [:]
|
||||
for alternativeRepresentation in baseFile.media.alternativeRepresentations {
|
||||
if let alternativeFile = alternativeRepresentation as? TelegramMediaFile {
|
||||
for attribute in alternativeFile.attributes {
|
||||
if case let .Video(_, size, _, _, _, videoCodec) = attribute {
|
||||
if let videoCodec, NativeVideoContent.isVideoCodecSupported(videoCodec: videoCodec, isHardwareAv1Supported: codecConfiguration.isHardwareAv1Supported, isSoftwareAv1Supported: codecConfiguration.isSoftwareAv1Supported) {
|
||||
let key = Int(min(size.width, size.height))
|
||||
if let currentFile = qualityFiles[key] {
|
||||
var currentCodec: String?
|
||||
for attribute in currentFile.media.attributes {
|
||||
if case let .Video(_, _, _, _, _, videoCodec) = attribute {
|
||||
currentCodec = videoCodec
|
||||
}
|
||||
}
|
||||
if let currentCodec, (currentCodec == "av1" || currentCodec == "av01") {
|
||||
} else {
|
||||
qualityFiles[key] = baseFile.withMedia(alternativeFile)
|
||||
let alternativeFile = alternativeRepresentation
|
||||
for attribute in alternativeFile.attributes {
|
||||
if case let .Video(_, size, _, _, _, videoCodec) = attribute {
|
||||
if let videoCodec, NativeVideoContent.isVideoCodecSupported(videoCodec: videoCodec, isHardwareAv1Supported: codecConfiguration.isHardwareAv1Supported, isSoftwareAv1Supported: codecConfiguration.isSoftwareAv1Supported) {
|
||||
let key = Int(min(size.width, size.height))
|
||||
if let currentFile = qualityFiles[key] {
|
||||
var currentCodec: String?
|
||||
for attribute in currentFile.media.attributes {
|
||||
if case let .Video(_, _, _, _, _, videoCodec) = attribute {
|
||||
currentCodec = videoCodec
|
||||
}
|
||||
}
|
||||
if let currentCodec, (currentCodec == "av1" || currentCodec == "av01") {
|
||||
} else {
|
||||
qualityFiles[key] = baseFile.withMedia(alternativeFile)
|
||||
}
|
||||
} else {
|
||||
qualityFiles[key] = baseFile.withMedia(alternativeFile)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -82,17 +81,16 @@ public final class HLSQualitySet {
|
||||
|
||||
var playlistFiles: [Int: FileMediaReference] = [:]
|
||||
for alternativeRepresentation in baseFile.media.alternativeRepresentations {
|
||||
if let alternativeFile = alternativeRepresentation as? TelegramMediaFile {
|
||||
if alternativeFile.mimeType == "application/x-mpegurl" {
|
||||
if let fileName = alternativeFile.fileName {
|
||||
if fileName.hasPrefix("mtproto:") {
|
||||
let fileIdString = String(fileName[fileName.index(fileName.startIndex, offsetBy: "mtproto:".count)...])
|
||||
if let fileId = Int64(fileIdString) {
|
||||
for (quality, file) in qualityFiles {
|
||||
if file.media.fileId.id == fileId {
|
||||
playlistFiles[quality] = baseFile.withMedia(alternativeFile)
|
||||
break
|
||||
}
|
||||
let alternativeFile = alternativeRepresentation
|
||||
if alternativeFile.mimeType == "application/x-mpegurl" {
|
||||
if let fileName = alternativeFile.fileName {
|
||||
if fileName.hasPrefix("mtproto:") {
|
||||
let fileIdString = String(fileName[fileName.index(fileName.startIndex, offsetBy: "mtproto:".count)...])
|
||||
if let fileId = Int64(fileIdString) {
|
||||
for (quality, file) in qualityFiles {
|
||||
if file.media.fileId.id == fileId {
|
||||
playlistFiles[quality] = baseFile.withMedia(alternativeFile)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -73,10 +73,8 @@ public final class NativeVideoContent: UniversalVideoContent {
|
||||
|
||||
public static func isHLSVideo(file: TelegramMediaFile) -> Bool {
|
||||
for alternativeRepresentation in file.alternativeRepresentations {
|
||||
if let alternativeFile = alternativeRepresentation as? TelegramMediaFile {
|
||||
if alternativeFile.mimeType == "application/x-mpegurl" {
|
||||
return true
|
||||
}
|
||||
if alternativeRepresentation.mimeType == "application/x-mpegurl" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
|
Loading…
x
Reference in New Issue
Block a user