no message

This commit is contained in:
Peter 2017-08-15 14:45:34 +03:00
parent e3a70b659f
commit b0d55fdea7
50 changed files with 1751 additions and 455 deletions

View File

@ -101,6 +101,12 @@
D018D3381E648ACF00C5E089 /* CreateChannel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D018D3361E648ACF00C5E089 /* CreateChannel.swift */; };
D019B1CC1E2E3B6A00F80DB3 /* SecretChatRekeySession.swift in Sources */ = {isa = PBXBuildFile; fileRef = D019B1CB1E2E3B6A00F80DB3 /* SecretChatRekeySession.swift */; };
D019B1CD1E2E3B6A00F80DB3 /* SecretChatRekeySession.swift in Sources */ = {isa = PBXBuildFile; fileRef = D019B1CB1E2E3B6A00F80DB3 /* SecretChatRekeySession.swift */; };
D01A21A61F38CDC700DDA104 /* SynchronizeSavedStickersOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01A21A51F38CDC700DDA104 /* SynchronizeSavedStickersOperation.swift */; };
D01A21A71F38CDC700DDA104 /* SynchronizeSavedStickersOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01A21A51F38CDC700DDA104 /* SynchronizeSavedStickersOperation.swift */; };
D01A21A91F38CDDC00DDA104 /* ManagedSynchronizeSavedStickersOperations.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01A21A81F38CDDC00DDA104 /* ManagedSynchronizeSavedStickersOperations.swift */; };
D01A21AA1F38CDDC00DDA104 /* ManagedSynchronizeSavedStickersOperations.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01A21A81F38CDDC00DDA104 /* ManagedSynchronizeSavedStickersOperations.swift */; };
D01A21AC1F38D10E00DDA104 /* SavedStickerItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01A21AB1F38D10E00DDA104 /* SavedStickerItem.swift */; };
D01A21AD1F38D10E00DDA104 /* SavedStickerItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01A21AB1F38D10E00DDA104 /* SavedStickerItem.swift */; };
D01AC91D1DD5DA5E00E8160F /* RequestMessageActionCallback.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01AC91C1DD5DA5E00E8160F /* RequestMessageActionCallback.swift */; };
D01AC9211DD5E7E500E8160F /* RequestEditMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01AC9201DD5E7E500E8160F /* RequestEditMessage.swift */; };
D01AC9231DD5E9A200E8160F /* ApplyUpdateMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01AC9221DD5E9A200E8160F /* ApplyUpdateMessage.swift */; };
@ -175,7 +181,6 @@
D03B0D5E1D631A6900955575 /* Network.swift in Sources */ = {isa = PBXBuildFile; fileRef = D03B0D581D631A6900955575 /* Network.swift */; };
D03B0D5F1D631A6900955575 /* Serialization.swift in Sources */ = {isa = PBXBuildFile; fileRef = D03B0D591D631A6900955575 /* Serialization.swift */; };
D03B0D651D631A8B00955575 /* Account.swift in Sources */ = {isa = PBXBuildFile; fileRef = D03B0D611D631A8B00955575 /* Account.swift */; };
D03B0D661D631A8B00955575 /* AccountSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = D03B0D621D631A8B00955575 /* AccountSettings.swift */; };
D03B0D671D631A8B00955575 /* AccountViewTracker.swift in Sources */ = {isa = PBXBuildFile; fileRef = D03B0D631D631A8B00955575 /* AccountViewTracker.swift */; };
D03B0D681D631A8B00955575 /* RecentPeers.swift in Sources */ = {isa = PBXBuildFile; fileRef = D03B0D641D631A8B00955575 /* RecentPeers.swift */; };
D03B0D6D1D631AA300955575 /* ContactManagement.swift in Sources */ = {isa = PBXBuildFile; fileRef = D03B0D6C1D631AA300955575 /* ContactManagement.swift */; };
@ -299,8 +304,16 @@
D0613FD01E60520700202CDB /* ChannelMembers.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0613FCE1E60520700202CDB /* ChannelMembers.swift */; };
D0613FD71E606B3B00202CDB /* ConvertGroupToSupergroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0613FD61E606B3B00202CDB /* ConvertGroupToSupergroup.swift */; };
D0613FD81E606B3B00202CDB /* ConvertGroupToSupergroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0613FD61E606B3B00202CDB /* ConvertGroupToSupergroup.swift */; };
D0642EF91F3E05D700792790 /* EarliestUnseenPersonalMentionMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0642EF81F3E05D700792790 /* EarliestUnseenPersonalMentionMessage.swift */; };
D0642EFA1F3E05D700792790 /* EarliestUnseenPersonalMentionMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0642EF81F3E05D700792790 /* EarliestUnseenPersonalMentionMessage.swift */; };
D067066C1D512ADB00DED3E3 /* Postbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D06706671D512ADB00DED3E3 /* Postbox.framework */; };
D067066D1D512ADB00DED3E3 /* SwiftSignalKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D06706681D512ADB00DED3E3 /* SwiftSignalKit.framework */; };
D07047B41F3DF1FE00F6A8D4 /* ConsumablePersonalMentionMessageAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = D07047B31F3DF1FE00F6A8D4 /* ConsumablePersonalMentionMessageAttribute.swift */; };
D07047B51F3DF1FE00F6A8D4 /* ConsumablePersonalMentionMessageAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = D07047B31F3DF1FE00F6A8D4 /* ConsumablePersonalMentionMessageAttribute.swift */; };
D07047B71F3DF2CD00F6A8D4 /* ManagedConsumePersonalMessagesActions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D07047B61F3DF2CD00F6A8D4 /* ManagedConsumePersonalMessagesActions.swift */; };
D07047B81F3DF2CD00F6A8D4 /* ManagedConsumePersonalMessagesActions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D07047B61F3DF2CD00F6A8D4 /* ManagedConsumePersonalMessagesActions.swift */; };
D07047BA1F3DF75500F6A8D4 /* ConsumePersonalMessageAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = D07047B91F3DF75500F6A8D4 /* ConsumePersonalMessageAction.swift */; };
D07047BB1F3DF75500F6A8D4 /* ConsumePersonalMessageAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = D07047B91F3DF75500F6A8D4 /* ConsumePersonalMessageAction.swift */; };
D073CE5D1DCB97F6007511FD /* ForwardSourceInfoAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = D073CE5C1DCB97F6007511FD /* ForwardSourceInfoAttribute.swift */; };
D073CE601DCB9D14007511FD /* OutgoingMessageInfoAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = D073CE5F1DCB9D14007511FD /* OutgoingMessageInfoAttribute.swift */; };
D073CE6A1DCBCF17007511FD /* ViewCountMessageAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = D03B0CE71D6224AD00955575 /* ViewCountMessageAttribute.swift */; };
@ -378,8 +391,6 @@
D0B418BA1D7E05BB004562A4 /* NetworkLogging.m in Sources */ = {isa = PBXBuildFile; fileRef = D03B0E421D631E6600955575 /* NetworkLogging.m */; };
D0B418BB1D7E05BE004562A4 /* NetworkLogging.h in Headers */ = {isa = PBXBuildFile; fileRef = D03B0E411D631E6600955575 /* NetworkLogging.h */; };
D0B418BC1D7E05D0004562A4 /* TelegramCoreIncludes.h in Headers */ = {isa = PBXBuildFile; fileRef = D03B0E5B1D63240700955575 /* TelegramCoreIncludes.h */; };
D0B477731EBF54A20033A0AB /* RecentCalls.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0B477721EBF54A20033A0AB /* RecentCalls.swift */; };
D0B477741EBF54A20033A0AB /* RecentCalls.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0B477721EBF54A20033A0AB /* RecentCalls.swift */; };
D0B843811DA6EDAE005F29E1 /* CachedUserData.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0B843801DA6EDAE005F29E1 /* CachedUserData.swift */; };
D0B843831DA6EDB8005F29E1 /* CachedGroupData.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0B843821DA6EDB8005F29E1 /* CachedGroupData.swift */; };
D0B843851DA6EDC4005F29E1 /* CachedChannelData.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0B843841DA6EDC4005F29E1 /* CachedChannelData.swift */; };
@ -436,7 +447,6 @@
D0B844351DAB91E0005F29E1 /* NBPhoneNumberDesc.m in Sources */ = {isa = PBXBuildFile; fileRef = D0B843AF1DA7FF30005F29E1 /* NBPhoneNumberDesc.m */; };
D0B844361DAB91E0005F29E1 /* NBPhoneNumberUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = D0B843B11DA7FF30005F29E1 /* NBPhoneNumberUtil.m */; };
D0B844431DAB91FD005F29E1 /* Account.swift in Sources */ = {isa = PBXBuildFile; fileRef = D03B0D611D631A8B00955575 /* Account.swift */; };
D0B844441DAB91FD005F29E1 /* AccountSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = D03B0D621D631A8B00955575 /* AccountSettings.swift */; };
D0B844451DAB91FD005F29E1 /* AccountViewTracker.swift in Sources */ = {isa = PBXBuildFile; fileRef = D03B0D631D631A8B00955575 /* AccountViewTracker.swift */; };
D0B844461DAB91FD005F29E1 /* RecentPeers.swift in Sources */ = {isa = PBXBuildFile; fileRef = D03B0D641D631A8B00955575 /* RecentPeers.swift */; };
D0B844471DAB91FD005F29E1 /* ManagedServiceViews.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0AB0B911D65E9FA002C78E7 /* ManagedServiceViews.swift */; };
@ -472,6 +482,8 @@
D0CAF2EA1D75EC600011F558 /* MtProtoKitDynamic.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0CAF2E91D75EC600011F558 /* MtProtoKitDynamic.framework */; };
D0D748021E7AE98B00F4B1F6 /* StickerPackInteractiveOperations.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D748011E7AE98B00F4B1F6 /* StickerPackInteractiveOperations.swift */; };
D0D748031E7AE98B00F4B1F6 /* StickerPackInteractiveOperations.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D748011E7AE98B00F4B1F6 /* StickerPackInteractiveOperations.swift */; };
D0DB7F031F43030C00591D48 /* InstallInteractiveReadMessagesAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DB7F021F43030C00591D48 /* InstallInteractiveReadMessagesAction.swift */; };
D0DB7F041F43030C00591D48 /* InstallInteractiveReadMessagesAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DB7F021F43030C00591D48 /* InstallInteractiveReadMessagesAction.swift */; };
D0DC354E1DE368F7000195EB /* RequestChatContextResults.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DC354D1DE368F7000195EB /* RequestChatContextResults.swift */; };
D0DC35501DE36900000195EB /* ChatContextResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DC354F1DE36900000195EB /* ChatContextResult.swift */; };
D0DC35511DE36908000195EB /* RequestChatContextResults.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DC354D1DE368F7000195EB /* RequestChatContextResults.swift */; };
@ -607,6 +619,9 @@
D0177B7A1DF8A16C00A5083A /* SecretChatState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SecretChatState.swift; sourceTree = "<group>"; };
D018D3361E648ACF00C5E089 /* CreateChannel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CreateChannel.swift; sourceTree = "<group>"; };
D019B1CB1E2E3B6A00F80DB3 /* SecretChatRekeySession.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SecretChatRekeySession.swift; sourceTree = "<group>"; };
D01A21A51F38CDC700DDA104 /* SynchronizeSavedStickersOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SynchronizeSavedStickersOperation.swift; sourceTree = "<group>"; };
D01A21A81F38CDDC00DDA104 /* ManagedSynchronizeSavedStickersOperations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ManagedSynchronizeSavedStickersOperations.swift; sourceTree = "<group>"; };
D01A21AB1F38D10E00DDA104 /* SavedStickerItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SavedStickerItem.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>"; };
D01AC9221DD5E9A200E8160F /* ApplyUpdateMessage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApplyUpdateMessage.swift; sourceTree = "<group>"; };
@ -667,7 +682,6 @@
D03B0D581D631A6900955575 /* Network.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Network.swift; sourceTree = "<group>"; };
D03B0D591D631A6900955575 /* Serialization.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Serialization.swift; sourceTree = "<group>"; };
D03B0D611D631A8B00955575 /* Account.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Account.swift; sourceTree = "<group>"; };
D03B0D621D631A8B00955575 /* AccountSettings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountSettings.swift; sourceTree = "<group>"; };
D03B0D631D631A8B00955575 /* AccountViewTracker.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountViewTracker.swift; sourceTree = "<group>"; };
D03B0D641D631A8B00955575 /* RecentPeers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecentPeers.swift; sourceTree = "<group>"; };
D03B0D6C1D631AA300955575 /* ContactManagement.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContactManagement.swift; sourceTree = "<group>"; };
@ -726,11 +740,15 @@
D0613FC91E60440600202CDB /* InvitationLinks.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InvitationLinks.swift; sourceTree = "<group>"; };
D0613FCE1E60520700202CDB /* ChannelMembers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChannelMembers.swift; sourceTree = "<group>"; };
D0613FD61E606B3B00202CDB /* ConvertGroupToSupergroup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConvertGroupToSupergroup.swift; sourceTree = "<group>"; };
D0642EF81F3E05D700792790 /* EarliestUnseenPersonalMentionMessage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EarliestUnseenPersonalMentionMessage.swift; sourceTree = "<group>"; };
D06706641D512ADB00DED3E3 /* AsyncDisplayKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = AsyncDisplayKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
D06706651D512ADB00DED3E3 /* Display.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Display.framework; sourceTree = BUILT_PRODUCTS_DIR; };
D06706671D512ADB00DED3E3 /* Postbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Postbox.framework; sourceTree = BUILT_PRODUCTS_DIR; };
D06706681D512ADB00DED3E3 /* SwiftSignalKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = SwiftSignalKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
D067066E1D512AEB00DED3E3 /* MtProtoKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = MtProtoKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
D07047B31F3DF1FE00F6A8D4 /* ConsumablePersonalMentionMessageAttribute.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConsumablePersonalMentionMessageAttribute.swift; sourceTree = "<group>"; };
D07047B61F3DF2CD00F6A8D4 /* ManagedConsumePersonalMessagesActions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ManagedConsumePersonalMessagesActions.swift; sourceTree = "<group>"; };
D07047B91F3DF75500F6A8D4 /* ConsumePersonalMessageAction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConsumePersonalMessageAction.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>"; };
D0754D291EEE10FC00884F6E /* BotPaymentForm.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BotPaymentForm.swift; sourceTree = "<group>"; };
@ -774,7 +792,6 @@
D0B418701D7E0409004562A4 /* PostboxMac.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = PostboxMac.framework; sourceTree = BUILT_PRODUCTS_DIR; };
D0B418711D7E0409004562A4 /* SwiftSignalKitMac.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = SwiftSignalKitMac.framework; sourceTree = BUILT_PRODUCTS_DIR; };
D0B4187E1D7E054E004562A4 /* MtProtoKitMac.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = MtProtoKitMac.framework; sourceTree = BUILT_PRODUCTS_DIR; };
D0B477721EBF54A20033A0AB /* RecentCalls.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecentCalls.swift; sourceTree = "<group>"; };
D0B843801DA6EDAE005F29E1 /* CachedUserData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CachedUserData.swift; sourceTree = "<group>"; };
D0B843821DA6EDB8005F29E1 /* CachedGroupData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CachedGroupData.swift; sourceTree = "<group>"; };
D0B843841DA6EDC4005F29E1 /* CachedChannelData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CachedChannelData.swift; sourceTree = "<group>"; };
@ -827,6 +844,7 @@
D0C50E331E93A86600F62E39 /* CallSessionManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CallSessionManager.swift; sourceTree = "<group>"; };
D0CAF2E91D75EC600011F558 /* MtProtoKitDynamic.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = MtProtoKitDynamic.framework; sourceTree = BUILT_PRODUCTS_DIR; };
D0D748011E7AE98B00F4B1F6 /* StickerPackInteractiveOperations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StickerPackInteractiveOperations.swift; sourceTree = "<group>"; };
D0DB7F021F43030C00591D48 /* InstallInteractiveReadMessagesAction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InstallInteractiveReadMessagesAction.swift; sourceTree = "<group>"; };
D0DC354D1DE368F7000195EB /* RequestChatContextResults.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RequestChatContextResults.swift; sourceTree = "<group>"; };
D0DC354F1DE36900000195EB /* ChatContextResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatContextResult.swift; sourceTree = "<group>"; };
D0DF0C891D819C7E008AEB01 /* JoinChannel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JoinChannel.swift; sourceTree = "<group>"; };
@ -926,6 +944,7 @@
children = (
D021E0DE1DB539FC00C6B04F /* StickerPack.swift */,
D049EAD41E43D98500A2CD3A /* RecentMediaItem.swift */,
D01A21AB1F38D10E00DDA104 /* SavedStickerItem.swift */,
D049EAE71E44B67100A2CD3A /* RecentPeerItem.swift */,
D0E23DD41E8042F500B9B6D2 /* FeaturedStickerPack.swift */,
D0C48F381E8138DF0075317D /* ArchivedStickerPacksInfo.swift */,
@ -1082,6 +1101,7 @@
D0E35A111DE4A25E00BC6096 /* OutgoingChatContextResultMessageAttribute.swift */,
D0458C871E69B4AB00FB34C1 /* OutgoingContentInfoMessageAttribute.swift */,
D00D343E1E6ED6E50057B307 /* ConsumableContentMessageAttribute.swift */,
D07047B31F3DF1FE00F6A8D4 /* ConsumablePersonalMentionMessageAttribute.swift */,
D099D7451EEF0C2700A3128C /* ChannelMessageStateVersionAttribute.swift */,
C28725411EF967E700613564 /* NotificationInfoMessageAttribute.swift */,
);
@ -1142,10 +1162,14 @@
D0F3A8A11E82C65E00B4C64C /* ManagedSynchronizeChatInputStateOperations.swift */,
D0575AF01E9FFA5D006F2541 /* SynchronizeSavedGifsOperation.swift */,
D0575AF31E9FFDDD006F2541 /* ManagedSynchronizeSavedGifsOperations.swift */,
D01A21A51F38CDC700DDA104 /* SynchronizeSavedStickersOperation.swift */,
D01A21A81F38CDDC00DDA104 /* ManagedSynchronizeSavedStickersOperations.swift */,
D058E0D01E8AD65C00A442DE /* StandaloneSendMessage.swift */,
D0F02CE41E9926C40065DEE2 /* ManagedConfigurationUpdates.swift */,
D0C0B58C1ED9DC5A000F4D2C /* SynchronizeLocalizationUpdatesOperation.swift */,
D0C0B5891ED9DA6B000F4D2C /* ManagedLocalizationUpdatesOperations.swift */,
D07047B91F3DF75500F6A8D4 /* ConsumePersonalMessageAction.swift */,
D07047B61F3DF2CD00F6A8D4 /* ManagedConsumePersonalMessagesActions.swift */,
);
name = State;
sourceTree = "<group>";
@ -1194,7 +1218,6 @@
children = (
D03B0D611D631A8B00955575 /* Account.swift */,
D049EAF41E44DF3300A2CD3A /* AccountState.swift */,
D03B0D621D631A8B00955575 /* AccountSettings.swift */,
D03B0D631D631A8B00955575 /* AccountViewTracker.swift */,
D03B0D641D631A8B00955575 /* RecentPeers.swift */,
D0AB0B911D65E9FA002C78E7 /* ManagedServiceViews.swift */,
@ -1238,6 +1261,8 @@
D0528E5F1E65B94E00E2FEF5 /* SingleMessageView.swift */,
D0528E691E65DD2100E2FEF5 /* WebpagePreview.swift */,
D0FA35071EA632E400E56FFA /* CollectCacheUsageStats.swift */,
D0642EF81F3E05D700792790 /* EarliestUnseenPersonalMentionMessage.swift */,
D0DB7F021F43030C00591D48 /* InstallInteractiveReadMessagesAction.swift */,
);
name = Messages;
sourceTree = "<group>";
@ -1395,7 +1420,6 @@
isa = PBXGroup;
children = (
D0C50E331E93A86600F62E39 /* CallSessionManager.swift */,
D0B477721EBF54A20033A0AB /* RecentCalls.swift */,
C2F4ED1C1EC60064005F2696 /* RateCall.swift */,
);
name = Calls;
@ -1673,7 +1697,6 @@
D03B0CB91D62233400955575 /* Either.swift in Sources */,
D0D748021E7AE98B00F4B1F6 /* StickerPackInteractiveOperations.swift in Sources */,
D03B0CBD1D62234300955575 /* Regex.swift in Sources */,
D03B0D661D631A8B00955575 /* AccountSettings.swift in Sources */,
D00BDA191EE593D600C64C5E /* TelegramChannelAdminRights.swift in Sources */,
D0B843B91DA7FF30005F29E1 /* NBMetadataCoreTest.m in Sources */,
D09A2FE61D7CD4940018FB72 /* TelegramChannel.swift in Sources */,
@ -1681,6 +1704,8 @@
D053B4181F18DE4F00E2D58A /* AuthorSignatureMessageAttribute.swift in Sources */,
D0F3A89F1E82C65400B4C64C /* SynchronizeChatInputStateOperation.swift in Sources */,
D01AC9231DD5E9A200E8160F /* ApplyUpdateMessage.swift in Sources */,
D01A21AC1F38D10E00DDA104 /* SavedStickerItem.swift in Sources */,
D0642EF91F3E05D700792790 /* EarliestUnseenPersonalMentionMessage.swift in Sources */,
D03B0CF71D62250800955575 /* TelegramMediaImage.swift in Sources */,
D0E23DDF1E8082A400B9B6D2 /* ArchivedStickerPacks.swift in Sources */,
D0BC386E1E3FDAB70044D6FE /* CreateGroup.swift in Sources */,
@ -1710,7 +1735,9 @@
D0F3CC7D1DDE289E008148FA /* ResolvePeerByName.swift in Sources */,
D0B843B71DA7FF30005F29E1 /* NBMetadataCoreMapper.m in Sources */,
D0AB0B921D65E9FA002C78E7 /* ManagedServiceViews.swift in Sources */,
D0DB7F031F43030C00591D48 /* InstallInteractiveReadMessagesAction.swift in Sources */,
D0AAD1B81E326FE200D5B9DE /* ManagedAutoremoveMessageOperations.swift in Sources */,
D01A21A91F38CDDC00DDA104 /* ManagedSynchronizeSavedStickersOperations.swift in Sources */,
D099EA1C1DE72867001AF5A8 /* PeerCommands.swift in Sources */,
D03B0CCE1D62239600955575 /* PhoneNumbers.swift in Sources */,
D00DBBDA1E64E67E00DB5485 /* UpdateSecretChat.swift in Sources */,
@ -1728,6 +1755,7 @@
C2E064681ECEEF0A00387BB8 /* TelegramMediaInvoice.swift in Sources */,
D0448C9F1E27F5EB005A61A7 /* Random.swift in Sources */,
D0B843B21DA7FF30005F29E1 /* NBAsYouTypeFormatter.m in Sources */,
D07047B71F3DF2CD00F6A8D4 /* ManagedConsumePersonalMessagesActions.swift in Sources */,
D03B0CDB1D62245F00955575 /* ApiUtils.swift in Sources */,
D01C7F0A1EFC3607008305F1 /* ManagedDeviceContacts.swift in Sources */,
D0B843C91DA7FF30005F29E1 /* NBPhoneNumberDesc.m in Sources */,
@ -1750,7 +1778,6 @@
D03B0D0A1D62255C00955575 /* Holes.swift in Sources */,
D0B843CB1DA7FF30005F29E1 /* NBPhoneNumberUtil.m in Sources */,
D03B0D5E1D631A6900955575 /* Network.swift in Sources */,
D0B477731EBF54A20033A0AB /* RecentCalls.swift in Sources */,
D0B8438E1DA7D296005F29E1 /* CachedGroupParticipants.swift in Sources */,
D0B843BD1DA7FF30005F29E1 /* NBMetadataHelper.m in Sources */,
D03B0CF51D62250800955575 /* TelegramMediaContact.swift in Sources */,
@ -1793,6 +1820,7 @@
D01D6BF91E42A713006151C6 /* SearchStickers.swift in Sources */,
D08F4A691E79CECB00A2AA15 /* ManagedSynchronizeInstalledStickerPacksOperations.swift in Sources */,
D0575AF11E9FFA5D006F2541 /* SynchronizeSavedGifsOperation.swift in Sources */,
D07047B41F3DF1FE00F6A8D4 /* ConsumablePersonalMentionMessageAttribute.swift in Sources */,
D0FA8BB91E2240B4001E855B /* SecretChatIncomingDecryptedOperation.swift in Sources */,
D0561DE31E5737FC00E6B9E9 /* UpdatePeerInfo.swift in Sources */,
D0DF0C8A1D819C7E008AEB01 /* JoinChannel.swift in Sources */,
@ -1860,6 +1888,7 @@
D0BC38751E40A7F70044D6FE /* RemovePeerChat.swift in Sources */,
D0AB0B961D662F0B002C78E7 /* ManagedChatListHoles.swift in Sources */,
D05A32E41E6F0B2E002760B4 /* RecentAccountSessions.swift in Sources */,
D01A21A61F38CDC700DDA104 /* SynchronizeSavedStickersOperation.swift in Sources */,
D03E5E0C1E55E02D0029569A /* LoggedOutAccountAttribute.swift in Sources */,
D0F3A8A51E82C94C00B4C64C /* SynchronizeableChatInputState.swift in Sources */,
D03B0CD71D62245300955575 /* TelegramGroup.swift in Sources */,
@ -1904,6 +1933,7 @@
D03B0D0D1D62255C00955575 /* SynchronizePeerReadState.swift in Sources */,
D03B0D081D62255C00955575 /* ChannelState.swift in Sources */,
C251D7431E65E50500283EDE /* StickerSetInstallation.swift in Sources */,
D07047BA1F3DF75500F6A8D4 /* ConsumePersonalMessageAction.swift in Sources */,
D0C0B58D1ED9DC5A000F4D2C /* SynchronizeLocalizationUpdatesOperation.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -1942,9 +1972,11 @@
D00D34401E6ED6E50057B307 /* ConsumableContentMessageAttribute.swift in Sources */,
D050F26E1E4A5B6D00988324 /* RemovePeerChat.swift in Sources */,
D0613FD81E606B3B00202CDB /* ConvertGroupToSupergroup.swift in Sources */,
D0DB7F041F43030C00591D48 /* InstallInteractiveReadMessagesAction.swift in Sources */,
D01D6BFA1E42A718006151C6 /* SearchStickers.swift in Sources */,
D0D748031E7AE98B00F4B1F6 /* StickerPackInteractiveOperations.swift in Sources */,
C2A315C01E2E776A00D89000 /* RequestStartBot.swift in Sources */,
D0642EFA1F3E05D700792790 /* EarliestUnseenPersonalMentionMessage.swift in Sources */,
D0F7B1EA1E045C87007EB8A5 /* ChangePeerNotificationSettings.swift in Sources */,
D0B418A71D7E0592004562A4 /* Fetch.swift in Sources */,
D02ABC7C1E30058F00CAE539 /* DeleteMessagesInteractively.swift in Sources */,
@ -1954,7 +1986,6 @@
D0E23DE01E8082A400B9B6D2 /* ArchivedStickerPacks.swift in Sources */,
D050F2521E4A59C200988324 /* JoinLink.swift in Sources */,
D0F7B1E91E045C87007EB8A5 /* PeerCommands.swift in Sources */,
D0B477741EBF54A20033A0AB /* RecentCalls.swift in Sources */,
D00D97C81E32901700E5C2B6 /* PeerInputActivity.swift in Sources */,
D0754D2B1EEE10FC00884F6E /* BotPaymentForm.swift in Sources */,
D0B844311DAB91E0005F29E1 /* NBPhoneMetaData.m in Sources */,
@ -1967,6 +1998,7 @@
D00D97CB1E32917C00E5C2B6 /* PeerInputActivityManager.swift in Sources */,
D0B844491DAB91FD005F29E1 /* ManagedChatListHoles.swift in Sources */,
D03C53711DAD5CA9004C17B3 /* CachedGroupParticipants.swift in Sources */,
D07047B81F3DF2CD00F6A8D4 /* ManagedConsumePersonalMessagesActions.swift in Sources */,
C2366C841E4F3EAA0097CCFF /* GroupReturnAndLeft.swift in Sources */,
C2E0646E1ECF171E00387BB8 /* TelegramMediaWebDocument.swift in Sources */,
D03C53671DAD5CA9004C17B3 /* ApiUtils.swift in Sources */,
@ -2001,10 +2033,10 @@
D0FA8BA81E1FA6DF001E855B /* TelegramSecretChat.swift in Sources */,
C23BC3881E9BE3CB00D79F92 /* ImportContact.swift in Sources */,
D001F3EB1E128A1C007A8C60 /* EnqueueMessage.swift in Sources */,
D01A21A71F38CDC700DDA104 /* SynchronizeSavedStickersOperation.swift in Sources */,
D00C7CEC1E37A8540080C3D5 /* SetSecretChatMessageAutoremoveTimeoutInteractively.swift in Sources */,
D0B844481DAB91FD005F29E1 /* ManagedMessageHistoryHoles.swift in Sources */,
D0F3CC7B1DDE2859008148FA /* RequestEditMessage.swift in Sources */,
D0B844441DAB91FD005F29E1 /* AccountSettings.swift in Sources */,
D049EAEC1E44B71B00A2CD3A /* RecentlySearchedPeerIds.swift in Sources */,
D0FA8B991E1E955C001E855B /* SecretChatOutgoingOperation.swift in Sources */,
D001F3F01E128A1C007A8C60 /* AccountStateManagementUtils.swift in Sources */,
@ -2032,6 +2064,7 @@
D0E23DDB1E806F7700B9B6D2 /* ManagedSynchronizeMarkFeaturedStickerPacksAsSeenOperations.swift in Sources */,
D0B844341DAB91E0005F29E1 /* NBPhoneNumberDefines.m in Sources */,
D0B8442A1DAB91E0005F29E1 /* NBAsYouTypeFormatter.m in Sources */,
D07047B51F3DF1FE00F6A8D4 /* ConsumablePersonalMentionMessageAttribute.swift in Sources */,
D0448C8F1E22993C005A61A7 /* ProcessSecretChatIncomingDecryptedOperations.swift in Sources */,
D073CE6E1DCBCF17007511FD /* ForwardSourceInfoAttribute.swift in Sources */,
D05A32E21E6F0982002760B4 /* UpdatedAccountPrivacySettings.swift in Sources */,
@ -2053,6 +2086,7 @@
D02ABC821E310E5D00CAE539 /* ManagedCloudChatRemoveMessagesOperations.swift in Sources */,
C2FD33E51E687BF1008D13D4 /* PeerPhotoUpdater.swift in Sources */,
D0B8442E1DAB91E0005F29E1 /* NBMetadataCoreTestMapper.m in Sources */,
D01A21AD1F38D10E00DDA104 /* SavedStickerItem.swift in Sources */,
D03C53731DAD5CA9004C17B3 /* CachedGroupData.swift in Sources */,
D019B1CD1E2E3B6A00F80DB3 /* SecretChatRekeySession.swift in Sources */,
C2F4ED1E1EC60064005F2696 /* RateCall.swift in Sources */,
@ -2100,6 +2134,7 @@
D0B4188E1D7E0578004562A4 /* StoreMessage_Telegram.swift in Sources */,
D0B844461DAB91FD005F29E1 /* RecentPeers.swift in Sources */,
D03C53681DAD5CA9004C17B3 /* PeerUtils.swift in Sources */,
D07047BB1F3DF75500F6A8D4 /* ConsumePersonalMessageAction.swift in Sources */,
D050F2621E4A5AE700988324 /* GlobalNotificationSettings.swift in Sources */,
D0B418991D7E0580004562A4 /* TelegramMediaMap.swift in Sources */,
D0561DEB1E5754FA00E6B9E9 /* ChannelAdmins.swift in Sources */,
@ -2119,6 +2154,7 @@
D073CE6A1DCBCF17007511FD /* ViewCountMessageAttribute.swift in Sources */,
C27982511E72C97800262BFD /* MacosLegacy.swift in Sources */,
D0B418AB1D7E0597004562A4 /* MultipartFetch.swift in Sources */,
D01A21AA1F38CDDC00DDA104 /* ManagedSynchronizeSavedStickersOperations.swift in Sources */,
D03C53741DAD5CA9004C17B3 /* CachedChannelData.swift in Sources */,
D0B418861D7E056D004562A4 /* Namespaces.swift in Sources */,
D05A32E51E6F0B2E002760B4 /* RecentAccountSessions.swift in Sources */,

