mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-22 22:25:57 +00:00
no message
This commit is contained in:
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
D003702B1DA42586004308D3 /* PhoneNumber.swift in Sources */ = {isa = PBXBuildFile; fileRef = D003702A1DA42586004308D3 /* PhoneNumber.swift */; };
|
D003702B1DA42586004308D3 /* PhoneNumber.swift in Sources */ = {isa = PBXBuildFile; fileRef = D003702A1DA42586004308D3 /* PhoneNumber.swift */; };
|
||||||
|
D0177B7B1DF8A16C00A5083A /* SecretChatState.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0177B7A1DF8A16C00A5083A /* SecretChatState.swift */; };
|
||||||
D01AC91D1DD5DA5E00E8160F /* RequestMessageActionCallback.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01AC91C1DD5DA5E00E8160F /* RequestMessageActionCallback.swift */; };
|
D01AC91D1DD5DA5E00E8160F /* RequestMessageActionCallback.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01AC91C1DD5DA5E00E8160F /* RequestMessageActionCallback.swift */; };
|
||||||
D01AC9211DD5E7E500E8160F /* RequestEditMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01AC9201DD5E7E500E8160F /* RequestEditMessage.swift */; };
|
D01AC9211DD5E7E500E8160F /* RequestEditMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01AC9201DD5E7E500E8160F /* RequestEditMessage.swift */; };
|
||||||
D01AC9231DD5E9A200E8160F /* ApplyUpdateMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01AC9221DD5E9A200E8160F /* ApplyUpdateMessage.swift */; };
|
D01AC9231DD5E9A200E8160F /* ApplyUpdateMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01AC9221DD5E9A200E8160F /* ApplyUpdateMessage.swift */; };
|
||||||
@@ -94,6 +95,9 @@
|
|||||||
D073CEA31DCBF3E1007511FD /* PendingMessageUploadedContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = D09BB6B51DB0428000A905C0 /* PendingMessageUploadedContent.swift */; };
|
D073CEA31DCBF3E1007511FD /* PendingMessageUploadedContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = D09BB6B51DB0428000A905C0 /* PendingMessageUploadedContent.swift */; };
|
||||||
D073CEA41DCBF3EA007511FD /* MultipartUpload.swift in Sources */ = {isa = PBXBuildFile; fileRef = D03C53761DAFF20F004C17B3 /* MultipartUpload.swift */; };
|
D073CEA41DCBF3EA007511FD /* MultipartUpload.swift in Sources */ = {isa = PBXBuildFile; fileRef = D03C53761DAFF20F004C17B3 /* MultipartUpload.swift */; };
|
||||||
D073CEA51DCBF3F5007511FD /* StickerManagement.swift in Sources */ = {isa = PBXBuildFile; fileRef = D021E0E11DB5401A00C6B04F /* StickerManagement.swift */; };
|
D073CEA51DCBF3F5007511FD /* StickerManagement.swift in Sources */ = {isa = PBXBuildFile; fileRef = D021E0E11DB5401A00C6B04F /* StickerManagement.swift */; };
|
||||||
|
D07827BB1E00451F00071108 /* SearchPeers.swift in Sources */ = {isa = PBXBuildFile; fileRef = D07827BA1E00451F00071108 /* SearchPeers.swift */; };
|
||||||
|
D07827C91E02F59C00071108 /* InstantPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = D07827C81E02F59C00071108 /* InstantPage.swift */; };
|
||||||
|
D07827CB1E02F5B200071108 /* RichText.swift in Sources */ = {isa = PBXBuildFile; fileRef = D07827CA1E02F5B200071108 /* RichText.swift */; };
|
||||||
D099EA1C1DE72867001AF5A8 /* PeerCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = D099EA1B1DE72867001AF5A8 /* PeerCommands.swift */; };
|
D099EA1C1DE72867001AF5A8 /* PeerCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = D099EA1B1DE72867001AF5A8 /* PeerCommands.swift */; };
|
||||||
D09A2FE61D7CD4940018FB72 /* TelegramChannel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D09A2FE51D7CD4940018FB72 /* TelegramChannel.swift */; };
|
D09A2FE61D7CD4940018FB72 /* TelegramChannel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D09A2FE51D7CD4940018FB72 /* TelegramChannel.swift */; };
|
||||||
D09A2FEB1D7CDC320018FB72 /* PeerAccessRestrictionInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D09A2FEA1D7CDC320018FB72 /* PeerAccessRestrictionInfo.swift */; };
|
D09A2FEB1D7CDC320018FB72 /* PeerAccessRestrictionInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D09A2FEA1D7CDC320018FB72 /* PeerAccessRestrictionInfo.swift */; };
|
||||||
@@ -206,9 +210,6 @@
|
|||||||
D0B844491DAB91FD005F29E1 /* ManagedChatListHoles.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0AB0B951D662F0B002C78E7 /* ManagedChatListHoles.swift */; };
|
D0B844491DAB91FD005F29E1 /* ManagedChatListHoles.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0AB0B951D662F0B002C78E7 /* ManagedChatListHoles.swift */; };
|
||||||
D0B8444B1DAB91FD005F29E1 /* ManagedSynchronizePeerReadStates.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0AB0B991D666520002C78E7 /* ManagedSynchronizePeerReadStates.swift */; };
|
D0B8444B1DAB91FD005F29E1 /* ManagedSynchronizePeerReadStates.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0AB0B991D666520002C78E7 /* ManagedSynchronizePeerReadStates.swift */; };
|
||||||
D0B8444C1DAB91FD005F29E1 /* UpdateCachedPeerData.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0B843861DA6F705005F29E1 /* UpdateCachedPeerData.swift */; };
|
D0B8444C1DAB91FD005F29E1 /* UpdateCachedPeerData.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0B843861DA6F705005F29E1 /* UpdateCachedPeerData.swift */; };
|
||||||
D0B8444D1DAB9206005F29E1 /* JoinChannel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DF0C891D819C7E008AEB01 /* JoinChannel.swift */; };
|
|
||||||
D0B8444E1DAB9206005F29E1 /* PeerParticipants.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DF0CA71D82BF32008AEB01 /* PeerParticipants.swift */; };
|
|
||||||
D0B8444F1DAB9206005F29E1 /* ChangePeerNotificationSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0B843961DA7FBBC005F29E1 /* ChangePeerNotificationSettings.swift */; };
|
|
||||||
D0B844531DAC0773005F29E1 /* TelegramUserPresence.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0B844521DAC0773005F29E1 /* TelegramUserPresence.swift */; };
|
D0B844531DAC0773005F29E1 /* TelegramUserPresence.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0B844521DAC0773005F29E1 /* TelegramUserPresence.swift */; };
|
||||||
D0CAF2EA1D75EC600011F558 /* MtProtoKitDynamic.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0CAF2E91D75EC600011F558 /* MtProtoKitDynamic.framework */; };
|
D0CAF2EA1D75EC600011F558 /* MtProtoKitDynamic.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0CAF2E91D75EC600011F558 /* MtProtoKitDynamic.framework */; };
|
||||||
D0DC354E1DE368F7000195EB /* RequestChatContextResults.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DC354D1DE368F7000195EB /* RequestChatContextResults.swift */; };
|
D0DC354E1DE368F7000195EB /* RequestChatContextResults.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DC354D1DE368F7000195EB /* RequestChatContextResults.swift */; };
|
||||||
@@ -229,11 +230,18 @@
|
|||||||
D0F3CC7A1DDE2859008148FA /* RequestMessageActionCallback.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01AC91C1DD5DA5E00E8160F /* RequestMessageActionCallback.swift */; };
|
D0F3CC7A1DDE2859008148FA /* RequestMessageActionCallback.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01AC91C1DD5DA5E00E8160F /* RequestMessageActionCallback.swift */; };
|
||||||
D0F3CC7B1DDE2859008148FA /* RequestEditMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01AC9201DD5E7E500E8160F /* RequestEditMessage.swift */; };
|
D0F3CC7B1DDE2859008148FA /* RequestEditMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01AC9201DD5E7E500E8160F /* RequestEditMessage.swift */; };
|
||||||
D0F3CC7D1DDE289E008148FA /* ResolvePeerByName.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F3CC7C1DDE289E008148FA /* ResolvePeerByName.swift */; };
|
D0F3CC7D1DDE289E008148FA /* ResolvePeerByName.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F3CC7C1DDE289E008148FA /* ResolvePeerByName.swift */; };
|
||||||
D0F3CC7E1DDE289E008148FA /* ResolvePeerByName.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F3CC7C1DDE289E008148FA /* ResolvePeerByName.swift */; };
|
|
||||||
D0F7AB2C1DCE889D009AD9A1 /* EditedMessageAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F7AB2B1DCE889D009AD9A1 /* EditedMessageAttribute.swift */; };
|
D0F7AB2C1DCE889D009AD9A1 /* EditedMessageAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F7AB2B1DCE889D009AD9A1 /* EditedMessageAttribute.swift */; };
|
||||||
D0F7AB2D1DCE889D009AD9A1 /* EditedMessageAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F7AB2B1DCE889D009AD9A1 /* EditedMessageAttribute.swift */; };
|
D0F7AB2D1DCE889D009AD9A1 /* EditedMessageAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F7AB2B1DCE889D009AD9A1 /* EditedMessageAttribute.swift */; };
|
||||||
D0F7AB2F1DCF507E009AD9A1 /* ReplyMarkupMessageAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F7AB2E1DCF507E009AD9A1 /* ReplyMarkupMessageAttribute.swift */; };
|
D0F7AB2F1DCF507E009AD9A1 /* ReplyMarkupMessageAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F7AB2E1DCF507E009AD9A1 /* ReplyMarkupMessageAttribute.swift */; };
|
||||||
D0F7AB301DCF507E009AD9A1 /* ReplyMarkupMessageAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F7AB2E1DCF507E009AD9A1 /* ReplyMarkupMessageAttribute.swift */; };
|
D0F7AB301DCF507E009AD9A1 /* ReplyMarkupMessageAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F7AB2E1DCF507E009AD9A1 /* ReplyMarkupMessageAttribute.swift */; };
|
||||||
|
D0F7B1E31E045C7B007EB8A5 /* RichText.swift in Sources */ = {isa = PBXBuildFile; fileRef = D07827CA1E02F5B200071108 /* RichText.swift */; };
|
||||||
|
D0F7B1E41E045C7B007EB8A5 /* InstantPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = D07827C81E02F59C00071108 /* InstantPage.swift */; };
|
||||||
|
D0F7B1E71E045C87007EB8A5 /* JoinChannel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DF0C891D819C7E008AEB01 /* JoinChannel.swift */; };
|
||||||
|
D0F7B1E81E045C87007EB8A5 /* PeerParticipants.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DF0CA71D82BF32008AEB01 /* PeerParticipants.swift */; };
|
||||||
|
D0F7B1E91E045C87007EB8A5 /* PeerCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = D099EA1B1DE72867001AF5A8 /* PeerCommands.swift */; };
|
||||||
|
D0F7B1EA1E045C87007EB8A5 /* ChangePeerNotificationSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0B843961DA7FBBC005F29E1 /* ChangePeerNotificationSettings.swift */; };
|
||||||
|
D0F7B1EB1E045C87007EB8A5 /* ResolvePeerByName.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F3CC7C1DDE289E008148FA /* ResolvePeerByName.swift */; };
|
||||||
|
D0F7B1EC1E045C87007EB8A5 /* SearchPeers.swift in Sources */ = {isa = PBXBuildFile; fileRef = D07827BA1E00451F00071108 /* SearchPeers.swift */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXContainerItemProxy section */
|
/* Begin PBXContainerItemProxy section */
|
||||||
@@ -248,6 +256,7 @@
|
|||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
D003702A1DA42586004308D3 /* PhoneNumber.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PhoneNumber.swift; sourceTree = "<group>"; };
|
D003702A1DA42586004308D3 /* PhoneNumber.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PhoneNumber.swift; sourceTree = "<group>"; };
|
||||||
|
D0177B7A1DF8A16C00A5083A /* SecretChatState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SecretChatState.swift; sourceTree = "<group>"; };
|
||||||
D01AC91C1DD5DA5E00E8160F /* RequestMessageActionCallback.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RequestMessageActionCallback.swift; sourceTree = "<group>"; };
|
D01AC91C1DD5DA5E00E8160F /* RequestMessageActionCallback.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RequestMessageActionCallback.swift; sourceTree = "<group>"; };
|
||||||
D01AC9201DD5E7E500E8160F /* RequestEditMessage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RequestEditMessage.swift; sourceTree = "<group>"; };
|
D01AC9201DD5E7E500E8160F /* RequestEditMessage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RequestEditMessage.swift; sourceTree = "<group>"; };
|
||||||
D01AC9221DD5E9A200E8160F /* ApplyUpdateMessage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApplyUpdateMessage.swift; sourceTree = "<group>"; };
|
D01AC9221DD5E9A200E8160F /* ApplyUpdateMessage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApplyUpdateMessage.swift; sourceTree = "<group>"; };
|
||||||
@@ -321,6 +330,9 @@
|
|||||||
D067066E1D512AEB00DED3E3 /* MtProtoKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MtProtoKit.framework; path = "../../../../Library/Developer/Xcode/DerivedData/Telegram-iOS-diblohvjozhgaifjcniwdlixlilx/Build/Products/Debug-iphonesimulator/MtProtoKit.framework"; sourceTree = "<group>"; };
|
D067066E1D512AEB00DED3E3 /* MtProtoKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MtProtoKit.framework; path = "../../../../Library/Developer/Xcode/DerivedData/Telegram-iOS-diblohvjozhgaifjcniwdlixlilx/Build/Products/Debug-iphonesimulator/MtProtoKit.framework"; sourceTree = "<group>"; };
|
||||||
D073CE5C1DCB97F6007511FD /* ForwardSourceInfoAttribute.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ForwardSourceInfoAttribute.swift; sourceTree = "<group>"; };
|
D073CE5C1DCB97F6007511FD /* ForwardSourceInfoAttribute.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ForwardSourceInfoAttribute.swift; sourceTree = "<group>"; };
|
||||||
D073CE5F1DCB9D14007511FD /* OutgoingMessageInfoAttribute.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OutgoingMessageInfoAttribute.swift; sourceTree = "<group>"; };
|
D073CE5F1DCB9D14007511FD /* OutgoingMessageInfoAttribute.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OutgoingMessageInfoAttribute.swift; sourceTree = "<group>"; };
|
||||||
|
D07827BA1E00451F00071108 /* SearchPeers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SearchPeers.swift; sourceTree = "<group>"; };
|
||||||
|
D07827C81E02F59C00071108 /* InstantPage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InstantPage.swift; sourceTree = "<group>"; };
|
||||||
|
D07827CA1E02F5B200071108 /* RichText.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RichText.swift; sourceTree = "<group>"; };
|
||||||
D099EA1B1DE72867001AF5A8 /* PeerCommands.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PeerCommands.swift; sourceTree = "<group>"; };
|
D099EA1B1DE72867001AF5A8 /* PeerCommands.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PeerCommands.swift; sourceTree = "<group>"; };
|
||||||
D09A2FE51D7CD4940018FB72 /* TelegramChannel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TelegramChannel.swift; sourceTree = "<group>"; };
|
D09A2FE51D7CD4940018FB72 /* TelegramChannel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TelegramChannel.swift; sourceTree = "<group>"; };
|
||||||
D09A2FEA1D7CDC320018FB72 /* PeerAccessRestrictionInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PeerAccessRestrictionInfo.swift; sourceTree = "<group>"; };
|
D09A2FEA1D7CDC320018FB72 /* PeerAccessRestrictionInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PeerAccessRestrictionInfo.swift; sourceTree = "<group>"; };
|
||||||
@@ -567,6 +579,8 @@
|
|||||||
D03B0CEF1D62250800955575 /* TelegramMediaImage.swift */,
|
D03B0CEF1D62250800955575 /* TelegramMediaImage.swift */,
|
||||||
D03B0CF11D62250800955575 /* TelegramMediaMap.swift */,
|
D03B0CF11D62250800955575 /* TelegramMediaMap.swift */,
|
||||||
D03B0CF31D62250800955575 /* TelegramMediaWebpage.swift */,
|
D03B0CF31D62250800955575 /* TelegramMediaWebpage.swift */,
|
||||||
|
D07827CA1E02F5B200071108 /* RichText.swift */,
|
||||||
|
D07827C81E02F59C00071108 /* InstantPage.swift */,
|
||||||
);
|
);
|
||||||
name = Media;
|
name = Media;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -575,6 +589,7 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
D03B0CFF1D62255C00955575 /* ChannelState.swift */,
|
D03B0CFF1D62255C00955575 /* ChannelState.swift */,
|
||||||
|
D0177B7A1DF8A16C00A5083A /* SecretChatState.swift */,
|
||||||
D03121011DA57E93006A2A60 /* TelegramPeerNotificationSettings.swift */,
|
D03121011DA57E93006A2A60 /* TelegramPeerNotificationSettings.swift */,
|
||||||
D03B0D001D62255C00955575 /* EnqueueMessage.swift */,
|
D03B0D001D62255C00955575 /* EnqueueMessage.swift */,
|
||||||
D03B0D011D62255C00955575 /* Holes.swift */,
|
D03B0D011D62255C00955575 /* Holes.swift */,
|
||||||
@@ -766,6 +781,7 @@
|
|||||||
D099EA1B1DE72867001AF5A8 /* PeerCommands.swift */,
|
D099EA1B1DE72867001AF5A8 /* PeerCommands.swift */,
|
||||||
D0B843961DA7FBBC005F29E1 /* ChangePeerNotificationSettings.swift */,
|
D0B843961DA7FBBC005F29E1 /* ChangePeerNotificationSettings.swift */,
|
||||||
D0F3CC7C1DDE289E008148FA /* ResolvePeerByName.swift */,
|
D0F3CC7C1DDE289E008148FA /* ResolvePeerByName.swift */,
|
||||||
|
D07827BA1E00451F00071108 /* SearchPeers.swift */,
|
||||||
);
|
);
|
||||||
name = Peers;
|
name = Peers;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -941,6 +957,8 @@
|
|||||||
files = (
|
files = (
|
||||||
D021E0DF1DB539FC00C6B04F /* StickerPack.swift in Sources */,
|
D021E0DF1DB539FC00C6B04F /* StickerPack.swift in Sources */,
|
||||||
D03B0D091D62255C00955575 /* EnqueueMessage.swift in Sources */,
|
D03B0D091D62255C00955575 /* EnqueueMessage.swift in Sources */,
|
||||||
|
D07827C91E02F59C00071108 /* InstantPage.swift in Sources */,
|
||||||
|
D07827CB1E02F5B200071108 /* RichText.swift in Sources */,
|
||||||
D03B0CE01D62249100955575 /* StoreMessage_Telegram.swift in Sources */,
|
D03B0CE01D62249100955575 /* StoreMessage_Telegram.swift in Sources */,
|
||||||
D03B0CB91D62233400955575 /* Either.swift in Sources */,
|
D03B0CB91D62233400955575 /* Either.swift in Sources */,
|
||||||
D03B0CBD1D62234300955575 /* Regex.swift in Sources */,
|
D03B0CBD1D62234300955575 /* Regex.swift in Sources */,
|
||||||
@@ -1000,6 +1018,7 @@
|
|||||||
D0F7AB2F1DCF507E009AD9A1 /* ReplyMarkupMessageAttribute.swift in Sources */,
|
D0F7AB2F1DCF507E009AD9A1 /* ReplyMarkupMessageAttribute.swift in Sources */,
|
||||||
D0B843971DA7FBBC005F29E1 /* ChangePeerNotificationSettings.swift in Sources */,
|
D0B843971DA7FBBC005F29E1 /* ChangePeerNotificationSettings.swift in Sources */,
|
||||||
D09BB6B41DB02C2B00A905C0 /* PendingMessageManager.swift in Sources */,
|
D09BB6B41DB02C2B00A905C0 /* PendingMessageManager.swift in Sources */,
|
||||||
|
D07827BB1E00451F00071108 /* SearchPeers.swift in Sources */,
|
||||||
D0DC354E1DE368F7000195EB /* RequestChatContextResults.swift in Sources */,
|
D0DC354E1DE368F7000195EB /* RequestChatContextResults.swift in Sources */,
|
||||||
D0B843851DA6EDC4005F29E1 /* CachedChannelData.swift in Sources */,
|
D0B843851DA6EDC4005F29E1 /* CachedChannelData.swift in Sources */,
|
||||||
D0B843831DA6EDB8005F29E1 /* CachedGroupData.swift in Sources */,
|
D0B843831DA6EDB8005F29E1 /* CachedGroupData.swift in Sources */,
|
||||||
@@ -1014,6 +1033,7 @@
|
|||||||
D073CE5D1DCB97F6007511FD /* ForwardSourceInfoAttribute.swift in Sources */,
|
D073CE5D1DCB97F6007511FD /* ForwardSourceInfoAttribute.swift in Sources */,
|
||||||
D03B0D721D631ABA00955575 /* SearchMessages.swift in Sources */,
|
D03B0D721D631ABA00955575 /* SearchMessages.swift in Sources */,
|
||||||
D0DC35501DE36900000195EB /* ChatContextResult.swift in Sources */,
|
D0DC35501DE36900000195EB /* ChatContextResult.swift in Sources */,
|
||||||
|
D0177B7B1DF8A16C00A5083A /* SecretChatState.swift in Sources */,
|
||||||
D03B0D5C1D631A6900955575 /* Download.swift in Sources */,
|
D03B0D5C1D631A6900955575 /* Download.swift in Sources */,
|
||||||
D0B843C71DA7FF30005F29E1 /* NBPhoneNumberDefines.m in Sources */,
|
D0B843C71DA7FF30005F29E1 /* NBPhoneNumberDefines.m in Sources */,
|
||||||
D03B0D5D1D631A6900955575 /* MultipartFetch.swift in Sources */,
|
D03B0D5D1D631A6900955575 /* MultipartFetch.swift in Sources */,
|
||||||
@@ -1056,8 +1076,10 @@
|
|||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
D0B8443D1DAB91EF005F29E1 /* StateManagement.swift in Sources */,
|
D0B8443D1DAB91EF005F29E1 /* StateManagement.swift in Sources */,
|
||||||
|
D0F7B1EA1E045C87007EB8A5 /* ChangePeerNotificationSettings.swift in Sources */,
|
||||||
D0B418A71D7E0592004562A4 /* Fetch.swift in Sources */,
|
D0B418A71D7E0592004562A4 /* Fetch.swift in Sources */,
|
||||||
D0B418B81D7E05A6004562A4 /* ContactManagement.swift in Sources */,
|
D0B418B81D7E05A6004562A4 /* ContactManagement.swift in Sources */,
|
||||||
|
D0F7B1E91E045C87007EB8A5 /* PeerCommands.swift in Sources */,
|
||||||
D0B844311DAB91E0005F29E1 /* NBPhoneMetaData.m in Sources */,
|
D0B844311DAB91E0005F29E1 /* NBPhoneMetaData.m in Sources */,
|
||||||
D0B418AC1D7E0597004562A4 /* Network.swift in Sources */,
|
D0B418AC1D7E0597004562A4 /* Network.swift in Sources */,
|
||||||
D0B844141DAB91CD005F29E1 /* PhoneNumbers.swift in Sources */,
|
D0B844141DAB91CD005F29E1 /* PhoneNumbers.swift in Sources */,
|
||||||
@@ -1065,13 +1087,13 @@
|
|||||||
D0B844491DAB91FD005F29E1 /* ManagedChatListHoles.swift in Sources */,
|
D0B844491DAB91FD005F29E1 /* ManagedChatListHoles.swift in Sources */,
|
||||||
D03C53711DAD5CA9004C17B3 /* CachedGroupParticipants.swift in Sources */,
|
D03C53711DAD5CA9004C17B3 /* CachedGroupParticipants.swift in Sources */,
|
||||||
D03C53671DAD5CA9004C17B3 /* ApiUtils.swift in Sources */,
|
D03C53671DAD5CA9004C17B3 /* ApiUtils.swift in Sources */,
|
||||||
|
D0F7B1EB1E045C87007EB8A5 /* ResolvePeerByName.swift in Sources */,
|
||||||
D0B844351DAB91E0005F29E1 /* NBPhoneNumberDesc.m in Sources */,
|
D0B844351DAB91E0005F29E1 /* NBPhoneNumberDesc.m in Sources */,
|
||||||
D0B8442F1DAB91E0005F29E1 /* NBMetadataHelper.m in Sources */,
|
D0B8442F1DAB91E0005F29E1 /* NBMetadataHelper.m in Sources */,
|
||||||
D0B8444C1DAB91FD005F29E1 /* UpdateCachedPeerData.swift in Sources */,
|
D0B8444C1DAB91FD005F29E1 /* UpdateCachedPeerData.swift in Sources */,
|
||||||
D0B418A81D7E0597004562A4 /* Api.swift in Sources */,
|
D0B418A81D7E0597004562A4 /* Api.swift in Sources */,
|
||||||
D03C536C1DAD5CA9004C17B3 /* TelegramChannel.swift in Sources */,
|
D03C536C1DAD5CA9004C17B3 /* TelegramChannel.swift in Sources */,
|
||||||
D0B418951D7E0580004562A4 /* TelegramMediaContact.swift in Sources */,
|
D0B418951D7E0580004562A4 /* TelegramMediaContact.swift in Sources */,
|
||||||
D0B8444F1DAB9206005F29E1 /* ChangePeerNotificationSettings.swift in Sources */,
|
|
||||||
D0B8443B1DAB91EF005F29E1 /* Holes.swift in Sources */,
|
D0B8443B1DAB91EF005F29E1 /* Holes.swift in Sources */,
|
||||||
D0F3CC7A1DDE2859008148FA /* RequestMessageActionCallback.swift in Sources */,
|
D0F3CC7A1DDE2859008148FA /* RequestMessageActionCallback.swift in Sources */,
|
||||||
D073CEA11DCBF3D3007511FD /* StickerPack.swift in Sources */,
|
D073CEA11DCBF3D3007511FD /* StickerPack.swift in Sources */,
|
||||||
@@ -1094,7 +1116,6 @@
|
|||||||
D0B8442A1DAB91E0005F29E1 /* NBAsYouTypeFormatter.m in Sources */,
|
D0B8442A1DAB91E0005F29E1 /* NBAsYouTypeFormatter.m in Sources */,
|
||||||
D073CE6E1DCBCF17007511FD /* ForwardSourceInfoAttribute.swift in Sources */,
|
D073CE6E1DCBCF17007511FD /* ForwardSourceInfoAttribute.swift in Sources */,
|
||||||
D0B844451DAB91FD005F29E1 /* AccountViewTracker.swift in Sources */,
|
D0B844451DAB91FD005F29E1 /* AccountViewTracker.swift in Sources */,
|
||||||
D0B8444E1DAB9206005F29E1 /* PeerParticipants.swift in Sources */,
|
|
||||||
D0B418A61D7E0592004562A4 /* CloudFileMediaResource.swift in Sources */,
|
D0B418A61D7E0592004562A4 /* CloudFileMediaResource.swift in Sources */,
|
||||||
D073CEA51DCBF3F5007511FD /* StickerManagement.swift in Sources */,
|
D073CEA51DCBF3F5007511FD /* StickerManagement.swift in Sources */,
|
||||||
D03C536D1DAD5CA9004C17B3 /* ApiGroupOrChannel.swift in Sources */,
|
D03C536D1DAD5CA9004C17B3 /* ApiGroupOrChannel.swift in Sources */,
|
||||||
@@ -1102,11 +1123,9 @@
|
|||||||
D0B418A91D7E0597004562A4 /* Buffer.swift in Sources */,
|
D0B418A91D7E0597004562A4 /* Buffer.swift in Sources */,
|
||||||
D0B8442E1DAB91E0005F29E1 /* NBMetadataCoreTestMapper.m in Sources */,
|
D0B8442E1DAB91E0005F29E1 /* NBMetadataCoreTestMapper.m in Sources */,
|
||||||
D0B8443F1DAB91EF005F29E1 /* UpdateGroup.swift in Sources */,
|
D0B8443F1DAB91EF005F29E1 /* UpdateGroup.swift in Sources */,
|
||||||
D0F3CC7E1DDE289E008148FA /* ResolvePeerByName.swift in Sources */,
|
|
||||||
D03C53731DAD5CA9004C17B3 /* CachedGroupData.swift in Sources */,
|
D03C53731DAD5CA9004C17B3 /* CachedGroupData.swift in Sources */,
|
||||||
D0F7AB2D1DCE889D009AD9A1 /* EditedMessageAttribute.swift in Sources */,
|
D0F7AB2D1DCE889D009AD9A1 /* EditedMessageAttribute.swift in Sources */,
|
||||||
D0B844121DAB91CD005F29E1 /* Log.swift in Sources */,
|
D0B844121DAB91CD005F29E1 /* Log.swift in Sources */,
|
||||||
D0B8444D1DAB9206005F29E1 /* JoinChannel.swift in Sources */,
|
|
||||||
D03C53721DAD5CA9004C17B3 /* CachedUserData.swift in Sources */,
|
D03C53721DAD5CA9004C17B3 /* CachedUserData.swift in Sources */,
|
||||||
D073CE6B1DCBCF17007511FD /* ReplyMessageAttribute.swift in Sources */,
|
D073CE6B1DCBCF17007511FD /* ReplyMessageAttribute.swift in Sources */,
|
||||||
D0B8444B1DAB91FD005F29E1 /* ManagedSynchronizePeerReadStates.swift in Sources */,
|
D0B8444B1DAB91FD005F29E1 /* ManagedSynchronizePeerReadStates.swift in Sources */,
|
||||||
@@ -1117,12 +1136,14 @@
|
|||||||
D073CE6D1DCBCF17007511FD /* InlineBotMessageAttribute.swift in Sources */,
|
D073CE6D1DCBCF17007511FD /* InlineBotMessageAttribute.swift in Sources */,
|
||||||
D0B8440F1DAB91CD005F29E1 /* Either.swift in Sources */,
|
D0B8440F1DAB91CD005F29E1 /* Either.swift in Sources */,
|
||||||
D0DC35511DE36908000195EB /* RequestChatContextResults.swift in Sources */,
|
D0DC35511DE36908000195EB /* RequestChatContextResults.swift in Sources */,
|
||||||
|
D0F7B1EC1E045C87007EB8A5 /* SearchPeers.swift in Sources */,
|
||||||
D03C536E1DAD5CA9004C17B3 /* PhoneNumber.swift in Sources */,
|
D03C536E1DAD5CA9004C17B3 /* PhoneNumber.swift in Sources */,
|
||||||
D0B844111DAB91CD005F29E1 /* Regex.swift in Sources */,
|
D0B844111DAB91CD005F29E1 /* Regex.swift in Sources */,
|
||||||
D0B8443C1DAB91EF005F29E1 /* SendUnsentMessage.swift in Sources */,
|
D0B8443C1DAB91EF005F29E1 /* SendUnsentMessage.swift in Sources */,
|
||||||
D0B844321DAB91E0005F29E1 /* NBPhoneMetaDataGenerator.m in Sources */,
|
D0B844321DAB91E0005F29E1 /* NBPhoneMetaDataGenerator.m in Sources */,
|
||||||
D073CEA41DCBF3EA007511FD /* MultipartUpload.swift in Sources */,
|
D073CEA41DCBF3EA007511FD /* MultipartUpload.swift in Sources */,
|
||||||
D03C53701DAD5CA9004C17B3 /* ExportedInvitation.swift in Sources */,
|
D03C53701DAD5CA9004C17B3 /* ExportedInvitation.swift in Sources */,
|
||||||
|
D0F7B1E31E045C7B007EB8A5 /* RichText.swift in Sources */,
|
||||||
D0B418AA1D7E0597004562A4 /* Download.swift in Sources */,
|
D0B418AA1D7E0597004562A4 /* Download.swift in Sources */,
|
||||||
D0B4188E1D7E0578004562A4 /* StoreMessage_Telegram.swift in Sources */,
|
D0B4188E1D7E0578004562A4 /* StoreMessage_Telegram.swift in Sources */,
|
||||||
D0B844461DAB91FD005F29E1 /* RecentPeers.swift in Sources */,
|
D0B844461DAB91FD005F29E1 /* RecentPeers.swift in Sources */,
|
||||||
@@ -1144,10 +1165,13 @@
|
|||||||
D03C53741DAD5CA9004C17B3 /* CachedChannelData.swift in Sources */,
|
D03C53741DAD5CA9004C17B3 /* CachedChannelData.swift in Sources */,
|
||||||
D073CEA31DCBF3E1007511FD /* PendingMessageUploadedContent.swift in Sources */,
|
D073CEA31DCBF3E1007511FD /* PendingMessageUploadedContent.swift in Sources */,
|
||||||
D0B418861D7E056D004562A4 /* Namespaces.swift in Sources */,
|
D0B418861D7E056D004562A4 /* Namespaces.swift in Sources */,
|
||||||
|
D0F7B1E41E045C7B007EB8A5 /* InstantPage.swift in Sources */,
|
||||||
D0B418AD1D7E0597004562A4 /* Serialization.swift in Sources */,
|
D0B418AD1D7E0597004562A4 /* Serialization.swift in Sources */,
|
||||||
D03C536F1DAD5CA9004C17B3 /* BotInfo.swift in Sources */,
|
D03C536F1DAD5CA9004C17B3 /* BotInfo.swift in Sources */,
|
||||||
D0B844101DAB91CD005F29E1 /* MergeLists.swift in Sources */,
|
D0B844101DAB91CD005F29E1 /* MergeLists.swift in Sources */,
|
||||||
|
D0F7B1E81E045C87007EB8A5 /* PeerParticipants.swift in Sources */,
|
||||||
D0B844331DAB91E0005F29E1 /* NBPhoneNumber.m in Sources */,
|
D0B844331DAB91E0005F29E1 /* NBPhoneNumber.m in Sources */,
|
||||||
|
D0F7B1E71E045C87007EB8A5 /* JoinChannel.swift in Sources */,
|
||||||
D0B844301DAB91E0005F29E1 /* NBNumberFormat.m in Sources */,
|
D0B844301DAB91E0005F29E1 /* NBNumberFormat.m in Sources */,
|
||||||
D073CEA21DCBF3E1007511FD /* PendingMessageManager.swift in Sources */,
|
D073CEA21DCBF3E1007511FD /* PendingMessageManager.swift in Sources */,
|
||||||
D0B418971D7E0580004562A4 /* TelegramMediaImage.swift in Sources */,
|
D0B418971D7E0580004562A4 /* TelegramMediaImage.swift in Sources */,
|
||||||
@@ -1243,7 +1267,8 @@
|
|||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
||||||
SWIFT_VERSION = 3.0.1;
|
SWIFT_REFLECTION_METADATA_LEVEL = none;
|
||||||
|
SWIFT_VERSION = 3.0;
|
||||||
USER_HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/third-party/FFmpeg-iOS/include";
|
USER_HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/third-party/FFmpeg-iOS/include";
|
||||||
};
|
};
|
||||||
name = Hockeyapp;
|
name = Hockeyapp;
|
||||||
@@ -1386,7 +1411,8 @@
|
|||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
SWIFT_VERSION = 3.0.1;
|
SWIFT_REFLECTION_METADATA_LEVEL = none;
|
||||||
|
SWIFT_VERSION = 3.0;
|
||||||
USER_HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/third-party/FFmpeg-iOS/include";
|
USER_HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/third-party/FFmpeg-iOS/include";
|
||||||
};
|
};
|
||||||
name = Debug;
|
name = Debug;
|
||||||
@@ -1420,7 +1446,8 @@
|
|||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
||||||
SWIFT_VERSION = 3.0.1;
|
SWIFT_REFLECTION_METADATA_LEVEL = none;
|
||||||
|
SWIFT_VERSION = 3.0;
|
||||||
USER_HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/third-party/FFmpeg-iOS/include";
|
USER_HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/third-party/FFmpeg-iOS/include";
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
|
|||||||
514
TelegramCore/InstantPage.swift
Normal file
514
TelegramCore/InstantPage.swift
Normal file
@@ -0,0 +1,514 @@
|
|||||||
|
import Foundation
|
||||||
|
#if os(macOS)
|
||||||
|
import PostboxMac
|
||||||
|
#else
|
||||||
|
import Postbox
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private enum InstantPageBlockType: Int32 {
|
||||||
|
case unsupported = 0
|
||||||
|
case title = 1
|
||||||
|
case subtitle = 2
|
||||||
|
case authorDate = 3
|
||||||
|
case header = 4
|
||||||
|
case subheader = 5
|
||||||
|
case paragraph = 6
|
||||||
|
case preformatted = 7
|
||||||
|
case footer = 8
|
||||||
|
case divider = 9
|
||||||
|
case anchor = 10
|
||||||
|
case list = 11
|
||||||
|
case blockQuote = 12
|
||||||
|
case pullQuote = 13
|
||||||
|
case image = 14
|
||||||
|
case video = 15
|
||||||
|
case cover = 16
|
||||||
|
case webEmbed = 17
|
||||||
|
case postEmbed = 18
|
||||||
|
case collage = 19
|
||||||
|
case slideshow = 20
|
||||||
|
}
|
||||||
|
|
||||||
|
public indirect enum InstantPageBlock: Coding, Equatable {
|
||||||
|
case unsupported
|
||||||
|
case title(RichText)
|
||||||
|
case subtitle(RichText)
|
||||||
|
case authorDate(author: RichText, date: Int32)
|
||||||
|
case header(RichText)
|
||||||
|
case subheader(RichText)
|
||||||
|
case paragraph(RichText)
|
||||||
|
case preformatted(RichText)
|
||||||
|
case footer(RichText)
|
||||||
|
case divider
|
||||||
|
case anchor(String)
|
||||||
|
case list(items: [RichText], ordered: Bool)
|
||||||
|
case blockQuote(text: RichText, caption: RichText)
|
||||||
|
case pullQuote(text: RichText, caption: RichText)
|
||||||
|
case image(id: MediaId, caption: RichText)
|
||||||
|
case video(id: MediaId, caption: RichText, autoplay: Bool, loop: Bool)
|
||||||
|
case cover(InstantPageBlock)
|
||||||
|
case webEmbed(url: String?, html: String?, dimensions: CGSize, caption: RichText, stretchToWidth: Bool, allowScrolling: Bool)
|
||||||
|
case postEmbed(url: String, webpageId: MediaId?, avatarId: MediaId?, author: String, date: Int32, blocks: [InstantPageBlock], caption: RichText)
|
||||||
|
case collage(items: [InstantPageBlock], caption: RichText)
|
||||||
|
case slideshow(items: [InstantPageBlock], caption: RichText)
|
||||||
|
|
||||||
|
public init(decoder: Decoder) {
|
||||||
|
switch decoder.decodeInt32ForKey("r") as Int32 {
|
||||||
|
case InstantPageBlockType.unsupported.rawValue:
|
||||||
|
self = .unsupported
|
||||||
|
case InstantPageBlockType.title.rawValue:
|
||||||
|
self = .title(decoder.decodeObjectForKey("t", decoder: { RichText(decoder: $0) }) as! RichText)
|
||||||
|
case InstantPageBlockType.subtitle.rawValue:
|
||||||
|
self = .subtitle(decoder.decodeObjectForKey("t", decoder: { RichText(decoder: $0) }) as! RichText)
|
||||||
|
case InstantPageBlockType.authorDate.rawValue:
|
||||||
|
self = .authorDate(author: decoder.decodeObjectForKey("a", decoder: { RichText(decoder: $0) }) as! RichText, date: decoder.decodeInt32ForKey("d"))
|
||||||
|
case InstantPageBlockType.header.rawValue:
|
||||||
|
self = .header(decoder.decodeObjectForKey("t", decoder: { RichText(decoder: $0) }) as! RichText)
|
||||||
|
case InstantPageBlockType.subheader.rawValue:
|
||||||
|
self = .subheader(decoder.decodeObjectForKey("t", decoder: { RichText(decoder: $0) }) as! RichText)
|
||||||
|
case InstantPageBlockType.paragraph.rawValue:
|
||||||
|
self = .paragraph(decoder.decodeObjectForKey("t", decoder: { RichText(decoder: $0) }) as! RichText)
|
||||||
|
case InstantPageBlockType.preformatted.rawValue:
|
||||||
|
self = .preformatted(decoder.decodeObjectForKey("t", decoder: { RichText(decoder: $0) }) as! RichText)
|
||||||
|
case InstantPageBlockType.footer.rawValue:
|
||||||
|
self = .footer(decoder.decodeObjectForKey("t", decoder: { RichText(decoder: $0) }) as! RichText)
|
||||||
|
case InstantPageBlockType.divider.rawValue:
|
||||||
|
self = .divider
|
||||||
|
case InstantPageBlockType.anchor.rawValue:
|
||||||
|
self = .anchor(decoder.decodeStringForKey("s"))
|
||||||
|
case InstantPageBlockType.list.rawValue:
|
||||||
|
self = .list(items: decoder.decodeObjectArrayWithDecoderForKey("l"), ordered: decoder.decodeInt32ForKey("o") != 0)
|
||||||
|
case InstantPageBlockType.blockQuote.rawValue:
|
||||||
|
self = .blockQuote(text: decoder.decodeObjectForKey("t", decoder: { RichText(decoder: $0) }) as! RichText, caption: decoder.decodeObjectForKey("c", decoder: { RichText(decoder: $0) }) as! RichText)
|
||||||
|
case InstantPageBlockType.pullQuote.rawValue:
|
||||||
|
self = .pullQuote(text: decoder.decodeObjectForKey("t", decoder: { RichText(decoder: $0) }) as! RichText, caption: decoder.decodeObjectForKey("c", decoder: { RichText(decoder: $0) }) as! RichText)
|
||||||
|
case InstantPageBlockType.image.rawValue:
|
||||||
|
self = .image(id: MediaId(namespace: decoder.decodeInt32ForKey("i.n"), id: decoder.decodeInt64ForKey("i.i")), caption: decoder.decodeObjectForKey("c", decoder: { RichText(decoder: $0) }) as! RichText)
|
||||||
|
case InstantPageBlockType.video.rawValue:
|
||||||
|
self = .video(id: MediaId(namespace: decoder.decodeInt32ForKey("i.n"), id: decoder.decodeInt64ForKey("i.i")), caption: decoder.decodeObjectForKey("c", decoder: { RichText(decoder: $0) }) as! RichText, autoplay: decoder.decodeInt32ForKey("ap") != 0, loop: decoder.decodeInt32ForKey("lo") != 0)
|
||||||
|
case InstantPageBlockType.cover.rawValue:
|
||||||
|
self = .cover(decoder.decodeObjectForKey("c", decoder: { InstantPageBlock(decoder: $0) }) as! InstantPageBlock)
|
||||||
|
case InstantPageBlockType.webEmbed.rawValue:
|
||||||
|
self = .webEmbed(url: decoder.decodeStringForKey("u"), html: decoder.decodeStringForKey("h"), dimensions: CGSize(width: CGFloat(decoder.decodeInt32ForKey("sw")), height: CGFloat(decoder.decodeInt32ForKey("sh"))), caption: decoder.decodeObjectForKey("c", decoder: { RichText(decoder: $0) }) as! RichText, stretchToWidth: decoder.decodeInt32ForKey("st") != 0, allowScrolling: decoder.decodeInt32ForKey("as") != 0)
|
||||||
|
case InstantPageBlockType.postEmbed.rawValue:
|
||||||
|
var avatarId: MediaId?
|
||||||
|
let avatarIdNamespace: Int32? = decoder.decodeInt32ForKey("av.n")
|
||||||
|
let avatarIdId: Int64? = decoder.decodeInt64ForKey("av.i")
|
||||||
|
if let avatarIdNamespace = avatarIdNamespace, let avatarIdId = avatarIdId {
|
||||||
|
avatarId = MediaId(namespace: avatarIdNamespace, id: avatarIdId)
|
||||||
|
}
|
||||||
|
self = .postEmbed(url: decoder.decodeStringForKey("u"), webpageId: MediaId(namespace: decoder.decodeInt32ForKey("w.n"), id: decoder.decodeInt64ForKey("w.i")), avatarId: avatarId, author: decoder.decodeStringForKey("a"), date: decoder.decodeInt32ForKey("d"), blocks: decoder.decodeObjectArrayWithDecoderForKey("b"), caption: decoder.decodeObjectForKey("c", decoder: { RichText(decoder: $0) }) as! RichText)
|
||||||
|
case InstantPageBlockType.collage.rawValue:
|
||||||
|
self = .collage(items: decoder.decodeObjectArrayWithDecoderForKey("b"), caption: decoder.decodeObjectForKey("c", decoder: { RichText(decoder: $0) }) as! RichText)
|
||||||
|
case InstantPageBlockType.slideshow.rawValue:
|
||||||
|
self = .slideshow(items: decoder.decodeObjectArrayWithDecoderForKey("b"), caption: decoder.decodeObjectForKey("c", decoder: { RichText(decoder: $0) }) as! RichText)
|
||||||
|
default:
|
||||||
|
self = .unsupported
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func encode(_ encoder: Encoder) {
|
||||||
|
switch self {
|
||||||
|
case .unsupported:
|
||||||
|
encoder.encodeInt32(InstantPageBlockType.unsupported.rawValue, forKey: "r")
|
||||||
|
case let .title(text):
|
||||||
|
encoder.encodeInt32(InstantPageBlockType.title.rawValue, forKey: "r")
|
||||||
|
encoder.encodeObject(text, forKey: "t")
|
||||||
|
case let .subtitle(text):
|
||||||
|
encoder.encodeInt32(InstantPageBlockType.subtitle.rawValue, forKey: "r")
|
||||||
|
encoder.encodeObject(text, forKey: "t")
|
||||||
|
case let .authorDate(author, date):
|
||||||
|
encoder.encodeInt32(InstantPageBlockType.authorDate.rawValue, forKey: "r")
|
||||||
|
encoder.encodeObject(author, forKey: "a")
|
||||||
|
encoder.encodeInt32(date, forKey: "d")
|
||||||
|
case let .header(text):
|
||||||
|
encoder.encodeInt32(InstantPageBlockType.header.rawValue, forKey: "r")
|
||||||
|
encoder.encodeObject(text, forKey: "t")
|
||||||
|
case let .subheader(text):
|
||||||
|
encoder.encodeInt32(InstantPageBlockType.subheader.rawValue, forKey: "r")
|
||||||
|
encoder.encodeObject(text, forKey: "t")
|
||||||
|
case let .paragraph(text):
|
||||||
|
encoder.encodeInt32(InstantPageBlockType.paragraph.rawValue, forKey: "r")
|
||||||
|
encoder.encodeObject(text, forKey: "t")
|
||||||
|
case let .preformatted(text):
|
||||||
|
encoder.encodeInt32(InstantPageBlockType.preformatted.rawValue, forKey: "r")
|
||||||
|
encoder.encodeObject(text, forKey: "t")
|
||||||
|
case let .footer(text):
|
||||||
|
encoder.encodeInt32(InstantPageBlockType.footer.rawValue, forKey: "r")
|
||||||
|
encoder.encodeObject(text, forKey: "t")
|
||||||
|
case .divider:
|
||||||
|
encoder.encodeInt32(InstantPageBlockType.divider.rawValue, forKey: "r")
|
||||||
|
case let .anchor(anchor):
|
||||||
|
encoder.encodeInt32(InstantPageBlockType.anchor.rawValue, forKey: "r")
|
||||||
|
encoder.encodeString(anchor, forKey: "s")
|
||||||
|
case let .list(items, ordered):
|
||||||
|
encoder.encodeInt32(InstantPageBlockType.list.rawValue, forKey: "r")
|
||||||
|
encoder.encodeObjectArray(items, forKey: "l")
|
||||||
|
encoder.encodeInt32(ordered ? 1 : 0, forKey: "o")
|
||||||
|
case let .blockQuote(text, caption):
|
||||||
|
encoder.encodeInt32(InstantPageBlockType.blockQuote.rawValue, forKey: "r")
|
||||||
|
encoder.encodeObject(text, forKey: "t")
|
||||||
|
encoder.encodeObject(caption, forKey: "c")
|
||||||
|
case let .pullQuote(text, caption):
|
||||||
|
encoder.encodeInt32(InstantPageBlockType.pullQuote.rawValue, forKey: "r")
|
||||||
|
encoder.encodeObject(text, forKey: "t")
|
||||||
|
encoder.encodeObject(caption, forKey: "c")
|
||||||
|
case let .image(id, caption):
|
||||||
|
encoder.encodeInt32(InstantPageBlockType.image.rawValue, forKey: "r")
|
||||||
|
encoder.encodeInt32(id.namespace, forKey: "i.n")
|
||||||
|
encoder.encodeInt64(id.id, forKey: "i.i")
|
||||||
|
encoder.encodeObject(caption, forKey: "c")
|
||||||
|
case let .video(id, caption, autoplay, loop):
|
||||||
|
encoder.encodeInt32(InstantPageBlockType.video.rawValue, forKey: "r")
|
||||||
|
encoder.encodeInt32(id.namespace, forKey: "i.n")
|
||||||
|
encoder.encodeInt64(id.id, forKey: "i.i")
|
||||||
|
encoder.encodeObject(caption, forKey: "c")
|
||||||
|
encoder.encodeInt32(autoplay ? 1 : 0, forKey: "ap")
|
||||||
|
encoder.encodeInt32(loop ? 1 : 0, forKey: "lo")
|
||||||
|
case let .cover(block):
|
||||||
|
encoder.encodeInt32(InstantPageBlockType.cover.rawValue, forKey: "r")
|
||||||
|
encoder.encodeObject(block, forKey: "c")
|
||||||
|
case let .webEmbed(url, html, dimensions, caption, stretchToWidth, allowScrolling):
|
||||||
|
encoder.encodeInt32(InstantPageBlockType.webEmbed.rawValue, forKey: "r")
|
||||||
|
if let url = url {
|
||||||
|
encoder.encodeString(url, forKey: "u")
|
||||||
|
} else {
|
||||||
|
encoder.encodeNil(forKey: "u")
|
||||||
|
}
|
||||||
|
if let html = html {
|
||||||
|
encoder.encodeString(html, forKey: "h")
|
||||||
|
} else {
|
||||||
|
encoder.encodeNil(forKey: "h")
|
||||||
|
}
|
||||||
|
encoder.encodeInt32(Int32(dimensions.width), forKey: "sw")
|
||||||
|
encoder.encodeInt32(Int32(dimensions.height), forKey: "sh")
|
||||||
|
encoder.encodeObject(caption, forKey: "c")
|
||||||
|
encoder.encodeInt32(stretchToWidth ? 1 : 0, forKey: "st")
|
||||||
|
encoder.encodeInt32(allowScrolling ? 1 : 0, forKey: "as")
|
||||||
|
case let .postEmbed(url, webpageId, avatarId, author, date, blocks, caption):
|
||||||
|
encoder.encodeInt32(InstantPageBlockType.postEmbed.rawValue, forKey: "r")
|
||||||
|
if let avatarId = avatarId {
|
||||||
|
encoder.encodeInt32(avatarId.namespace, forKey: "av.n")
|
||||||
|
encoder.encodeInt64(avatarId.id, forKey: "av.i")
|
||||||
|
} else {
|
||||||
|
encoder.encodeNil(forKey: "av.n")
|
||||||
|
encoder.encodeNil(forKey: "av.i")
|
||||||
|
}
|
||||||
|
encoder.encodeString(url, forKey: "u")
|
||||||
|
if let webpageId = webpageId {
|
||||||
|
encoder.encodeInt32(webpageId.namespace, forKey: "w.n")
|
||||||
|
encoder.encodeInt64(webpageId.id, forKey: "w.i")
|
||||||
|
} else {
|
||||||
|
encoder.encodeNil(forKey: "w.n")
|
||||||
|
encoder.encodeNil(forKey: "w.i")
|
||||||
|
}
|
||||||
|
encoder.encodeString(author, forKey: "a")
|
||||||
|
encoder.encodeInt32(date, forKey: "d")
|
||||||
|
encoder.encodeObjectArray(blocks, forKey: "b")
|
||||||
|
encoder.encodeObject(caption, forKey: "c")
|
||||||
|
case let .collage(items, caption):
|
||||||
|
encoder.encodeInt32(InstantPageBlockType.collage.rawValue, forKey: "r")
|
||||||
|
encoder.encodeObjectArray(items, forKey: "b")
|
||||||
|
encoder.encodeObject(caption, forKey: "c")
|
||||||
|
case let .slideshow(items, caption):
|
||||||
|
encoder.encodeInt32(InstantPageBlockType.slideshow.rawValue, forKey: "r")
|
||||||
|
encoder.encodeObjectArray(items, forKey: "b")
|
||||||
|
encoder.encodeObject(caption, forKey: "c")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func ==(lhs: InstantPageBlock, rhs: InstantPageBlock) -> Bool {
|
||||||
|
switch lhs {
|
||||||
|
case .unsupported:
|
||||||
|
if case .unsupported = rhs {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case let .title(text):
|
||||||
|
if case .title(text) = rhs {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case let .subtitle(text):
|
||||||
|
if case .subtitle(text) = rhs {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case let .authorDate(author, date):
|
||||||
|
if case .authorDate(author, date) = rhs {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case let .header(text):
|
||||||
|
if case .header(text) = rhs {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case let .subheader(text):
|
||||||
|
if case .subheader(text) = rhs {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case let .paragraph(text):
|
||||||
|
if case .paragraph(text) = rhs {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case let .preformatted(text):
|
||||||
|
if case .preformatted(text) = rhs {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case let .footer(text):
|
||||||
|
if case .footer(text) = rhs {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case .divider:
|
||||||
|
if case .divider = rhs {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case let .anchor(anchor):
|
||||||
|
if case .anchor(anchor) = rhs {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case let .list(lhsItems, lhsOrdered):
|
||||||
|
if case let .list(rhsItems, rhsOrdered) = rhs, lhsItems == rhsItems, lhsOrdered == rhsOrdered {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case let .blockQuote(text, caption):
|
||||||
|
if case .blockQuote(text, caption) = rhs {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case let .pullQuote(text, caption):
|
||||||
|
if case .pullQuote(text, caption) = rhs {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case let .image(id, caption):
|
||||||
|
if case .image(id, caption) = rhs {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case let .video(id, caption, autoplay, loop):
|
||||||
|
if case .video(id, caption, autoplay, loop) = rhs {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case let .cover(block):
|
||||||
|
if case .cover(block) = rhs {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case let .webEmbed(lhsUrl, lhsHtml, lhsDimensions, lhsCaption, lhsStretchToWidth, lhsAllowScrolling):
|
||||||
|
if case let .webEmbed(rhsUrl, rhsHtml, rhsDimensions, rhsCaption, rhsStretchToWidth, rhsAllowScrolling) = rhs, lhsUrl == rhsUrl && lhsHtml == rhsHtml && lhsDimensions == rhsDimensions && lhsCaption == rhsCaption && lhsStretchToWidth == rhsStretchToWidth && lhsAllowScrolling == rhsAllowScrolling {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case let .postEmbed(lhsUrl, lhsWebpageId, lhsAvatarId, lhsAuthor, lhsDate, lhsBlocks, lhsCaption):
|
||||||
|
if case let .postEmbed(rhsUrl, rhsWebpageId, rhsAvatarId, rhsAuthor, rhsDate, rhsBlocks, rhsCaption) = rhs, lhsUrl == rhsUrl && lhsWebpageId == rhsWebpageId && lhsAvatarId == rhsAvatarId && lhsAuthor == rhsAuthor && lhsDate == rhsDate && lhsBlocks == rhsBlocks && lhsCaption == rhsCaption {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case let .collage(lhsItems, lhsCaption):
|
||||||
|
if case let .collage(rhsItems, rhsCaption) = rhs, lhsItems == rhsItems && lhsCaption == rhsCaption {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case let .slideshow(lhsItems, lhsCaption):
|
||||||
|
if case let .slideshow(rhsItems, rhsCaption) = rhs, lhsItems == rhsItems && lhsCaption == rhsCaption {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final class MediaDictionary: Coding {
|
||||||
|
let dict: [MediaId: Media]
|
||||||
|
|
||||||
|
init(dict: [MediaId: Media]) {
|
||||||
|
self.dict = dict
|
||||||
|
}
|
||||||
|
|
||||||
|
init(decoder: Decoder) {
|
||||||
|
let idsBufer = decoder.decodeBytesForKey("i")!
|
||||||
|
let mediaIds = MediaId.decodeArrayFromBuffer(idsBufer)
|
||||||
|
let medias = decoder.decodeObjectArrayForKey("m")
|
||||||
|
var dict: [MediaId: Media] = [:]
|
||||||
|
assert(mediaIds.count == medias.count)
|
||||||
|
for i in 0 ..< mediaIds.count {
|
||||||
|
dict[mediaIds[i]] = medias[i] as! Media
|
||||||
|
}
|
||||||
|
self.dict = dict
|
||||||
|
}
|
||||||
|
|
||||||
|
func encode(_ encoder: Encoder) {
|
||||||
|
var mediaIds: [MediaId] = []
|
||||||
|
var medias: [Coding] = []
|
||||||
|
for mediaId in self.dict.keys {
|
||||||
|
mediaIds.append(mediaId)
|
||||||
|
medias.append(self.dict[mediaId]!)
|
||||||
|
}
|
||||||
|
let buffer = WriteBuffer()
|
||||||
|
MediaId.encodeArrayToBuffer(mediaIds, buffer: buffer)
|
||||||
|
encoder.encodeBytes(buffer, forKey: "i")
|
||||||
|
encoder.encodeGenericObjectArray(medias, forKey: "m")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class InstantPage: Coding, Equatable {
|
||||||
|
public let blocks: [InstantPageBlock]
|
||||||
|
public let media: [MediaId: Media]
|
||||||
|
public let isComplete: Bool
|
||||||
|
|
||||||
|
init(blocks: [InstantPageBlock], media: [MediaId: Media], isComplete: Bool) {
|
||||||
|
self.blocks = blocks
|
||||||
|
self.media = media
|
||||||
|
self.isComplete = isComplete
|
||||||
|
}
|
||||||
|
|
||||||
|
public init(decoder: Decoder) {
|
||||||
|
self.blocks = decoder.decodeObjectArrayWithDecoderForKey("b")
|
||||||
|
self.media = MediaDictionary(decoder: decoder).dict
|
||||||
|
self.isComplete = decoder.decodeInt32ForKey("c") != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
public func encode(_ encoder: Encoder) {
|
||||||
|
encoder.encodeObjectArray(self.blocks, forKey: "b")
|
||||||
|
MediaDictionary(dict: self.media).encode(encoder)
|
||||||
|
encoder.encodeInt32(self.isComplete ? 1 : 0, forKey: "c")
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func ==(lhs: InstantPage, rhs: InstantPage) -> Bool {
|
||||||
|
if lhs.blocks != rhs.blocks {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if lhs.media.count != rhs.media.count {
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
|
for (lhsKey, lhsValue) in lhs.media {
|
||||||
|
if let media = rhs.media[lhsKey] {
|
||||||
|
if !lhsValue.isEqual(media) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if lhs.isComplete != rhs.isComplete {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension InstantPageBlock {
|
||||||
|
init(apiBlock: Api.PageBlock) {
|
||||||
|
switch apiBlock {
|
||||||
|
case .pageBlockUnsupported:
|
||||||
|
self = .unsupported
|
||||||
|
case let .pageBlockTitle(text):
|
||||||
|
self = .title(RichText(apiText: text))
|
||||||
|
case let .pageBlockSubtitle(text):
|
||||||
|
self = .subtitle(RichText(apiText: text))
|
||||||
|
case let .pageBlockAuthorDate(author, publishedDate):
|
||||||
|
self = .authorDate(author: .plain(author), date: publishedDate)
|
||||||
|
case let .pageBlockHeader(text):
|
||||||
|
self = .header(RichText(apiText: text))
|
||||||
|
case let .pageBlockSubheader(text):
|
||||||
|
self = .subheader(RichText(apiText: text))
|
||||||
|
case let .pageBlockParagraph(text):
|
||||||
|
self = .paragraph(RichText(apiText: text))
|
||||||
|
case let .pageBlockPreformatted(text, _):
|
||||||
|
self = .preformatted(RichText(apiText: text))
|
||||||
|
case let .pageBlockFooter(text):
|
||||||
|
self = .footer(RichText(apiText: text))
|
||||||
|
case .pageBlockDivider:
|
||||||
|
self = .divider
|
||||||
|
case let .pageBlockAnchor(name):
|
||||||
|
self = .anchor(name)
|
||||||
|
case let .pageBlockList(ordered, items):
|
||||||
|
self = .list(items: items.map({ RichText(apiText: $0) }), ordered: ordered == .boolTrue)
|
||||||
|
case let .pageBlockBlockquote(text, caption):
|
||||||
|
self = .blockQuote(text: RichText(apiText: text), caption: RichText(apiText: caption))
|
||||||
|
case let .pageBlockPullquote(text, caption):
|
||||||
|
self = .pullQuote(text: RichText(apiText: text), caption: RichText(apiText: caption))
|
||||||
|
case let .pageBlockPhoto(photoId, caption):
|
||||||
|
self = .image(id: MediaId(namespace: Namespaces.Media.CloudImage, id: photoId), caption: RichText(apiText: caption))
|
||||||
|
case let .pageBlockVideo(flags, videoId, caption):
|
||||||
|
self = .video(id: MediaId(namespace: Namespaces.Media.CloudVideo, id: videoId), caption: RichText(apiText: caption), autoplay: (flags & (1 << 0)) != 0, loop: (flags & (1 << 1)) != 0)
|
||||||
|
case let .pageBlockCover(cover):
|
||||||
|
self = .cover(InstantPageBlock(apiBlock: cover))
|
||||||
|
case let .pageBlockEmbed(flags, url, html, w, h, caption):
|
||||||
|
self = .webEmbed(url: url, html: html, dimensions: CGSize(width: CGFloat(w), height: CGFloat(h)), caption: RichText(apiText: caption), stretchToWidth: (flags & (1 << 0)) != 0, allowScrolling: (flags & (1 << 3)) != 0)
|
||||||
|
case let .pageBlockEmbedPost(url, webpageId, authorPhotoId, author, date, blocks, caption):
|
||||||
|
self = .postEmbed(url: url, webpageId: webpageId == 0 ? nil : MediaId(namespace: Namespaces.Media.CloudWebpage, id: webpageId), avatarId: authorPhotoId == 0 ? nil : MediaId(namespace: Namespaces.Media.CloudImage, id: authorPhotoId), author: author, date: date, blocks: blocks.map({ InstantPageBlock(apiBlock: $0) }), caption: RichText(apiText: caption))
|
||||||
|
case let .pageBlockCollage(items, caption):
|
||||||
|
self = .collage(items: items.map({ InstantPageBlock(apiBlock: $0) }), caption: RichText(apiText: caption))
|
||||||
|
case let .pageBlockSlideshow(items, caption):
|
||||||
|
self = .slideshow(items: items.map({ InstantPageBlock(apiBlock: $0) }), caption: RichText(apiText: caption))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension InstantPage {
|
||||||
|
convenience init(apiPage: Api.Page) {
|
||||||
|
let blocks: [Api.PageBlock]
|
||||||
|
let photos: [Api.Photo]
|
||||||
|
let files: [Api.Document]
|
||||||
|
let isComplete: Bool
|
||||||
|
switch apiPage {
|
||||||
|
case let .pageFull(apiBlocks, apiPhotos, apiVideos):
|
||||||
|
blocks = apiBlocks
|
||||||
|
photos = apiPhotos
|
||||||
|
files = apiVideos
|
||||||
|
isComplete = true
|
||||||
|
case let .pagePart(apiBlocks, apiPhotos, apiVideos):
|
||||||
|
blocks = apiBlocks
|
||||||
|
photos = apiPhotos
|
||||||
|
files = apiVideos
|
||||||
|
isComplete = false
|
||||||
|
}
|
||||||
|
var media: [MediaId: Media] = [:]
|
||||||
|
for photo in photos {
|
||||||
|
if let image = telegramMediaImageFromApiPhoto(photo), let id = image.id {
|
||||||
|
media[id] = image
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for file in files {
|
||||||
|
if let file = telegramMediaFileFromApiDocument(file), let id = file.id {
|
||||||
|
media[id] = file
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.init(blocks: blocks.map({ InstantPageBlock(apiBlock: $0) }), media: media, isComplete: isComplete)
|
||||||
|
}
|
||||||
|
}
|
||||||
231
TelegramCore/RichText.swift
Normal file
231
TelegramCore/RichText.swift
Normal file
@@ -0,0 +1,231 @@
|
|||||||
|
import Foundation
|
||||||
|
#if os(macOS)
|
||||||
|
import PostboxMac
|
||||||
|
#else
|
||||||
|
import Postbox
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private enum RichTextTypes: Int32 {
|
||||||
|
case empty = 0
|
||||||
|
case plain = 1
|
||||||
|
case bold = 2
|
||||||
|
case italic = 3
|
||||||
|
case underline = 4
|
||||||
|
case strikethrough = 5
|
||||||
|
case fixed = 6
|
||||||
|
case url = 7
|
||||||
|
case email = 8
|
||||||
|
case concat = 9
|
||||||
|
}
|
||||||
|
|
||||||
|
public indirect enum RichText: Coding, Equatable {
|
||||||
|
case empty
|
||||||
|
case plain(String)
|
||||||
|
case bold(RichText)
|
||||||
|
case italic(RichText)
|
||||||
|
case underline(RichText)
|
||||||
|
case strikethrough(RichText)
|
||||||
|
case fixed(RichText)
|
||||||
|
case url(text: RichText, url: String, webpageId: MediaId?)
|
||||||
|
case email(text: RichText, email: String)
|
||||||
|
case concat([RichText])
|
||||||
|
|
||||||
|
public init(decoder: Decoder) {
|
||||||
|
switch decoder.decodeInt32ForKey("r") as Int32 {
|
||||||
|
case RichTextTypes.empty.rawValue:
|
||||||
|
self = .empty
|
||||||
|
case RichTextTypes.plain.rawValue:
|
||||||
|
self = .plain(decoder.decodeStringForKey("s"))
|
||||||
|
case RichTextTypes.bold.rawValue:
|
||||||
|
self = .bold(decoder.decodeObjectForKey("t", decoder: { RichText(decoder: $0) }) as! RichText)
|
||||||
|
case RichTextTypes.italic.rawValue:
|
||||||
|
self = .italic(decoder.decodeObjectForKey("t", decoder: { RichText(decoder: $0) }) as! RichText)
|
||||||
|
case RichTextTypes.underline.rawValue:
|
||||||
|
self = .underline(decoder.decodeObjectForKey("t", decoder: { RichText(decoder: $0) }) as! RichText)
|
||||||
|
case RichTextTypes.strikethrough.rawValue:
|
||||||
|
self = .strikethrough(decoder.decodeObjectForKey("t", decoder: { RichText(decoder: $0) }) as! RichText)
|
||||||
|
case RichTextTypes.fixed.rawValue:
|
||||||
|
self = .fixed(decoder.decodeObjectForKey("t", decoder: { RichText(decoder: $0) }) as! RichText)
|
||||||
|
case RichTextTypes.url.rawValue:
|
||||||
|
let webpageIdNamespace: Int32? = decoder.decodeInt32ForKey("w.n")
|
||||||
|
let webpageIdId: Int64? = decoder.decodeInt64ForKey("w.i")
|
||||||
|
var webpageId: MediaId?
|
||||||
|
if let webpageIdNamespace = webpageIdNamespace, let webpageIdId = webpageIdId {
|
||||||
|
webpageId = MediaId(namespace: webpageIdNamespace, id: webpageIdId)
|
||||||
|
}
|
||||||
|
self = .url(text: decoder.decodeObjectForKey("t", decoder: { RichText(decoder: $0) }) as! RichText, url: decoder.decodeStringForKey("u"), webpageId: webpageId)
|
||||||
|
case RichTextTypes.email.rawValue:
|
||||||
|
self = .email(text: decoder.decodeObjectForKey("t", decoder: { RichText(decoder: $0) }) as! RichText, email: decoder.decodeStringForKey("e"))
|
||||||
|
case RichTextTypes.concat.rawValue:
|
||||||
|
self = .concat(decoder.decodeObjectArrayWithDecoderForKey("a"))
|
||||||
|
default:
|
||||||
|
self = .empty
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func encode(_ encoder: Encoder) {
|
||||||
|
switch self {
|
||||||
|
case .empty:
|
||||||
|
encoder.encodeInt32(RichTextTypes.empty.rawValue, forKey: "r")
|
||||||
|
case let .plain(string):
|
||||||
|
encoder.encodeInt32(RichTextTypes.plain.rawValue, forKey: "r")
|
||||||
|
encoder.encodeString(string, forKey: "s")
|
||||||
|
case let .bold(text):
|
||||||
|
encoder.encodeInt32(RichTextTypes.bold.rawValue, forKey: "r")
|
||||||
|
encoder.encodeObject(text, forKey: "t")
|
||||||
|
case let .italic(text):
|
||||||
|
encoder.encodeInt32(RichTextTypes.italic.rawValue, forKey: "r")
|
||||||
|
encoder.encodeObject(text, forKey: "t")
|
||||||
|
case let .underline(text):
|
||||||
|
encoder.encodeInt32(RichTextTypes.underline.rawValue, forKey: "r")
|
||||||
|
encoder.encodeObject(text, forKey: "t")
|
||||||
|
case let .strikethrough(text):
|
||||||
|
encoder.encodeInt32(RichTextTypes.strikethrough.rawValue, forKey: "r")
|
||||||
|
encoder.encodeObject(text, forKey: "t")
|
||||||
|
case let .fixed(text):
|
||||||
|
encoder.encodeInt32(RichTextTypes.fixed.rawValue, forKey: "r")
|
||||||
|
encoder.encodeObject(text, forKey: "t")
|
||||||
|
case let .url(text, url, webpageId):
|
||||||
|
encoder.encodeInt32(RichTextTypes.url.rawValue, forKey: "r")
|
||||||
|
encoder.encodeObject(text, forKey: "t")
|
||||||
|
encoder.encodeString(url, forKey: "u")
|
||||||
|
if let webpageId = webpageId {
|
||||||
|
encoder.encodeInt32(webpageId.namespace, forKey: "w.n")
|
||||||
|
encoder.encodeInt64(webpageId.id, forKey: "w.i")
|
||||||
|
} else {
|
||||||
|
encoder.encodeNil(forKey: "w.n")
|
||||||
|
encoder.encodeNil(forKey: "w.i")
|
||||||
|
}
|
||||||
|
case let .email(text, email):
|
||||||
|
encoder.encodeInt32(RichTextTypes.email.rawValue, forKey: "r")
|
||||||
|
encoder.encodeObject(text, forKey: "t")
|
||||||
|
encoder.encodeString(email, forKey: "e")
|
||||||
|
case let .concat(texts):
|
||||||
|
encoder.encodeInt32(RichTextTypes.concat.rawValue, forKey: "r")
|
||||||
|
encoder.encodeObjectArray(texts, forKey: "a")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func ==(lhs: RichText, rhs: RichText) -> Bool {
|
||||||
|
switch lhs {
|
||||||
|
case .empty:
|
||||||
|
if case .empty = rhs {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case let .plain(string):
|
||||||
|
if case .plain(string) = rhs {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case let .bold(text):
|
||||||
|
if case .bold(text) = rhs {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case let .italic(text):
|
||||||
|
if case .italic(text) = rhs {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case let .underline(text):
|
||||||
|
if case .underline(text) = rhs {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case let .strikethrough(text):
|
||||||
|
if case .strikethrough(text) = rhs {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case let .fixed(text):
|
||||||
|
if case .fixed(text) = rhs {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case let .url(lhsText, lhsUrl, lhsWebpageId):
|
||||||
|
if case let .url(rhsText, rhsUrl, rhsWebpageId) = rhs, lhsText == rhsText && lhsUrl == rhsUrl && lhsWebpageId == rhsWebpageId {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case let .email(text, email):
|
||||||
|
if case .email(text, email) = rhs {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case let .concat(lhsTexts):
|
||||||
|
if case let .concat(rhsTexts) = rhs, lhsTexts == rhsTexts {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension RichText {
|
||||||
|
var plainText: String {
|
||||||
|
switch self {
|
||||||
|
case .empty:
|
||||||
|
return ""
|
||||||
|
case let .plain(string):
|
||||||
|
return string
|
||||||
|
case let .bold(text):
|
||||||
|
return text.plainText
|
||||||
|
case let .italic(text):
|
||||||
|
return text.plainText
|
||||||
|
case let .underline(text):
|
||||||
|
return text.plainText
|
||||||
|
case let .strikethrough(text):
|
||||||
|
return text.plainText
|
||||||
|
case let .fixed(text):
|
||||||
|
return text.plainText
|
||||||
|
case let .url(text, _, _):
|
||||||
|
return text.plainText
|
||||||
|
case let .email(text, _):
|
||||||
|
return text.plainText
|
||||||
|
case let .concat(texts):
|
||||||
|
var string = ""
|
||||||
|
for text in texts {
|
||||||
|
string += text.plainText
|
||||||
|
}
|
||||||
|
return string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension RichText {
|
||||||
|
init(apiText: Api.RichText) {
|
||||||
|
switch apiText {
|
||||||
|
case .textEmpty:
|
||||||
|
self = .empty
|
||||||
|
case let .textPlain(text):
|
||||||
|
self = .plain(text)
|
||||||
|
case let .textBold(text):
|
||||||
|
self = .bold(RichText(apiText: text))
|
||||||
|
case let .textItalic(text):
|
||||||
|
self = .italic(RichText(apiText: text))
|
||||||
|
case let .textUnderline(text):
|
||||||
|
self = .underline(RichText(apiText: text))
|
||||||
|
case let .textStrike(text):
|
||||||
|
self = .strikethrough(RichText(apiText: text))
|
||||||
|
case let .textFixed(text):
|
||||||
|
self = .fixed(RichText(apiText: text))
|
||||||
|
case let .textUrl(text, url, webpageId):
|
||||||
|
self = .url(text: RichText(apiText: text), url: url, webpageId: webpageId == 0 ? nil : MediaId(namespace: Namespaces.Media.CloudWebpage, id: webpageId))
|
||||||
|
case let .textEmail(text, email):
|
||||||
|
self = .email(text: RichText(apiText: text), email: email)
|
||||||
|
case let .textConcat(texts):
|
||||||
|
self = .concat(texts.map({ RichText(apiText: $0) }))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
57
TelegramCore/SearchPeers.swift
Normal file
57
TelegramCore/SearchPeers.swift
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
import Foundation
|
||||||
|
#if os(macOS)
|
||||||
|
import PostboxMac
|
||||||
|
import SwiftSignalKitMac
|
||||||
|
import MtProtoKitMac
|
||||||
|
#else
|
||||||
|
import Postbox
|
||||||
|
import SwiftSignalKit
|
||||||
|
import MtProtoKitDynamic
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public func searchPeers(account: Account, query: String) -> Signal<[Peer], NoError> {
|
||||||
|
let searchResult = account.network.request(Api.functions.contacts.search(q: query, limit: 10))
|
||||||
|
|> retryRequest
|
||||||
|
|
||||||
|
let processedSearchResult = searchResult
|
||||||
|
|> mapToSignal { result -> Signal<[Peer], NoError> in
|
||||||
|
switch result {
|
||||||
|
case let .found(results, chats, users):
|
||||||
|
return account.postbox.modify { modifier -> [Peer] in
|
||||||
|
var peers: [PeerId: Peer] = [:]
|
||||||
|
|
||||||
|
for user in users {
|
||||||
|
if let user = TelegramUser.merge(modifier.getPeer(user.peerId) as? TelegramUser, rhs: user) {
|
||||||
|
peers[user.id] = user
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for chat in chats {
|
||||||
|
if let groupOrChannel = parseTelegramGroupOrChannel(chat: chat) {
|
||||||
|
peers[groupOrChannel.id] = groupOrChannel
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var renderedPeers: [Peer] = []
|
||||||
|
for result in results {
|
||||||
|
let peerId: PeerId
|
||||||
|
switch result {
|
||||||
|
case let .peerUser(userId):
|
||||||
|
peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: userId)
|
||||||
|
case let .peerChat(chatId):
|
||||||
|
peerId = PeerId(namespace: Namespaces.Peer.CloudGroup, id: chatId)
|
||||||
|
case let .peerChannel(channelId):
|
||||||
|
peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: channelId)
|
||||||
|
}
|
||||||
|
if let peer = peers[peerId] {
|
||||||
|
renderedPeers.append(peer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return renderedPeers
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return processedSearchResult
|
||||||
|
}
|
||||||
130
TelegramCore/SecretChatState.swift
Normal file
130
TelegramCore/SecretChatState.swift
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
import Foundation
|
||||||
|
#if os(macOS)
|
||||||
|
import PostboxMac
|
||||||
|
#else
|
||||||
|
import Postbox
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum SecretChatRole {
|
||||||
|
case creator
|
||||||
|
case participant
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SecretChatFingerprint: Equatable {
|
||||||
|
let k0: Int64
|
||||||
|
let k1: Int64
|
||||||
|
let k2: Int64
|
||||||
|
let k3: Int64
|
||||||
|
|
||||||
|
static func ==(lhs: SecretChatFingerprint, rhs: SecretChatFingerprint) -> Bool {
|
||||||
|
if lhs.k0 != rhs.k0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if lhs.k1 != rhs.k1 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if lhs.k2 != rhs.k2 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if lhs.k3 != rhs.k3 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SecretChatSequenceState: Equatable {
|
||||||
|
let seqIn: Int32
|
||||||
|
let seqOut: Int32
|
||||||
|
|
||||||
|
static func ==(lhs: SecretChatSequenceState, rhs: SecretChatSequenceState) -> Bool {
|
||||||
|
if lhs.seqIn == rhs.seqIn && lhs.seqOut == rhs.seqOut {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SecretChatLayerState: Equatable {
|
||||||
|
let effectiveLayer: Int32
|
||||||
|
let sentLayer: Int32?
|
||||||
|
let receivedLayer: Int32?
|
||||||
|
let sequenceState: SecretChatSequenceState?
|
||||||
|
|
||||||
|
static func ==(lhs: SecretChatLayerState, rhs: SecretChatLayerState) -> Bool {
|
||||||
|
if lhs.effectiveLayer != rhs.effectiveLayer {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if lhs.sentLayer != rhs.sentLayer {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if lhs.receivedLayer != rhs.receivedLayer {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if lhs.sequenceState != rhs.sequenceState {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum SecretChatEmbeddedState: Equatable {
|
||||||
|
case requested(accessHash: Int64, gA: MemoryBuffer)
|
||||||
|
case active(accessHash: Int64, role: SecretChatRole, baseKeyFingerprint: SecretChatFingerprint, layerState: SecretChatLayerState)
|
||||||
|
case closed
|
||||||
|
|
||||||
|
static func ==(lhs: SecretChatEmbeddedState, rhs: SecretChatEmbeddedState) -> Bool {
|
||||||
|
switch lhs {
|
||||||
|
case let .requested(lhsAccessHash, lhsGA):
|
||||||
|
if case let .requested(rhsAccessHash, rhsGA) = rhs, lhsAccessHash == rhsAccessHash, lhsGA == rhsGA {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case let .active(lhsAccessHash, lhsRole, lhsBaseKeyFingerprint, lhsLayerState):
|
||||||
|
if case let .active(rhsAccessHash, rhsRole, rhsBaseKeyFingerprint, rhsLayerState) = rhs, lhsAccessHash == rhsAccessHash, lhsRole == rhsRole, lhsBaseKeyFingerprint == rhsBaseKeyFingerprint, lhsLayerState == rhsLayerState {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case .closed:
|
||||||
|
if case .closed = rhs {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final class SecretChatState: PeerChatState, Equatable, CustomStringConvertible {
|
||||||
|
let embeddedState: SecretChatEmbeddedState
|
||||||
|
|
||||||
|
init(embeddedState: SecretChatEmbeddedState) {
|
||||||
|
self.embeddedState = embeddedState
|
||||||
|
}
|
||||||
|
|
||||||
|
init(decoder: Decoder) {
|
||||||
|
preconditionFailure()
|
||||||
|
}
|
||||||
|
|
||||||
|
func encode(_ encoder: Encoder) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func equals(_ other: PeerChatState) -> Bool {
|
||||||
|
if let other = other as? SecretChatState, other == self {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
var description: String {
|
||||||
|
return "(embeddedState: \(self.embeddedState))"
|
||||||
|
}
|
||||||
|
|
||||||
|
static func ==(lhs: SecretChatState, rhs: SecretChatState) -> Bool {
|
||||||
|
return lhs.embeddedState == rhs.embeddedState
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -187,7 +187,7 @@ public final class TelegramChannel: Peer {
|
|||||||
public let restrictionInfo: PeerAccessRestrictionInfo?
|
public let restrictionInfo: PeerAccessRestrictionInfo?
|
||||||
|
|
||||||
public var indexName: PeerIndexNameRepresentation {
|
public var indexName: PeerIndexNameRepresentation {
|
||||||
return .title(self.title)
|
return .title(title: self.title, addressName: self.username)
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(id: PeerId, accessHash: Int64?, title: String, username: String?, photo: [TelegramMediaImageRepresentation], creationDate: Int32, version: Int32, participationStatus: TelegramChannelParticipationStatus, role: TelegramChannelRole, info: TelegramChannelInfo, flags: TelegramChannelFlags, restrictionInfo: PeerAccessRestrictionInfo?) {
|
public init(id: PeerId, accessHash: Int64?, title: String, username: String?, photo: [TelegramMediaImageRepresentation], creationDate: Int32, version: Int32, participationStatus: TelegramChannelParticipationStatus, role: TelegramChannelRole, info: TelegramChannelInfo, flags: TelegramChannelFlags, restrictionInfo: PeerAccessRestrictionInfo?) {
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ public final class TelegramGroup: Peer {
|
|||||||
public let version: Int
|
public let version: Int
|
||||||
|
|
||||||
public var indexName: PeerIndexNameRepresentation {
|
public var indexName: PeerIndexNameRepresentation {
|
||||||
return .title(self.title)
|
return .title(title: self.title, addressName: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(id: PeerId, title: String, photo: [TelegramMediaImageRepresentation], participantCount: Int, role: TelegramGroupRole, membership: TelegramGroupMembership, flags: TelegramGroupFlags, migrationReference: TelegramGroupToChannelMigrationReference?, version: Int) {
|
public init(id: PeerId, title: String, photo: [TelegramMediaImageRepresentation], participantCount: Int, role: TelegramGroupRole, membership: TelegramGroupMembership, flags: TelegramGroupFlags, migrationReference: TelegramGroupToChannelMigrationReference?, version: Int) {
|
||||||
|
|||||||
@@ -20,8 +20,9 @@ public final class TelegramMediaWebpageLoadedContent: Coding, Equatable {
|
|||||||
|
|
||||||
public let image: TelegramMediaImage?
|
public let image: TelegramMediaImage?
|
||||||
public let file: TelegramMediaFile?
|
public let file: TelegramMediaFile?
|
||||||
|
public let instantPage: InstantPage?
|
||||||
|
|
||||||
public init(url: String, displayUrl: String, type: String?, websiteName: String?, title: String?, text: String?, embedUrl: String?, embedType: String?, embedSize: CGSize?, duration: Int?, author: String?, image: TelegramMediaImage?, file: TelegramMediaFile?) {
|
public init(url: String, displayUrl: String, type: String?, websiteName: String?, title: String?, text: String?, embedUrl: String?, embedType: String?, embedSize: CGSize?, duration: Int?, author: String?, image: TelegramMediaImage?, file: TelegramMediaFile?, instantPage: InstantPage?) {
|
||||||
self.url = url
|
self.url = url
|
||||||
self.displayUrl = displayUrl
|
self.displayUrl = displayUrl
|
||||||
self.type = type
|
self.type = type
|
||||||
@@ -35,6 +36,7 @@ public final class TelegramMediaWebpageLoadedContent: Coding, Equatable {
|
|||||||
self.author = author
|
self.author = author
|
||||||
self.image = image
|
self.image = image
|
||||||
self.file = file
|
self.file = file
|
||||||
|
self.instantPage = instantPage
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(decoder: Decoder) {
|
public init(decoder: Decoder) {
|
||||||
@@ -69,6 +71,12 @@ public final class TelegramMediaWebpageLoadedContent: Coding, Equatable {
|
|||||||
} else {
|
} else {
|
||||||
self.file = nil
|
self.file = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let instantPage = decoder.decodeObjectForKey("ip", decoder: { InstantPage(decoder: $0) }) as? InstantPage {
|
||||||
|
self.instantPage = instantPage
|
||||||
|
} else {
|
||||||
|
self.instantPage = nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(_ encoder: Encoder) {
|
public func encode(_ encoder: Encoder) {
|
||||||
@@ -76,37 +84,65 @@ public final class TelegramMediaWebpageLoadedContent: Coding, Equatable {
|
|||||||
encoder.encodeString(self.displayUrl, forKey: "d")
|
encoder.encodeString(self.displayUrl, forKey: "d")
|
||||||
if let type = self.type {
|
if let type = self.type {
|
||||||
encoder.encodeString(type, forKey: "ty")
|
encoder.encodeString(type, forKey: "ty")
|
||||||
|
} else {
|
||||||
|
encoder.encodeNil(forKey: "ty")
|
||||||
}
|
}
|
||||||
if let websiteName = self.websiteName {
|
if let websiteName = self.websiteName {
|
||||||
encoder.encodeString(websiteName, forKey: "ws")
|
encoder.encodeString(websiteName, forKey: "ws")
|
||||||
|
} else {
|
||||||
|
encoder.encodeNil(forKey: "ws")
|
||||||
}
|
}
|
||||||
if let title = self.title {
|
if let title = self.title {
|
||||||
encoder.encodeString(title, forKey: "ti")
|
encoder.encodeString(title, forKey: "ti")
|
||||||
|
} else {
|
||||||
|
encoder.encodeNil(forKey: "ti")
|
||||||
}
|
}
|
||||||
if let text = self.text {
|
if let text = self.text {
|
||||||
encoder.encodeString(text, forKey: "tx")
|
encoder.encodeString(text, forKey: "tx")
|
||||||
|
} else {
|
||||||
|
encoder.encodeNil(forKey: "tx")
|
||||||
}
|
}
|
||||||
if let embedUrl = self.embedUrl {
|
if let embedUrl = self.embedUrl {
|
||||||
encoder.encodeString(embedUrl, forKey: "eu")
|
encoder.encodeString(embedUrl, forKey: "eu")
|
||||||
|
} else {
|
||||||
|
encoder.encodeNil(forKey: "eu")
|
||||||
}
|
}
|
||||||
if let embedType = self.embedType {
|
if let embedType = self.embedType {
|
||||||
encoder.encodeString(embedType, forKey: "et")
|
encoder.encodeString(embedType, forKey: "et")
|
||||||
|
} else {
|
||||||
|
encoder.encodeNil(forKey: "et")
|
||||||
}
|
}
|
||||||
if let embedSize = self.embedSize {
|
if let embedSize = self.embedSize {
|
||||||
encoder.encodeInt32(Int32(embedSize.width), forKey: "esw")
|
encoder.encodeInt32(Int32(embedSize.width), forKey: "esw")
|
||||||
encoder.encodeInt32(Int32(embedSize.height), forKey: "esh")
|
encoder.encodeInt32(Int32(embedSize.height), forKey: "esh")
|
||||||
|
} else {
|
||||||
|
encoder.encodeNil(forKey: "esw")
|
||||||
|
encoder.encodeNil(forKey: "esh")
|
||||||
}
|
}
|
||||||
if let duration = self.duration {
|
if let duration = self.duration {
|
||||||
encoder.encodeInt32(Int32(duration), forKey: "du")
|
encoder.encodeInt32(Int32(duration), forKey: "du")
|
||||||
|
} else {
|
||||||
|
encoder.encodeNil(forKey: "du")
|
||||||
}
|
}
|
||||||
if let author = self.author {
|
if let author = self.author {
|
||||||
encoder.encodeString(author, forKey: "au")
|
encoder.encodeString(author, forKey: "au")
|
||||||
|
} else {
|
||||||
|
encoder.encodeNil(forKey: "au")
|
||||||
}
|
}
|
||||||
if let image = self.image {
|
if let image = self.image {
|
||||||
encoder.encodeObject(image, forKey: "im")
|
encoder.encodeObject(image, forKey: "im")
|
||||||
|
} else {
|
||||||
|
encoder.encodeNil(forKey: "im")
|
||||||
}
|
}
|
||||||
if let file = self.file {
|
if let file = self.file {
|
||||||
encoder.encodeObject(file, forKey: "fi")
|
encoder.encodeObject(file, forKey: "fi")
|
||||||
|
} else {
|
||||||
|
encoder.encodeNil(forKey: "fi")
|
||||||
|
}
|
||||||
|
if let instantPage = self.instantPage {
|
||||||
|
encoder.encodeObject(instantPage, forKey: "ip")
|
||||||
|
} else {
|
||||||
|
encoder.encodeNil(forKey: "ip")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -142,6 +178,10 @@ public func ==(lhs: TelegramMediaWebpageLoadedContent, rhs: TelegramMediaWebpage
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if lhs.instantPage != rhs.instantPage {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,7 +190,7 @@ public enum TelegramMediaWebpageContent {
|
|||||||
case Loaded(TelegramMediaWebpageLoadedContent)
|
case Loaded(TelegramMediaWebpageLoadedContent)
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class TelegramMediaWebpage: Media {
|
public final class TelegramMediaWebpage: Media, Equatable {
|
||||||
public var id: MediaId? {
|
public var id: MediaId? {
|
||||||
return self.webpageId
|
return self.webpageId
|
||||||
}
|
}
|
||||||
@@ -191,25 +231,33 @@ public final class TelegramMediaWebpage: Media {
|
|||||||
|
|
||||||
public func isEqual(_ other: Media) -> Bool {
|
public func isEqual(_ other: Media) -> Bool {
|
||||||
if let other = other as? TelegramMediaWebpage, self.webpageId == other.webpageId {
|
if let other = other as? TelegramMediaWebpage, self.webpageId == other.webpageId {
|
||||||
switch self.content {
|
return self == other
|
||||||
case let .Pending(lhsDate):
|
|
||||||
switch other.content {
|
|
||||||
case let .Pending(rhsDate) where lhsDate == rhsDate:
|
|
||||||
return true
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
case let .Loaded(lhsContent):
|
|
||||||
switch other.content {
|
|
||||||
case let .Loaded(rhsContent) where lhsContent == rhsContent:
|
|
||||||
return true
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static func ==(lhs: TelegramMediaWebpage, rhs: TelegramMediaWebpage) -> Bool {
|
||||||
|
if lhs.webpageId != rhs.webpageId {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
switch lhs.content {
|
||||||
|
case let .Pending(lhsDate):
|
||||||
|
switch rhs.content {
|
||||||
|
case let .Pending(rhsDate) where lhsDate == rhsDate:
|
||||||
|
return true
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case let .Loaded(lhsContent):
|
||||||
|
switch rhs.content {
|
||||||
|
case let .Loaded(rhsContent) where lhsContent == rhsContent:
|
||||||
|
return true
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func telegramMediaWebpageFromApiWebpage(_ webpage: Api.WebPage) -> TelegramMediaWebpage? {
|
func telegramMediaWebpageFromApiWebpage(_ webpage: Api.WebPage) -> TelegramMediaWebpage? {
|
||||||
@@ -227,7 +275,19 @@ func telegramMediaWebpageFromApiWebpage(_ webpage: Api.WebPage) -> TelegramMedia
|
|||||||
if let duration = duration {
|
if let duration = duration {
|
||||||
webpageDuration = Int(duration)
|
webpageDuration = Int(duration)
|
||||||
}
|
}
|
||||||
return TelegramMediaWebpage(webpageId: MediaId(namespace: Namespaces.Media.CloudWebpage, id: id), content: .Loaded(TelegramMediaWebpageLoadedContent(url: url, displayUrl: displayUrl, type: type, websiteName: siteName, title: title, text: description, embedUrl: embedUrl, embedType: embedType, embedSize: embedSize, duration: webpageDuration, author: author, image: photo == nil ? nil : telegramMediaImageFromApiPhoto(photo!), file:document == nil ? nil : telegramMediaFileFromApiDocument(document!))))
|
var image: TelegramMediaImage?
|
||||||
|
if let photo = photo {
|
||||||
|
image = telegramMediaImageFromApiPhoto(photo)
|
||||||
|
}
|
||||||
|
var file: TelegramMediaFile?
|
||||||
|
if let document = document {
|
||||||
|
file = telegramMediaFileFromApiDocument(document)
|
||||||
|
}
|
||||||
|
var instantPage: InstantPage?
|
||||||
|
if let cachedPage = cachedPage {
|
||||||
|
instantPage = InstantPage(apiPage: cachedPage)
|
||||||
|
}
|
||||||
|
return TelegramMediaWebpage(webpageId: MediaId(namespace: Namespaces.Media.CloudWebpage, id: id), content: .Loaded(TelegramMediaWebpageLoadedContent(url: url, displayUrl: displayUrl, type: type, websiteName: siteName, title: title, text: description, embedUrl: embedUrl, embedType: embedType, embedSize: embedSize, duration: webpageDuration, author: author, image: image, file: file, instantPage: instantPage)))
|
||||||
case .webPageEmpty:
|
case .webPageEmpty:
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ public final class TelegramUser: Peer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public var indexName: PeerIndexNameRepresentation {
|
public var indexName: PeerIndexNameRepresentation {
|
||||||
return .personName(first: self.firstName ?? "", last: self.lastName ?? "")
|
return .personName(first: self.firstName ?? "", last: self.lastName ?? "", addressName: self.username)
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(id: PeerId, accessHash: Int64?, firstName: String?, lastName: String?, username: String?, phone: String?, photo: [TelegramMediaImageRepresentation], botInfo: BotUserInfo?) {
|
public init(id: PeerId, accessHash: Int64?, firstName: String?, lastName: String?, username: String?, phone: String?, photo: [TelegramMediaImageRepresentation], botInfo: BotUserInfo?) {
|
||||||
|
|||||||
Reference in New Issue
Block a user