View File

@ -12,7 +12,7 @@
<key>TelegramCoreMac.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>6</integer>
<integer>5</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>

View File

@ -227,6 +227,7 @@ private var declaredEncodables: Void = {
declareEncodable(ArchivedStickerPacksInfo.self, f: { ArchivedStickerPacksInfo(decoder: $0) })
declareEncodable(SynchronizeChatInputStateOperation.self, f: { SynchronizeChatInputStateOperation(decoder: $0) })
declareEncodable(SynchronizeSavedGifsOperation.self, f: { SynchronizeSavedGifsOperation(decoder: $0) })
declareEncodable(SynchronizeSavedStickersOperation.self, f: { SynchronizeSavedStickersOperation(decoder: $0) })
declareEncodable(CacheStorageSettings.self, f: { CacheStorageSettings(decoder: $0) })
declareEncodable(LocalizationSettings.self, f: { LocalizationSettings(decoder: $0) })
declareEncodable(ProxySettings.self, f: { ProxySettings(decoder: $0) })
@ -240,6 +241,9 @@ private var declaredEncodables: Void = {
declareEncodable(TemporaryTwoStepPasswordToken.self, f: { TemporaryTwoStepPasswordToken(decoder: $0) })
declareEncodable(AuthorSignatureMessageAttribute.self, f: { AuthorSignatureMessageAttribute(decoder: $0) })
declareEncodable(TelegramMediaExpiredContent.self, f: { TelegramMediaExpiredContent(decoder: $0) })
declareEncodable(SavedStickerItem.self, f: { SavedStickerItem(decoder: $0) })
declareEncodable(ConsumablePersonalMentionMessageAttribute.self, f: { ConsumablePersonalMentionMessageAttribute(decoder: $0) })
declareEncodable(ConsumePersonalMessageAction.self, f: { ConsumePersonalMessageAction(decoder: $0) })
return
}()
@ -268,7 +272,7 @@ public func accountWithId(networkArguments: NetworkInitializationArguments, id:
initializeMessageNamespacesWithHoles.append((peerNamespace, Namespaces.Message.Cloud))
}
let seedConfiguration = SeedConfiguration(initializeChatListWithHoles: [ChatListHole(index: MessageIndex(id: MessageId(peerId: PeerId(namespace: Namespaces.Peer.Empty, id: 0), namespace: Namespaces.Message.Cloud, id: 1), timestamp: 1))], initializeMessageNamespacesWithHoles: initializeMessageNamespacesWithHoles, existingMessageTags: MessageTags.all, existingGlobalMessageTags: GlobalMessageTags.all, peerNamespacesRequiringMessageTextIndex: [Namespaces.Peer.SecretChat])
let seedConfiguration = SeedConfiguration(initializeChatListWithHoles: [ChatListHole(index: MessageIndex(id: MessageId(peerId: PeerId(namespace: Namespaces.Peer.Empty, id: 0), namespace: Namespaces.Message.Cloud, id: 1), timestamp: 1))], initializeMessageNamespacesWithHoles: initializeMessageNamespacesWithHoles, existingMessageTags: MessageTags.all, messageTagsWithSummary: MessageTags.unseenPersonalMessage, existingGlobalMessageTags: GlobalMessageTags.all, peerNamespacesRequiringMessageTextIndex: [Namespaces.Peer.SecretChat])
let postbox = openPostbox(basePath: path + "/postbox", globalMessageIdsNamespace: Namespaces.Message.Cloud, seedConfiguration: seedConfiguration)
@ -456,8 +460,6 @@ public class Account {
public var applicationContext: Any?
public let settings: AccountSettings = defaultAccountSettings()
public let notificationToken = Promise<Data>()
public let voipToken = Promise<Data>()
private let notificationTokenDisposable = MetaDisposable()
@ -636,9 +638,11 @@ public class Account {
self.managedOperationsDisposable.add(managedSynchronizeMarkFeaturedStickerPacksAsSeenOperations(postbox: self.postbox, network: self.network).start())
self.managedOperationsDisposable.add(managedRecentStickers(postbox: self.postbox, network: self.network).start())
self.managedOperationsDisposable.add(managedSynchronizeSavedGifsOperations(postbox: self.postbox, network: self.network).start())
self.managedOperationsDisposable.add(managedSynchronizeSavedStickersOperations(postbox: self.postbox, network: self.network).start())
self.managedOperationsDisposable.add(managedRecentlyUsedInlineBots(postbox: self.postbox, network: self.network).start())
self.managedOperationsDisposable.add(managedLocalTypingActivities(activities: self.localInputActivityManager.allActivities(), postbox: self.postbox, network: self.network).start())
self.managedOperationsDisposable.add(managedSynchronizeConsumeMessageContentOperations(postbox: self.postbox, network: self.network, stateManager: self.stateManager).start())
self.managedOperationsDisposable.add(managedConsumePersonalMessagesActions(postbox: self.postbox, network: self.network, stateManager: self.stateManager).start())
self.managedOperationsDisposable.add(managedSynchronizeChatInputStateOperations(postbox: self.postbox, network: self.network).start())
self.managedOperationsDisposable.add(managedConfigurationUpdates(postbox: self.postbox, network: self.network).start())
self.managedOperationsDisposable.add(managedLocalizationUpdatesOperations(postbox: self.postbox, network: self.network).start())

View File

@ -1,31 +0,0 @@
import Foundation
#if os(macOS)
import PostboxMac
#else
import Postbox
#endif
public struct AutomaticDownloadSettings {
public let downloadPhotos: Bool
public let downloadVoiceMessages: Bool
public let downloadGifs: Bool
}
public struct AccountSettings {
public let oneToOneChatsAutomaticDownloadSettings: AutomaticDownloadSettings
public let groupChatsAutomaticDownloadSettings: AutomaticDownloadSettings
}
func defaultAccountSettings() -> AccountSettings {
return AccountSettings(oneToOneChatsAutomaticDownloadSettings: AutomaticDownloadSettings(downloadPhotos: true, downloadVoiceMessages: true, downloadGifs: true), groupChatsAutomaticDownloadSettings: AutomaticDownloadSettings(downloadPhotos: true, downloadVoiceMessages: true, downloadGifs: true))
}
public extension AccountSettings {
public func automaticDownloadSettingsForPeerId(_ peerId: PeerId) -> AutomaticDownloadSettings {
if peerId.namespace == Namespaces.Peer.CloudUser {
return self.oneToOneChatsAutomaticDownloadSettings
} else {
return self.groupChatsAutomaticDownloadSettings
}
}
}

View File

@ -1287,7 +1287,7 @@ private func pollChannel(_ account: Account, peer: Peer, state: AccountMutableSt
channelState = ChannelState(pts: pts, invalidatedPts: nil)
}
updatedState.updateChannelState(peer.id, state: channelState)
case let .channelDifferenceTooLong(_, pts, timeout, topMessage, readInboxMaxId, readOutboxMaxId, unreadCount, messages, chats, users):
case let .channelDifferenceTooLong(_, pts, timeout, topMessage, readInboxMaxId, readOutboxMaxId, unreadCount, unreadMentionsCount, messages, chats, users):
apiTimeout = timeout
let channelState = ChannelState(pts: pts, invalidatedPts: pts)

View File

@ -200,6 +200,8 @@ public final class AccountViewTracker {
private var nextUpdatedViewCountDisposableId: Int32 = 0
private var updatedViewCountDisposables = DisposableDict<Int32>()
private var updatedSeenPersonalMessageIds = Set<MessageId>()
private var cachedDataContexts: [PeerId: PeerCachedDataContext] = [:]
private var cachedChannelParticipantsContexts: [PeerId: CachedChannelParticipantsContext] = [:]
@ -407,6 +409,49 @@ public final class AccountViewTracker {
}
}
public func updateMarkMentionsSeenForMessageIds(messageIds: Set<MessageId>) {
self.queue.async {
var addedMessageIds: [MessageId] = []
for messageId in messageIds {
if !self.updatedSeenPersonalMessageIds.contains(messageId) {
self.updatedSeenPersonalMessageIds.insert(messageId)
addedMessageIds.append(messageId)
}
}
if !addedMessageIds.isEmpty {
if let account = self.account {
let _ = (account.postbox.modify { modifier -> Void in
for id in addedMessageIds {
if let message = modifier.getMessage(id) {
var consume = false
inner: for attribute in message.attributes {
if let attribute = attribute as? ConsumablePersonalMentionMessageAttribute, !attribute.consumed, !attribute.pending {
consume = true
break inner
}
}
if consume {
modifier.updateMessage(id, update: { currentMessage in
var attributes = currentMessage.attributes
loop: for j in 0 ..< attributes.count {
if let attribute = attributes[j] as? ConsumablePersonalMentionMessageAttribute {
attributes[j] = ConsumablePersonalMentionMessageAttribute(consumed: attribute.consumed, pending: true)
break loop
}
}
return .update(StoreMessage(id: currentMessage.id, globallyUniqueId: currentMessage.globallyUniqueId, timestamp: currentMessage.timestamp, flags: StoreMessageFlags(currentMessage.flags), tags: currentMessage.tags, globalTags: currentMessage.globalTags, forwardInfo: currentMessage.forwardInfo.flatMap(StoreMessageForwardInfo.init), authorId: currentMessage.author?.id, text: currentMessage.text, attributes: attributes, media: currentMessage.media))
})
modifier.setPendingMessageAction(type: .consumeUnseenPersonalMessage, id: id, action: ConsumePersonalMessageAction())
}
}
}
}).start()
}
}
}
}
private func updateCachedPeerData(peerId: PeerId, viewId: Int32, referenceData: CachedPeerData?) {
self.queue.async {
let context: PeerCachedDataContext
@ -794,4 +839,42 @@ public final class AccountViewTracker {
return .never()
}
}
public func unseenPersonalMessagesCount(peerId: PeerId) -> Signal<Int32, NoError> {
if let account = self.account {
let pendingKey: PostboxViewKey = .pendingMessageActionsSummary(type: .consumeUnseenPersonalMessage, peerId: peerId, namespace: Namespaces.Message.Cloud)
let summaryKey: PostboxViewKey = .historyTagSummaryView(tag: .unseenPersonalMessage, peerId: peerId, namespace: Namespaces.Message.Cloud)
return account.postbox.combinedView(keys: [pendingKey, summaryKey])
|> map { views -> Int32 in
var count: Int32 = 0
if let view = views.views[pendingKey] as? PendingMessageActionsSummaryView {
count -= view.count
}
if let view = views.views[summaryKey] as? MessageHistoryTagSummaryView {
if let unseenCount = view.count {
count += unseenCount
}
}
return max(0, count)
} |> distinctUntilChanged
} else {
return .never()
}
}
public func tailChatListView(count: Int) -> Signal<(ChatListView, ViewUpdateType), NoError> {
if let account = self.account {
return account.postbox.tailChatListView(count: count, summaryComponents: ChatListEntrySummaryComponents(tagSummary: ChatListEntryMessageTagSummaryComponent(tag: .unseenPersonalMessage, namespace: Namespaces.Message.Cloud), actionsSummary: ChatListEntryPendingMessageActionsSummaryComponent(type: PendingMessageActionType.consumeUnseenPersonalMessage, namespace: Namespaces.Message.Cloud)))
} else {
return .never()
}
}
public func aroundChatListView(index: ChatListIndex, count: Int) -> Signal<(ChatListView, ViewUpdateType), NoError> {
if let account = self.account {
return account.postbox.aroundChatListView(index: index, count: count, summaryComponents: ChatListEntrySummaryComponents(tagSummary: ChatListEntryMessageTagSummaryComponent(tag: .unseenPersonalMessage, namespace: Namespaces.Message.Cloud), actionsSummary: ChatListEntryPendingMessageActionsSummaryComponent(type: PendingMessageActionType.consumeUnseenPersonalMessage, namespace: Namespaces.Message.Cloud)))
} else {
return .never()
}
}
}

View File

@ -21,7 +21,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-206066487] = { return Api.InputGeoPoint.parse_inputGeoPoint($0) }
dict[-784000893] = { return Api.payments.ValidatedRequestedInfo.parse_validatedRequestedInfo($0) }
dict[771925524] = { return Api.ChatFull.parse_chatFull($0) }
dict[-1781833897] = { return Api.ChatFull.parse_channelFull($0) }
dict[401891279] = { return Api.ChatFull.parse_channelFull($0) }
dict[-925415106] = { return Api.ChatParticipant.parse_chatParticipant($0) }
dict[-636267638] = { return Api.ChatParticipant.parse_chatParticipantCreator($0) }
dict[-489233354] = { return Api.ChatParticipant.parse_chatParticipantAdmin($0) }
@ -119,7 +119,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-496024847] = { return Api.UserStatus.parse_userStatusRecently($0) }
dict[129960444] = { return Api.UserStatus.parse_userStatusLastWeek($0) }
dict[2011940674] = { return Api.UserStatus.parse_userStatusLastMonth($0) }
dict[1728035348] = { return Api.Dialog.parse_dialog($0) }
dict[-455150117] = { return Api.Dialog.parse_dialog($0) }
dict[381645902] = { return Api.SendMessageAction.parse_sendMessageTypingAction($0) }
dict[-44119819] = { return Api.SendMessageAction.parse_sendMessageCancelAction($0) }
dict[-1584933265] = { return Api.SendMessageAction.parse_sendMessageRecordVideoAction($0) }
@ -198,6 +198,9 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-1425052898] = { return Api.Update.parse_updatePhoneCall($0) }
dict[281165899] = { return Api.Update.parse_updateLangPackTooLong($0) }
dict[1442983757] = { return Api.Update.parse_updateLangPack($0) }
dict[-451831443] = { return Api.Update.parse_updateFavedStickers($0) }
dict[-1987495099] = { return Api.Update.parse_updateChannelReadMessagesContents($0) }
dict[1887741886] = { return Api.Update.parse_updateContactsReset($0) }
dict[1558266229] = { return Api.PopularContact.parse_popularContact($0) }
dict[367766557] = { return Api.ChannelParticipant.parse_channelParticipant($0) }
dict[-1557620115] = { return Api.ChannelParticipant.parse_channelParticipantSelf($0) }
@ -258,7 +261,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[371037736] = { return Api.TopPeerCategory.parse_topPeerCategoryChannels($0) }
dict[511092620] = { return Api.TopPeerCategory.parse_topPeerCategoryPhoneCalls($0) }
dict[-1219778094] = { return Api.contacts.Contacts.parse_contactsNotModified($0) }
dict[1871416498] = { return Api.contacts.Contacts.parse_contacts($0) }
dict[-353862078] = { return Api.contacts.Contacts.parse_contacts($0) }
dict[-1798033689] = { return Api.ChannelMessagesFilter.parse_channelMessagesFilterEmpty($0) }
dict[-847783593] = { return Api.ChannelMessagesFilter.parse_channelMessagesFilter($0) }
dict[326715557] = { return Api.auth.PasswordRecovery.parse_passwordRecovery($0) }
@ -315,6 +318,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-484690728] = { return Api.ChannelAdminLogEventAction.parse_channelAdminLogEventActionParticipantInvite($0) }
dict[-422036098] = { return Api.ChannelAdminLogEventAction.parse_channelAdminLogEventActionParticipantToggleBan($0) }
dict[-714643696] = { return Api.ChannelAdminLogEventAction.parse_channelAdminLogEventActionParticipantToggleAdmin($0) }
dict[-1312568665] = { return Api.ChannelAdminLogEventAction.parse_channelAdminLogEventActionChangeStickerSet($0) }
dict[-543777747] = { return Api.auth.ExportedAuthorization.parse_exportedAuthorization($0) }
dict[-1269012015] = { return Api.messages.AffectedHistory.parse_affectedHistory($0) }
dict[-2037289493] = { return Api.account.PasswordInputSettings.parse_passwordInputSettings($0) }
@ -361,7 +365,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[182649427] = { return Api.MessageRange.parse_messageRange($0) }
dict[946083368] = { return Api.messages.StickerSetInstallResult.parse_stickerSetInstallResultSuccess($0) }
dict[904138920] = { return Api.messages.StickerSetInstallResult.parse_stickerSetInstallResultArchive($0) }
dict[2146355336] = { return Api.Config.parse_config($0) }
dict[-1913424220] = { return Api.Config.parse_config($0) }
dict[-75283823] = { return Api.TopPeerCategoryPeers.parse_topPeerCategoryPeers($0) }
dict[-1107729093] = { return Api.Game.parse_game($0) }
dict[-1032140601] = { return Api.BotCommand.parse_botCommand($0) }
@ -484,6 +488,8 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-2134272152] = { return Api.MessagesFilter.parse_inputMessagesFilterPhoneCalls($0) }
dict[2054952868] = { return Api.MessagesFilter.parse_inputMessagesFilterRoundVoice($0) }
dict[-1253451181] = { return Api.MessagesFilter.parse_inputMessagesFilterRoundVideo($0) }
dict[-1040652646] = { return Api.MessagesFilter.parse_inputMessagesFilterMyMentions($0) }
dict[1187706024] = { return Api.MessagesFilter.parse_inputMessagesFilterMyMentionsUnread($0) }
dict[364538944] = { return Api.messages.Dialogs.parse_dialogs($0) }
dict[1910543603] = { return Api.messages.Dialogs.parse_dialogsSlice($0) }
dict[-290921362] = { return Api.upload.CdnFile.parse_cdnFileReuploadNeeded($0) }
@ -495,6 +501,8 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[1130767150] = { return Api.BotInlineMessage.parse_botInlineMessageMediaVenue($0) }
dict[904770772] = { return Api.BotInlineMessage.parse_botInlineMessageMediaContact($0) }
dict[949182130] = { return Api.InputPeerNotifySettings.parse_inputPeerNotifySettings($0) }
dict[-1634752813] = { return Api.messages.FavedStickers.parse_favedStickersNotModified($0) }
dict[-209768682] = { return Api.messages.FavedStickers.parse_favedStickers($0) }
dict[1776236393] = { return Api.ExportedChatInvite.parse_chatInviteEmpty($0) }
dict[-64092740] = { return Api.ExportedChatInvite.parse_chatInviteExported($0) }
dict[2079516406] = { return Api.Authorization.parse_authorization($0) }
@ -557,7 +565,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-715532088] = { return Api.UserProfilePhoto.parse_userProfilePhoto($0) }
dict[-74456004] = { return Api.payments.SavedInfo.parse_savedInfo($0) }
dict[1041346555] = { return Api.updates.ChannelDifference.parse_channelDifferenceEmpty($0) }
dict[1091431943] = { return Api.updates.ChannelDifference.parse_channelDifferenceTooLong($0) }
dict[1788705589] = { return Api.updates.ChannelDifference.parse_channelDifferenceTooLong($0) }
dict[543450958] = { return Api.updates.ChannelDifference.parse_channelDifference($0) }
dict[-309659827] = { return Api.channels.AdminLogResults.parse_adminLogResults($0) }
dict[1996904104] = { return Api.InputAppEvent.parse_inputAppEvent($0) }
@ -976,6 +984,8 @@ public struct Api {
return _1.serialize(buffer, boxed)
case let _1 as Api.InputPeerNotifySettings:
return _1.serialize(buffer, boxed)
case let _1 as Api.messages.FavedStickers:
return _1.serialize(buffer, boxed)
case let _1 as Api.ExportedChatInvite:
return _1.serialize(buffer, boxed)
case let _1 as Api.Authorization:
@ -2387,6 +2397,75 @@ public struct Api {
}
}
public enum FavedStickers: CustomStringConvertible {
case favedStickersNotModified
case favedStickers(hash: Int32, packs: [Api.StickerPack], stickers: [Api.Document])
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) -> Swift.Bool {
switch self {
case .favedStickersNotModified:
if boxed {
buffer.appendInt32(-1634752813)
}
break
case .favedStickers(let hash, let packs, let stickers):
if boxed {
buffer.appendInt32(-209768682)
}
serializeInt32(hash, buffer: buffer, boxed: false)
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(packs.count))
for item in packs {
item.serialize(buffer, true)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(stickers.count))
for item in stickers {
item.serialize(buffer, true)
}
break
}
return true
}
fileprivate static func parse_favedStickersNotModified(_ reader: BufferReader) -> FavedStickers? {
return Api.messages.FavedStickers.favedStickersNotModified
}
fileprivate static func parse_favedStickers(_ reader: BufferReader) -> FavedStickers? {
var _1: Int32?
_1 = reader.readInt32()
var _2: [Api.StickerPack]?
if let _ = reader.readInt32() {
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.StickerPack.self)
}
var _3: [Api.Document]?
if let _ = reader.readInt32() {
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Document.self)
}
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
if _c1 && _c2 && _c3 {
return Api.messages.FavedStickers.favedStickers(hash: _1!, packs: _2!, stickers: _3!)
}
else {
return nil
}
}
public var description: String {
get {
switch self {
case .favedStickersNotModified:
return "(messages.favedStickersNotModified)"
case .favedStickers(let hash, let packs, let stickers):
return "(messages.favedStickers hash: \(hash), packs: \(packs), stickers: \(stickers))"
}
}
}
}
public enum AllStickers: CustomStringConvertible {
case allStickersNotModified
case allStickers(hash: Int32, sets: [Api.StickerSet])
@ -2555,7 +2634,7 @@ public struct Api {
public enum ChatFull: CustomStringConvertible {
case chatFull(id: Int32, participants: Api.ChatParticipants, chatPhoto: Api.Photo, notifySettings: Api.PeerNotifySettings, exportedInvite: Api.ExportedChatInvite, botInfo: [Api.BotInfo])
case channelFull(flags: Int32, id: Int32, about: String, participantsCount: Int32?, adminsCount: Int32?, kickedCount: Int32?, bannedCount: Int32?, readInboxMaxId: Int32, readOutboxMaxId: Int32, unreadCount: Int32, chatPhoto: Api.Photo, notifySettings: Api.PeerNotifySettings, exportedInvite: Api.ExportedChatInvite, botInfo: [Api.BotInfo], migratedFromChatId: Int32?, migratedFromMaxId: Int32?, pinnedMsgId: Int32?)
case channelFull(flags: Int32, id: Int32, about: String, participantsCount: Int32?, adminsCount: Int32?, kickedCount: Int32?, bannedCount: Int32?, readInboxMaxId: Int32, readOutboxMaxId: Int32, unreadCount: Int32, chatPhoto: Api.Photo, notifySettings: Api.PeerNotifySettings, exportedInvite: Api.ExportedChatInvite, botInfo: [Api.BotInfo], migratedFromChatId: Int32?, migratedFromMaxId: Int32?, pinnedMsgId: Int32?, stickerset: Api.StickerSet?)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) -> Swift.Bool {
switch self {
@ -2574,9 +2653,9 @@ public struct Api {
item.serialize(buffer, true)
}
break
case .channelFull(let flags, let id, let about, let participantsCount, let adminsCount, let kickedCount, let bannedCount, let readInboxMaxId, let readOutboxMaxId, let unreadCount, let chatPhoto, let notifySettings, let exportedInvite, let botInfo, let migratedFromChatId, let migratedFromMaxId, let pinnedMsgId):
case .channelFull(let flags, let id, let about, let participantsCount, let adminsCount, let kickedCount, let bannedCount, let readInboxMaxId, let readOutboxMaxId, let unreadCount, let chatPhoto, let notifySettings, let exportedInvite, let botInfo, let migratedFromChatId, let migratedFromMaxId, let pinnedMsgId, let stickerset):
if boxed {
buffer.appendInt32(-1781833897)
buffer.appendInt32(401891279)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt32(id, buffer: buffer, boxed: false)
@ -2599,6 +2678,7 @@ public struct Api {
if Int(flags) & Int(1 << 4) != 0 {serializeInt32(migratedFromChatId!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 4) != 0 {serializeInt32(migratedFromMaxId!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 5) != 0 {serializeInt32(pinnedMsgId!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 8) != 0 {stickerset!.serialize(buffer, true)}
break
}
return true
@ -2683,6 +2763,10 @@ public struct Api {
if Int(_1!) & Int(1 << 4) != 0 {_16 = reader.readInt32() }
var _17: Int32?
if Int(_1!) & Int(1 << 5) != 0 {_17 = reader.readInt32() }
var _18: Api.StickerSet?
if Int(_1!) & Int(1 << 8) != 0 {if let signature = reader.readInt32() {
_18 = Api.parse(reader, signature: signature) as? Api.StickerSet
} }
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
@ -2700,8 +2784,9 @@ public struct Api {
let _c15 = (Int(_1!) & Int(1 << 4) == 0) || _15 != nil
let _c16 = (Int(_1!) & Int(1 << 4) == 0) || _16 != nil
let _c17 = (Int(_1!) & Int(1 << 5) == 0) || _17 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 {
return Api.ChatFull.channelFull(flags: _1!, id: _2!, about: _3!, participantsCount: _4, adminsCount: _5, kickedCount: _6, bannedCount: _7, readInboxMaxId: _8!, readOutboxMaxId: _9!, unreadCount: _10!, chatPhoto: _11!, notifySettings: _12!, exportedInvite: _13!, botInfo: _14!, migratedFromChatId: _15, migratedFromMaxId: _16, pinnedMsgId: _17)
let _c18 = (Int(_1!) & Int(1 << 8) == 0) || _18 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 && _c18 {
return Api.ChatFull.channelFull(flags: _1!, id: _2!, about: _3!, participantsCount: _4, adminsCount: _5, kickedCount: _6, bannedCount: _7, readInboxMaxId: _8!, readOutboxMaxId: _9!, unreadCount: _10!, chatPhoto: _11!, notifySettings: _12!, exportedInvite: _13!, botInfo: _14!, migratedFromChatId: _15, migratedFromMaxId: _16, pinnedMsgId: _17, stickerset: _18)
}
else {
return nil
@ -2713,8 +2798,8 @@ public struct Api {
switch self {
case .chatFull(let id, let participants, let chatPhoto, let notifySettings, let exportedInvite, let botInfo):
return "(chatFull id: \(id), participants: \(participants), chatPhoto: \(chatPhoto), notifySettings: \(notifySettings), exportedInvite: \(exportedInvite), botInfo: \(botInfo))"
case .channelFull(let flags, let id, let about, let participantsCount, let adminsCount, let kickedCount, let bannedCount, let readInboxMaxId, let readOutboxMaxId, let unreadCount, let chatPhoto, let notifySettings, let exportedInvite, let botInfo, let migratedFromChatId, let migratedFromMaxId, let pinnedMsgId):
return "(channelFull flags: \(flags), id: \(id), about: \(about), participantsCount: \(participantsCount), adminsCount: \(adminsCount), kickedCount: \(kickedCount), bannedCount: \(bannedCount), readInboxMaxId: \(readInboxMaxId), readOutboxMaxId: \(readOutboxMaxId), unreadCount: \(unreadCount), chatPhoto: \(chatPhoto), notifySettings: \(notifySettings), exportedInvite: \(exportedInvite), botInfo: \(botInfo), migratedFromChatId: \(migratedFromChatId), migratedFromMaxId: \(migratedFromMaxId), pinnedMsgId: \(pinnedMsgId))"
case .channelFull(let flags, let id, let about, let participantsCount, let adminsCount, let kickedCount, let bannedCount, let readInboxMaxId, let readOutboxMaxId, let unreadCount, let chatPhoto, let notifySettings, let exportedInvite, let botInfo, let migratedFromChatId, let migratedFromMaxId, let pinnedMsgId, let stickerset):
return "(channelFull flags: \(flags), id: \(id), about: \(about), participantsCount: \(participantsCount), adminsCount: \(adminsCount), kickedCount: \(kickedCount), bannedCount: \(bannedCount), readInboxMaxId: \(readInboxMaxId), readOutboxMaxId: \(readOutboxMaxId), unreadCount: \(unreadCount), chatPhoto: \(chatPhoto), notifySettings: \(notifySettings), exportedInvite: \(exportedInvite), botInfo: \(botInfo), migratedFromChatId: \(migratedFromChatId), migratedFromMaxId: \(migratedFromMaxId), pinnedMsgId: \(pinnedMsgId), stickerset: \(stickerset))"
}
}
}
@ -4955,13 +5040,13 @@ public struct Api {
}
public enum Dialog: CustomStringConvertible {
case dialog(flags: Int32, peer: Api.Peer, topMessage: Int32, readInboxMaxId: Int32, readOutboxMaxId: Int32, unreadCount: Int32, notifySettings: Api.PeerNotifySettings, pts: Int32?, draft: Api.DraftMessage?)
case dialog(flags: Int32, peer: Api.Peer, topMessage: Int32, readInboxMaxId: Int32, readOutboxMaxId: Int32, unreadCount: Int32, unreadMentionsCount: Int32, notifySettings: Api.PeerNotifySettings, pts: Int32?, draft: Api.DraftMessage?)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) -> Swift.Bool {
switch self {
case .dialog(let flags, let peer, let topMessage, let readInboxMaxId, let readOutboxMaxId, let unreadCount, let notifySettings, let pts, let draft):
case .dialog(let flags, let peer, let topMessage, let readInboxMaxId, let readOutboxMaxId, let unreadCount, let unreadMentionsCount, let notifySettings, let pts, let draft):
if boxed {
buffer.appendInt32(1728035348)
buffer.appendInt32(-455150117)
}
serializeInt32(flags, buffer: buffer, boxed: false)
peer.serialize(buffer, true)
@ -4969,6 +5054,7 @@ public struct Api {
serializeInt32(readInboxMaxId, buffer: buffer, boxed: false)
serializeInt32(readOutboxMaxId, buffer: buffer, boxed: false)
serializeInt32(unreadCount, buffer: buffer, boxed: false)
serializeInt32(unreadMentionsCount, buffer: buffer, boxed: false)
notifySettings.serialize(buffer, true)
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(pts!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 1) != 0 {draft!.serialize(buffer, true)}
@ -4992,15 +5078,17 @@ public struct Api {
_5 = reader.readInt32()
var _6: Int32?
_6 = reader.readInt32()
var _7: Api.PeerNotifySettings?
var _7: Int32?
_7 = reader.readInt32()
var _8: Api.PeerNotifySettings?
if let signature = reader.readInt32() {
_7 = Api.parse(reader, signature: signature) as? Api.PeerNotifySettings
_8 = Api.parse(reader, signature: signature) as? Api.PeerNotifySettings
}
var _8: Int32?
if Int(_1!) & Int(1 << 0) != 0 {_8 = reader.readInt32() }
var _9: Api.DraftMessage?
var _9: Int32?
if Int(_1!) & Int(1 << 0) != 0 {_9 = reader.readInt32() }
var _10: Api.DraftMessage?
if Int(_1!) & Int(1 << 1) != 0 {if let signature = reader.readInt32() {
_9 = Api.parse(reader, signature: signature) as? Api.DraftMessage
_10 = Api.parse(reader, signature: signature) as? Api.DraftMessage
} }
let _c1 = _1 != nil
let _c2 = _2 != nil
@ -5009,10 +5097,11 @@ public struct Api {
let _c5 = _5 != nil
let _c6 = _6 != nil
let _c7 = _7 != nil
let _c8 = (Int(_1!) & Int(1 << 0) == 0) || _8 != nil
let _c9 = (Int(_1!) & Int(1 << 1) == 0) || _9 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 {
return Api.Dialog.dialog(flags: _1!, peer: _2!, topMessage: _3!, readInboxMaxId: _4!, readOutboxMaxId: _5!, unreadCount: _6!, notifySettings: _7!, pts: _8, draft: _9)
let _c8 = _8 != nil
let _c9 = (Int(_1!) & Int(1 << 0) == 0) || _9 != nil
let _c10 = (Int(_1!) & Int(1 << 1) == 0) || _10 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 {
return Api.Dialog.dialog(flags: _1!, peer: _2!, topMessage: _3!, readInboxMaxId: _4!, readOutboxMaxId: _5!, unreadCount: _6!, unreadMentionsCount: _7!, notifySettings: _8!, pts: _9, draft: _10)
}
else {
return nil
@ -5022,8 +5111,8 @@ public struct Api {
public var description: String {
get {
switch self {
case .dialog(let flags, let peer, let topMessage, let readInboxMaxId, let readOutboxMaxId, let unreadCount, let notifySettings, let pts, let draft):
return "(dialog flags: \(flags), peer: \(peer), topMessage: \(topMessage), readInboxMaxId: \(readInboxMaxId), readOutboxMaxId: \(readOutboxMaxId), unreadCount: \(unreadCount), notifySettings: \(notifySettings), pts: \(pts), draft: \(draft))"
case .dialog(let flags, let peer, let topMessage, let readInboxMaxId, let readOutboxMaxId, let unreadCount, let unreadMentionsCount, let notifySettings, let pts, let draft):
return "(dialog flags: \(flags), peer: \(peer), topMessage: \(topMessage), readInboxMaxId: \(readInboxMaxId), readOutboxMaxId: \(readOutboxMaxId), unreadCount: \(unreadCount), unreadMentionsCount: \(unreadMentionsCount), notifySettings: \(notifySettings), pts: \(pts), draft: \(draft))"
}
}
}
@ -5350,6 +5439,9 @@ public struct Api {
case updatePhoneCall(phoneCall: Api.PhoneCall)
case updateLangPackTooLong
case updateLangPack(difference: Api.LangPackDifference)
case updateFavedStickers
case updateChannelReadMessagesContents(channelId: Int32, messages: [Int32])
case updateContactsReset
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) -> Swift.Bool {
switch self {
@ -5866,6 +5958,29 @@ public struct Api {
buffer.appendInt32(1442983757)
}
difference.serialize(buffer, true)
break
case .updateFavedStickers:
if boxed {
buffer.appendInt32(-451831443)
}
break
case .updateChannelReadMessagesContents(let channelId, let messages):
if boxed {
buffer.appendInt32(-1987495099)
}
serializeInt32(channelId, buffer: buffer, boxed: false)
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(messages.count))
for item in messages {
serializeInt32(item, buffer: buffer, boxed: false)
}
break
case .updateContactsReset:
if boxed {
buffer.appendInt32(1887741886)
}
break
}
return true
@ -6923,6 +7038,28 @@ public struct Api {
return nil
}
}
fileprivate static func parse_updateFavedStickers(_ reader: BufferReader) -> Update? {
return Api.Update.updateFavedStickers
}
fileprivate static func parse_updateChannelReadMessagesContents(_ reader: BufferReader) -> Update? {
var _1: Int32?
_1 = reader.readInt32()
var _2: [Int32]?
if let _ = reader.readInt32() {
_2 = Api.parseVector(reader, elementSignature: -1471112230, elementType: Int32.self)
}
let _c1 = _1 != nil
let _c2 = _2 != nil
if _c1 && _c2 {
return Api.Update.updateChannelReadMessagesContents(channelId: _1!, messages: _2!)
}
else {
return nil
}
}
fileprivate static func parse_updateContactsReset(_ reader: BufferReader) -> Update? {
return Api.Update.updateContactsReset
}
public var description: String {
get {
@ -7051,6 +7188,12 @@ public struct Api {
return "(updateLangPackTooLong)"
case .updateLangPack(let difference):
return "(updateLangPack difference: \(difference))"
case .updateFavedStickers:
return "(updateFavedStickers)"
case .updateChannelReadMessagesContents(let channelId, let messages):
return "(updateChannelReadMessagesContents channelId: \(channelId), messages: \(messages))"
case .updateContactsReset:
return "(updateContactsReset)"
}
}
}
@ -9649,6 +9792,7 @@ public struct Api {
case channelAdminLogEventActionParticipantInvite(participant: Api.ChannelParticipant)
case channelAdminLogEventActionParticipantToggleBan(prevParticipant: Api.ChannelParticipant, newParticipant: Api.ChannelParticipant)
case channelAdminLogEventActionParticipantToggleAdmin(prevParticipant: Api.ChannelParticipant, newParticipant: Api.ChannelParticipant)
case channelAdminLogEventActionChangeStickerSet(prevStickerset: Api.InputStickerSet, newStickerset: Api.InputStickerSet)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) -> Swift.Bool {
switch self {
@ -9743,6 +9887,13 @@ public struct Api {
prevParticipant.serialize(buffer, true)
newParticipant.serialize(buffer, true)
break
case .channelAdminLogEventActionChangeStickerSet(let prevStickerset, let newStickerset):
if boxed {
buffer.appendInt32(-1312568665)
}
prevStickerset.serialize(buffer, true)
newStickerset.serialize(buffer, true)
break
}
return true
}
@ -9932,6 +10083,24 @@ public struct Api {
return nil
}
}
fileprivate static func parse_channelAdminLogEventActionChangeStickerSet(_ reader: BufferReader) -> ChannelAdminLogEventAction? {
var _1: Api.InputStickerSet?
if let signature = reader.readInt32() {
_1 = Api.parse(reader, signature: signature) as? Api.InputStickerSet
}
var _2: Api.InputStickerSet?
if let signature = reader.readInt32() {
_2 = Api.parse(reader, signature: signature) as? Api.InputStickerSet
}
let _c1 = _1 != nil
let _c2 = _2 != nil
if _c1 && _c2 {
return Api.ChannelAdminLogEventAction.channelAdminLogEventActionChangeStickerSet(prevStickerset: _1!, newStickerset: _2!)
}
else {
return nil
}
}
public var description: String {
get {
@ -9964,6 +10133,8 @@ public struct Api {
return "(channelAdminLogEventActionParticipantToggleBan prevParticipant: \(prevParticipant), newParticipant: \(newParticipant))"
case .channelAdminLogEventActionParticipantToggleAdmin(let prevParticipant, let newParticipant):
return "(channelAdminLogEventActionParticipantToggleAdmin prevParticipant: \(prevParticipant), newParticipant: \(newParticipant))"
case .channelAdminLogEventActionChangeStickerSet(let prevStickerset, let newStickerset):
return "(channelAdminLogEventActionChangeStickerSet prevStickerset: \(prevStickerset), newStickerset: \(newStickerset))"
}
}
}
@ -11010,13 +11181,13 @@ public struct Api {
}
public enum Config: CustomStringConvertible {
case config(flags: Int32, date: Int32, expires: Int32, testMode: Api.Bool, thisDc: Int32, dcOptions: [Api.DcOption], chatSizeMax: Int32, megagroupSizeMax: Int32, forwardedCountMax: Int32, onlineUpdatePeriodMs: Int32, offlineBlurTimeoutMs: Int32, offlineIdleTimeoutMs: Int32, onlineCloudTimeoutMs: Int32, notifyCloudDelayMs: Int32, notifyDefaultDelayMs: Int32, chatBigSize: Int32, pushChatPeriodMs: Int32, pushChatLimit: Int32, savedGifsLimit: Int32, editTimeLimit: Int32, ratingEDecay: Int32, stickersRecentLimit: Int32, tmpSessions: Int32?, pinnedDialogsCountMax: Int32, callReceiveTimeoutMs: Int32, callRingTimeoutMs: Int32, callConnectTimeoutMs: Int32, callPacketTimeoutMs: Int32, meUrlPrefix: String, suggestedLangCode: String?, langPackVersion: Int32?, disabledFeatures: [Api.DisabledFeature])
case config(flags: Int32, date: Int32, expires: Int32, testMode: Api.Bool, thisDc: Int32, dcOptions: [Api.DcOption], chatSizeMax: Int32, megagroupSizeMax: Int32, forwardedCountMax: Int32, onlineUpdatePeriodMs: Int32, offlineBlurTimeoutMs: Int32, offlineIdleTimeoutMs: Int32, onlineCloudTimeoutMs: Int32, notifyCloudDelayMs: Int32, notifyDefaultDelayMs: Int32, chatBigSize: Int32, pushChatPeriodMs: Int32, pushChatLimit: Int32, savedGifsLimit: Int32, editTimeLimit: Int32, ratingEDecay: Int32, stickersRecentLimit: Int32, stickersFavedLimit: Int32, tmpSessions: Int32?, pinnedDialogsCountMax: Int32, callReceiveTimeoutMs: Int32, callRingTimeoutMs: Int32, callConnectTimeoutMs: Int32, callPacketTimeoutMs: Int32, meUrlPrefix: String, suggestedLangCode: String?, langPackVersion: Int32?, disabledFeatures: [Api.DisabledFeature])
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) -> Swift.Bool {
switch self {
case .config(let flags, let date, let expires, let testMode, let thisDc, let dcOptions, let chatSizeMax, let megagroupSizeMax, let forwardedCountMax, let onlineUpdatePeriodMs, let offlineBlurTimeoutMs, let offlineIdleTimeoutMs, let onlineCloudTimeoutMs, let notifyCloudDelayMs, let notifyDefaultDelayMs, let chatBigSize, let pushChatPeriodMs, let pushChatLimit, let savedGifsLimit, let editTimeLimit, let ratingEDecay, let stickersRecentLimit, let tmpSessions, let pinnedDialogsCountMax, let callReceiveTimeoutMs, let callRingTimeoutMs, let callConnectTimeoutMs, let callPacketTimeoutMs, let meUrlPrefix, let suggestedLangCode, let langPackVersion, let disabledFeatures):
case .config(let flags, let date, let expires, let testMode, let thisDc, let dcOptions, let chatSizeMax, let megagroupSizeMax, let forwardedCountMax, let onlineUpdatePeriodMs, let offlineBlurTimeoutMs, let offlineIdleTimeoutMs, let onlineCloudTimeoutMs, let notifyCloudDelayMs, let notifyDefaultDelayMs, let chatBigSize, let pushChatPeriodMs, let pushChatLimit, let savedGifsLimit, let editTimeLimit, let ratingEDecay, let stickersRecentLimit, let stickersFavedLimit, let tmpSessions, let pinnedDialogsCountMax, let callReceiveTimeoutMs, let callRingTimeoutMs, let callConnectTimeoutMs, let callPacketTimeoutMs, let meUrlPrefix, let suggestedLangCode, let langPackVersion, let disabledFeatures):
if boxed {
buffer.appendInt32(2146355336)
buffer.appendInt32(-1913424220)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt32(date, buffer: buffer, boxed: false)
@ -11044,6 +11215,7 @@ public struct Api {
serializeInt32(editTimeLimit, buffer: buffer, boxed: false)
serializeInt32(ratingEDecay, buffer: buffer, boxed: false)
serializeInt32(stickersRecentLimit, buffer: buffer, boxed: false)
serializeInt32(stickersFavedLimit, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(tmpSessions!, buffer: buffer, boxed: false)}
serializeInt32(pinnedDialogsCountMax, buffer: buffer, boxed: false)
serializeInt32(callReceiveTimeoutMs, buffer: buffer, boxed: false)
@ -11113,9 +11285,9 @@ public struct Api {
var _22: Int32?
_22 = reader.readInt32()
var _23: Int32?
if Int(_1!) & Int(1 << 0) != 0 {_23 = reader.readInt32() }
_23 = reader.readInt32()
var _24: Int32?
_24 = reader.readInt32()
if Int(_1!) & Int(1 << 0) != 0 {_24 = reader.readInt32() }
var _25: Int32?
_25 = reader.readInt32()
var _26: Int32?
@ -11124,15 +11296,17 @@ public struct Api {
_27 = reader.readInt32()
var _28: Int32?
_28 = reader.readInt32()
var _29: String?
_29 = parseString(reader)
var _29: Int32?
_29 = reader.readInt32()
var _30: String?
if Int(_1!) & Int(1 << 2) != 0 {_30 = parseString(reader) }
var _31: Int32?
if Int(_1!) & Int(1 << 2) != 0 {_31 = reader.readInt32() }
var _32: [Api.DisabledFeature]?
_30 = parseString(reader)
var _31: String?
if Int(_1!) & Int(1 << 2) != 0 {_31 = parseString(reader) }
var _32: Int32?
if Int(_1!) & Int(1 << 2) != 0 {_32 = reader.readInt32() }
var _33: [Api.DisabledFeature]?
if let _ = reader.readInt32() {
_32 = Api.parseVector(reader, elementSignature: 0, elementType: Api.DisabledFeature.self)
_33 = Api.parseVector(reader, elementSignature: 0, elementType: Api.DisabledFeature.self)
}
let _c1 = _1 != nil
let _c2 = _2 != nil
@ -11156,18 +11330,19 @@ public struct Api {
let _c20 = _20 != nil
let _c21 = _21 != nil
let _c22 = _22 != nil
let _c23 = (Int(_1!) & Int(1 << 0) == 0) || _23 != nil
let _c24 = _24 != nil
let _c23 = _23 != nil
let _c24 = (Int(_1!) & Int(1 << 0) == 0) || _24 != nil
let _c25 = _25 != nil
let _c26 = _26 != nil
let _c27 = _27 != nil
let _c28 = _28 != nil
let _c29 = _29 != nil
let _c30 = (Int(_1!) & Int(1 << 2) == 0) || _30 != nil
let _c30 = _30 != nil
let _c31 = (Int(_1!) & Int(1 << 2) == 0) || _31 != nil
let _c32 = _32 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 && _c18 && _c19 && _c20 && _c21 && _c22 && _c23 && _c24 && _c25 && _c26 && _c27 && _c28 && _c29 && _c30 && _c31 && _c32 {
return Api.Config.config(flags: _1!, date: _2!, expires: _3!, testMode: _4!, thisDc: _5!, dcOptions: _6!, chatSizeMax: _7!, megagroupSizeMax: _8!, forwardedCountMax: _9!, onlineUpdatePeriodMs: _10!, offlineBlurTimeoutMs: _11!, offlineIdleTimeoutMs: _12!, onlineCloudTimeoutMs: _13!, notifyCloudDelayMs: _14!, notifyDefaultDelayMs: _15!, chatBigSize: _16!, pushChatPeriodMs: _17!, pushChatLimit: _18!, savedGifsLimit: _19!, editTimeLimit: _20!, ratingEDecay: _21!, stickersRecentLimit: _22!, tmpSessions: _23, pinnedDialogsCountMax: _24!, callReceiveTimeoutMs: _25!, callRingTimeoutMs: _26!, callConnectTimeoutMs: _27!, callPacketTimeoutMs: _28!, meUrlPrefix: _29!, suggestedLangCode: _30, langPackVersion: _31, disabledFeatures: _32!)
let _c32 = (Int(_1!) & Int(1 << 2) == 0) || _32 != nil
let _c33 = _33 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 && _c18 && _c19 && _c20 && _c21 && _c22 && _c23 && _c24 && _c25 && _c26 && _c27 && _c28 && _c29 && _c30 && _c31 && _c32 && _c33 {
return Api.Config.config(flags: _1!, date: _2!, expires: _3!, testMode: _4!, thisDc: _5!, dcOptions: _6!, chatSizeMax: _7!, megagroupSizeMax: _8!, forwardedCountMax: _9!, onlineUpdatePeriodMs: _10!, offlineBlurTimeoutMs: _11!, offlineIdleTimeoutMs: _12!, onlineCloudTimeoutMs: _13!, notifyCloudDelayMs: _14!, notifyDefaultDelayMs: _15!, chatBigSize: _16!, pushChatPeriodMs: _17!, pushChatLimit: _18!, savedGifsLimit: _19!, editTimeLimit: _20!, ratingEDecay: _21!, stickersRecentLimit: _22!, stickersFavedLimit: _23!, tmpSessions: _24, pinnedDialogsCountMax: _25!, callReceiveTimeoutMs: _26!, callRingTimeoutMs: _27!, callConnectTimeoutMs: _28!, callPacketTimeoutMs: _29!, meUrlPrefix: _30!, suggestedLangCode: _31, langPackVersion: _32, disabledFeatures: _33!)
}
else {
return nil
@ -11177,8 +11352,8 @@ public struct Api {
public var description: String {
get {
switch self {
case .config(let flags, let date, let expires, let testMode, let thisDc, let dcOptions, let chatSizeMax, let megagroupSizeMax, let forwardedCountMax, let onlineUpdatePeriodMs, let offlineBlurTimeoutMs, let offlineIdleTimeoutMs, let onlineCloudTimeoutMs, let notifyCloudDelayMs, let notifyDefaultDelayMs, let chatBigSize, let pushChatPeriodMs, let pushChatLimit, let savedGifsLimit, let editTimeLimit, let ratingEDecay, let stickersRecentLimit, let tmpSessions, let pinnedDialogsCountMax, let callReceiveTimeoutMs, let callRingTimeoutMs, let callConnectTimeoutMs, let callPacketTimeoutMs, let meUrlPrefix, let suggestedLangCode, let langPackVersion, let disabledFeatures):
return "(config flags: \(flags), date: \(date), expires: \(expires), testMode: \(testMode), thisDc: \(thisDc), dcOptions: \(dcOptions), chatSizeMax: \(chatSizeMax), megagroupSizeMax: \(megagroupSizeMax), forwardedCountMax: \(forwardedCountMax), onlineUpdatePeriodMs: \(onlineUpdatePeriodMs), offlineBlurTimeoutMs: \(offlineBlurTimeoutMs), offlineIdleTimeoutMs: \(offlineIdleTimeoutMs), onlineCloudTimeoutMs: \(onlineCloudTimeoutMs), notifyCloudDelayMs: \(notifyCloudDelayMs), notifyDefaultDelayMs: \(notifyDefaultDelayMs), chatBigSize: \(chatBigSize), pushChatPeriodMs: \(pushChatPeriodMs), pushChatLimit: \(pushChatLimit), savedGifsLimit: \(savedGifsLimit), editTimeLimit: \(editTimeLimit), ratingEDecay: \(ratingEDecay), stickersRecentLimit: \(stickersRecentLimit), tmpSessions: \(tmpSessions), pinnedDialogsCountMax: \(pinnedDialogsCountMax), callReceiveTimeoutMs: \(callReceiveTimeoutMs), callRingTimeoutMs: \(callRingTimeoutMs), callConnectTimeoutMs: \(callConnectTimeoutMs), callPacketTimeoutMs: \(callPacketTimeoutMs), meUrlPrefix: \(meUrlPrefix), suggestedLangCode: \(suggestedLangCode), langPackVersion: \(langPackVersion), disabledFeatures: \(disabledFeatures))"
case .config(let flags, let date, let expires, let testMode, let thisDc, let dcOptions, let chatSizeMax, let megagroupSizeMax, let forwardedCountMax, let onlineUpdatePeriodMs, let offlineBlurTimeoutMs, let offlineIdleTimeoutMs, let onlineCloudTimeoutMs, let notifyCloudDelayMs, let notifyDefaultDelayMs, let chatBigSize, let pushChatPeriodMs, let pushChatLimit, let savedGifsLimit, let editTimeLimit, let ratingEDecay, let stickersRecentLimit, let stickersFavedLimit, let tmpSessions, let pinnedDialogsCountMax, let callReceiveTimeoutMs, let callRingTimeoutMs, let callConnectTimeoutMs, let callPacketTimeoutMs, let meUrlPrefix, let suggestedLangCode, let langPackVersion, let disabledFeatures):
return "(config flags: \(flags), date: \(date), expires: \(expires), testMode: \(testMode), thisDc: \(thisDc), dcOptions: \(dcOptions), chatSizeMax: \(chatSizeMax), megagroupSizeMax: \(megagroupSizeMax), forwardedCountMax: \(forwardedCountMax), onlineUpdatePeriodMs: \(onlineUpdatePeriodMs), offlineBlurTimeoutMs: \(offlineBlurTimeoutMs), offlineIdleTimeoutMs: \(offlineIdleTimeoutMs), onlineCloudTimeoutMs: \(onlineCloudTimeoutMs), notifyCloudDelayMs: \(notifyCloudDelayMs), notifyDefaultDelayMs: \(notifyDefaultDelayMs), chatBigSize: \(chatBigSize), pushChatPeriodMs: \(pushChatPeriodMs), pushChatLimit: \(pushChatLimit), savedGifsLimit: \(savedGifsLimit), editTimeLimit: \(editTimeLimit), ratingEDecay: \(ratingEDecay), stickersRecentLimit: \(stickersRecentLimit), stickersFavedLimit: \(stickersFavedLimit), tmpSessions: \(tmpSessions), pinnedDialogsCountMax: \(pinnedDialogsCountMax), callReceiveTimeoutMs: \(callReceiveTimeoutMs), callRingTimeoutMs: \(callRingTimeoutMs), callConnectTimeoutMs: \(callConnectTimeoutMs), callPacketTimeoutMs: \(callPacketTimeoutMs), meUrlPrefix: \(meUrlPrefix), suggestedLangCode: \(suggestedLangCode), langPackVersion: \(langPackVersion), disabledFeatures: \(disabledFeatures))"
}
}
}
@ -14321,6 +14496,8 @@ public struct Api {
case inputMessagesFilterPhoneCalls(flags: Int32)
case inputMessagesFilterRoundVoice
case inputMessagesFilterRoundVideo
case inputMessagesFilterMyMentions
case inputMessagesFilterMyMentionsUnread
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) -> Swift.Bool {
switch self {
@ -14407,6 +14584,18 @@ public struct Api {
buffer.appendInt32(-1253451181)
}
break
case .inputMessagesFilterMyMentions:
if boxed {
buffer.appendInt32(-1040652646)
}
break
case .inputMessagesFilterMyMentionsUnread:
if boxed {
buffer.appendInt32(1187706024)
}
break
}
return true
@ -14462,6 +14651,12 @@ public struct Api {
fileprivate static func parse_inputMessagesFilterRoundVideo(_ reader: BufferReader) -> MessagesFilter? {
return Api.MessagesFilter.inputMessagesFilterRoundVideo
}
fileprivate static func parse_inputMessagesFilterMyMentions(_ reader: BufferReader) -> MessagesFilter? {
return Api.MessagesFilter.inputMessagesFilterMyMentions
}
fileprivate static func parse_inputMessagesFilterMyMentionsUnread(_ reader: BufferReader) -> MessagesFilter? {
return Api.MessagesFilter.inputMessagesFilterMyMentionsUnread
}
public var description: String {
get {
@ -14494,6 +14689,10 @@ public struct Api {
return "(inputMessagesFilterRoundVoice)"
case .inputMessagesFilterRoundVideo:
return "(inputMessagesFilterRoundVideo)"
case .inputMessagesFilterMyMentions:
return "(inputMessagesFilterMyMentions)"
case .inputMessagesFilterMyMentionsUnread:
return "(inputMessagesFilterMyMentionsUnread)"
}
}
}
@ -18183,7 +18382,7 @@ public struct Api {
public enum Contacts: CustomStringConvertible {
case contactsNotModified
case contacts(contacts: [Api.Contact], users: [Api.User])
case contacts(contacts: [Api.Contact], savedCount: Int32, users: [Api.User])
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) -> Swift.Bool {
switch self {
@ -18193,15 +18392,16 @@ public struct Api {
}
break
case .contacts(let contacts, let users):
case .contacts(let contacts, let savedCount, let users):
if boxed {
buffer.appendInt32(1871416498)
buffer.appendInt32(-353862078)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(contacts.count))
for item in contacts {
item.serialize(buffer, true)
}
serializeInt32(savedCount, buffer: buffer, boxed: false)
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(users.count))
for item in users {
@ -18220,14 +18420,17 @@ public struct Api {
if let _ = reader.readInt32() {
_1 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Contact.self)
}
var _2: [Api.User]?
var _2: Int32?
_2 = reader.readInt32()
var _3: [Api.User]?
if let _ = reader.readInt32() {
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
}
let _c1 = _1 != nil
let _c2 = _2 != nil
if _c1 && _c2 {
return Api.contacts.Contacts.contacts(contacts: _1!, users: _2!)
let _c3 = _3 != nil
if _c1 && _c2 && _c3 {
return Api.contacts.Contacts.contacts(contacts: _1!, savedCount: _2!, users: _3!)
}
else {
return nil
@ -18239,8 +18442,8 @@ public struct Api {
switch self {
case .contactsNotModified:
return "(contacts.contactsNotModified)"
case .contacts(let contacts, let users):
return "(contacts.contacts contacts: \(contacts), users: \(users))"
case .contacts(let contacts, let savedCount, let users):
return "(contacts.contacts contacts: \(contacts), savedCount: \(savedCount), users: \(users))"
}
}
}
@ -19011,7 +19214,7 @@ public struct Api {
public enum ChannelDifference: CustomStringConvertible {
case channelDifferenceEmpty(flags: Int32, pts: Int32, timeout: Int32?)
case channelDifferenceTooLong(flags: Int32, pts: Int32, timeout: Int32?, topMessage: Int32, readInboxMaxId: Int32, readOutboxMaxId: Int32, unreadCount: Int32, messages: [Api.Message], chats: [Api.Chat], users: [Api.User])
case channelDifferenceTooLong(flags: Int32, pts: Int32, timeout: Int32?, topMessage: Int32, readInboxMaxId: Int32, readOutboxMaxId: Int32, unreadCount: Int32, unreadMentionsCount: Int32, messages: [Api.Message], chats: [Api.Chat], users: [Api.User])
case channelDifference(flags: Int32, pts: Int32, timeout: Int32?, newMessages: [Api.Message], otherUpdates: [Api.Update], chats: [Api.Chat], users: [Api.User])
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) -> Swift.Bool {
@ -19024,9 +19227,9 @@ public struct Api {
serializeInt32(pts, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 1) != 0 {serializeInt32(timeout!, buffer: buffer, boxed: false)}
break
case .channelDifferenceTooLong(let flags, let pts, let timeout, let topMessage, let readInboxMaxId, let readOutboxMaxId, let unreadCount, let messages, let chats, let users):
case .channelDifferenceTooLong(let flags, let pts, let timeout, let topMessage, let readInboxMaxId, let readOutboxMaxId, let unreadCount, let unreadMentionsCount, let messages, let chats, let users):
if boxed {
buffer.appendInt32(1091431943)
buffer.appendInt32(1788705589)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt32(pts, buffer: buffer, boxed: false)
@ -19035,6 +19238,7 @@ public struct Api {
serializeInt32(readInboxMaxId, buffer: buffer, boxed: false)
serializeInt32(readOutboxMaxId, buffer: buffer, boxed: false)
serializeInt32(unreadCount, buffer: buffer, boxed: false)
serializeInt32(unreadMentionsCount, buffer: buffer, boxed: false)
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(messages.count))
for item in messages {
@ -19115,17 +19319,19 @@ public struct Api {
_6 = reader.readInt32()
var _7: Int32?
_7 = reader.readInt32()
var _8: [Api.Message]?
var _8: Int32?
_8 = reader.readInt32()
var _9: [Api.Message]?
if let _ = reader.readInt32() {
_8 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Message.self)
_9 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Message.self)
}
var _9: [Api.Chat]?
var _10: [Api.Chat]?
if let _ = reader.readInt32() {
_9 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
_10 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
}
var _10: [Api.User]?
var _11: [Api.User]?
if let _ = reader.readInt32() {
_10 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
_11 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
}
let _c1 = _1 != nil
let _c2 = _2 != nil
@ -19137,8 +19343,9 @@ public struct Api {
let _c8 = _8 != nil
let _c9 = _9 != nil
let _c10 = _10 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 {
return Api.updates.ChannelDifference.channelDifferenceTooLong(flags: _1!, pts: _2!, timeout: _3, topMessage: _4!, readInboxMaxId: _5!, readOutboxMaxId: _6!, unreadCount: _7!, messages: _8!, chats: _9!, users: _10!)
let _c11 = _11 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 {
return Api.updates.ChannelDifference.channelDifferenceTooLong(flags: _1!, pts: _2!, timeout: _3, topMessage: _4!, readInboxMaxId: _5!, readOutboxMaxId: _6!, unreadCount: _7!, unreadMentionsCount: _8!, messages: _9!, chats: _10!, users: _11!)
}
else {
return nil
@ -19187,8 +19394,8 @@ public struct Api {
switch self {
case .channelDifferenceEmpty(let flags, let pts, let timeout):
return "(updates.channelDifferenceEmpty flags: \(flags), pts: \(pts), timeout: \(timeout))"
case .channelDifferenceTooLong(let flags, let pts, let timeout, let topMessage, let readInboxMaxId, let readOutboxMaxId, let unreadCount, let messages, let chats, let users):
return "(updates.channelDifferenceTooLong flags: \(flags), pts: \(pts), timeout: \(timeout), topMessage: \(topMessage), readInboxMaxId: \(readInboxMaxId), readOutboxMaxId: \(readOutboxMaxId), unreadCount: \(unreadCount), messages: \(messages), chats: \(chats), users: \(users))"
case .channelDifferenceTooLong(let flags, let pts, let timeout, let topMessage, let readInboxMaxId, let readOutboxMaxId, let unreadCount, let unreadMentionsCount, let messages, let chats, let users):
return "(updates.channelDifferenceTooLong flags: \(flags), pts: \(pts), timeout: \(timeout), topMessage: \(topMessage), readInboxMaxId: \(readInboxMaxId), readOutboxMaxId: \(readOutboxMaxId), unreadCount: \(unreadCount), unreadMentionsCount: \(unreadMentionsCount), messages: \(messages), chats: \(chats), users: \(users))"
case .channelDifference(let flags, let pts, let timeout, let newMessages, let otherUpdates, let chats, let users):
return "(updates.channelDifference flags: \(flags), pts: \(pts), timeout: \(timeout), newMessages: \(newMessages), otherUpdates: \(otherUpdates), chats: \(chats), users: \(users))"
}
@ -21427,29 +21634,6 @@ public struct Api {
})
}
public static func search(flags: Int32, peer: Api.InputPeer, q: String, fromId: Api.InputUser?, filter: Api.MessagesFilter, minDate: Int32, maxDate: Int32, offset: Int32, maxId: Int32, limit: Int32) -> (CustomStringConvertible, Buffer, (Buffer) -> Api.messages.Messages?) {
let buffer = Buffer()
buffer.appendInt32(-225926539)
serializeInt32(flags, buffer: buffer, boxed: false)
peer.serialize(buffer, true)
serializeString(q, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 0) != 0 {fromId!.serialize(buffer, true)}
filter.serialize(buffer, true)
serializeInt32(minDate, buffer: buffer, boxed: false)
serializeInt32(maxDate, buffer: buffer, boxed: false)
serializeInt32(offset, buffer: buffer, boxed: false)
serializeInt32(maxId, buffer: buffer, boxed: false)
serializeInt32(limit, buffer: buffer, boxed: false)
return (FunctionDescription({return "(messages.search flags: \(flags), peer: \(peer), q: \(q), fromId: \(fromId), filter: \(filter), minDate: \(minDate), maxDate: \(maxDate), offset: \(offset), maxId: \(maxId), limit: \(limit))"}), buffer, { (buffer: Buffer) -> Api.messages.Messages? in
let reader = BufferReader(buffer)
var result: Api.messages.Messages?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.messages.Messages
}
return result
})
}
public static func sendScreenshotNotification(peer: Api.InputPeer, replyToMsgId: Int32, randomId: Int64) -> (CustomStringConvertible, Buffer, (Buffer) -> Api.Updates?) {
let buffer = Buffer()
buffer.appendInt32(-914493408)
@ -21465,6 +21649,79 @@ public struct Api {
return result
})
}
public static func getFavedStickers(hash: Int32) -> (CustomStringConvertible, Buffer, (Buffer) -> Api.messages.FavedStickers?) {
let buffer = Buffer()
buffer.appendInt32(567151374)
serializeInt32(hash, buffer: buffer, boxed: false)
return (FunctionDescription({return "(messages.getFavedStickers hash: \(hash))"}), buffer, { (buffer: Buffer) -> Api.messages.FavedStickers? in
let reader = BufferReader(buffer)
var result: Api.messages.FavedStickers?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.messages.FavedStickers
}
return result
})
}
public static func faveSticker(id: Api.InputDocument, unfave: Api.Bool) -> (CustomStringConvertible, Buffer, (Buffer) -> Api.Bool?) {
let buffer = Buffer()
buffer.appendInt32(-1174420133)
id.serialize(buffer, true)
unfave.serialize(buffer, true)
return (FunctionDescription({return "(messages.faveSticker id: \(id), unfave: \(unfave))"}), buffer, { (buffer: Buffer) -> Api.Bool? in
let reader = BufferReader(buffer)
var result: Api.Bool?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.Bool
}
return result
})
}
public static func search(flags: Int32, peer: Api.InputPeer, q: String, fromId: Api.InputUser?, filter: Api.MessagesFilter, minDate: Int32, maxDate: Int32, offsetId: Int32, addOffset: Int32, limit: Int32, maxId: Int32, minId: Int32) -> (CustomStringConvertible, Buffer, (Buffer) -> Api.messages.Messages?) {
let buffer = Buffer()
buffer.appendInt32(60726944)
serializeInt32(flags, buffer: buffer, boxed: false)
peer.serialize(buffer, true)
serializeString(q, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 0) != 0 {fromId!.serialize(buffer, true)}
filter.serialize(buffer, true)
serializeInt32(minDate, buffer: buffer, boxed: false)
serializeInt32(maxDate, buffer: buffer, boxed: false)
serializeInt32(offsetId, buffer: buffer, boxed: false)
serializeInt32(addOffset, buffer: buffer, boxed: false)
serializeInt32(limit, buffer: buffer, boxed: false)
serializeInt32(maxId, buffer: buffer, boxed: false)
serializeInt32(minId, buffer: buffer, boxed: false)
return (FunctionDescription({return "(messages.search flags: \(flags), peer: \(peer), q: \(q), fromId: \(fromId), filter: \(filter), minDate: \(minDate), maxDate: \(maxDate), offsetId: \(offsetId), addOffset: \(addOffset), limit: \(limit), maxId: \(maxId), minId: \(minId))"}), buffer, { (buffer: Buffer) -> Api.messages.Messages? in
let reader = BufferReader(buffer)
var result: Api.messages.Messages?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.messages.Messages
}
return result
})
}
public static func getUnreadMentions(peer: Api.InputPeer, offsetId: Int32, addOffset: Int32, limit: Int32, maxId: Int32, minId: Int32) -> (CustomStringConvertible, Buffer, (Buffer) -> Api.messages.Messages?) {
let buffer = Buffer()
buffer.appendInt32(1180140658)
peer.serialize(buffer, true)
serializeInt32(offsetId, buffer: buffer, boxed: false)
serializeInt32(addOffset, buffer: buffer, boxed: false)
serializeInt32(limit, buffer: buffer, boxed: false)
serializeInt32(maxId, buffer: buffer, boxed: false)
serializeInt32(minId, buffer: buffer, boxed: false)
return (FunctionDescription({return "(messages.getUnreadMentions peer: \(peer), offsetId: \(offsetId), addOffset: \(addOffset), limit: \(limit), maxId: \(maxId), minId: \(minId))"}), buffer, { (buffer: Buffer) -> Api.messages.Messages? in
let reader = BufferReader(buffer)
var result: Api.messages.Messages?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.messages.Messages
}
return result
})
}
}
public struct channels {
public static func readHistory(channel: Api.InputChannel, maxId: Int32) -> (CustomStringConvertible, Buffer, (Buffer) -> Api.Bool?) {
@ -21932,6 +22189,40 @@ public struct Api {
return result
})
}
public static func setStickers(channel: Api.InputChannel, stickerset: Api.InputStickerSet) -> (CustomStringConvertible, Buffer, (Buffer) -> Api.Bool?) {
let buffer = Buffer()
buffer.appendInt32(-359881479)
channel.serialize(buffer, true)
stickerset.serialize(buffer, true)
return (FunctionDescription({return "(channels.setStickers channel: \(channel), stickerset: \(stickerset))"}), buffer, { (buffer: Buffer) -> Api.Bool? in
let reader = BufferReader(buffer)
var result: Api.Bool?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.Bool
}
return result
})
}
public static func readMessageContents(channel: Api.InputChannel, id: [Int32]) -> (CustomStringConvertible, Buffer, (Buffer) -> Api.Bool?) {
let buffer = Buffer()
buffer.appendInt32(-357180360)
channel.serialize(buffer, true)
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(id.count))
for item in id {
serializeInt32(item, buffer: buffer, boxed: false)
}
return (FunctionDescription({return "(channels.readMessageContents channel: \(channel), id: \(id))"}), buffer, { (buffer: Buffer) -> Api.Bool? in
let reader = BufferReader(buffer)
var result: Api.Bool?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.Bool
}
return result
})
}
}
public struct payments {
public static func getPaymentForm(msgId: Int32) -> (CustomStringConvertible, Buffer, (Buffer) -> Api.payments.PaymentForm?) {
@ -22370,39 +22661,6 @@ public struct Api {
})
}
public static func getContacts(hash: String) -> (CustomStringConvertible, Buffer, (Buffer) -> Api.contacts.Contacts?) {
let buffer = Buffer()
buffer.appendInt32(583445000)
serializeString(hash, buffer: buffer, boxed: false)
return (FunctionDescription({return "(contacts.getContacts hash: \(hash))"}), buffer, { (buffer: Buffer) -> Api.contacts.Contacts? in
let reader = BufferReader(buffer)
var result: Api.contacts.Contacts?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.contacts.Contacts
}
return result
})
}
public static func importContacts(contacts: [Api.InputContact], replace: Api.Bool) -> (CustomStringConvertible, Buffer, (Buffer) -> Api.contacts.ImportedContacts?) {
let buffer = Buffer()
buffer.appendInt32(-634342611)
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(contacts.count))
for item in contacts {
item.serialize(buffer, true)
}
replace.serialize(buffer, true)
return (FunctionDescription({return "(contacts.importContacts contacts: \(contacts), replace: \(replace))"}), buffer, { (buffer: Buffer) -> Api.contacts.ImportedContacts? in
let reader = BufferReader(buffer)
var result: Api.contacts.ImportedContacts?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.contacts.ImportedContacts
}
return result
})
}
public static func deleteContact(id: Api.InputUser) -> (CustomStringConvertible, Buffer, (Buffer) -> Api.contacts.Link?) {
let buffer = Buffer()
buffer.appendInt32(-1902823612)
@ -22570,6 +22828,52 @@ public struct Api {
return result
})
}
public static func importContacts(contacts: [Api.InputContact]) -> (CustomStringConvertible, Buffer, (Buffer) -> Api.contacts.ImportedContacts?) {
let buffer = Buffer()
buffer.appendInt32(746589157)
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(contacts.count))
for item in contacts {
item.serialize(buffer, true)
}
return (FunctionDescription({return "(contacts.importContacts contacts: \(contacts))"}), buffer, { (buffer: Buffer) -> Api.contacts.ImportedContacts? in
let reader = BufferReader(buffer)
var result: Api.contacts.ImportedContacts?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.contacts.ImportedContacts
}
return result
})
}
public static func resetSaved() -> (CustomStringConvertible, Buffer, (Buffer) -> Api.Bool?) {
let buffer = Buffer()
buffer.appendInt32(-2020263951)
return (FunctionDescription({return "(contacts.resetSaved )"}), buffer, { (buffer: Buffer) -> Api.Bool? in
let reader = BufferReader(buffer)
var result: Api.Bool?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.Bool
}
return result
})
}
public static func getContacts(hash: Int32) -> (CustomStringConvertible, Buffer, (Buffer) -> Api.contacts.Contacts?) {
let buffer = Buffer()
buffer.appendInt32(-1071414113)
serializeInt32(hash, buffer: buffer, boxed: false)
return (FunctionDescription({return "(contacts.getContacts hash: \(hash))"}), buffer, { (buffer: Buffer) -> Api.contacts.Contacts? in
let reader = BufferReader(buffer)
var result: Api.contacts.Contacts?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.contacts.Contacts
}
return result
})
}
}
public struct help {
public static func getConfig() -> (CustomStringConvertible, Buffer, (Buffer) -> Api.Config?) {

View File

@ -109,6 +109,7 @@ public final class CachedChannelData: CachedPeerData {
public let topParticipants: CachedChannelParticipants?
public let reportStatus: PeerReportStatus
public let pinnedMessageId: MessageId?
public let stickerPack: StickerPackCollectionInfo?
public let peerIds: Set<PeerId>
@ -122,9 +123,10 @@ public final class CachedChannelData: CachedPeerData {
self.reportStatus = .unknown
self.pinnedMessageId = nil
self.peerIds = Set()
self.stickerPack = nil
}
init(flags: CachedChannelFlags, about: String?, participantsSummary: CachedChannelParticipantsSummary, exportedInvitation: ExportedInvitation?, botInfos: [CachedPeerBotInfo], topParticipants: CachedChannelParticipants?, reportStatus: PeerReportStatus, pinnedMessageId: MessageId?) {
init(flags: CachedChannelFlags, about: String?, participantsSummary: CachedChannelParticipantsSummary, exportedInvitation: ExportedInvitation?, botInfos: [CachedPeerBotInfo], topParticipants: CachedChannelParticipants?, reportStatus: PeerReportStatus, pinnedMessageId: MessageId?, stickerPack: StickerPackCollectionInfo?) {
self.flags = flags
self.about = about
self.participantsSummary = participantsSummary
@ -133,6 +135,7 @@ public final class CachedChannelData: CachedPeerData {
self.topParticipants = topParticipants
self.reportStatus = reportStatus
self.pinnedMessageId = pinnedMessageId
self.stickerPack = stickerPack
var peerIds = Set<PeerId>()
if let topParticipants = topParticipants {
@ -147,35 +150,39 @@ public final class CachedChannelData: CachedPeerData {
}
func withUpdatedFlags(_ flags: CachedChannelFlags) -> CachedChannelData {
return CachedChannelData(flags: flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, topParticipants: self.topParticipants, reportStatus: self.reportStatus, pinnedMessageId: self.pinnedMessageId)
return CachedChannelData(flags: flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, topParticipants: self.topParticipants, reportStatus: self.reportStatus, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack)
}
func withUpdatedAbout(_ about: String?) -> CachedChannelData {
return CachedChannelData(flags: self.flags, about: about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, topParticipants: self.topParticipants, reportStatus: self.reportStatus, pinnedMessageId: self.pinnedMessageId)
return CachedChannelData(flags: self.flags, about: about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, topParticipants: self.topParticipants, reportStatus: self.reportStatus, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack)
}
func withUpdatedParticipantsSummary(_ participantsSummary: CachedChannelParticipantsSummary) -> CachedChannelData {
return CachedChannelData(flags: self.flags, about: self.about, participantsSummary: participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, topParticipants: self.topParticipants, reportStatus: self.reportStatus, pinnedMessageId: self.pinnedMessageId)
return CachedChannelData(flags: self.flags, about: self.about, participantsSummary: participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, topParticipants: self.topParticipants, reportStatus: self.reportStatus, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack)
}
func withUpdatedExportedInvitation(_ exportedInvitation: ExportedInvitation?) -> CachedChannelData {
return CachedChannelData(flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: exportedInvitation, botInfos: self.botInfos, topParticipants: self.topParticipants, reportStatus: self.reportStatus, pinnedMessageId: self.pinnedMessageId)
return CachedChannelData(flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: exportedInvitation, botInfos: self.botInfos, topParticipants: self.topParticipants, reportStatus: self.reportStatus, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack)
}
func withUpdatedBotInfos(_ botInfos: [CachedPeerBotInfo]) -> CachedChannelData {
return CachedChannelData(flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: botInfos, topParticipants: self.topParticipants, reportStatus: self.reportStatus, pinnedMessageId: self.pinnedMessageId)
return CachedChannelData(flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: botInfos, topParticipants: self.topParticipants, reportStatus: self.reportStatus, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack)
}
func withUpdatedTopParticipants(_ topParticipants: CachedChannelParticipants?) -> CachedChannelData {
return CachedChannelData(flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, topParticipants: topParticipants, reportStatus: self.reportStatus, pinnedMessageId: self.pinnedMessageId)
return CachedChannelData(flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, topParticipants: topParticipants, reportStatus: self.reportStatus, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack)
}
func withUpdatedReportStatus(_ reportStatus: PeerReportStatus) -> CachedChannelData {
return CachedChannelData(flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, topParticipants: self.topParticipants, reportStatus: reportStatus, pinnedMessageId: self.pinnedMessageId)
return CachedChannelData(flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, topParticipants: self.topParticipants, reportStatus: reportStatus, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack)
}
func withUpdatedPinnedMessageId(_ pinnedMessageId: MessageId?) -> CachedChannelData {
return CachedChannelData(flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, topParticipants: self.topParticipants, reportStatus: self.reportStatus, pinnedMessageId: pinnedMessageId)
return CachedChannelData(flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, topParticipants: self.topParticipants, reportStatus: self.reportStatus, pinnedMessageId: pinnedMessageId, stickerPack: self.stickerPack)
}
func withUpdatedStickerPack(_ stickerPack: StickerPackCollectionInfo?) -> CachedChannelData {
return CachedChannelData(flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, topParticipants: self.topParticipants, reportStatus: self.reportStatus, pinnedMessageId: self.pinnedMessageId, stickerPack: stickerPack)
}
public init(decoder: Decoder) {
@ -193,6 +200,12 @@ public final class CachedChannelData: CachedPeerData {
self.pinnedMessageId = nil
}
if let stickerPack = decoder.decodeObjectForKey("sp", decoder: { StickerPackCollectionInfo(decoder: $0) }) as? StickerPackCollectionInfo {
self.stickerPack = stickerPack
} else {
self.stickerPack = nil
}
if let topParticipants = self.topParticipants {
for participant in topParticipants.participants {
peerIds.insert(participant.peerId)
@ -234,6 +247,11 @@ public final class CachedChannelData: CachedPeerData {
encoder.encodeNil(forKey: "pm.n")
encoder.encodeNil(forKey: "pm.i")
}
if let stickerPack = self.stickerPack {
encoder.encodeObject(stickerPack, forKey: "sp")
} else {
encoder.encodeNil(forKey: "sp")
}
}
public func isEqual(to: CachedPeerData) -> Bool {
@ -273,6 +291,10 @@ public final class CachedChannelData: CachedPeerData {
return false
}
if other.stickerPack != self.stickerPack {
return false
}
return true
}
}

View File

@ -38,6 +38,7 @@ public enum AdminLogEventAction {
case participantInvite(RenderedChannelParticipant)
case participantToggleBan(prev: RenderedChannelParticipant, new: RenderedChannelParticipant)
case participantToggleAdmin(prev: RenderedChannelParticipant, new: RenderedChannelParticipant)
case changeStickerPack(prev: StickerPackReference?, new: StickerPackReference?)
}
public enum ChannelAdminLogEventError {
@ -175,6 +176,8 @@ public func channelAdminLogEvents(_ account:Account, peerId:PeerId, maxId:AdminL
if let prevPeer = peers[prevParticipant.peerId], let newPeer = peers[newParticipant.peerId] {
action = .participantToggleAdmin(prev: RenderedChannelParticipant(participant: prevParticipant, peer: prevPeer), new: RenderedChannelParticipant(participant: newParticipant, peer: newPeer))
}
case let .channelAdminLogEventActionChangeStickerSet(prevStickerset, newStickerset):
action = .changeStickerPack(prev: StickerPackReference(apiInputSet: prevStickerset), new: StickerPackReference(apiInputSet: newStickerset))
}
let peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: userId)
if let action = action {

View File

@ -45,9 +45,9 @@ public struct CloudFileMediaResourceId: MediaResourceId {
public class CloudFileMediaResource: TelegramCloudMediaResource, TelegramMultipartFetchableResource {
public let datacenterId: Int
let volumeId: Int64
let localId: Int32
let secret: Int64
public let volumeId: Int64
public let localId: Int32
public let secret: Int64
public let size: Int?
public var id: MediaResourceId {
@ -130,7 +130,7 @@ public struct CloudDocumentMediaResourceId: MediaResourceId {
public class CloudDocumentMediaResource: TelegramCloudMediaResource, TelegramMultipartFetchableResource {
public let datacenterId: Int
let fileId: Int64
let accessHash: Int64
public let accessHash: Int64
public let size: Int?
public var id: MediaResourceId {

View File

@ -0,0 +1,26 @@
import Foundation
#if os(macOS)
import PostboxMac
#else
import Postbox
#endif
public class ConsumablePersonalMentionMessageAttribute: MessageAttribute {
public let consumed: Bool
public let pending: Bool
public init(consumed: Bool, pending: Bool) {
self.consumed = consumed
self.pending = pending
}
required public init(decoder: Decoder) {
self.consumed = decoder.decodeInt32ForKey("c", orElse: 0) != 0
self.pending = decoder.decodeInt32ForKey("p", orElse: 0) != 0
}
public func encode(_ encoder: Encoder) {
encoder.encodeInt32(self.consumed ? 1 : 0, forKey: "c")
encoder.encodeInt32(self.pending ? 1 : 0, forKey: "p")
}
}

View File

@ -0,0 +1,27 @@
import Foundation
#if os(macOS)
import PostboxMac
import SwiftSignalKitMac
#else
import Postbox
import SwiftSignalKit
#endif
final class ConsumePersonalMessageAction: PendingMessageActionData {
init() {
}
init(decoder: Decoder) {
}
func encode(_ encoder: Encoder) {
}
func isEqual(to: PendingMessageActionData) -> Bool {
if let _ = to as? ConsumePersonalMessageAction {
return true
} else {
return false
}
}
}

View File

@ -19,14 +19,14 @@ private func md5(_ data : Data) -> Data {
return res
}
private func updatedRemoteContactPeers(network: Network, hash: String) -> Signal<([Peer], [PeerId: PeerPresence])?, NoError> {
private func updatedRemoteContactPeers(network: Network, hash: Int32) -> Signal<([Peer], [PeerId: PeerPresence], Int32)?, NoError> {
return network.request(Api.functions.contacts.getContacts(hash: hash))
|> retryRequest
|> map { result -> ([Peer], [PeerId: PeerPresence])? in
|> map { result -> ([Peer], [PeerId: PeerPresence], Int32)? in
switch result {
case .contactsNotModified:
return nil
case let .contacts(_, users):
case let .contacts(_, savedCount, users):
var peers: [Peer] = []
var peerPresences: [PeerId: PeerPresence] = [:]
for user in users {
@ -36,52 +36,45 @@ private func updatedRemoteContactPeers(network: Network, hash: String) -> Signal
peerPresences[telegramUser.id] = presence
}
}
return (peers, peerPresences)
return (peers, peerPresences, savedCount)
}
}
}
private func hashForCountAndIds(count: Int32, ids: [Int32]) -> Int32 {
var acc: UInt32 = 0
acc = (acc &* 20261) &+ UInt32(bitPattern: count)
for id in ids {
let low = UInt32(bitPattern: id)
acc = (acc &* 20261) &+ low
}
return Int32(bitPattern: acc % UInt32(0x7FFFFFFF))
}
func manageContacts(network: Network, postbox: Postbox) -> Signal<Void, NoError> {
let initialContactPeerIdsHash = postbox.contactPeerIdsView()
|> take(1)
|> map { peerIds -> String in
var stringToHash = ""
var first = true
let sortedUserIds = Set(peerIds.peerIds.filter({ $0.namespace == Namespaces.Peer.CloudUser }).map({ $0.id })).sorted()
for userId in sortedUserIds {
if first {
first = false
} else {
stringToHash.append(",")
}
stringToHash.append("\(userId)")
}
|> map { view -> Int32 in
let sortedUserIds = Set(view.peerIds.filter({ $0.namespace == Namespaces.Peer.CloudUser }).map({ $0.id })).sorted()
let hashData = md5(stringToHash.data(using: .utf8)!)
let hashString = hashData.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) -> String in
let hexString = NSMutableString()
for i in 0 ..< hashData.count {
let byteValue = UInt(bytes.advanced(by: i).pointee)
hexString.appendFormat("%02x", byteValue)
}
return hexString as String
}
return hashString
return hashForCountAndIds(count: view.remoteTotalCount, ids: sortedUserIds)
}
let updatedPeers = initialContactPeerIdsHash
|> mapToSignal { hash -> Signal<([Peer], [PeerId: PeerPresence])?, NoError> in
|> mapToSignal { hash -> Signal<([Peer], [PeerId: PeerPresence], Int32)?, NoError> in
return updatedRemoteContactPeers(network: network, hash: hash)
}
let appliedUpdatedPeers = updatedPeers
|> mapToSignal { peersAndPresences -> Signal<Void, NoError> in
if let (peers, peerPresences) = peersAndPresences {
if let (peers, peerPresences, totalCount) = peersAndPresences {
return postbox.modify { modifier in
updatePeers(modifier: modifier, peers: peers, update: { return $1 })
modifier.updatePeerPresences(peerPresences)
modifier.replaceContactPeerIds(Set(peers.map { $0.id }))
modifier.replaceRemoteContactCount(totalCount)
}
} else {
return .complete()
@ -94,7 +87,7 @@ func manageContacts(network: Network, postbox: Postbox) -> Signal<Void, NoError>
public func addContactPeerInteractively(account: Account, peerId: PeerId) -> Signal<Void, NoError> {
return account.postbox.modify { modifier -> Signal<Void, NoError> in
if let peer = modifier.getPeer(peerId) as? TelegramUser, let phone = peer.phone, !phone.isEmpty {
return account.network.request(Api.functions.contacts.importContacts(contacts: [Api.InputContact.inputPhoneContact(clientId: 1, phone: phone, firstName: peer.firstName ?? "", lastName: peer.lastName ?? "")], replace: .boolFalse))
return account.network.request(Api.functions.contacts.importContacts(contacts: [Api.InputContact.inputPhoneContact(clientId: 1, phone: phone, firstName: peer.firstName ?? "", lastName: peer.lastName ?? "")]))
|> map { Optional($0) }
|> `catch` { _ -> Signal<Api.contacts.ImportedContacts?, NoError> in
return .single(nil)

View File

@ -0,0 +1,37 @@
import Foundation
#if os(macOS)
import PostboxMac
import SwiftSignalKitMac
import MtProtoKitMac
#else
import Postbox
import SwiftSignalKit
import MtProtoKitDynamic
#endif
public func earliestUnseenPersonalMentionMessage(postbox: Postbox, peerId: PeerId) -> Signal<MessageId?, NoError> {
return postbox.modify { modifier -> Signal<MessageId?, NoError> in
var resultMessageId: MessageId?
modifier.scanMessages(peerId: peerId, tagMask: .unseenPersonalMessage, { entry in
switch entry {
case let .message(message):
for attribute in message.attributes {
if let attribute = attribute as? ConsumablePersonalMentionMessageAttribute, !attribute.pending {
resultMessageId = message.id
return false
}
}
break
case let .hole(hole):
break
}
return true
})
if let resultMessageId = resultMessageId {
return .single(resultMessageId)
}
return .single(nil)
} |> switchToLatest
}

View File

@ -36,6 +36,8 @@ private func filterMessageAttributesForOutgoingMessage(_ attributes: [MessageAtt
return true
case _ as OutgoingChatContextResultMessageAttribute:
return true
case _ as AutoremoveTimeoutMessageAttribute:
return true
default:
return false
}

View File

@ -216,7 +216,7 @@ private func validateBatch(postbox: Postbox, network: Network, messageIds: [Mess
}
case let .channelDifferenceEmpty(_, pts, _):
finalPts = pts
case let .channelDifferenceTooLong(_, pts, _, _, _, _, _, _, _, _):
case let .channelDifferenceTooLong(_, pts, _, _, _, _, _, _, _, _, _):
finalPts = pts
}

View File

@ -10,15 +10,15 @@ import Foundation
#endif
private func messageFilterForTagMask(_ tagMask: MessageTags) -> Api.MessagesFilter? {
if tagMask == .PhotoOrVideo {
if tagMask == .photoOrVideo {
return Api.MessagesFilter.inputMessagesFilterPhotoVideo
} else if tagMask == .File {
} else if tagMask == .file {
return Api.MessagesFilter.inputMessagesFilterDocument
} else if tagMask == .Music {
} else if tagMask == .music {
return Api.MessagesFilter.inputMessagesFilterMusic
} else if tagMask == .WebPage {
} else if tagMask == .webPage {
return Api.MessagesFilter.inputMessagesFilterUrl
} else if tagMask == .VoiceOrInstantVideo {
} else if tagMask == .voiceOrInstantVideo {
return Api.MessagesFilter.inputMessagesFilterRoundVoice
} else {
return nil
@ -35,16 +35,58 @@ func fetchMessageHistoryHole(network: Network, postbox: Postbox, hole: MessageHi
let request: Signal<Api.messages.Messages, MTRpcError>
if let tagMask = tagMask, let filter = messageFilterForTagMask(tagMask) {
if tagMask == MessageTags.unseenPersonalMessage {
let offsetId: Int32
let addOffset: Int32
let selectedLimit = limit
let maxId: Int32
let minId: Int32
switch direction {
case .UpperToLower:
break
offsetId = hole.maxIndex.id.id == Int32.max ? hole.maxIndex.id.id : (hole.maxIndex.id.id + 1)
addOffset = 0
maxId = hole.maxIndex.id.id == Int32.max ? hole.maxIndex.id.id : (hole.maxIndex.id.id + 1)
minId = 1
case .LowerToUpper:
assertionFailure(".LowerToUpper not supported")
case .AroundIndex:
assertionFailure(".AroundIndex not supported")
offsetId = hole.min <= 1 ? 1 : (hole.min - 1)
addOffset = Int32(-limit)
maxId = Int32.max
minId = hole.min - 1
case let .AroundIndex(index):
offsetId = index.id.id
addOffset = Int32(-limit / 2)
maxId = Int32.max
minId = 1
}
request = network.request(Api.functions.messages.getUnreadMentions(peer: inputPeer, offsetId: offsetId, addOffset: addOffset, limit: Int32(selectedLimit), maxId: maxId, minId: minId))
} else {
let offsetId: Int32
let addOffset: Int32
let selectedLimit = limit
let maxId: Int32
let minId: Int32
switch direction {
case .UpperToLower:
offsetId = hole.maxIndex.id.id == Int32.max ? hole.maxIndex.id.id : (hole.maxIndex.id.id + 1)
addOffset = 0
maxId = hole.maxIndex.id.id == Int32.max ? hole.maxIndex.id.id : (hole.maxIndex.id.id + 1)
minId = 1
case .LowerToUpper:
offsetId = hole.min <= 1 ? 1 : (hole.min - 1)
addOffset = Int32(-limit)
maxId = Int32.max
minId = hole.min - 1
case let .AroundIndex(index):
offsetId = index.id.id
addOffset = Int32(-limit / 2)
maxId = Int32.max
minId = 1
}
request = network.request(Api.functions.messages.search(flags: 0, peer: inputPeer, q: "", fromId: nil, filter: filter, minDate: 0, maxDate: hole.maxIndex.timestamp, offsetId: offsetId, addOffset: addOffset, limit: Int32(selectedLimit), maxId: maxId, minId: minId))
}
//request = network.request(Api.functions.messages.search(flags: 0, peer: inputPeer, q: "", filter: filter, minDate: 0, maxDate: hole.maxIndex.timestamp, offset: 0, maxId: hole.maxIndex.id.id + 1, limit: Int32(limit)))
request = network.request(Api.functions.messages.search(flags: 0, peer: inputPeer, q: "", fromId: nil, filter: filter, minDate: 0, maxDate: hole.maxIndex.timestamp, offset: 0, maxId: Int32.max, limit: Int32(limit)))
} else {
let offsetId: Int32
let addOffset: Int32
@ -70,7 +112,6 @@ func fetchMessageHistoryHole(network: Network, postbox: Postbox, hole: MessageHi
minId = 1
}
//request = network.request(Api.functions.messages.getHistory(peer: inputPeer, offsetId: offsetId, offsetDate: hole.maxIndex.timestamp, addOffset: addOffset, limit: Int32(selectedLimit), maxId: hole.maxIndex.id.id == Int32.max ? hole.maxIndex.id.id : (hole.maxIndex.id.id + 1), minId: hole.min - 1))
request = network.request(Api.functions.messages.getHistory(peer: inputPeer, offsetId: offsetId, offsetDate: hole.maxIndex.timestamp, addOffset: addOffset, limit: Int32(selectedLimit), maxId: maxId, minId: minId))
}
@ -183,6 +224,7 @@ func fetchChatListHole(network: Network, postbox: Postbox, hole: ChatListHole) -
var replacementHole: ChatListHole?
var storeMessages: [StoreMessage] = []
var readStates: [PeerId: [MessageId.Namespace: PeerReadState]] = [:]
var mentionTagSummaries: [PeerId: MessageHistoryTagNamespaceSummary] = [:]
var chatStates: [PeerId: PeerChatState] = [:]
var notificationSettings: [PeerId: PeerNotificationSettings] = [:]
@ -197,15 +239,17 @@ func fetchChatListHole(network: Network, postbox: Postbox, hole: ChatListHole) -
let apiReadOutboxMaxId: Int32
let apiTopMessage: Int32
let apiUnreadCount: Int32
let apiUnreadMentionsCount: Int32
var apiChannelPts: Int32?
let apiNotificationSettings: Api.PeerNotifySettings
switch dialog {
case let .dialog(_, peer, topMessage, readInboxMaxId, readOutboxMaxId, unreadCount, peerNotificationSettings, pts, _):
case let .dialog(_, peer, topMessage, readInboxMaxId, readOutboxMaxId, unreadCount, unreadMentionsCount, peerNotificationSettings, pts, _):
apiPeer = peer
apiTopMessage = topMessage
apiReadInboxMaxId = readInboxMaxId
apiReadOutboxMaxId = readOutboxMaxId
apiUnreadCount = unreadCount
apiUnreadMentionsCount = unreadMentionsCount
apiNotificationSettings = peerNotificationSettings
apiChannelPts = pts
}
@ -225,6 +269,10 @@ func fetchChatListHole(network: Network, postbox: Postbox, hole: ChatListHole) -
}
readStates[peerId]![Namespaces.Message.Cloud] = .idBased(maxIncomingReadId: apiReadInboxMaxId, maxOutgoingReadId: apiReadOutboxMaxId, maxKnownId: apiTopMessage, count: apiUnreadCount)
if apiUnreadMentionsCount != 0 && apiTopMessage != 0 {
mentionTagSummaries[peerId] = MessageHistoryTagNamespaceSummary(version: 1, count: apiUnreadMentionsCount, range: MessageHistoryTagNamespaceCountValidityRange(maxId: apiTopMessage))
}
if let apiChannelPts = apiChannelPts {
chatStates[peerId] = ChannelState(pts: apiChannelPts, invalidatedPts: nil)
}
@ -253,16 +301,18 @@ func fetchChatListHole(network: Network, postbox: Postbox, hole: ChatListHole) -
let apiReadInboxMaxId: Int32
let apiReadOutboxMaxId: Int32
let apiUnreadCount: Int32
let apiUnreadMentionsCount: Int32
let apiNotificationSettings: Api.PeerNotifySettings
let isPinned: Bool
switch dialog {
case let .dialog(flags, peer, topMessage, readInboxMaxId, readOutboxMaxId, unreadCount, peerNotificationSettings, _, _):
case let .dialog(flags, peer, topMessage, readInboxMaxId, readOutboxMaxId, unreadCount, unreadMentionsCount, peerNotificationSettings, _, _):
isPinned = (flags & (1 << 2)) != 0
apiPeer = peer
apiTopMessage = topMessage
apiReadInboxMaxId = readInboxMaxId
apiReadOutboxMaxId = readOutboxMaxId
apiUnreadCount = unreadCount
apiUnreadMentionsCount = unreadMentionsCount
apiNotificationSettings = peerNotificationSettings
}
@ -281,6 +331,10 @@ func fetchChatListHole(network: Network, postbox: Postbox, hole: ChatListHole) -
}
readStates[peerId]![Namespaces.Message.Cloud] = .idBased(maxIncomingReadId: apiReadInboxMaxId, maxOutgoingReadId: apiReadOutboxMaxId, maxKnownId: apiTopMessage, count: apiUnreadCount)
if apiUnreadMentionsCount != 0 && apiTopMessage != 0 {
mentionTagSummaries[peerId] = MessageHistoryTagNamespaceSummary(version: 1, count: apiUnreadMentionsCount, range: MessageHistoryTagNamespaceCountValidityRange(maxId: apiTopMessage))
}
notificationSettings[peerId] = TelegramPeerNotificationSettings(apiSettings: apiNotificationSettings)
let topMessageId = MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: apiTopMessage)
@ -317,15 +371,17 @@ func fetchChatListHole(network: Network, postbox: Postbox, hole: ChatListHole) -
let apiReadOutboxMaxId: Int32
let apiTopMessage: Int32
let apiUnreadCount: Int32
let apiUnreadMentionsCount: Int32
var apiChannelPts: Int32?
let apiNotificationSettings: Api.PeerNotifySettings
switch dialog {
case let .dialog(_, peer, topMessage, readInboxMaxId, readOutboxMaxId, unreadCount, peerNotificationSettings, pts, _):
case let .dialog(_, peer, topMessage, readInboxMaxId, readOutboxMaxId, unreadCount, unreadMentionsCount, peerNotificationSettings, pts, _):
apiPeer = peer
apiTopMessage = topMessage
apiReadInboxMaxId = readInboxMaxId
apiReadOutboxMaxId = readOutboxMaxId
apiUnreadCount = unreadCount
apiUnreadMentionsCount = unreadMentionsCount
apiNotificationSettings = peerNotificationSettings
apiChannelPts = pts
}
@ -347,6 +403,10 @@ func fetchChatListHole(network: Network, postbox: Postbox, hole: ChatListHole) -
}
readStates[peerId]![Namespaces.Message.Cloud] = .idBased(maxIncomingReadId: apiReadInboxMaxId, maxOutgoingReadId: apiReadOutboxMaxId, maxKnownId: apiTopMessage, count: apiUnreadCount)
if apiUnreadMentionsCount != 0 && apiTopMessage != 0 {
mentionTagSummaries[peerId] = MessageHistoryTagNamespaceSummary(version: 1, count: apiUnreadMentionsCount, range: MessageHistoryTagNamespaceCountValidityRange(maxId: apiTopMessage))
}
if let apiChannelPts = apiChannelPts {
chatStates[peerId] = ChannelState(pts: apiChannelPts, invalidatedPts: nil)
}
@ -413,6 +473,10 @@ func fetchChatListHole(network: Network, postbox: Postbox, hole: ChatListHole) -
if let replacePinnedPeerIds = replacePinnedPeerIds {
modifier.setPinnedPeerIds(replacePinnedPeerIds)
}
for (peerId, summary) in mentionTagSummaries {
modifier.replaceMessageTagSummary(peerId: peerId, tagMask: .unseenPersonalMessage, namespace: Namespaces.Message.Cloud, count: summary.count, maxId: summary.range.maxId)
}
}
}
}
@ -431,7 +495,7 @@ func fetchCallListHole(network: Network, postbox: Postbox, holeIndex: MessageInd
}
return offset
|> mapToSignal { (timestamp, id, peer) -> Signal<Void, NoError> in
let searchResult = network.request(Api.functions.messages.search(flags: 0, peer: peer, q: "", fromId: nil, filter: .inputMessagesFilterPhoneCalls(flags: 0), minDate: 0, maxDate: holeIndex.timestamp, offset: 0, maxId: holeIndex.id.id, limit: limit))
let searchResult = network.request(Api.functions.messages.search(flags: 0, peer: peer, q: "", fromId: nil, filter: .inputMessagesFilterPhoneCalls(flags: 0), minDate: 0, maxDate: holeIndex.timestamp, offsetId: 0, addOffset: 0, limit: limit, maxId: holeIndex.id.id, minId: 0))
|> retryRequest
|> mapToSignal { result -> Signal<Void, NoError> in
let messages: [Api.Message]

View File

@ -10,7 +10,7 @@ public func importContact(account:Account, firstName:String, lastName:String, ph
let input = Api.InputContact.inputPhoneContact(clientId: 1, phone: phoneNumber, firstName: firstName, lastName: lastName)
return account.network.request(Api.functions.contacts.importContacts(contacts: [input], replace: .boolFalse))
return account.network.request(Api.functions.contacts.importContacts(contacts: [input]))
|> map { Optional($0) }
|> `catch` { _ -> Signal<Api.contacts.ImportedContacts?, NoError> in
return .single(nil)

View File

@ -0,0 +1,42 @@
import Foundation
#if os(macOS)
import PostboxMac
import SwiftSignalKitMac
#else
import Postbox
import SwiftSignalKit
#endif
public func installInteractiveReadMessagesAction(postbox: Postbox, peerId: PeerId) -> Disposable {
return postbox.installStoreMessageAction(peerId: peerId, { messages, modifier in
var consumeMessageIds: [MessageId] = []
for message in messages {
if case let .Id(id) = message.id {
if message.tags.contains(.unseenPersonalMessage) {
inner: for attribute in message.attributes {
if let attribute = attribute as? ConsumablePersonalMentionMessageAttribute, !attribute.consumed, !attribute.pending {
consumeMessageIds.append(id)
break inner
}
}
}
}
}
for id in consumeMessageIds {
modifier.updateMessage(id, update: { currentMessage in
var attributes = currentMessage.attributes
loop: for j in 0 ..< attributes.count {
if let attribute = attributes[j] as? ConsumablePersonalMentionMessageAttribute {
attributes[j] = ConsumablePersonalMentionMessageAttribute(consumed: attribute.consumed, pending: true)
break loop
}
}
return .update(StoreMessage(id: currentMessage.id, globallyUniqueId: currentMessage.globallyUniqueId, timestamp: currentMessage.timestamp, flags: StoreMessageFlags(currentMessage.flags), tags: currentMessage.tags, globalTags: currentMessage.globalTags, forwardInfo: currentMessage.forwardInfo.flatMap(StoreMessageForwardInfo.init), authorId: currentMessage.author?.id, text: currentMessage.text, attributes: attributes, media: currentMessage.media))
})
modifier.setPendingMessageAction(type: .consumeUnseenPersonalMessage, id: id, action: ConsumePersonalMessageAction())
}
})
}

View File

@ -9,7 +9,6 @@ import Foundation
import MtProtoKitDynamic
#endif
public enum GetMessagesStrategy {
case local
case cloud

View File

@ -94,7 +94,6 @@ public func loadedStickerPack(account: Account, reference: StickerPackReference)
indexKeysByFile[mediaId]!.append(key)
}
}
break
}
}

View File

@ -12,7 +12,8 @@ public func currentlySuggestedLocalization(network: Network, extractKeys: [Strin
|> retryRequest
|> mapToSignal { result -> Signal<SuggestedLocalizationInfo?, NoError> in
switch result {
case let .config(flags, date, expires, testMode, thisDc, dcOptions, chatSizeMax, megagroupSizeMax, forwardedCountMax, onlineUpdatePeriodMs, offlineBlurTimeoutMs, offlineIdleTimeoutMs, onlineCloudTimeoutMs, notifyCloudDelayMs, notifyDefaultDelayMs, chatBigSize, pushChatPeriodMs, pushChatLimit, savedGifsLimit, editTimeLimit, ratingEDecay, stickersRecentLimit, tmpSessions, pinnedDialogsCountMax, callReceiveTimeoutMs, callRingTimeoutMs, callConnectTimeoutMs, callPacketTimeoutMs, meUrlPrefix, suggestedLangCode, _, disabledFeatures):
//config flags:# date:int expires:int test_mode:Bool this_dc:int dc_options:Vector<DcOption> chat_size_max:int megagroup_size_max:int forwarded_count_max:int online_update_period_ms:int offline_blur_timeout_ms:int offline_idle_timeout_ms:int online_cloud_timeout_ms:int notify_cloud_delay_ms:int notify_default_delay_ms:int chat_big_size:int push_chat_period_ms:int push_chat_limit:int saved_gifs_limit:int edit_time_limit:int rating_e_decay:int stickers_recent_limit:int stickers_faved_limit:int tmp_sessions:flags.0?int pinned_dialogs_count_max:int phonecalls_enabled:flags.1?true call_receive_timeout_ms:int call_ring_timeout_ms:int call_connect_timeout_ms:int call_packet_timeout_ms:int me_url_prefix:string suggested_lang_code:flags.2?string lang_pack_version:flags.2?int disabled_features:Vector<DisabledFeature> = Config;
case let .config(flags, _, _, _, _, _, chatSizeMax, megagroupSizeMax, forwardedCountMax, onlineUpdatePeriodMs, offlineBlurTimeoutMs, offlineIdleTimeoutMs, onlineCloudTimeoutMs, notifyCloudDelayMs, notifyDefaultDelayMs, chatBigSize, pushChatPeriodMs, pushChatLimit, savedGifsLimit, editTimeLimit, ratingEDecay, stickersRecentLimit, stickersFavedLimit, _, pinnedDialogsCountMax, callReceiveTimeoutMs, callRingTimeoutMs, callConnectTimeoutMs, callPacketTimeoutMs, meUrlPrefix, suggestedLangCode, _, disabledFeatures):
if let suggestedLangCode = suggestedLangCode {
return suggestedLocalizationInfo(network: network, languageCode: suggestedLangCode, extractKeys: extractKeys) |> map { Optional($0) }
} else {

View File

@ -14,7 +14,7 @@ func managedConfigurationUpdates(postbox: Postbox, network: Network) -> Signal<V
return (network.request(Api.functions.help.getConfig()) |> retryRequest |> mapToSignal { result -> Signal<Void, NoError> in
return postbox.modify { modifier -> Void in
switch result {
case let .config(_, _, _, _, _, dcOptions, chatSizeMax, megagroupSizeMax, forwardedCountMax, _, _, _, onlineCloudTimeoutMs, notifyCloudDelayMs, notifyDefaultDelayMs, chatBigSize, pushChatPeriodMs, pushChatLimit, savedGifsLimit, editTimeLimit, ratingEDecay, stickersRecentLimit, tmpSessions, pinnedDialogsCountMax, callReceiveTimeoutMs, callRingTimeoutMs, callConnectTimeoutMs, callPacketTimeoutMs, meUrlPrefix, suggestedLangCode, langPackVersion, disabledFeatures):
case let .config(_, _, _, _, _, dcOptions, chatSizeMax, megagroupSizeMax, forwardedCountMax, _, _, _, onlineCloudTimeoutMs, notifyCloudDelayMs, notifyDefaultDelayMs, chatBigSize, pushChatPeriodMs, pushChatLimit, savedGifsLimit, editTimeLimit, ratingEDecay, stickersRecentLimit, stickersFavedLimit, tmpSessions, pinnedDialogsCountMax, callReceiveTimeoutMs, callRingTimeoutMs, callConnectTimeoutMs, callPacketTimeoutMs, meUrlPrefix, suggestedLangCode, langPackVersion, disabledFeatures):
var addressList: [Int: [MTDatacenterAddress]] = [:]
for option in dcOptions {
switch option {

View File

@ -0,0 +1,185 @@
import Foundation
#if os(macOS)
import PostboxMac
import SwiftSignalKitMac
import MtProtoKitMac
#else
import Postbox
import SwiftSignalKit
import MtProtoKitDynamic
#endif
private final class ManagedConsumePersonalMessagesActionsHelper {
var operationDisposables: [MessageId: Disposable] = [:]
func update(_ entries: [PendingMessageActionsEntry]) -> (disposeOperations: [Disposable], beginOperations: [(PendingMessageActionsEntry, MetaDisposable)]) {
var disposeOperations: [Disposable] = []
var beginOperations: [(PendingMessageActionsEntry, MetaDisposable)] = []
var hasRunningOperationForPeerId = Set<PeerId>()
var validIds = Set<MessageId>()
for entry in entries {
if !hasRunningOperationForPeerId.contains(entry.id.peerId) {
hasRunningOperationForPeerId.insert(entry.id.peerId)
validIds.insert(entry.id)
if self.operationDisposables[entry.id] == nil {
let disposable = MetaDisposable()
beginOperations.append((entry, disposable))
self.operationDisposables[entry.id] = disposable
}
}
}
var removeMergedIds: [MessageId] = []
for (id, disposable) in self.operationDisposables {
if !validIds.contains(id) {
removeMergedIds.append(id)
disposeOperations.append(disposable)
}
}
for id in removeMergedIds {
self.operationDisposables.removeValue(forKey: id)
}
return (disposeOperations, beginOperations)
}
func reset() -> [Disposable] {
let disposables = Array(self.operationDisposables.values)
self.operationDisposables.removeAll()
return disposables
}
}
private func withTakenAction(postbox: Postbox, type: PendingMessageActionType, id: MessageId, _ f: @escaping (Modifier, PendingMessageActionsEntry?) -> Signal<Void, NoError>) -> Signal<Void, NoError> {
return postbox.modify { modifier -> Signal<Void, NoError> in
var result: PendingMessageActionsEntry?
if let action = modifier.getPendingMessageAction(type: type, id: id) as? ConsumePersonalMessageAction {
result = PendingMessageActionsEntry(id: id, action: action)
}
return f(modifier, result)
} |> switchToLatest
}
func managedConsumePersonalMessagesActions(postbox: Postbox, network: Network, stateManager: AccountStateManager) -> Signal<Void, NoError> {
return Signal { _ in
let helper = Atomic<ManagedConsumePersonalMessagesActionsHelper>(value: ManagedConsumePersonalMessagesActionsHelper())
let key = PostboxViewKey.pendingMessageActions(type: .consumeUnseenPersonalMessage)
let disposable = postbox.combinedView(keys: [key]).start(next: { view in
var entries: [PendingMessageActionsEntry] = []
if let v = view.views[key] as? PendingMessageActionsView {
entries = v.entries
}
let (disposeOperations, beginOperations) = helper.with { helper -> (disposeOperations: [Disposable], beginOperations: [(PendingMessageActionsEntry, MetaDisposable)]) in
return helper.update(entries)
}
for disposable in disposeOperations {
disposable.dispose()
}
for (entry, disposable) in beginOperations {
let signal = withTakenAction(postbox: postbox, type: .consumeUnseenPersonalMessage, id: entry.id, { modifier, entry -> Signal<Void, NoError> in
if let entry = entry {
if let _ = entry.action as? ConsumePersonalMessageAction {
return synchronizeConsumeMessageContents(modifier: modifier, postbox: postbox, network: network, stateManager: stateManager, id: entry.id)
} else {
assertionFailure()
}
}
return .complete()
})
|> then(postbox.modify { modifier -> Void in
modifier.setPendingMessageAction(type: .consumeUnseenPersonalMessage, id: entry.id, action: nil)
})
disposable.set(signal.start())
}
})
return ActionDisposable {
let disposables = helper.with { helper -> [Disposable] in
return helper.reset()
}
for disposable in disposables {
disposable.dispose()
}
disposable.dispose()
}
}
}
private func synchronizeConsumeMessageContents(modifier: Modifier, postbox: Postbox, network: Network, stateManager: AccountStateManager, id: MessageId) -> Signal<Void, NoError> {
if id.peerId.namespace == Namespaces.Peer.CloudUser || id.peerId.namespace == Namespaces.Peer.CloudGroup {
return network.request(Api.functions.messages.readMessageContents(id: [id.id]))
|> map { Optional($0) }
|> `catch` { _ -> Signal<Api.messages.AffectedMessages?, NoError> in
return .single(nil)
}
|> mapToSignal { result -> Signal<Void, NoError> in
if let result = result {
switch result {
case let .affectedMessages(pts, ptsCount):
stateManager.addUpdateGroups([.updatePts(pts: pts, ptsCount: ptsCount)])
}
}
return postbox.modify { modifier -> Void in
modifier.setPendingMessageAction(type: .consumeUnseenPersonalMessage, id: id, action: nil)
modifier.updateMessage(id, update: { currentMessage in
var storeForwardInfo: StoreMessageForwardInfo?
if let forwardInfo = currentMessage.forwardInfo {
storeForwardInfo = StoreMessageForwardInfo(authorId: forwardInfo.author.id, sourceId: forwardInfo.source?.id, sourceMessageId: forwardInfo.sourceMessageId, date: forwardInfo.date, authorSignature: forwardInfo.authorSignature)
}
var attributes = currentMessage.attributes
loop: for j in 0 ..< attributes.count {
if let attribute = attributes[j] as? ConsumablePersonalMentionMessageAttribute, !attribute.consumed {
attributes[j] = ConsumablePersonalMentionMessageAttribute(consumed: true, pending: false)
break loop
}
}
var updatedTags = currentMessage.tags
updatedTags.remove(.unseenPersonalMessage)
return .update(StoreMessage(id: currentMessage.id, globallyUniqueId: currentMessage.globallyUniqueId, timestamp: currentMessage.timestamp, flags: StoreMessageFlags(currentMessage.flags), tags: updatedTags, globalTags: currentMessage.globalTags, forwardInfo: storeForwardInfo, authorId: currentMessage.author?.id, text: currentMessage.text, attributes: attributes, media: currentMessage.media))
})
}
}
} else if id.peerId.namespace == Namespaces.Peer.CloudChannel {
if let peer = modifier.getPeer(id.peerId), let inputChannel = apiInputChannel(peer) {
return network.request(Api.functions.channels.readMessageContents(channel: inputChannel, id: [id.id]))
|> `catch` { _ -> Signal<Api.Bool, NoError> in
return .single(.boolFalse)
} |> mapToSignal { result -> Signal<Void, NoError> in
return postbox.modify { modifier -> Void in
modifier.setPendingMessageAction(type: .consumeUnseenPersonalMessage, id: id, action: nil)
modifier.updateMessage(id, update: { currentMessage in
var storeForwardInfo: StoreMessageForwardInfo?
if let forwardInfo = currentMessage.forwardInfo {
storeForwardInfo = StoreMessageForwardInfo(authorId: forwardInfo.author.id, sourceId: forwardInfo.source?.id, sourceMessageId: forwardInfo.sourceMessageId, date: forwardInfo.date, authorSignature: forwardInfo.authorSignature)
}
var attributes = currentMessage.attributes
loop: for j in 0 ..< attributes.count {
if let attribute = attributes[j] as? ConsumablePersonalMentionMessageAttribute, !attribute.consumed {
attributes[j] = ConsumablePersonalMentionMessageAttribute(consumed: true, pending: false)
break loop
}
}
var updatedTags = currentMessage.tags
updatedTags.remove(.unseenPersonalMessage)
return .update(StoreMessage(id: currentMessage.id, globallyUniqueId: currentMessage.globallyUniqueId, timestamp: currentMessage.timestamp, flags: StoreMessageFlags(currentMessage.flags), tags: updatedTags, globalTags: currentMessage.globalTags, forwardInfo: storeForwardInfo, authorId: currentMessage.author?.id, text: currentMessage.text, attributes: attributes, media: currentMessage.media))
})
}
}
} else {
return .complete()
}
} else {
return .complete()
}
}

View File

@ -234,7 +234,7 @@ private func applyAddedOrUpdatedContacts(network: Network, contacts: [ManagedDev
apiContacts.append(.inputPhoneContact(clientId: nextId, phone: contact.phoneNumber, firstName: contact.firstName, lastName: contact.lastName))
nextId += 1
}
return network.request(Api.functions.contacts.importContacts(contacts: apiContacts, replace: .boolFalse))
return network.request(Api.functions.contacts.importContacts(contacts: apiContacts))
|> `catch` { _ -> Signal<Api.contacts.ImportedContacts, ManagedDeviceContactsError> in
return .fail(.generic)
}

View File

@ -7,7 +7,7 @@ import Foundation
import SwiftSignalKit
#endif
private func hashForIdsReverse(_ ids: [Int64]) -> Int32 {
private func hashForIds(_ ids: [Int64]) -> Int32 {
var acc: UInt32 = 0
for id in ids {
@ -20,12 +20,15 @@ private func hashForIdsReverse(_ ids: [Int64]) -> Int32 {
return Int32(bitPattern: acc % UInt32(0x7FFFFFFF))
}
private func managedRecentMedia(postbox: Postbox, network: Network, collectionId: Int32, fetch: @escaping (Int32) -> Signal<[OrderedItemListEntry]?, NoError>) -> Signal<Void, NoError> {
private func managedRecentMedia(postbox: Postbox, network: Network, collectionId: Int32, reverseHashOrder: Bool, fetch: @escaping (Int32) -> Signal<[OrderedItemListEntry]?, NoError>) -> Signal<Void, NoError> {
return postbox.modify { modifier -> Signal<Void, NoError> in
let itemIds = modifier.getOrderedListItemIds(collectionId: collectionId).map {
var itemIds = modifier.getOrderedListItemIds(collectionId: collectionId).map {
RecentMediaItemId($0).mediaId.id
}
return fetch(hashForIdsReverse(itemIds))
if reverseHashOrder {
itemIds.reverse()
}
return fetch(hashForIds(itemIds))
|> mapToSignal { items in
if let items = items {
return postbox.modify { modifier -> Void in
@ -39,7 +42,7 @@ private func managedRecentMedia(postbox: Postbox, network: Network, collectionId
}
func managedRecentStickers(postbox: Postbox, network: Network) -> Signal<Void, NoError> {
return managedRecentMedia(postbox: postbox, network: network, collectionId: Namespaces.OrderedItemList.CloudRecentStickers, fetch: { hash in
return managedRecentMedia(postbox: postbox, network: network, collectionId: Namespaces.OrderedItemList.CloudRecentStickers, reverseHashOrder: false, fetch: { hash in
return network.request(Api.functions.messages.getRecentStickers(flags: 0, hash: hash))
|> retryRequest
|> mapToSignal { result -> Signal<[OrderedItemListEntry]?, NoError> in
@ -60,7 +63,7 @@ func managedRecentStickers(postbox: Postbox, network: Network) -> Signal<Void, N
}
func managedRecentGifs(postbox: Postbox, network: Network) -> Signal<Void, NoError> {
return managedRecentMedia(postbox: postbox, network: network, collectionId: Namespaces.OrderedItemList.CloudRecentGifs, fetch: { hash in
return managedRecentMedia(postbox: postbox, network: network, collectionId: Namespaces.OrderedItemList.CloudRecentGifs, reverseHashOrder: false, fetch: { hash in
return network.request(Api.functions.messages.getSavedGifs(hash: hash))
|> retryRequest
|> mapToSignal { result -> Signal<[OrderedItemListEntry]?, NoError> in
@ -79,3 +82,43 @@ func managedRecentGifs(postbox: Postbox, network: Network) -> Signal<Void, NoErr
}
})
}
func managedSavedStickers(postbox: Postbox, network: Network) -> Signal<Void, NoError> {
return managedRecentMedia(postbox: postbox, network: network, collectionId: Namespaces.OrderedItemList.CloudSavedStickers, reverseHashOrder: true, fetch: { hash in
return network.request(Api.functions.messages.getFavedStickers(hash: hash))
|> retryRequest
|> mapToSignal { result -> Signal<[OrderedItemListEntry]?, NoError> in
switch result {
case .favedStickersNotModified:
return .single(nil)
case let .favedStickers(_, packs, stickers):
var fileStringRepresentations: [MediaId: [String]] = [:]
for pack in packs {
switch pack {
case let .stickerPack(text, fileIds):
for fileId in fileIds {
let mediaId = MediaId(namespace: Namespaces.Media.CloudFile, id: fileId)
if fileStringRepresentations[mediaId] == nil {
fileStringRepresentations[mediaId] = [text]
} else {
fileStringRepresentations[mediaId]!.append(text)
}
}
}
}
var items: [OrderedItemListEntry] = []
for sticker in stickers {
if let file = telegramMediaFileFromApiDocument(sticker), let id = file.id {
var stringRepresentations: [String] = []
if let representations = fileStringRepresentations[id] {
stringRepresentations = representations
}
items.append(OrderedItemListEntry(id: RecentMediaItemId(id).rawValue, contents: SavedStickerItem(file: file, stringRepresentations: stringRepresentations)))
}
}
return .single(items)
}
}
})
}

View File

@ -417,7 +417,7 @@ private func decryptedAttributes46(_ attributes: [TelegramMediaFileAttribute]) -
result.append(.documentAttributeFilename(fileName: fileName))
case .Animated:
result.append(.documentAttributeAnimated)
case let .Sticker(displayText, packReference):
case let .Sticker(displayText, packReference, _):
var stickerSet: SecretApi46.InputStickerSet = .inputStickerSetEmpty
if let packReference = packReference, case let .name(name) = packReference {
stickerSet = .inputStickerSetShortName(shortName: name)

View File

@ -150,7 +150,7 @@ private func synchronizePinnedChats(modifier: Modifier, postbox: Postbox, networ
var apiChannelPts: Int32?
let apiNotificationSettings: Api.PeerNotifySettings
switch dialog {
case let .dialog(_, peer, topMessage, readInboxMaxId, readOutboxMaxId, unreadCount, peerNotificationSettings, pts, _):
case let .dialog(_, peer, topMessage, readInboxMaxId, readOutboxMaxId, unreadCount, unreadMentionsCount, peerNotificationSettings, pts, _):
apiPeer = peer
apiTopMessage = topMessage
apiReadInboxMaxId = readInboxMaxId

View File

@ -0,0 +1,139 @@
import Foundation
#if os(macOS)
import PostboxMac
import SwiftSignalKitMac
import MtProtoKitMac
#else
import Postbox
import SwiftSignalKit
import MtProtoKitDynamic
#endif
private final class ManagedSynchronizeSavedStickersOperationsHelper {
var operationDisposables: [Int32: Disposable] = [:]
func update(_ entries: [PeerMergedOperationLogEntry]) -> (disposeOperations: [Disposable], beginOperations: [(PeerMergedOperationLogEntry, MetaDisposable)]) {
var disposeOperations: [Disposable] = []
var beginOperations: [(PeerMergedOperationLogEntry, MetaDisposable)] = []
var hasRunningOperationForPeerId = Set<PeerId>()
var validMergedIndices = Set<Int32>()
for entry in entries {
if !hasRunningOperationForPeerId.contains(entry.peerId) {
hasRunningOperationForPeerId.insert(entry.peerId)
validMergedIndices.insert(entry.mergedIndex)
if self.operationDisposables[entry.mergedIndex] == nil {
let disposable = MetaDisposable()
beginOperations.append((entry, disposable))
self.operationDisposables[entry.mergedIndex] = disposable
}
}
}
var removeMergedIndices: [Int32] = []
for (mergedIndex, disposable) in self.operationDisposables {
if !validMergedIndices.contains(mergedIndex) {
removeMergedIndices.append(mergedIndex)
disposeOperations.append(disposable)
}
}
for mergedIndex in removeMergedIndices {
self.operationDisposables.removeValue(forKey: mergedIndex)
}
return (disposeOperations, beginOperations)
}
func reset() -> [Disposable] {
let disposables = Array(self.operationDisposables.values)
self.operationDisposables.removeAll()
return disposables
}
}
private func withTakenOperation(postbox: Postbox, peerId: PeerId, tag: PeerOperationLogTag, tagLocalIndex: Int32, _ f: @escaping (Modifier, PeerMergedOperationLogEntry?) -> Signal<Void, NoError>) -> Signal<Void, NoError> {
return postbox.modify { modifier -> Signal<Void, NoError> in
var result: PeerMergedOperationLogEntry?
modifier.operationLogUpdateEntry(peerId: peerId, tag: tag, tagLocalIndex: tagLocalIndex, { entry in
if let entry = entry, let _ = entry.mergedIndex, entry.contents is SynchronizeSavedStickersOperation {
result = entry.mergedEntry!
return PeerOperationLogEntryUpdate(mergedIndex: .none, contents: .none)
} else {
return PeerOperationLogEntryUpdate(mergedIndex: .none, contents: .none)
}
})
return f(modifier, result)
} |> switchToLatest
}
func managedSynchronizeSavedStickersOperations(postbox: Postbox, network: Network) -> Signal<Void, NoError> {
return Signal { _ in
let tag: PeerOperationLogTag = OperationLogTags.SynchronizeSavedStickers
let helper = Atomic<ManagedSynchronizeSavedStickersOperationsHelper>(value: ManagedSynchronizeSavedStickersOperationsHelper())
let disposable = postbox.mergedOperationLogView(tag: tag, limit: 10).start(next: { view in
let (disposeOperations, beginOperations) = helper.with { helper -> (disposeOperations: [Disposable], beginOperations: [(PeerMergedOperationLogEntry, MetaDisposable)]) in
return helper.update(view.entries)
}
for disposable in disposeOperations {
disposable.dispose()
}
for (entry, disposable) in beginOperations {
let signal = withTakenOperation(postbox: postbox, peerId: entry.peerId, tag: tag, tagLocalIndex: entry.tagLocalIndex, { modifier, entry -> Signal<Void, NoError> in
if let entry = entry {
if let operation = entry.contents as? SynchronizeSavedStickersOperation {
return synchronizeSavedStickers(modifier: modifier, postbox: postbox, network: network, operation: operation)
} else {
assertionFailure()
}
}
return .complete()
})
|> then(postbox.modify { modifier -> Void in
let _ = modifier.operationLogRemoveEntry(peerId: entry.peerId, tag: tag, tagLocalIndex: entry.tagLocalIndex)
})
disposable.set(signal.start())
}
})
return ActionDisposable {
let disposables = helper.with { helper -> [Disposable] in
return helper.reset()
}
for disposable in disposables {
disposable.dispose()
}
disposable.dispose()
}
}
}
private func synchronizeSavedStickers(modifier: Modifier, postbox: Postbox, network: Network, operation: SynchronizeSavedStickersOperation) -> Signal<Void, NoError> {
switch operation.content {
case let .add(id, accessHash):
return network.request(Api.functions.messages.faveSticker(id: .inputDocument(id: id, accessHash: accessHash), unfave: .boolFalse))
|> `catch` { _ -> Signal<Api.Bool, NoError> in
return .single(.boolFalse)
}
|> mapToSignal { _ -> Signal<Void, NoError> in
return .complete()
}
case let .remove(id, accessHash):
return network.request(Api.functions.messages.faveSticker(id: .inputDocument(id: id, accessHash: accessHash), unfave: .boolTrue))
|> `catch` { _ -> Signal<Api.Bool, NoError> in
return .single(.boolFalse)
}
|> mapToSignal { _ -> Signal<Void, NoError> in
return .complete()
}
case .sync:
return managedSavedStickers(postbox: postbox, network: network)
}
}

View File

@ -49,6 +49,7 @@ public struct Namespaces {
public static let CloudFeaturedStickerPacks: Int32 = 4
public static let CloudArchivedStickerPacks: Int32 = 5
public static let CloudWallpapers: Int32 = 6
public static let CloudSavedStickers: Int32 = 7
}
struct CachedItemCollection {
@ -66,13 +67,14 @@ public struct Namespaces {
}
public extension MessageTags {
static let PhotoOrVideo = MessageTags(rawValue: 1 << 0)
static let File = MessageTags(rawValue: 1 << 1)
static let Music = MessageTags(rawValue: 1 << 2)
static let WebPage = MessageTags(rawValue: 1 << 3)
static let VoiceOrInstantVideo = MessageTags(rawValue: 1 << 4)
static let photoOrVideo = MessageTags(rawValue: 1 << 0)
static let file = MessageTags(rawValue: 1 << 1)
static let music = MessageTags(rawValue: 1 << 2)
static let webPage = MessageTags(rawValue: 1 << 3)
static let voiceOrInstantVideo = MessageTags(rawValue: 1 << 4)
static let unseenPersonalMessage = MessageTags(rawValue: 1 << 5)
static let all: MessageTags = [.PhotoOrVideo, .File, .Music, .WebPage, .VoiceOrInstantVideo]
static let all: MessageTags = [.photoOrVideo, .file, .music, .webPage, .voiceOrInstantVideo, .unseenPersonalMessage]
}
public extension GlobalMessageTags {
@ -82,6 +84,10 @@ public extension GlobalMessageTags {
static let all: GlobalMessageTags = [.Calls, .MissedCalls]
}
public extension PendingMessageActionType {
static let consumeUnseenPersonalMessage = PendingMessageActionType(rawValue: 0)
}
let peerIdNamespacesWithInitialCloudMessageHoles = [Namespaces.Peer.CloudUser, Namespaces.Peer.CloudGroup, Namespaces.Peer.CloudChannel]
struct OperationLogTags {
@ -99,6 +105,7 @@ struct OperationLogTags {
static let SynchronizeChatInputStates = PeerOperationLogTag(value: 11)
static let SynchronizeSavedGifs = PeerOperationLogTag(value: 12)
static let SynchronizeLocalizationUpdates = PeerOperationLogTag(value: 13)
static let SynchronizeSavedStickers = PeerOperationLogTag(value: 14)
}
private enum PreferencesKeyValues: Int32 {

View File

@ -35,9 +35,12 @@ func messageContentToUpload(network: Network, postbox: Postbox, transformOutgoin
func messageContentToUpload(network: Network, postbox: Postbox, transformOutgoingMessageMedia: TransformOutgoingMessageMedia?, peerId: PeerId, messageId: MessageId?, attributes: [MessageAttribute], text: String, media: [Media]) -> PendingMessageUploadContent {
var contextResult: OutgoingChatContextResultMessageAttribute?
var autoremoveAttribute: AutoremoveTimeoutMessageAttribute?
for attribute in attributes {
if let attribute = attribute as? OutgoingChatContextResultMessageAttribute {
contextResult = attribute
} else if let attribute = attribute as? AutoremoveTimeoutMessageAttribute {
autoremoveAttribute = attribute
}
}
@ -58,7 +61,7 @@ func messageContentToUpload(network: Network, postbox: Postbox, transformOutgoin
return .ready(.chatContextResult(contextResult))
} else if let media = media.first {
if let image = media as? TelegramMediaImage, let _ = largestImageRepresentation(image.representations) {
return .upload(uploadedMediaImageContent(network: network, postbox: postbox, peerId: peerId, image: image, text: text))
return .upload(uploadedMediaImageContent(network: network, postbox: postbox, peerId: peerId, image: image, text: text, autoremoveAttribute: autoremoveAttribute))
} else if let file = media as? TelegramMediaFile {
if let resource = file.resource as? CloudDocumentMediaResource {
return .ready(.media(Api.InputMedia.inputMediaDocument(id: Api.InputDocument.inputDocument(id: resource.fileId, accessHash: resource.accessHash), caption: text)))
@ -84,7 +87,7 @@ func messageContentToUpload(network: Network, postbox: Postbox, transformOutgoin
}
}
private func uploadedMediaImageContent(network: Network, postbox: Postbox, peerId: PeerId, image: TelegramMediaImage, text: String) -> Signal<PendingMessageUploadedContentResult, PendingMessageUploadError> {
private func uploadedMediaImageContent(network: Network, postbox: Postbox, peerId: PeerId, image: TelegramMediaImage, text: String, autoremoveAttribute: AutoremoveTimeoutMessageAttribute?) -> Signal<PendingMessageUploadedContentResult, PendingMessageUploadError> {
if let largestRepresentation = largestImageRepresentation(image.representations) {
return multipartUpload(network: network, postbox: postbox, source: .resource(largestRepresentation.resource), encrypt: peerId.namespace == Namespaces.Peer.SecretChat, tag: TelegramMediaResourceFetchTag(statsCategory: .image))
|> mapError { _ -> PendingMessageUploadError in return .generic }
@ -93,7 +96,13 @@ private func uploadedMediaImageContent(network: Network, postbox: Postbox, peerI
case let .progress(progress):
return .progress(progress)
case let .inputFile(file):
return .content(.media(Api.InputMedia.inputMediaUploadedPhoto(flags: 0, file: file, caption: text, stickers: nil, ttlSeconds: nil)))
var flags: Int32 = 0
var ttlSeconds: Int32?
if let autoremoveAttribute = autoremoveAttribute {
flags |= 1 << 1
ttlSeconds = autoremoveAttribute.timeout
}
return .content(.media(Api.InputMedia.inputMediaUploadedPhoto(flags: flags, file: file, caption: text, stickers: nil, ttlSeconds: ttlSeconds)))
case let .inputSecretFile(file, size, key):
return .content(.secretMedia(file, size, key))
}
@ -113,9 +122,9 @@ func inputDocumentAttributesFromFileAttributes(_ fileAttributes: [TelegramMediaF
attributes.append(.documentAttributeFilename(fileName: fileName))
case let .ImageSize(size):
attributes.append(.documentAttributeImageSize(w: Int32(size.width), h: Int32(size.height)))
case let .Sticker(displayText, packReference):
case let .Sticker(displayText, packReference, maskCoords):
var stickerSet: Api.InputStickerSet = .inputStickerSetEmpty
let flags: Int32 = 0
var flags: Int32 = 0
if let packReference = packReference {
switch packReference {
case let .id(id, accessHash):
@ -124,7 +133,12 @@ func inputDocumentAttributesFromFileAttributes(_ fileAttributes: [TelegramMediaF
stickerSet = .inputStickerSetShortName(shortName: name)
}
}
attributes.append(.documentAttributeSticker(flags: flags, alt: displayText, stickerset: stickerSet, maskCoords: nil))
var inputMaskCoords: Api.MaskCoords?
if let maskCoords = maskCoords {
flags |= 1 << 0
inputMaskCoords = .maskCoords(n: maskCoords.n, x: maskCoords.x, y: maskCoords.y, zoom: maskCoords.zoom)
}
attributes.append(.documentAttributeSticker(flags: flags, alt: displayText, stickerset: stickerSet, maskCoords: inputMaskCoords))
case .HasLinkedStickers:
attributes.append(.documentAttributeHasStickers)
case let .Video(duration, size, videoFlags):
@ -272,11 +286,22 @@ private func uploadedMediaFileContent(network: Network, postbox: Postbox, transf
case let .inputFile(inputFile):
if case let .done(thumbnail) = media {
let inputMedia: Api.InputMedia
if let thumbnail = thumbnail {
inputMedia = Api.InputMedia.inputMediaUploadedDocument(flags: (1 << 2), file: inputFile, thumb: thumbnail, mimeType: file.mimeType, attributes: inputDocumentAttributesFromFileAttributes(file.attributes), caption: text, stickers: nil, ttlSeconds: nil)
} else {
inputMedia = Api.InputMedia.inputMediaUploadedDocument(flags: 0, file: inputFile, thumb: nil, mimeType: file.mimeType, attributes: inputDocumentAttributesFromFileAttributes(file.attributes), caption: text, stickers: nil, ttlSeconds: nil)
var flags: Int32 = 0
if let _ = thumbnail {
flags |= 1 << 2
}
var ttlSeconds: Int32?
for attribute in attributes {
if let attribute = attribute as? AutoremoveTimeoutMessageAttribute {
flags |= 1 << 1
ttlSeconds = attribute.timeout
}
}
inputMedia = Api.InputMedia.inputMediaUploadedDocument(flags: flags, file: inputFile, thumb: thumbnail, mimeType: file.mimeType, attributes: inputDocumentAttributesFromFileAttributes(file.attributes), caption: text, stickers: nil, ttlSeconds: ttlSeconds)
return .single(.content(.media(inputMedia)))
} else {
return .complete()

View File

@ -428,7 +428,7 @@ extension TelegramMediaFileAttribute {
case let .inputStickerSetShortName(shortName):
packReference = .name(shortName)
}
self = .Sticker(displayText: alt, packReference: packReference)
self = .Sticker(displayText: alt, packReference: packReference, maskData: nil)
case let .documentAttributeVideo(duration, w, h):
self = .Video(duration: Int(duration), size: CGSize(width: CGFloat(w), height: CGFloat(h)), flags: [])
default:

View File

@ -13,11 +13,12 @@ private enum MessagePreParsingError: Error {
func processSecretChatIncomingEncryptedOperations(modifier: Modifier, peerId: PeerId) -> Bool {
if let state = modifier.getPeerChatState(peerId) as? SecretChatState {
var updatedState = state
var removeTagLocalIndices: [Int32] = []
var addedDecryptedOperations = false
modifier.operationLogEnumerateEntries(peerId: peerId, tag: OperationLogTags.SecretIncomingEncrypted, { entry in
if let operation = entry.contents as? SecretChatIncomingEncryptedOperation {
if let key = state.keychain.key(fingerprint: operation.keyFingerprint) {
if let key = updatedState.keychain.key(fingerprint: operation.keyFingerprint) {
withDecryptedMessageContents(key: key, data: operation.contents, { decryptedContents in
if let decryptedContents = decryptedContents {
withExtendedLifetime(decryptedContents, {
@ -47,7 +48,7 @@ func processSecretChatIncomingEncryptedOperations(modifier: Modifier, peerId: Pe
throw MessagePreParsingError.malformedData
}
switch state.role {
switch updatedState.role {
case .creator:
if seqOutValue < 0 || (seqInValue >= 0 && (seqInValue & 1) == 0) || (seqOutValue & 1) != 0 {
throw MessagePreParsingError.protocolViolation
@ -77,7 +78,7 @@ func processSecretChatIncomingEncryptedOperations(modifier: Modifier, peerId: Pe
let entryTagLocalIndex: StorePeerOperationLogEntryTagLocalIndex
switch state.embeddedState {
switch updatedState.embeddedState {
case .terminated:
throw MessagePreParsingError.invalidChatState
case .handshake:
@ -88,7 +89,7 @@ func processSecretChatIncomingEncryptedOperations(modifier: Modifier, peerId: Pe
throw MessagePreParsingError.protocolViolation
}
let sequenceBasedLayerState = SecretChatSequenceBasedLayerState(layerNegotiationState: SecretChatLayerNegotiationState(activeLayer: parsedLayer, locallyRequestedLayer: nil, remotelyRequestedLayer: nil), rekeyState: nil, baseIncomingOperationIndex: entry.tagLocalIndex, baseOutgoingOperationIndex: modifier.operationLogGetNextEntryLocalIndex(peerId: peerId, tag: OperationLogTags.SecretOutgoing), topProcessedCanonicalIncomingOperationIndex: nil)
let updatedState = state.withUpdatedEmbeddedState(.sequenceBasedLayer(sequenceBasedLayerState))
updatedState = updatedState.withUpdatedEmbeddedState(.sequenceBasedLayer(sequenceBasedLayerState))
modifier.setPeerChatState(peerId, state: updatedState)
entryTagLocalIndex = .manual(sequenceBasedLayerState.baseIncomingOperationIndex + sequenceInfo.operationIndex)
} else {

View File

@ -1,66 +0,0 @@
import Foundation
#if os(macOS)
import PostboxMac
import MtProtoKitMac
import SwiftSignalKitMac
#else
import Postbox
import MtProtoKitDynamic
import SwiftSignalKit
#endif
public func recentCalls(account: Account, limit: Int) -> Signal<[Message], NoError> {
let filter: Api.MessagesFilter = .inputMessagesFilterPhoneCalls(flags: 0)
let searchResult = account.network.request(Api.functions.messages.search(flags: 0, peer: .inputPeerEmpty, q: "", fromId: nil, filter: filter, minDate: 0, maxDate: Int32.max, offset: 0, maxId: Int32.max, limit: Int32(limit)))
|> retryRequest
let processedSearchResult = searchResult
|> mapToSignal { result -> Signal<[Message], NoError> in
let messages: [Api.Message]
let chats: [Api.Chat]
let users: [Api.User]
switch result {
case let .channelMessages(_, _, _, apiMessages, apiChats, apiUsers):
messages = apiMessages
chats = apiChats
users = apiUsers
case let .messages(apiMessages, apiChats, apiUsers):
messages = apiMessages
chats = apiChats
users = apiUsers
case let.messagesSlice(_, apiMessages, apiChats, apiUsers):
messages = apiMessages
chats = apiChats
users = apiUsers
}
return account.postbox.modify { modifier -> [Message] 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 renderedMessages: [Message] = []
for message in messages {
if let message = StoreMessage(apiMessage: message), let renderedMessage = locallyRenderedMessage(message: message, peers: peers) {
renderedMessages.append(renderedMessage)
}
}
return renderedMessages
}
}
return processedSearchResult
}

View File

@ -19,7 +19,7 @@ public struct RecentMediaItemId {
self.mediaId = MediaId(namespace: mediaIdNamespace, id: mediaIdId)
}
init(_ mediaId: MediaId) {
public init(_ mediaId: MediaId) {
self.mediaId = mediaId
var mediaIdNamespace: Int32 = mediaId.namespace
var mediaIdId: Int64 = mediaId.id

View File

@ -60,7 +60,7 @@ public func requestPeerPhotos(account:Account, peerId:PeerId) -> Signal<[Telegra
}
}
} else if let peer = peer, let inputPeer = apiInputPeer(peer) {
return account.network.request(Api.functions.messages.search(flags: 0, peer: inputPeer, q: "", fromId: nil, filter: .inputMessagesFilterChatPhotos, minDate: 0, maxDate: 0, offset: 0, maxId: 0, limit: 1000)) |> map {Optional($0)}
return account.network.request(Api.functions.messages.search(flags: 0, peer: inputPeer, q: "", fromId: nil, filter: .inputMessagesFilterChatPhotos, minDate: 0, maxDate: 0, offsetId: 0, addOffset: 0, limit: 1000, maxId: 0, minId: 0)) |> map {Optional($0)}
|> mapError {_ in}
|> `catch` {
return Signal<Api.messages.Messages?, Void>.single(nil)

View File

@ -172,8 +172,8 @@ public indirect enum RichText: Coding, Equatable {
}
}
extension RichText {
var plainText: String {
public extension RichText {
public var plainText: String {
switch self {
case .empty:
return ""

View File

@ -0,0 +1,30 @@
import Foundation
#if os(macOS)
import PostboxMac
#else
import Postbox
#endif
public final class SavedStickerItem: OrderedItemListEntryContents, Equatable {
public let file: TelegramMediaFile
public let stringRepresentations: [String]
init(file: TelegramMediaFile, stringRepresentations: [String]) {
self.file = file
self.stringRepresentations = stringRepresentations
}
public init(decoder: Decoder) {
self.file = decoder.decodeObjectForKey("f") as! TelegramMediaFile
self.stringRepresentations = decoder.decodeStringArrayForKey("sr")
}
public func encode(_ encoder: Encoder) {
encoder.encodeObject(self.file, forKey: "f")
encoder.encodeStringArray(self.stringRepresentations, forKey: "sr")
}
public static func ==(lhs: SavedStickerItem, rhs: SavedStickerItem) -> Bool {
return lhs.file.isEqual(rhs.file) && lhs.stringRepresentations == rhs.stringRepresentations
}
}

View File

@ -20,11 +20,11 @@ public func searchMessages(account: Account, peerId: PeerId?, query: String, tag
let filter: Api.MessagesFilter
if let tags = tagMask {
if tags.contains(.File) {
if tags.contains(.file) {
filter = .inputMessagesFilterDocument
} else if tags.contains(.Music) {
} else if tags.contains(.music) {
filter = .inputMessagesFilterMusic
} else if tags.contains(.WebPage) {
} else if tags.contains(.webPage) {
filter = .inputMessagesFilterUrl
} else {
filter = .inputMessagesFilterEmpty
@ -37,7 +37,7 @@ public func searchMessages(account: Account, peerId: PeerId?, query: String, tag
searchResult = account.postbox.loadedPeerWithId(peerId)
|> mapToSignal { peer -> Signal<Api.messages.Messages, NoError> in
if let inputPeer = apiInputPeer(peer) {
return account.network.request(Api.functions.messages.search(flags: 0, peer: inputPeer, q: query, fromId: nil, filter: filter, minDate: 0, maxDate: Int32.max - 1, offset: 0, maxId: Int32.max - 1, limit: 64))
return account.network.request(Api.functions.messages.search(flags: 0, peer: inputPeer, q: query, fromId: nil, filter: filter, minDate: 0, maxDate: Int32.max - 1, offsetId: 0, addOffset: 0, limit: 64, maxId: Int32.max - 1, minId: 0))
|> retryRequest
} else {
return .never()

View File

@ -7,12 +7,56 @@ import Foundation
import SwiftSignalKit
#endif
public func searchStickers(postbox: Postbox, query: String) -> Signal<[StickerPackItem], NoError> {
return postbox.modify { modifier -> [StickerPackItem] in
var result: [StickerPackItem] = []
public final class FoundStickerItem: Equatable {
public let file: TelegramMediaFile
public let stringRepresentations: [String]
init(file: TelegramMediaFile, stringRepresentations: [String]) {
self.file = file
self.stringRepresentations = stringRepresentations
}
public static func ==(lhs: FoundStickerItem, rhs: FoundStickerItem) -> Bool {
if !lhs.file.isEqual(rhs.file) {
return false
}
if lhs.stringRepresentations != rhs.stringRepresentations {
return false
}
return true
}
}
public func searchStickers(postbox: Postbox, query: String) -> Signal<[FoundStickerItem], NoError> {
return postbox.modify { modifier -> [FoundStickerItem] in
var result: [FoundStickerItem] = []
var idsSet = Set<MediaId>()
for item in modifier.getOrderedListItems(collectionId: Namespaces.OrderedItemList.CloudSavedStickers) {
if let stickerItem = item.contents as? SavedStickerItem {
for string in stickerItem.stringRepresentations {
if string == query {
idsSet.insert(stickerItem.file.fileId)
result.append(FoundStickerItem(file: stickerItem.file, stringRepresentations: stickerItem.stringRepresentations))
}
}
}
}
for item in modifier.searchItemCollection(namespace: Namespaces.ItemCollection.CloudStickerPacks, key: ValueBoxKey(query).toMemoryBuffer()) {
if let item = item as? StickerPackItem {
result.append(item)
if !idsSet.contains(item.file.fileId) {
idsSet.insert(item.file.fileId)
var stringRepresentations: [String] = []
for key in item.indexKeys {
key.withDataNoCopy { data in
if let string = String(data: data, encoding: .utf8) {
stringRepresentations.append(string)
}
}
}
result.append(FoundStickerItem(file: item.file, stringRepresentations: stringRepresentations))
}
}
}
return result

View File

@ -20,7 +20,7 @@ public class BoxedMessage: NSObject {
public class Serialization: NSObject, MTSerialization {
public func currentLayer() -> UInt {
return 70
return 71
}
public func parseMessage(_ data: Data!) -> Any! {
@ -56,7 +56,7 @@ public class Serialization: NSObject, MTSerialization {
return { response -> MTDatacenterAddressListData! in
if let config = parse(Buffer(data: response)) {
switch config {
case let .config(_, _, _, _, _, dcOptions, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _):
case let .config(_, _, _, _, _, dcOptions, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _):
var addressDict: [NSNumber: [Any]] = [:]
for option in dcOptions {
switch option {

View File

@ -107,7 +107,7 @@ public final class StickerPackCollectionInfo: ItemCollectionInfo, Equatable {
public final class StickerPackItem: ItemCollectionItem, Equatable {
public let index: ItemCollectionItemIndex
public let file: TelegramMediaFile
public var indexKeys: [MemoryBuffer]
public let indexKeys: [MemoryBuffer]
public init(index: ItemCollectionItemIndex, file: TelegramMediaFile, indexKeys: [MemoryBuffer]) {
self.index = index
@ -131,6 +131,18 @@ public final class StickerPackItem: ItemCollectionItem, Equatable {
public static func ==(lhs: StickerPackItem, rhs: StickerPackItem) -> Bool {
return lhs.index == rhs.index && lhs.file == rhs.file && lhs.indexKeys == rhs.indexKeys
}
public func getStringRepresentationsOfIndexKeys() -> [String] {
var stringRepresentations: [String] = []
for key in self.indexKeys {
key.withDataNoCopy { data in
if let string = String(data: data, encoding: .utf8) {
stringRepresentations.append(string)
}
}
}
return stringRepresentations
}
}
extension StickerPackCollectionInfo {

View File

@ -7,32 +7,41 @@ import Foundation
public func tagsForStoreMessage(incoming: Bool, attributes: [MessageAttribute], media: [Media], textEntities: [MessageTextEntity]?) -> (MessageTags, GlobalMessageTags) {
var isSecret = false
var isUnconsumedPersonalMention = false
for attribute in attributes {
if let timerAttribute = attribute as? AutoremoveTimeoutMessageAttribute {
if timerAttribute.timeout > 0 && timerAttribute.timeout <= 60 {
isSecret = true
}
break
} else if let mentionAttribute = attribute as? ConsumablePersonalMentionMessageAttribute {
if !mentionAttribute.consumed {
isUnconsumedPersonalMention = true
}
}
}
var tags = MessageTags()
var globalTags = GlobalMessageTags()
if isUnconsumedPersonalMention {
tags.insert(.unseenPersonalMessage)
}
for attachment in media {
if let _ = attachment as? TelegramMediaImage {
if !isSecret {
tags.insert(.PhotoOrVideo)
tags.insert(.photoOrVideo)
}
} else if let file = attachment as? TelegramMediaFile {
var refinedTag: MessageTags? = .File
var refinedTag: MessageTags? = .file
inner: for attribute in file.attributes {
switch attribute {
case let .Video(_, _, flags):
if flags.contains(.instantRoundVideo) {
refinedTag = .VoiceOrInstantVideo
refinedTag = .voiceOrInstantVideo
} else {
if !isSecret {
refinedTag = .PhotoOrVideo
refinedTag = .photoOrVideo
} else {
refinedTag = nil
}
@ -40,9 +49,9 @@ public func tagsForStoreMessage(incoming: Bool, attributes: [MessageAttribute],
break inner
case let .Audio(isVoice, _, _, _, _):
if isVoice {
refinedTag = .VoiceOrInstantVideo
refinedTag = .voiceOrInstantVideo
} else {
refinedTag = .Music
refinedTag = .music
}
break inner
case .Sticker:
@ -56,7 +65,7 @@ public func tagsForStoreMessage(incoming: Bool, attributes: [MessageAttribute],
tags.insert(refinedTag)
}
} else if let webpage = attachment as? TelegramMediaWebpage, case .Loaded = webpage.content {
tags.insert(.WebPage)
tags.insert(.webPage)
} else if let action = attachment as? TelegramMediaAction {
switch action.action {
case let .phoneCall(_, discardReason, _):
@ -69,16 +78,17 @@ public func tagsForStoreMessage(incoming: Bool, attributes: [MessageAttribute],
}
}
}
if let textEntities = textEntities, !textEntities.isEmpty && !tags.contains(.WebPage) {
if let textEntities = textEntities, !textEntities.isEmpty && !tags.contains(.webPage) {
for entity in textEntities {
switch entity.type {
case .Url, .Email:
tags.insert(.WebPage)
tags.insert(.webPage)
default:
break
}
}
}
return (tags, globalTags)
}
@ -474,6 +484,8 @@ extension StoreMessage {
var notificationFlags: NotificationInfoMessageAttributeFlags = []
if (flags & (1 << 4)) != 0 {
notificationFlags.insert(.personal)
let notConsumed = (flags & (1 << 5)) != 0
attributes.append(ConsumablePersonalMentionMessageAttribute(consumed: !notConsumed, pending: false))
}
if (flags & (1 << 13)) != 0 {
notificationFlags.insert(.muted)

View File

@ -74,7 +74,7 @@ func fetchPeerCloudReadState(network: Network, postbox: Postbox, peerId: PeerId,
let apiReadOutboxMaxId: Int32
let apiUnreadCount: Int32
switch dialog {
case let .dialog(_, _, topMessage, readInboxMaxId, readOutboxMaxId, unreadCount, _, _, _):
case let .dialog(_, _, topMessage, readInboxMaxId, readOutboxMaxId, unreadCount, _, _, _, _):
apiTopMessage = topMessage
apiReadInboxMaxId = readInboxMaxId
apiReadOutboxMaxId = readOutboxMaxId
@ -109,7 +109,7 @@ private func dialogReadState(network: Network, postbox: Postbox, peerId: PeerId)
let apiUnreadCount: Int32
var apiChannelPts: Int32 = 0
switch dialog {
case let .dialog(_, _, topMessage, readInboxMaxId, readOutboxMaxId, unreadCount, _, pts, _):
case let .dialog(_, _, topMessage, readInboxMaxId, readOutboxMaxId, unreadCount, _, _, pts, _):
apiTopMessage = topMessage
apiReadInboxMaxId = readInboxMaxId
apiReadOutboxMaxId = readOutboxMaxId

View File

@ -0,0 +1,175 @@
import Foundation
#if os(macOS)
import PostboxMac
import SwiftSignalKitMac
#else
import Postbox
import SwiftSignalKit
#endif
private enum SynchronizeSavedStickersOperationContentType: Int32 {
case add
case remove
case sync
}
enum SynchronizeSavedStickersOperationContent: Coding {
case add(id: Int64, accessHash: Int64)
case remove(id: Int64, accessHash: Int64)
case sync
init(decoder: Decoder) {
switch decoder.decodeInt32ForKey("r", orElse: 0) {
case SynchronizeSavedStickersOperationContentType.add.rawValue:
self = .add(id: decoder.decodeInt64ForKey("i", orElse: 0), accessHash: decoder.decodeInt64ForKey("h", orElse: 0))
case SynchronizeSavedStickersOperationContentType.remove.rawValue:
self = .remove(id: decoder.decodeInt64ForKey("i", orElse: 0), accessHash: decoder.decodeInt64ForKey("h", orElse: 0))
case SynchronizeSavedStickersOperationContentType.sync.rawValue:
self = .sync
default:
assertionFailure()
self = .sync
}
}
func encode(_ encoder: Encoder) {
switch self {
case let .add(id, accessHash):
encoder.encodeInt32(SynchronizeSavedStickersOperationContentType.add.rawValue, forKey: "r")
encoder.encodeInt64(id, forKey: "i")
encoder.encodeInt64(accessHash, forKey: "h")
case let .remove(id, accessHash):
encoder.encodeInt32(SynchronizeSavedStickersOperationContentType.remove.rawValue, forKey: "r")
encoder.encodeInt64(id, forKey: "i")
encoder.encodeInt64(accessHash, forKey: "h")
case .sync:
encoder.encodeInt32(SynchronizeSavedStickersOperationContentType.sync.rawValue, forKey: "r")
}
}
}
final class SynchronizeSavedStickersOperation: Coding {
let content: SynchronizeSavedStickersOperationContent
init(content: SynchronizeSavedStickersOperationContent) {
self.content = content
}
init(decoder: Decoder) {
self.content = decoder.decodeObjectForKey("c", decoder: { SynchronizeSavedStickersOperationContent(decoder: $0) }) as! SynchronizeSavedStickersOperationContent
}
func encode(_ encoder: Encoder) {
encoder.encodeObject(self.content, forKey: "c")
}
}
func addSynchronizeSavedStickersOperation(modifier: Modifier, operation: SynchronizeSavedStickersOperationContent) {
let tag: PeerOperationLogTag = OperationLogTags.SynchronizeSavedStickers
let peerId = PeerId(namespace: 0, id: 0)
var topOperation: (SynchronizeSavedStickersOperation, Int32)?
modifier.operationLogEnumerateEntries(peerId: peerId, tag: tag, { entry in
if let operation = entry.contents as? SynchronizeSavedStickersOperation {
topOperation = (operation, entry.tagLocalIndex)
}
return false
})
if let (topOperation, topLocalIndex) = topOperation, case .sync = topOperation.content {
let _ = modifier.operationLogRemoveEntry(peerId: peerId, tag: tag, tagLocalIndex: topLocalIndex)
}
modifier.operationLogAddEntry(peerId: peerId, tag: tag, tagLocalIndex: .automatic, tagMergedIndex: .automatic, contents: SynchronizeSavedStickersOperation(content: operation))
modifier.operationLogAddEntry(peerId: peerId, tag: tag, tagLocalIndex: .automatic, tagMergedIndex: .automatic, contents: SynchronizeSavedStickersOperation(content: .sync))
}
public enum AddSavedStickerError {
case generic
case notFound
}
public func getIsStickerSaved(modifier: Modifier, fileId: MediaId) -> Bool {
if let _ = modifier.getOrderedItemListItem(collectionId: Namespaces.OrderedItemList.CloudSavedStickers, itemId: RecentMediaItemId(fileId).rawValue) {
return true
} else{
return false
}
}
public func addSavedSticker(postbox: Postbox, network: Network, file: TelegramMediaFile) -> Signal<Void, AddSavedStickerError> {
return postbox.modify { modifier -> Signal<Void, AddSavedStickerError> in
for attribute in file.attributes {
if case let .Sticker(_, maybePackReference, _) = attribute, let packReference = maybePackReference {
var fetchReference: StickerPackReference?
switch packReference {
case .name:
fetchReference = packReference
case let .id(id, _):
let items = modifier.getItemCollectionItems(collectionId: ItemCollectionId(namespace: Namespaces.ItemCollection.CloudStickerPacks, id: id))
inner: for item in items {
if let stickerItem = item as? StickerPackItem {
if stickerItem.file.fileId == file.fileId {
let stringRepresentations = stickerItem.getStringRepresentationsOfIndexKeys()
addSavedSticker(modifier: modifier, file: stickerItem.file, stringRepresentations: stringRepresentations)
break inner
}
}
}
}
if let fetchReference = fetchReference {
return network.request(Api.functions.messages.getStickerSet(stickerset: fetchReference.apiInputStickerSet))
|> mapError { _ -> AddSavedStickerError in
return .generic
}
|> mapToSignal { result -> Signal<Void, AddSavedStickerError> in
var stickerStringRepresentations: [String]?
switch result {
case let .stickerSet(_, packs, _):
var stringRepresentationsByFile: [MediaId: [String]] = [:]
for pack in packs {
switch pack {
case let .stickerPack(text, fileIds):
for fileId in fileIds {
let mediaId = MediaId(namespace: Namespaces.Media.CloudFile, id: fileId)
if stringRepresentationsByFile[mediaId] == nil {
stringRepresentationsByFile[mediaId] = [text]
} else {
stringRepresentationsByFile[mediaId]!.append(text)
}
}
}
}
stickerStringRepresentations = stringRepresentationsByFile[file.fileId]
}
if let stickerStringRepresentations = stickerStringRepresentations {
return postbox.modify { modifier -> Void in
addSavedSticker(modifier: modifier, file: file, stringRepresentations: stickerStringRepresentations)
} |> mapError { _ in return AddSavedStickerError.generic }
} else {
return .fail(.notFound)
}
}
}
return .complete()
}
}
return .complete()
} |> mapError { _ in return AddSavedStickerError.generic } |> switchToLatest
}
public func addSavedSticker(modifier: Modifier, file: TelegramMediaFile, stringRepresentations: [String]) {
if let resource = file.resource as? CloudDocumentMediaResource {
modifier.addOrMoveToFirstPositionOrderedItemListItem(collectionId: Namespaces.OrderedItemList.CloudSavedStickers, item: OrderedItemListEntry(id: RecentMediaItemId(file.fileId).rawValue, contents: SavedStickerItem(file: file, stringRepresentations: stringRepresentations)), removeTailIfCountExceeds: 30)
addSynchronizeSavedStickersOperation(modifier: modifier, operation: .add(id: resource.fileId, accessHash: resource.accessHash))
}
}
public func removeSavedSticker(modifier: Modifier, mediaId: MediaId) {
if let entry = modifier.getOrderedItemListItem(collectionId: Namespaces.OrderedItemList.CloudSavedStickers, itemId: RecentMediaItemId(mediaId).rawValue), let item = entry.contents as? SavedStickerItem {
if let resource = item.file.resource as? CloudDocumentMediaResource {
modifier.removeOrderedItemListItem(collectionId: Namespaces.OrderedItemList.CloudSavedStickers, itemId: entry.id)
addSynchronizeSavedStickersOperation(modifier: modifier, operation: .remove(id: resource.fileId, accessHash: resource.accessHash))
}
}
}

View File

@ -13,7 +13,7 @@ private let typeVideo: Int32 = 4
private let typeAudio: Int32 = 5
private let typeHasLinkedStickers: Int32 = 6
public enum StickerPackReference: Coding {
public enum StickerPackReference: Coding, Equatable {
case id(id: Int64, accessHash: Int64)
case name(String)
@ -40,6 +40,23 @@ public enum StickerPackReference: Coding {
encoder.encodeString(name, forKey: "n")
}
}
public static func ==(lhs: StickerPackReference, rhs: StickerPackReference) -> Bool {
switch lhs {
case let .id(id, accessHash):
if case .id(id, accessHash) = rhs {
return true
} else {
return false
}
case let .name(name):
if case .name(name) = rhs {
return true
} else {
return false
}
}
}
}
public struct TelegramMediaVideoFlags: OptionSet {
@ -56,9 +73,37 @@ public struct TelegramMediaVideoFlags: OptionSet {
public static let instantRoundVideo = TelegramMediaVideoFlags(rawValue: 1 << 0)
}
public struct StickerMaskCoords: Coding {
public let n: Int32
public let x: Double
public let y: Double
public let zoom: Double
public init(n: Int32, x: Double, y: Double, zoom: Double) {
self.n = n
self.x = x
self.y = y
self.zoom = zoom
}
public init(decoder: Decoder) {
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)
}
public func encode(_ encoder: Encoder) {
encoder.encodeInt32(self.n, forKey: "n")
encoder.encodeDouble(self.x, forKey: "x")
encoder.encodeDouble(self.y, forKey: "y")
encoder.encodeDouble(self.zoom, forKey: "z")
}
}
public enum TelegramMediaFileAttribute: Coding {
case FileName(fileName: String)
case Sticker(displayText: String, packReference: StickerPackReference?)
case Sticker(displayText: String, packReference: StickerPackReference?, maskData: StickerMaskCoords?)
case ImageSize(size: CGSize)
case Animated
case Video(duration: Int, size: CGSize, flags: TelegramMediaVideoFlags)
@ -71,7 +116,7 @@ public enum TelegramMediaFileAttribute: Coding {
case typeFileName:
self = .FileName(fileName: decoder.decodeStringForKey("fn", orElse: ""))
case typeSticker:
self = .Sticker(displayText: decoder.decodeStringForKey("dt", orElse: ""), packReference: decoder.decodeObjectForKey("pr", decoder: { StickerPackReference(decoder: $0) }) as? StickerPackReference)
self = .Sticker(displayText: decoder.decodeStringForKey("dt", orElse: ""), packReference: decoder.decodeObjectForKey("pr", decoder: { StickerPackReference(decoder: $0) }) as? StickerPackReference, maskData: decoder.decodeObjectForKey("mc", decoder: { StickerMaskCoords(decoder: $0) }) as? StickerMaskCoords)
case typeImageSize:
self = .ImageSize(size: CGSize(width: CGFloat(decoder.decodeInt32ForKey("w", orElse: 0)), height: CGFloat(decoder.decodeInt32ForKey("h", orElse: 0))))
case typeAnimated:
@ -97,7 +142,7 @@ public enum TelegramMediaFileAttribute: Coding {
case let .FileName(fileName):
encoder.encodeInt32(typeFileName, forKey: "t")
encoder.encodeString(fileName, forKey: "fn")
case let .Sticker(displayText, packReference):
case let .Sticker(displayText, packReference, maskCoords):
encoder.encodeInt32(typeSticker, forKey: "t")
encoder.encodeString(displayText, forKey: "dt")
if let packReference = packReference {
@ -105,6 +150,11 @@ public enum TelegramMediaFileAttribute: Coding {
} else {
encoder.encodeNil(forKey: "pr")
}
if let maskCoords = maskCoords {
encoder.encodeObject(maskCoords, forKey: "mc")
} else {
encoder.encodeNil(forKey: "mc")
}
case let .ImageSize(size):
encoder.encodeInt32(typeImageSize, forKey: "t")
encoder.encodeInt32(Int32(size.width), forKey: "w")
@ -317,6 +367,28 @@ public func ==(lhs: TelegramMediaFile, rhs: TelegramMediaFile) -> Bool {
return lhs.isEqual(rhs)
}
extension StickerPackReference {
init?(apiInputSet: Api.InputStickerSet) {
switch apiInputSet {
case .inputStickerSetEmpty:
return nil
case let .inputStickerSetID(id, accessHash):
self = .id(id: id, accessHash: accessHash)
case let .inputStickerSetShortName(shortName):
self = .name(shortName)
}
}
}
extension StickerMaskCoords {
init(apiMaskCoords: Api.MaskCoords) {
switch apiMaskCoords {
case let .maskCoords(n, x, y, zoom):
self.init(n: n, x: x, y: y, zoom: zoom)
}
}
}
public func telegramMediaFileAttributesFromApiAttributes(_ attributes: [Api.DocumentAttribute]) -> [TelegramMediaFileAttribute] {
var result: [TelegramMediaFileAttribute] = []
for attribute in attributes {
@ -324,16 +396,7 @@ public func telegramMediaFileAttributesFromApiAttributes(_ attributes: [Api.Docu
case let .documentAttributeFilename(fileName):
result.append(.FileName(fileName: fileName))
case let .documentAttributeSticker(_, alt, stickerSet, maskCoords):
let packReference: StickerPackReference?
switch stickerSet {
case .inputStickerSetEmpty:
packReference = nil
case let .inputStickerSetID(id, accessHash):
packReference = .id(id: id, accessHash: accessHash)
case let .inputStickerSetShortName(shortName):
packReference = .name(shortName)
}
result.append(.Sticker(displayText: alt, packReference: packReference))
result.append(.Sticker(displayText: alt, packReference: StickerPackReference(apiInputSet: stickerSet), maskData: maskCoords.flatMap(StickerMaskCoords.init)))
case .documentAttributeHasStickers:
result.append(.HasLinkedStickers)
case let .documentAttributeImageSize(w, h):

View File

@ -210,14 +210,14 @@ func fetchAndUpdateCachedPeerData(peerId: PeerId, network: Network, postbox: Pos
switch result {
case let .chatFull(fullChat, chats, users):
switch fullChat {
case let .channelFull(_, _, _, _, _, _, _, _, _, _, _, notifySettings, _, _, _, _, _):
case let .channelFull(_, _, _, _, _, _, _, _, _, _, _, notifySettings, _, _, _, _, _, _):
modifier.updatePeerNotificationSettings([peerId: TelegramPeerNotificationSettings(apiSettings: notifySettings)])
case .chatFull:
break
}
switch fullChat {
case let .channelFull(flags, _, about, participantsCount, adminsCount, kickedCount, bannedCount, _, _, _, _, _, apiExportedInvite, apiBotInfos, migratedFromChatId, migratedFromMaxId, pinnedMsgId):
case let .channelFull(flags, _, about, participantsCount, adminsCount, kickedCount, bannedCount, _, _, _, _, _, apiExportedInvite, apiBotInfos, migratedFromChatId, migratedFromMaxId, pinnedMsgId, stickerSet):
var channelFlags = CachedChannelFlags()
if (flags & (1 << 3)) != 0 {
channelFlags.insert(.canDisplayParticipants)
@ -261,6 +261,20 @@ func fetchAndUpdateCachedPeerData(peerId: PeerId, network: Network, postbox: Pos
modifier.updatePeerPresences(peerPresences)
let stickerPack: StickerPackCollectionInfo? = stickerSet.flatMap { apiSet -> StickerPackCollectionInfo in
let namespace: ItemCollectionId.Namespace
switch apiSet {
case let .stickerSet(flags, _, _, _, _, _, _):
if (flags & (1 << 3)) != 0 {
namespace = Namespaces.ItemCollection.CloudMaskPacks
} else {
namespace = Namespaces.ItemCollection.CloudStickerPacks
}
}
return StickerPackCollectionInfo(apiSet: apiSet, namespace: namespace)
}
modifier.updatePeerCachedData(peerIds: [peerId], update: { _, current in
let previous: CachedChannelData
if let current = current as? CachedChannelData {
@ -275,6 +289,7 @@ func fetchAndUpdateCachedPeerData(peerId: PeerId, network: Network, postbox: Pos
.withUpdatedExportedInvitation(ExportedInvitation(apiExportedInvite: apiExportedInvite))
.withUpdatedBotInfos(botInfos)
.withUpdatedPinnedMessageId(pinnedMessageId)
.withUpdatedStickerPack(stickerPack)
})
case .chatFull:
break

View File

@ -16,7 +16,7 @@ public enum UpdateContactNameError {
public func updateContactName(account: Account, peerId: PeerId, firstName: String, lastName: String) -> Signal<Void, UpdateContactNameError> {
return account.postbox.modify { modifier -> Signal<Void, UpdateContactNameError> in
if let peer = modifier.getPeer(peerId) as? TelegramUser, let phone = peer.phone, !phone.isEmpty {
return account.network.request(Api.functions.contacts.importContacts(contacts: [Api.InputContact.inputPhoneContact(clientId: 1, phone: phone, firstName: firstName, lastName: lastName)], replace: .boolFalse))
return account.network.request(Api.functions.contacts.importContacts(contacts: [Api.InputContact.inputPhoneContact(clientId: 1, phone: phone, firstName: firstName, lastName: lastName)]))
|> mapError { _ -> UpdateContactNameError in
return .generic
}

View File

@ -157,7 +157,7 @@ extension Api.Peer {
extension Api.Dialog {
var peerId: PeerId {
switch self {
case let .dialog(_, peer, _, _, _, _, _, _, _):
case let .dialog(_, peer, _, _, _, _, _, _, _, _):
return peer.peerId
}
}