mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-11-25 09:32:46 +00:00
no message
This commit is contained in:
parent
15c9274a8e
commit
2d6ed76631
@ -135,6 +135,18 @@
|
|||||||
D0448CA31E291B14005A61A7 /* FetchSecretFileResource.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0448CA11E291B14005A61A7 /* FetchSecretFileResource.swift */; };
|
D0448CA31E291B14005A61A7 /* FetchSecretFileResource.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0448CA11E291B14005A61A7 /* FetchSecretFileResource.swift */; };
|
||||||
D0448CA51E29215A005A61A7 /* MediaResourceApiUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0448CA41E29215A005A61A7 /* MediaResourceApiUtils.swift */; };
|
D0448CA51E29215A005A61A7 /* MediaResourceApiUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0448CA41E29215A005A61A7 /* MediaResourceApiUtils.swift */; };
|
||||||
D0448CA61E29215A005A61A7 /* MediaResourceApiUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0448CA41E29215A005A61A7 /* MediaResourceApiUtils.swift */; };
|
D0448CA61E29215A005A61A7 /* MediaResourceApiUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0448CA41E29215A005A61A7 /* MediaResourceApiUtils.swift */; };
|
||||||
|
D049EAD51E43D98500A2CD3A /* RecentMediaItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D049EAD41E43D98500A2CD3A /* RecentMediaItem.swift */; };
|
||||||
|
D049EAD61E43D98500A2CD3A /* RecentMediaItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D049EAD41E43D98500A2CD3A /* RecentMediaItem.swift */; };
|
||||||
|
D049EAD81E43DAD200A2CD3A /* ManagedRecentStickers.swift in Sources */ = {isa = PBXBuildFile; fileRef = D049EAD71E43DAD200A2CD3A /* ManagedRecentStickers.swift */; };
|
||||||
|
D049EAD91E43DAD200A2CD3A /* ManagedRecentStickers.swift in Sources */ = {isa = PBXBuildFile; fileRef = D049EAD71E43DAD200A2CD3A /* ManagedRecentStickers.swift */; };
|
||||||
|
D049EAE81E44B67100A2CD3A /* RecentPeerItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D049EAE71E44B67100A2CD3A /* RecentPeerItem.swift */; };
|
||||||
|
D049EAE91E44B67100A2CD3A /* RecentPeerItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D049EAE71E44B67100A2CD3A /* RecentPeerItem.swift */; };
|
||||||
|
D049EAEB1E44B71B00A2CD3A /* RecentlySearchedPeerIds.swift in Sources */ = {isa = PBXBuildFile; fileRef = D049EAEA1E44B71B00A2CD3A /* RecentlySearchedPeerIds.swift */; };
|
||||||
|
D049EAEC1E44B71B00A2CD3A /* RecentlySearchedPeerIds.swift in Sources */ = {isa = PBXBuildFile; fileRef = D049EAEA1E44B71B00A2CD3A /* RecentlySearchedPeerIds.swift */; };
|
||||||
|
D049EAF51E44DF3300A2CD3A /* AccountState.swift in Sources */ = {isa = PBXBuildFile; fileRef = D049EAF41E44DF3300A2CD3A /* AccountState.swift */; };
|
||||||
|
D049EAF61E44DF3300A2CD3A /* AccountState.swift in Sources */ = {isa = PBXBuildFile; fileRef = D049EAF41E44DF3300A2CD3A /* AccountState.swift */; };
|
||||||
|
D050F2101E48AB0600988324 /* InteractivePhoneFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = D050F20F1E48AB0600988324 /* InteractivePhoneFormatter.swift */; };
|
||||||
|
D050F2111E48AB0600988324 /* InteractivePhoneFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = D050F20F1E48AB0600988324 /* InteractivePhoneFormatter.swift */; };
|
||||||
D067066C1D512ADB00DED3E3 /* Postbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D06706671D512ADB00DED3E3 /* Postbox.framework */; };
|
D067066C1D512ADB00DED3E3 /* Postbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D06706671D512ADB00DED3E3 /* Postbox.framework */; };
|
||||||
D067066D1D512ADB00DED3E3 /* SwiftSignalKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D06706681D512ADB00DED3E3 /* SwiftSignalKit.framework */; };
|
D067066D1D512ADB00DED3E3 /* SwiftSignalKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D06706681D512ADB00DED3E3 /* SwiftSignalKit.framework */; };
|
||||||
D073CE5D1DCB97F6007511FD /* ForwardSourceInfoAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = D073CE5C1DCB97F6007511FD /* ForwardSourceInfoAttribute.swift */; };
|
D073CE5D1DCB97F6007511FD /* ForwardSourceInfoAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = D073CE5C1DCB97F6007511FD /* ForwardSourceInfoAttribute.swift */; };
|
||||||
@ -424,6 +436,12 @@
|
|||||||
D0448C9E1E27F5EB005A61A7 /* Random.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Random.swift; sourceTree = "<group>"; };
|
D0448C9E1E27F5EB005A61A7 /* Random.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Random.swift; sourceTree = "<group>"; };
|
||||||
D0448CA11E291B14005A61A7 /* FetchSecretFileResource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FetchSecretFileResource.swift; sourceTree = "<group>"; };
|
D0448CA11E291B14005A61A7 /* FetchSecretFileResource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FetchSecretFileResource.swift; sourceTree = "<group>"; };
|
||||||
D0448CA41E29215A005A61A7 /* MediaResourceApiUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MediaResourceApiUtils.swift; sourceTree = "<group>"; };
|
D0448CA41E29215A005A61A7 /* MediaResourceApiUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MediaResourceApiUtils.swift; sourceTree = "<group>"; };
|
||||||
|
D049EAD41E43D98500A2CD3A /* RecentMediaItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecentMediaItem.swift; sourceTree = "<group>"; };
|
||||||
|
D049EAD71E43DAD200A2CD3A /* ManagedRecentStickers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ManagedRecentStickers.swift; sourceTree = "<group>"; };
|
||||||
|
D049EAE71E44B67100A2CD3A /* RecentPeerItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecentPeerItem.swift; sourceTree = "<group>"; };
|
||||||
|
D049EAEA1E44B71B00A2CD3A /* RecentlySearchedPeerIds.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecentlySearchedPeerIds.swift; sourceTree = "<group>"; };
|
||||||
|
D049EAF41E44DF3300A2CD3A /* AccountState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountState.swift; sourceTree = "<group>"; };
|
||||||
|
D050F20F1E48AB0600988324 /* InteractivePhoneFormatter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InteractivePhoneFormatter.swift; sourceTree = "<group>"; };
|
||||||
D06706641D512ADB00DED3E3 /* AsyncDisplayKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AsyncDisplayKit.framework; path = "../../../../Library/Developer/Xcode/DerivedData/Telegram-iOS-diblohvjozhgaifjcniwdlixlilx/Build/Products/Debug-iphonesimulator/AsyncDisplayKit.framework"; sourceTree = "<group>"; };
|
D06706641D512ADB00DED3E3 /* AsyncDisplayKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AsyncDisplayKit.framework; path = "../../../../Library/Developer/Xcode/DerivedData/Telegram-iOS-diblohvjozhgaifjcniwdlixlilx/Build/Products/Debug-iphonesimulator/AsyncDisplayKit.framework"; sourceTree = "<group>"; };
|
||||||
D06706651D512ADB00DED3E3 /* Display.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Display.framework; path = "../../../../Library/Developer/Xcode/DerivedData/Telegram-iOS-diblohvjozhgaifjcniwdlixlilx/Build/Products/Debug-iphonesimulator/Display.framework"; sourceTree = "<group>"; };
|
D06706651D512ADB00DED3E3 /* Display.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Display.framework; path = "../../../../Library/Developer/Xcode/DerivedData/Telegram-iOS-diblohvjozhgaifjcniwdlixlilx/Build/Products/Debug-iphonesimulator/Display.framework"; sourceTree = "<group>"; };
|
||||||
D06706671D512ADB00DED3E3 /* Postbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Postbox.framework; path = "../../../../Library/Developer/Xcode/DerivedData/Telegram-iOS-diblohvjozhgaifjcniwdlixlilx/Build/Products/Debug-iphonesimulator/Postbox.framework"; sourceTree = "<group>"; };
|
D06706671D512ADB00DED3E3 /* Postbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Postbox.framework; path = "../../../../Library/Developer/Xcode/DerivedData/Telegram-iOS-diblohvjozhgaifjcniwdlixlilx/Build/Products/Debug-iphonesimulator/Postbox.framework"; sourceTree = "<group>"; };
|
||||||
@ -575,6 +593,8 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
D021E0DE1DB539FC00C6B04F /* StickerPack.swift */,
|
D021E0DE1DB539FC00C6B04F /* StickerPack.swift */,
|
||||||
|
D049EAD41E43D98500A2CD3A /* RecentMediaItem.swift */,
|
||||||
|
D049EAE71E44B67100A2CD3A /* RecentPeerItem.swift */,
|
||||||
);
|
);
|
||||||
name = "Item Collections";
|
name = "Item Collections";
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -584,6 +604,7 @@
|
|||||||
children = (
|
children = (
|
||||||
D021E0E11DB5401A00C6B04F /* StickerManagement.swift */,
|
D021E0E11DB5401A00C6B04F /* StickerManagement.swift */,
|
||||||
D01D6BF81E42A713006151C6 /* SearchStickers.swift */,
|
D01D6BF81E42A713006151C6 /* SearchStickers.swift */,
|
||||||
|
D049EAD71E43DAD200A2CD3A /* ManagedRecentStickers.swift */,
|
||||||
);
|
);
|
||||||
name = "Sticker Management";
|
name = "Sticker Management";
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -643,6 +664,7 @@
|
|||||||
D03B0CCD1D62239600955575 /* PhoneNumbers.swift */,
|
D03B0CCD1D62239600955575 /* PhoneNumbers.swift */,
|
||||||
D0FA8BAC1E1FD6E2001E855B /* MemoryBufferExtensions.swift */,
|
D0FA8BAC1E1FD6E2001E855B /* MemoryBufferExtensions.swift */,
|
||||||
D0448C9E1E27F5EB005A61A7 /* Random.swift */,
|
D0448C9E1E27F5EB005A61A7 /* Random.swift */,
|
||||||
|
D050F20F1E48AB0600988324 /* InteractivePhoneFormatter.swift */,
|
||||||
);
|
);
|
||||||
name = Utils;
|
name = Utils;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -796,6 +818,7 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
D03B0D611D631A8B00955575 /* Account.swift */,
|
D03B0D611D631A8B00955575 /* Account.swift */,
|
||||||
|
D049EAF41E44DF3300A2CD3A /* AccountState.swift */,
|
||||||
D03B0D621D631A8B00955575 /* AccountSettings.swift */,
|
D03B0D621D631A8B00955575 /* AccountSettings.swift */,
|
||||||
D03B0D631D631A8B00955575 /* AccountViewTracker.swift */,
|
D03B0D631D631A8B00955575 /* AccountViewTracker.swift */,
|
||||||
D03B0D641D631A8B00955575 /* RecentPeers.swift */,
|
D03B0D641D631A8B00955575 /* RecentPeers.swift */,
|
||||||
@ -946,6 +969,7 @@
|
|||||||
D0BC386D1E3FDAB70044D6FE /* CreateGroup.swift */,
|
D0BC386D1E3FDAB70044D6FE /* CreateGroup.swift */,
|
||||||
D0BC38741E40A7F70044D6FE /* RemovePeerChat.swift */,
|
D0BC38741E40A7F70044D6FE /* RemovePeerChat.swift */,
|
||||||
D0BC387A1E40D2880044D6FE /* TogglePeerChatPinned.swift */,
|
D0BC387A1E40D2880044D6FE /* TogglePeerChatPinned.swift */,
|
||||||
|
D049EAEA1E44B71B00A2CD3A /* RecentlySearchedPeerIds.swift */,
|
||||||
);
|
);
|
||||||
name = Peers;
|
name = Peers;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -1182,6 +1206,7 @@
|
|||||||
D0DF0C911D81A857008AEB01 /* ImageRepresentationsUtils.swift in Sources */,
|
D0DF0C911D81A857008AEB01 /* ImageRepresentationsUtils.swift in Sources */,
|
||||||
D0E6521F1E3A364A004EEA91 /* UpdateAccountPeerName.swift in Sources */,
|
D0E6521F1E3A364A004EEA91 /* UpdateAccountPeerName.swift in Sources */,
|
||||||
D03B0D5A1D631A6900955575 /* Api.swift in Sources */,
|
D03B0D5A1D631A6900955575 /* Api.swift in Sources */,
|
||||||
|
D049EAE81E44B67100A2CD3A /* RecentPeerItem.swift in Sources */,
|
||||||
D02ABC7B1E30058F00CAE539 /* DeleteMessagesInteractively.swift in Sources */,
|
D02ABC7B1E30058F00CAE539 /* DeleteMessagesInteractively.swift in Sources */,
|
||||||
D0448C9F1E27F5EB005A61A7 /* Random.swift in Sources */,
|
D0448C9F1E27F5EB005A61A7 /* Random.swift in Sources */,
|
||||||
D0B843B21DA7FF30005F29E1 /* NBAsYouTypeFormatter.m in Sources */,
|
D0B843B21DA7FF30005F29E1 /* NBAsYouTypeFormatter.m in Sources */,
|
||||||
@ -1193,6 +1218,7 @@
|
|||||||
D03C53771DAFF20F004C17B3 /* MultipartUpload.swift in Sources */,
|
D03C53771DAFF20F004C17B3 /* MultipartUpload.swift in Sources */,
|
||||||
D00C7CE01E3785710080C3D5 /* MarkMessageContentAsConsumedInteractively.swift in Sources */,
|
D00C7CE01E3785710080C3D5 /* MarkMessageContentAsConsumedInteractively.swift in Sources */,
|
||||||
D0B843811DA6EDAE005F29E1 /* CachedUserData.swift in Sources */,
|
D0B843811DA6EDAE005F29E1 /* CachedUserData.swift in Sources */,
|
||||||
|
D049EAD51E43D98500A2CD3A /* RecentMediaItem.swift in Sources */,
|
||||||
D03B0D0A1D62255C00955575 /* Holes.swift in Sources */,
|
D03B0D0A1D62255C00955575 /* Holes.swift in Sources */,
|
||||||
D0B843CB1DA7FF30005F29E1 /* NBPhoneNumberUtil.m in Sources */,
|
D0B843CB1DA7FF30005F29E1 /* NBPhoneNumberUtil.m in Sources */,
|
||||||
D03B0D5E1D631A6900955575 /* Network.swift in Sources */,
|
D03B0D5E1D631A6900955575 /* Network.swift in Sources */,
|
||||||
@ -1202,10 +1228,12 @@
|
|||||||
D03B0CFB1D62250800955575 /* TelegramMediaWebpage.swift in Sources */,
|
D03B0CFB1D62250800955575 /* TelegramMediaWebpage.swift in Sources */,
|
||||||
D09A2FEB1D7CDC320018FB72 /* PeerAccessRestrictionInfo.swift in Sources */,
|
D09A2FEB1D7CDC320018FB72 /* PeerAccessRestrictionInfo.swift in Sources */,
|
||||||
D0E35A101DE49E1C00BC6096 /* OutgoingMessageWithChatContextResult.swift in Sources */,
|
D0E35A101DE49E1C00BC6096 /* OutgoingMessageWithChatContextResult.swift in Sources */,
|
||||||
|
D049EAD81E43DAD200A2CD3A /* ManagedRecentStickers.swift in Sources */,
|
||||||
D0448C991E268F9A005A61A7 /* SecretApiLayer46.swift in Sources */,
|
D0448C991E268F9A005A61A7 /* SecretApiLayer46.swift in Sources */,
|
||||||
D003702B1DA42586004308D3 /* PhoneNumber.swift in Sources */,
|
D003702B1DA42586004308D3 /* PhoneNumber.swift in Sources */,
|
||||||
D03B0CF91D62250800955575 /* TelegramMediaMap.swift in Sources */,
|
D03B0CF91D62250800955575 /* TelegramMediaMap.swift in Sources */,
|
||||||
D0BC38791E40BAF20044D6FE /* SynchronizePinnedChatsOperation.swift in Sources */,
|
D0BC38791E40BAF20044D6FE /* SynchronizePinnedChatsOperation.swift in Sources */,
|
||||||
|
D050F2101E48AB0600988324 /* InteractivePhoneFormatter.swift in Sources */,
|
||||||
D03B0D671D631A8B00955575 /* AccountViewTracker.swift in Sources */,
|
D03B0D671D631A8B00955575 /* AccountViewTracker.swift in Sources */,
|
||||||
D0B843BB1DA7FF30005F29E1 /* NBMetadataCoreTestMapper.m in Sources */,
|
D0B843BB1DA7FF30005F29E1 /* NBMetadataCoreTestMapper.m in Sources */,
|
||||||
D03B0D101D62255C00955575 /* UpdatesApiUtils.swift in Sources */,
|
D03B0D101D62255C00955575 /* UpdatesApiUtils.swift in Sources */,
|
||||||
@ -1219,6 +1247,7 @@
|
|||||||
D019B1CC1E2E3B6A00F80DB3 /* SecretChatRekeySession.swift in Sources */,
|
D019B1CC1E2E3B6A00F80DB3 /* SecretChatRekeySession.swift in Sources */,
|
||||||
D03B0CD91D62245B00955575 /* PeerUtils.swift in Sources */,
|
D03B0CD91D62245B00955575 /* PeerUtils.swift in Sources */,
|
||||||
D03B0CE41D62249F00955575 /* TextEntitiesMessageAttribute.swift in Sources */,
|
D03B0CE41D62249F00955575 /* TextEntitiesMessageAttribute.swift in Sources */,
|
||||||
|
D049EAEB1E44B71B00A2CD3A /* RecentlySearchedPeerIds.swift in Sources */,
|
||||||
D03B0CD31D62244300955575 /* Namespaces.swift in Sources */,
|
D03B0CD31D62244300955575 /* Namespaces.swift in Sources */,
|
||||||
D01D6BF91E42A713006151C6 /* SearchStickers.swift in Sources */,
|
D01D6BF91E42A713006151C6 /* SearchStickers.swift in Sources */,
|
||||||
D0FA8BB91E2240B4001E855B /* SecretChatIncomingDecryptedOperation.swift in Sources */,
|
D0FA8BB91E2240B4001E855B /* SecretChatIncomingDecryptedOperation.swift in Sources */,
|
||||||
@ -1258,6 +1287,7 @@
|
|||||||
D017495E1E118F790057C89A /* AccountStateManager.swift in Sources */,
|
D017495E1E118F790057C89A /* AccountStateManager.swift in Sources */,
|
||||||
D0FA8BB61E223C16001E855B /* SecretApiLayer8.swift in Sources */,
|
D0FA8BB61E223C16001E855B /* SecretApiLayer8.swift in Sources */,
|
||||||
D0B843C71DA7FF30005F29E1 /* NBPhoneNumberDefines.m in Sources */,
|
D0B843C71DA7FF30005F29E1 /* NBPhoneNumberDefines.m in Sources */,
|
||||||
|
D049EAF51E44DF3300A2CD3A /* AccountState.swift in Sources */,
|
||||||
D03B0D5D1D631A6900955575 /* MultipartFetch.swift in Sources */,
|
D03B0D5D1D631A6900955575 /* MultipartFetch.swift in Sources */,
|
||||||
D0BC38751E40A7F70044D6FE /* RemovePeerChat.swift in Sources */,
|
D0BC38751E40A7F70044D6FE /* RemovePeerChat.swift in Sources */,
|
||||||
D0AB0B961D662F0B002C78E7 /* ManagedChatListHoles.swift in Sources */,
|
D0AB0B961D662F0B002C78E7 /* ManagedChatListHoles.swift in Sources */,
|
||||||
@ -1308,6 +1338,7 @@
|
|||||||
D0F7B1EA1E045C87007EB8A5 /* ChangePeerNotificationSettings.swift in Sources */,
|
D0F7B1EA1E045C87007EB8A5 /* ChangePeerNotificationSettings.swift in Sources */,
|
||||||
D0B418A71D7E0592004562A4 /* Fetch.swift in Sources */,
|
D0B418A71D7E0592004562A4 /* Fetch.swift in Sources */,
|
||||||
D02ABC7C1E30058F00CAE539 /* DeleteMessagesInteractively.swift in Sources */,
|
D02ABC7C1E30058F00CAE539 /* DeleteMessagesInteractively.swift in Sources */,
|
||||||
|
D050F2111E48AB0600988324 /* InteractivePhoneFormatter.swift in Sources */,
|
||||||
D0B418B81D7E05A6004562A4 /* ContactManagement.swift in Sources */,
|
D0B418B81D7E05A6004562A4 /* ContactManagement.swift in Sources */,
|
||||||
D0F7B1E91E045C87007EB8A5 /* PeerCommands.swift in Sources */,
|
D0F7B1E91E045C87007EB8A5 /* PeerCommands.swift in Sources */,
|
||||||
D00D97C81E32901700E5C2B6 /* PeerInputActivity.swift in Sources */,
|
D00D97C81E32901700E5C2B6 /* PeerInputActivity.swift in Sources */,
|
||||||
@ -1343,11 +1374,13 @@
|
|||||||
D0B844481DAB91FD005F29E1 /* ManagedMessageHistoryHoles.swift in Sources */,
|
D0B844481DAB91FD005F29E1 /* ManagedMessageHistoryHoles.swift in Sources */,
|
||||||
D0F3CC7B1DDE2859008148FA /* RequestEditMessage.swift in Sources */,
|
D0F3CC7B1DDE2859008148FA /* RequestEditMessage.swift in Sources */,
|
||||||
D0B844441DAB91FD005F29E1 /* AccountSettings.swift in Sources */,
|
D0B844441DAB91FD005F29E1 /* AccountSettings.swift in Sources */,
|
||||||
|
D049EAEC1E44B71B00A2CD3A /* RecentlySearchedPeerIds.swift in Sources */,
|
||||||
D0FA8B991E1E955C001E855B /* SecretChatOutgoingOperation.swift in Sources */,
|
D0FA8B991E1E955C001E855B /* SecretChatOutgoingOperation.swift in Sources */,
|
||||||
D001F3F01E128A1C007A8C60 /* AccountStateManagementUtils.swift in Sources */,
|
D001F3F01E128A1C007A8C60 /* AccountStateManagementUtils.swift in Sources */,
|
||||||
D0F3CC791DDE2859008148FA /* SearchMessages.swift in Sources */,
|
D0F3CC791DDE2859008148FA /* SearchMessages.swift in Sources */,
|
||||||
D0B8442B1DAB91E0005F29E1 /* NBMetadataCore.m in Sources */,
|
D0B8442B1DAB91E0005F29E1 /* NBMetadataCore.m in Sources */,
|
||||||
D00C7CD01E3628180080C3D5 /* UpdateCachedChannelParticipants.swift in Sources */,
|
D00C7CD01E3628180080C3D5 /* UpdateCachedChannelParticipants.swift in Sources */,
|
||||||
|
D049EAE91E44B67100A2CD3A /* RecentPeerItem.swift in Sources */,
|
||||||
D001F3F31E128A1C007A8C60 /* UpdateMessageService.swift in Sources */,
|
D001F3F31E128A1C007A8C60 /* UpdateMessageService.swift in Sources */,
|
||||||
D0B8442D1DAB91E0005F29E1 /* NBMetadataCoreTest.m in Sources */,
|
D0B8442D1DAB91E0005F29E1 /* NBMetadataCoreTest.m in Sources */,
|
||||||
D0B844131DAB91CD005F29E1 /* StringFormat.swift in Sources */,
|
D0B844131DAB91CD005F29E1 /* StringFormat.swift in Sources */,
|
||||||
@ -1362,6 +1395,7 @@
|
|||||||
D073CE6E1DCBCF17007511FD /* ForwardSourceInfoAttribute.swift in Sources */,
|
D073CE6E1DCBCF17007511FD /* ForwardSourceInfoAttribute.swift in Sources */,
|
||||||
D001F3E81E128A1C007A8C60 /* ChannelState.swift in Sources */,
|
D001F3E81E128A1C007A8C60 /* ChannelState.swift in Sources */,
|
||||||
D0B844451DAB91FD005F29E1 /* AccountViewTracker.swift in Sources */,
|
D0B844451DAB91FD005F29E1 /* AccountViewTracker.swift in Sources */,
|
||||||
|
D049EAD91E43DAD200A2CD3A /* ManagedRecentStickers.swift in Sources */,
|
||||||
D0B418A61D7E0592004562A4 /* CloudFileMediaResource.swift in Sources */,
|
D0B418A61D7E0592004562A4 /* CloudFileMediaResource.swift in Sources */,
|
||||||
D073CEA51DCBF3F5007511FD /* StickerManagement.swift in Sources */,
|
D073CEA51DCBF3F5007511FD /* StickerManagement.swift in Sources */,
|
||||||
D03C536D1DAD5CA9004C17B3 /* ApiGroupOrChannel.swift in Sources */,
|
D03C536D1DAD5CA9004C17B3 /* ApiGroupOrChannel.swift in Sources */,
|
||||||
@ -1427,6 +1461,7 @@
|
|||||||
D0448CA61E29215A005A61A7 /* MediaResourceApiUtils.swift in Sources */,
|
D0448CA61E29215A005A61A7 /* MediaResourceApiUtils.swift in Sources */,
|
||||||
D001F3F11E128A1C007A8C60 /* SynchronizePeerReadState.swift in Sources */,
|
D001F3F11E128A1C007A8C60 /* SynchronizePeerReadState.swift in Sources */,
|
||||||
D0F7B1E81E045C87007EB8A5 /* PeerParticipants.swift in Sources */,
|
D0F7B1E81E045C87007EB8A5 /* PeerParticipants.swift in Sources */,
|
||||||
|
D049EAD61E43D98500A2CD3A /* RecentMediaItem.swift in Sources */,
|
||||||
D0B844331DAB91E0005F29E1 /* NBPhoneNumber.m in Sources */,
|
D0B844331DAB91E0005F29E1 /* NBPhoneNumber.m in Sources */,
|
||||||
D001F3F51E128A1C007A8C60 /* PendingMessageManager.swift in Sources */,
|
D001F3F51E128A1C007A8C60 /* PendingMessageManager.swift in Sources */,
|
||||||
D001F3F61E128A1C007A8C60 /* PendingMessageUploadedContent.swift in Sources */,
|
D001F3F61E128A1C007A8C60 /* PendingMessageUploadedContent.swift in Sources */,
|
||||||
@ -1438,6 +1473,7 @@
|
|||||||
D0B844301DAB91E0005F29E1 /* NBNumberFormat.m in Sources */,
|
D0B844301DAB91E0005F29E1 /* NBNumberFormat.m in Sources */,
|
||||||
D001F3F71E128A1C007A8C60 /* ApplyUpdateMessage.swift in Sources */,
|
D001F3F71E128A1C007A8C60 /* ApplyUpdateMessage.swift in Sources */,
|
||||||
D0B418971D7E0580004562A4 /* TelegramMediaImage.swift in Sources */,
|
D0B418971D7E0580004562A4 /* TelegramMediaImage.swift in Sources */,
|
||||||
|
D049EAF61E44DF3300A2CD3A /* AccountState.swift in Sources */,
|
||||||
D0B844361DAB91E0005F29E1 /* NBPhoneNumberUtil.m in Sources */,
|
D0B844361DAB91E0005F29E1 /* NBPhoneNumberUtil.m in Sources */,
|
||||||
D073CE6F1DCBCF17007511FD /* OutgoingMessageInfoAttribute.swift in Sources */,
|
D073CE6F1DCBCF17007511FD /* OutgoingMessageInfoAttribute.swift in Sources */,
|
||||||
D0B844431DAB91FD005F29E1 /* Account.swift in Sources */,
|
D0B844431DAB91FD005F29E1 /* Account.swift in Sources */,
|
||||||
|
|||||||
@ -12,7 +12,7 @@
|
|||||||
<key>TelegramCoreMac.xcscheme</key>
|
<key>TelegramCoreMac.xcscheme</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>orderHint</key>
|
<key>orderHint</key>
|
||||||
<integer>7</integer>
|
<integer>5</integer>
|
||||||
</dict>
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
<key>SuppressBuildableAutocreation</key>
|
<key>SuppressBuildableAutocreation</key>
|
||||||
|
|||||||
@ -45,32 +45,6 @@ public func ==(lhs: AccountState, rhs: AccountState) -> Bool {
|
|||||||
return lhs.equalsTo(rhs)
|
return lhs.equalsTo(rhs)
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class UnauthorizedAccountState: AccountState {
|
|
||||||
let masterDatacenterId: Int32
|
|
||||||
|
|
||||||
public required init(decoder: Decoder) {
|
|
||||||
self.masterDatacenterId = decoder.decodeInt32ForKey("masterDatacenterId")
|
|
||||||
super.init()
|
|
||||||
}
|
|
||||||
|
|
||||||
override public func encode(_ encoder: Encoder) {
|
|
||||||
encoder.encodeInt32(self.masterDatacenterId, forKey: "masterDatacenterId")
|
|
||||||
}
|
|
||||||
|
|
||||||
init(masterDatacenterId: Int32) {
|
|
||||||
self.masterDatacenterId = masterDatacenterId
|
|
||||||
super.init()
|
|
||||||
}
|
|
||||||
|
|
||||||
override func equalsTo(_ other: AccountState) -> Bool {
|
|
||||||
if let other = other as? UnauthorizedAccountState {
|
|
||||||
return self.masterDatacenterId == other.masterDatacenterId
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class AuthorizedAccountState: AccountState {
|
public class AuthorizedAccountState: AccountState {
|
||||||
public final class State: Coding, Equatable, CustomStringConvertible {
|
public final class State: Coding, Equatable, CustomStringConvertible {
|
||||||
let pts: Int32
|
let pts: Int32
|
||||||
@ -177,21 +151,25 @@ public func generateAccountId() -> AccountId {
|
|||||||
|
|
||||||
public class UnauthorizedAccount {
|
public class UnauthorizedAccount {
|
||||||
public let id: AccountId
|
public let id: AccountId
|
||||||
|
public let appGroupPath: String
|
||||||
public let basePath: String
|
public let basePath: String
|
||||||
public let testingEnvironment: Bool
|
public let testingEnvironment: Bool
|
||||||
public let postbox: Postbox
|
public let postbox: Postbox
|
||||||
public let network: Network
|
public let network: Network
|
||||||
|
public let logger: Logger
|
||||||
|
|
||||||
public var masterDatacenterId: Int32 {
|
public var masterDatacenterId: Int32 {
|
||||||
return Int32(self.network.mtProto.datacenterId)
|
return Int32(self.network.mtProto.datacenterId)
|
||||||
}
|
}
|
||||||
|
|
||||||
init(id: AccountId, basePath: String, testingEnvironment: Bool, postbox: Postbox, network: Network) {
|
init(id: AccountId, appGroupPath: String, basePath: String, logger: Logger, testingEnvironment: Bool, postbox: Postbox, network: Network) {
|
||||||
self.id = id
|
self.id = id
|
||||||
|
self.appGroupPath = appGroupPath
|
||||||
self.basePath = basePath
|
self.basePath = basePath
|
||||||
self.testingEnvironment = testingEnvironment
|
self.testingEnvironment = testingEnvironment
|
||||||
self.postbox = postbox
|
self.postbox = postbox
|
||||||
self.network = network
|
self.network = network
|
||||||
|
self.logger = logger
|
||||||
network.shouldKeepConnection.set(.single(true))
|
network.shouldKeepConnection.set(.single(true))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,7 +188,7 @@ public class UnauthorizedAccount {
|
|||||||
|
|
||||||
return initializedNetwork(datacenterId: Int(masterDatacenterId), keychain: keychain, networkUsageInfoPath: accountNetworkUsageInfoPath(basePath: self.basePath), testingEnvironment: self.testingEnvironment)
|
return initializedNetwork(datacenterId: Int(masterDatacenterId), keychain: keychain, networkUsageInfoPath: accountNetworkUsageInfoPath(basePath: self.basePath), testingEnvironment: self.testingEnvironment)
|
||||||
|> map { network in
|
|> map { network in
|
||||||
return UnauthorizedAccount(id: self.id, basePath: self.basePath, testingEnvironment: self.testingEnvironment, postbox: self.postbox, network: network)
|
return UnauthorizedAccount(id: self.id, appGroupPath: self.appGroupPath, basePath: self.basePath, logger: self.logger, testingEnvironment: self.testingEnvironment, postbox: self.postbox, network: network)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -267,6 +245,8 @@ private var declaredEncodables: Void = {
|
|||||||
declareEncodable(GlobalNotificationSettings.self, f: { GlobalNotificationSettings(decoder: $0) })
|
declareEncodable(GlobalNotificationSettings.self, f: { GlobalNotificationSettings(decoder: $0) })
|
||||||
declareEncodable(CloudChatRemoveChatOperation.self, f: { CloudChatRemoveChatOperation(decoder: $0) })
|
declareEncodable(CloudChatRemoveChatOperation.self, f: { CloudChatRemoveChatOperation(decoder: $0) })
|
||||||
declareEncodable(SynchronizePinnedChatsOperation.self, f: { SynchronizePinnedChatsOperation(decoder: $0) })
|
declareEncodable(SynchronizePinnedChatsOperation.self, f: { SynchronizePinnedChatsOperation(decoder: $0) })
|
||||||
|
declareEncodable(RecentMediaItem.self, f: { RecentMediaItem(decoder: $0) })
|
||||||
|
declareEncodable(RecentPeerItem.self, f: { RecentPeerItem(decoder: $0) })
|
||||||
|
|
||||||
return
|
return
|
||||||
}()
|
}()
|
||||||
@ -275,8 +255,13 @@ func accountNetworkUsageInfoPath(basePath: String) -> String {
|
|||||||
return basePath + "/network-usage"
|
return basePath + "/network-usage"
|
||||||
}
|
}
|
||||||
|
|
||||||
public func accountWithId(_ id: AccountId, appGroupPath: String, testingEnvironment: Bool) -> Signal<Either<UnauthorizedAccount, Account>, NoError> {
|
public enum AccountLogger {
|
||||||
return Signal<(String, Postbox, AccountState?), NoError> { subscriber in
|
case named(String)
|
||||||
|
case instance(Logger)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func accountWithId(_ id: AccountId, appGroupPath: String, logger: AccountLogger, testingEnvironment: Bool) -> Signal<Either<UnauthorizedAccount, Account>, NoError> {
|
||||||
|
return Signal<(String, Postbox, Coding?), NoError> { subscriber in
|
||||||
let _ = declaredEncodables
|
let _ = declaredEncodables
|
||||||
|
|
||||||
let path = "\(appGroupPath)/account\(id.stringValue)"
|
let path = "\(appGroupPath)/account\(id.stringValue)"
|
||||||
@ -289,8 +274,9 @@ public func accountWithId(_ id: AccountId, appGroupPath: String, testingEnvironm
|
|||||||
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: allMessageTags)
|
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: allMessageTags)
|
||||||
|
|
||||||
let postbox = Postbox(basePath: path + "/postbox", globalMessageIdsNamespace: Namespaces.Message.Cloud, seedConfiguration: seedConfiguration)
|
let postbox = Postbox(basePath: path + "/postbox", globalMessageIdsNamespace: Namespaces.Message.Cloud, seedConfiguration: seedConfiguration)
|
||||||
return (postbox.state() |> take(1) |> map { accountState in
|
return (postbox.stateView() |> take(1) |> map { view -> (String, Postbox, Coding?) in
|
||||||
return (path, postbox, accountState as? AccountState)
|
let accountState = view.state
|
||||||
|
return (path, postbox, accountState)
|
||||||
}).start(next: { args in
|
}).start(next: { args in
|
||||||
subscriber.putNext(args)
|
subscriber.putNext(args)
|
||||||
subscriber.putCompletion()
|
subscriber.putCompletion()
|
||||||
@ -304,17 +290,25 @@ public func accountWithId(_ id: AccountId, appGroupPath: String, testingEnvironm
|
|||||||
postbox.removeKeychainEntryForKey(key)
|
postbox.removeKeychainEntryForKey(key)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
let concreteLogger: Logger
|
||||||
|
switch logger {
|
||||||
|
case let .named(name):
|
||||||
|
concreteLogger = Logger(basePath: basePath + "/" + name)
|
||||||
|
case let .instance(instance):
|
||||||
|
concreteLogger = instance
|
||||||
|
}
|
||||||
|
|
||||||
if let accountState = accountState {
|
if let accountState = accountState {
|
||||||
switch accountState {
|
switch accountState {
|
||||||
case let unauthorizedState as UnauthorizedAccountState:
|
case let unauthorizedState as UnauthorizedAccountState:
|
||||||
return initializedNetwork(datacenterId: Int(unauthorizedState.masterDatacenterId), keychain: keychain, networkUsageInfoPath: accountNetworkUsageInfoPath(basePath: basePath), testingEnvironment: testingEnvironment)
|
return initializedNetwork(datacenterId: Int(unauthorizedState.masterDatacenterId), keychain: keychain, networkUsageInfoPath: accountNetworkUsageInfoPath(basePath: basePath), testingEnvironment: testingEnvironment)
|
||||||
|> map { network -> Either<UnauthorizedAccount, Account> in
|
|> map { network -> Either<UnauthorizedAccount, Account> in
|
||||||
.left(value: UnauthorizedAccount(id: id, basePath: basePath, testingEnvironment: testingEnvironment, postbox: postbox, network: network))
|
.left(value: UnauthorizedAccount(id: id, appGroupPath: appGroupPath, basePath: basePath, logger: concreteLogger, testingEnvironment: testingEnvironment, postbox: postbox, network: network))
|
||||||
}
|
}
|
||||||
case let authorizedState as AuthorizedAccountState:
|
case let authorizedState as AuthorizedAccountState:
|
||||||
return initializedNetwork(datacenterId: Int(authorizedState.masterDatacenterId), keychain: keychain, networkUsageInfoPath: accountNetworkUsageInfoPath(basePath: basePath), testingEnvironment: testingEnvironment)
|
return initializedNetwork(datacenterId: Int(authorizedState.masterDatacenterId), keychain: keychain, networkUsageInfoPath: accountNetworkUsageInfoPath(basePath: basePath), testingEnvironment: testingEnvironment)
|
||||||
|> map { network -> Either<UnauthorizedAccount, Account> in
|
|> map { network -> Either<UnauthorizedAccount, Account> in
|
||||||
return .right(value: Account(id: id, basePath: basePath, testingEnvironment: testingEnvironment, postbox: postbox, network: network, peerId: authorizedState.peerId))
|
return .right(value: Account(id: id, basePath: basePath, logger: concreteLogger, testingEnvironment: testingEnvironment, postbox: postbox, network: network, peerId: authorizedState.peerId))
|
||||||
}
|
}
|
||||||
case _:
|
case _:
|
||||||
assertionFailure("Unexpected accountState \(accountState)")
|
assertionFailure("Unexpected accountState \(accountState)")
|
||||||
@ -323,7 +317,7 @@ public func accountWithId(_ id: AccountId, appGroupPath: String, testingEnvironm
|
|||||||
|
|
||||||
return initializedNetwork(datacenterId: 2, keychain: keychain, networkUsageInfoPath: accountNetworkUsageInfoPath(basePath: basePath), testingEnvironment: testingEnvironment)
|
return initializedNetwork(datacenterId: 2, keychain: keychain, networkUsageInfoPath: accountNetworkUsageInfoPath(basePath: basePath), testingEnvironment: testingEnvironment)
|
||||||
|> map { network -> Either<UnauthorizedAccount, Account> in
|
|> map { network -> Either<UnauthorizedAccount, Account> in
|
||||||
return .left(value: UnauthorizedAccount(id: id, basePath: basePath, testingEnvironment: testingEnvironment, postbox: postbox, network: network))
|
return .left(value: UnauthorizedAccount(id: id, appGroupPath: appGroupPath, basePath: basePath, logger: concreteLogger, testingEnvironment: testingEnvironment, postbox: postbox, network: network))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -393,6 +387,8 @@ public class Account {
|
|||||||
public let network: Network
|
public let network: Network
|
||||||
public let peerId: PeerId
|
public let peerId: PeerId
|
||||||
|
|
||||||
|
public let logger: Logger
|
||||||
|
|
||||||
public private(set) var stateManager: AccountStateManager!
|
public private(set) var stateManager: AccountStateManager!
|
||||||
public private(set) var viewTracker: AccountViewTracker!
|
public private(set) var viewTracker: AccountViewTracker!
|
||||||
public private(set) var pendingMessageManager: PendingMessageManager!
|
public private(set) var pendingMessageManager: PendingMessageManager!
|
||||||
@ -426,13 +422,14 @@ public class Account {
|
|||||||
return self.networkStateValue.get()
|
return self.networkStateValue.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(id: AccountId, basePath: String, testingEnvironment: Bool, postbox: Postbox, network: Network, peerId: PeerId) {
|
public init(id: AccountId, basePath: String, logger: Logger, testingEnvironment: Bool, postbox: Postbox, network: Network, peerId: PeerId) {
|
||||||
self.id = id
|
self.id = id
|
||||||
self.basePath = basePath
|
self.basePath = basePath
|
||||||
self.testingEnvironment = testingEnvironment
|
self.testingEnvironment = testingEnvironment
|
||||||
self.postbox = postbox
|
self.postbox = postbox
|
||||||
self.network = network
|
self.network = network
|
||||||
self.peerId = peerId
|
self.peerId = peerId
|
||||||
|
self.logger = logger
|
||||||
|
|
||||||
self.peerInputActivityManager = PeerInputActivityManager()
|
self.peerInputActivityManager = PeerInputActivityManager()
|
||||||
self.stateManager = AccountStateManager(account: self, peerInputActivityManager: self.peerInputActivityManager)
|
self.stateManager = AccountStateManager(account: self, peerInputActivityManager: self.peerInputActivityManager)
|
||||||
@ -471,8 +468,6 @@ public class Account {
|
|||||||
|
|
||||||
let appVersionString = "\(Bundle.main.infoDictionary?["CFBundleShortVersionString"] ?? "") (\(Bundle.main.infoDictionary?["CFBundleVersion"] ?? ""))"
|
let appVersionString = "\(Bundle.main.infoDictionary?["CFBundleShortVersionString"] ?? "") (\(Bundle.main.infoDictionary?["CFBundleVersion"] ?? ""))"
|
||||||
|
|
||||||
let langCode = NSLocale.preferredLanguages.first ?? "en"
|
|
||||||
|
|
||||||
#if os(macOS)
|
#if os(macOS)
|
||||||
let pInfo = ProcessInfo.processInfo
|
let pInfo = ProcessInfo.processInfo
|
||||||
let systemVersion = pInfo.operatingSystemVersionString
|
let systemVersion = pInfo.operatingSystemVersionString
|
||||||
@ -506,8 +501,6 @@ public class Account {
|
|||||||
|
|
||||||
let appVersionString = "\(Bundle.main.infoDictionary?["CFBundleShortVersionString"] ?? "") (\(Bundle.main.infoDictionary?["CFBundleVersion"] ?? ""))"
|
let appVersionString = "\(Bundle.main.infoDictionary?["CFBundleShortVersionString"] ?? "") (\(Bundle.main.infoDictionary?["CFBundleVersion"] ?? ""))"
|
||||||
|
|
||||||
let langCode = NSLocale.preferredLanguages.first ?? "en"
|
|
||||||
|
|
||||||
#if os(macOS)
|
#if os(macOS)
|
||||||
let pInfo = ProcessInfo.processInfo
|
let pInfo = ProcessInfo.processInfo
|
||||||
let systemVersion = pInfo.operatingSystemVersionString
|
let systemVersion = pInfo.operatingSystemVersionString
|
||||||
@ -567,6 +560,9 @@ public class Account {
|
|||||||
self.managedOperationsDisposable.add(managedAutoremoveMessageOperations(postbox: self.postbox).start())
|
self.managedOperationsDisposable.add(managedAutoremoveMessageOperations(postbox: self.postbox).start())
|
||||||
self.managedOperationsDisposable.add(managedGlobalNotificationSettings(postbox: self.postbox, network: self.network).start())
|
self.managedOperationsDisposable.add(managedGlobalNotificationSettings(postbox: self.postbox, network: self.network).start())
|
||||||
self.managedOperationsDisposable.add(managedSynchronizePinnedChatsOperations(postbox: self.postbox, network: self.network, stateManager: self.stateManager).start())
|
self.managedOperationsDisposable.add(managedSynchronizePinnedChatsOperations(postbox: self.postbox, network: self.network, stateManager: self.stateManager).start())
|
||||||
|
self.managedOperationsDisposable.add(managedRecentStickers(postbox: self.postbox, network: self.network).start())
|
||||||
|
self.managedOperationsDisposable.add(managedRecentGifs(postbox: self.postbox, network: self.network).start())
|
||||||
|
self.managedOperationsDisposable.add(managedRecentlyUsedInlineBots(postbox: self.postbox, network: self.network).start())
|
||||||
|
|
||||||
let updatedPresence = self.shouldKeepOnlinePresence.get()
|
let updatedPresence = self.shouldKeepOnlinePresence.get()
|
||||||
|> distinctUntilChanged
|
|> distinctUntilChanged
|
||||||
@ -597,8 +593,6 @@ public class Account {
|
|||||||
return combineLatest(pushStatusOnce, updatePresenceLocally)
|
return combineLatest(pushStatusOnce, updatePresenceLocally)
|
||||||
|> mapToSignal { _ -> Signal<Void, NoError> in return .complete() }
|
|> mapToSignal { _ -> Signal<Void, NoError> in return .complete() }
|
||||||
}
|
}
|
||||||
|
|
||||||
return .complete()
|
|
||||||
} else {
|
} else {
|
||||||
return .complete()
|
return .complete()
|
||||||
}
|
}
|
||||||
@ -616,7 +610,7 @@ public class Account {
|
|||||||
self.managedOperationsDisposable.dispose()
|
self.managedOperationsDisposable.dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
public func currentNetworkStats() -> Signal<MTNetworkUsageManagerStats, NoError> {
|
/*public func currentNetworkStats() -> Signal<MTNetworkUsageManagerStats, NoError> {
|
||||||
return Signal { subscriber in
|
return Signal { subscriber in
|
||||||
let manager = MTNetworkUsageManager(info: MTNetworkUsageCalculationInfo(filePath: accountNetworkUsageInfoPath(basePath: self.basePath)))!
|
let manager = MTNetworkUsageManager(info: MTNetworkUsageCalculationInfo(filePath: accountNetworkUsageInfoPath(basePath: self.basePath)))!
|
||||||
manager.currentStats().start(next: { next in
|
manager.currentStats().start(next: { next in
|
||||||
@ -628,7 +622,7 @@ public class Account {
|
|||||||
|
|
||||||
return EmptyDisposable
|
return EmptyDisposable
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
public func peerInputActivities(peerId: PeerId) -> Signal<[(PeerId, PeerInputActivity)], NoError> {
|
public func peerInputActivities(peerId: PeerId) -> Signal<[(PeerId, PeerInputActivity)], NoError> {
|
||||||
return self.peerInputActivityManager.activities(peerId: peerId)
|
return self.peerInputActivityManager.activities(peerId: peerId)
|
||||||
|
|||||||
194
TelegramCore/AccountState.swift
Normal file
194
TelegramCore/AccountState.swift
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
import Foundation
|
||||||
|
import Postbox
|
||||||
|
|
||||||
|
private enum SentAuthorizationCodeTypeValue: Int32 {
|
||||||
|
case otherSession = 0
|
||||||
|
case sms = 1
|
||||||
|
case call = 2
|
||||||
|
case flashCall = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum SentAuthorizationCodeType: Coding, Equatable {
|
||||||
|
case otherSession(length: Int32)
|
||||||
|
case sms(length: Int32)
|
||||||
|
case call(length: Int32)
|
||||||
|
case flashCall(pattern: String)
|
||||||
|
|
||||||
|
public init(decoder: Decoder) {
|
||||||
|
switch decoder.decodeInt32ForKey("v") as Int32 {
|
||||||
|
case SentAuthorizationCodeTypeValue.otherSession.rawValue:
|
||||||
|
self = .otherSession(length: decoder.decodeInt32ForKey("l"))
|
||||||
|
case SentAuthorizationCodeTypeValue.sms.rawValue:
|
||||||
|
self = .sms(length: decoder.decodeInt32ForKey("l"))
|
||||||
|
case SentAuthorizationCodeTypeValue.call.rawValue:
|
||||||
|
self = .call(length: decoder.decodeInt32ForKey("l"))
|
||||||
|
case SentAuthorizationCodeTypeValue.flashCall.rawValue:
|
||||||
|
self = .flashCall(pattern: decoder.decodeStringForKey("p"))
|
||||||
|
default:
|
||||||
|
preconditionFailure()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func encode(_ encoder: Encoder) {
|
||||||
|
switch self {
|
||||||
|
case let .otherSession(length):
|
||||||
|
encoder.encodeInt32(SentAuthorizationCodeTypeValue.otherSession.rawValue, forKey: "v")
|
||||||
|
encoder.encodeInt32(length, forKey: "l")
|
||||||
|
case let .sms(length):
|
||||||
|
encoder.encodeInt32(SentAuthorizationCodeTypeValue.sms.rawValue, forKey: "v")
|
||||||
|
encoder.encodeInt32(length, forKey: "l")
|
||||||
|
case let .call(length):
|
||||||
|
encoder.encodeInt32(SentAuthorizationCodeTypeValue.call.rawValue, forKey: "v")
|
||||||
|
encoder.encodeInt32(length, forKey: "l")
|
||||||
|
case let .flashCall(pattern):
|
||||||
|
encoder.encodeInt32(SentAuthorizationCodeTypeValue.flashCall.rawValue, forKey: "v")
|
||||||
|
encoder.encodeString(pattern, forKey: "p")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func ==(lhs: SentAuthorizationCodeType, rhs: SentAuthorizationCodeType) -> Bool {
|
||||||
|
switch lhs {
|
||||||
|
case let .otherSession(length):
|
||||||
|
if case .otherSession(length) = rhs {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case let .sms(length):
|
||||||
|
if case .sms(length) = rhs {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case let .call(length):
|
||||||
|
if case .call(length) = rhs {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case let .flashCall(pattern):
|
||||||
|
if case .flashCall(pattern) = rhs {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum AuthorizationCodeNextType: Int32 {
|
||||||
|
case sms = 0
|
||||||
|
case call = 1
|
||||||
|
case flashCall = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum UnauthorizedAccountStateContentsValue: Int32 {
|
||||||
|
case empty = 0
|
||||||
|
case phoneEntry = 1
|
||||||
|
case confirmationCodeEntry = 2
|
||||||
|
case passwordEntry = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum UnauthorizedAccountStateContents: Coding {
|
||||||
|
case empty
|
||||||
|
case phoneEntry(countryCode: Int32, number: String)
|
||||||
|
case confirmationCodeEntry(number: String, type: SentAuthorizationCodeType, hash: String, timeout: Int32?, nextType: AuthorizationCodeNextType?)
|
||||||
|
case passwordEntry(hint: String)
|
||||||
|
|
||||||
|
public init(decoder: Decoder) {
|
||||||
|
switch decoder.decodeInt32ForKey("v") as Int32 {
|
||||||
|
case UnauthorizedAccountStateContentsValue.empty.rawValue:
|
||||||
|
self = .empty
|
||||||
|
case UnauthorizedAccountStateContentsValue.phoneEntry.rawValue:
|
||||||
|
self = .phoneEntry(countryCode: decoder.decodeInt32ForKey("cc"), number: decoder.decodeStringForKey("n"))
|
||||||
|
case UnauthorizedAccountStateContentsValue.confirmationCodeEntry.rawValue:
|
||||||
|
var nextType: AuthorizationCodeNextType?
|
||||||
|
if let value = decoder.decodeInt32ForKey("nt") as Int32? {
|
||||||
|
nextType = AuthorizationCodeNextType(rawValue: value)
|
||||||
|
}
|
||||||
|
self = .confirmationCodeEntry(number: decoder.decodeStringForKey("num"), type: decoder.decodeObjectForKey("t", decoder: { SentAuthorizationCodeType(decoder: $0) }) as! SentAuthorizationCodeType, hash: decoder.decodeStringForKey("h"), timeout: decoder.decodeInt32ForKey("tm"), nextType: nextType)
|
||||||
|
case UnauthorizedAccountStateContentsValue.passwordEntry.rawValue:
|
||||||
|
self = .passwordEntry(hint: decoder.decodeStringForKey("h"))
|
||||||
|
default:
|
||||||
|
assertionFailure()
|
||||||
|
self = .empty
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func encode(_ encoder: Encoder) {
|
||||||
|
switch self {
|
||||||
|
case .empty:
|
||||||
|
encoder.encodeInt32(UnauthorizedAccountStateContentsValue.empty.rawValue, forKey: "v")
|
||||||
|
case let .phoneEntry(countryCode, number):
|
||||||
|
encoder.encodeInt32(UnauthorizedAccountStateContentsValue.phoneEntry.rawValue, forKey: "v")
|
||||||
|
encoder.encodeInt32(countryCode, forKey: "cc")
|
||||||
|
encoder.encodeString(number, forKey: "n")
|
||||||
|
case let .confirmationCodeEntry(number, type, hash, timeout, nextType):
|
||||||
|
encoder.encodeInt32(UnauthorizedAccountStateContentsValue.confirmationCodeEntry.rawValue, forKey: "v")
|
||||||
|
encoder.encodeString(number, forKey: "num")
|
||||||
|
encoder.encodeObject(type, forKey: "t")
|
||||||
|
encoder.encodeString(hash, forKey: "h")
|
||||||
|
if let timeout = timeout {
|
||||||
|
encoder.encodeInt32(timeout, forKey: "tm")
|
||||||
|
} else {
|
||||||
|
encoder.encodeNil(forKey: "tm")
|
||||||
|
}
|
||||||
|
if let nextType = nextType {
|
||||||
|
encoder.encodeInt32(nextType.rawValue, forKey: "nt")
|
||||||
|
} else {
|
||||||
|
encoder.encodeNil(forKey: "nt")
|
||||||
|
}
|
||||||
|
case let .passwordEntry(hint):
|
||||||
|
encoder.encodeInt32(UnauthorizedAccountStateContentsValue.passwordEntry.rawValue, forKey: "v")
|
||||||
|
encoder.encodeString(hint, forKey: "h")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class UnauthorizedAccountState: Coding {
|
||||||
|
public let masterDatacenterId: Int32
|
||||||
|
public let contents: UnauthorizedAccountStateContents
|
||||||
|
|
||||||
|
public init(masterDatacenterId: Int32, contents: UnauthorizedAccountStateContents) {
|
||||||
|
self.masterDatacenterId = masterDatacenterId
|
||||||
|
self.contents = contents
|
||||||
|
}
|
||||||
|
|
||||||
|
public init(decoder: Decoder) {
|
||||||
|
self.masterDatacenterId = decoder.decodeInt32ForKey("dc")
|
||||||
|
self.contents = decoder.decodeObjectForKey("c", decoder: { UnauthorizedAccountStateContents(decoder: $0) }) as! UnauthorizedAccountStateContents
|
||||||
|
}
|
||||||
|
|
||||||
|
public func encode(_ encoder: Encoder) {
|
||||||
|
encoder.encodeInt32(self.masterDatacenterId, forKey: "dc")
|
||||||
|
encoder.encodeObject(self.contents, forKey: "c")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public extension SentAuthorizationCodeType {
|
||||||
|
init(apiType: Api.auth.SentCodeType) {
|
||||||
|
switch apiType {
|
||||||
|
case let .sentCodeTypeApp(length):
|
||||||
|
self = .otherSession(length: length)
|
||||||
|
case let .sentCodeTypeSms(length):
|
||||||
|
self = .sms(length: length)
|
||||||
|
case let .sentCodeTypeCall(length):
|
||||||
|
self = .call(length: length)
|
||||||
|
case let .sentCodeTypeFlashCall(pattern):
|
||||||
|
self = .flashCall(pattern: pattern)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public extension AuthorizationCodeNextType {
|
||||||
|
init(apiType: Api.auth.CodeType) {
|
||||||
|
switch apiType {
|
||||||
|
case .codeTypeSms:
|
||||||
|
self = .sms
|
||||||
|
case .codeTypeCall:
|
||||||
|
self = .call
|
||||||
|
case .codeTypeFlashCall:
|
||||||
|
self = .flashCall
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1003,8 +1003,6 @@ private func resolveMissingPeerNotificationSettings(account: Account, state: Acc
|
|||||||
return updatedState
|
return updatedState
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return .single(state)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func pollChannel(_ account: Account, peer: Peer, state: AccountMutableState) -> Signal<AccountMutableState, NoError> {
|
private func pollChannel(_ account: Account, peer: Peer, state: AccountMutableState) -> Signal<AccountMutableState, NoError> {
|
||||||
@ -1135,7 +1133,7 @@ private func verifyTransaction(_ modifier: Modifier, finalState: AccountMutableS
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !previousStateMatches {
|
if !previousStateMatches {
|
||||||
trace("State", what: ".UpdateState previous state \(previousState) doesn't match current state \(currentState)")
|
trace("State", what: ".UpdateState previous state \(previousState) doesn't match current state \(String(describing: currentState))")
|
||||||
failed = true
|
failed = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1152,7 +1150,7 @@ private func verifyTransaction(_ modifier: Modifier, finalState: AccountMutableS
|
|||||||
previousStateMatches = true
|
previousStateMatches = true
|
||||||
}
|
}
|
||||||
if !previousStateMatches {
|
if !previousStateMatches {
|
||||||
trace("State", what: ".UpdateChannelState for \(peerId), previous state \(previousState) doesn't match current state \(currentState)")
|
trace("State", what: ".UpdateChannelState for \(peerId), previous state \(previousState) doesn't match current state \(String(describing: currentState))")
|
||||||
failed = true
|
failed = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -198,18 +198,17 @@ public final class AccountStateManager {
|
|||||||
self.currentIsUpdatingValue = true
|
self.currentIsUpdatingValue = true
|
||||||
let account = self.account
|
let account = self.account
|
||||||
let mediaBox = account.postbox.mediaBox
|
let mediaBox = account.postbox.mediaBox
|
||||||
let queue = self.queue
|
let signal = account.postbox.stateView()
|
||||||
let signal = account.postbox.state()
|
|> mapToSignal { view -> Signal<AuthorizedAccountState, NoError> in
|
||||||
|> filter { state in
|
if let state = view.state as? AuthorizedAccountState {
|
||||||
if let _ = state as? AuthorizedAccountState {
|
return .single(state)
|
||||||
return true
|
|
||||||
} else {
|
} else {
|
||||||
return false
|
return .complete()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|> take(1)
|
|> take(1)
|
||||||
|> mapToSignal { state -> Signal<(Api.updates.Difference?, AccountReplayedFinalState?), NoError> in
|
|> mapToSignal { state -> Signal<(Api.updates.Difference?, AccountReplayedFinalState?), NoError> in
|
||||||
if let authorizedState = (state as! AuthorizedAccountState).state {
|
if let authorizedState = state.state {
|
||||||
let request = account.network.request(Api.functions.updates.getDifference(flags: 0, pts: authorizedState.pts, ptsTotalLimit: nil, date: authorizedState.date, qts: authorizedState.qts))
|
let request = account.network.request(Api.functions.updates.getDifference(flags: 0, pts: authorizedState.pts, ptsTotalLimit: nil, date: authorizedState.date, qts: authorizedState.qts))
|
||||||
|> retryRequest
|
|> retryRequest
|
||||||
return request |> mapToSignal { difference -> Signal<(Api.updates.Difference?, AccountReplayedFinalState?), NoError> in
|
return request |> mapToSignal { difference -> Signal<(Api.updates.Difference?, AccountReplayedFinalState?), NoError> in
|
||||||
@ -255,9 +254,9 @@ public final class AccountStateManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|> deliverOn(self.queue)
|
|> deliverOn(self.queue)
|
||||||
signal.start(next: { [weak self] difference, finalState in
|
let _ = signal.start(next: { [weak self] difference, finalState in
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
if case let .pollDifference = strongSelf.operations.removeFirst() {
|
if case .pollDifference = strongSelf.operations.removeFirst() {
|
||||||
let events: AccountFinalStateEvents
|
let events: AccountFinalStateEvents
|
||||||
if let finalState = finalState {
|
if let finalState = finalState {
|
||||||
events = currentEvents.union(with: AccountFinalStateEvents(state: finalState))
|
events = currentEvents.union(with: AccountFinalStateEvents(state: finalState))
|
||||||
@ -365,7 +364,7 @@ public final class AccountStateManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(signal |> deliverOn(self.queue)).start(error: { _ in
|
let _ = (signal |> deliverOn(self.queue)).start(error: { _ in
|
||||||
completed()
|
completed()
|
||||||
}, completed: {
|
}, completed: {
|
||||||
completed()
|
completed()
|
||||||
@ -441,10 +440,10 @@ public final class AccountStateManager {
|
|||||||
return messages
|
return messages
|
||||||
}
|
}
|
||||||
|
|
||||||
(signal |> deliverOn(self.queue)).start(next: { [weak self] messages in
|
let _ = (signal |> deliverOn(self.queue)).start(next: { [weak self] messages in
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
for message in messages {
|
for message in messages {
|
||||||
print("notify: \(messageMainPeer(message)?.displayTitle): \(message.id)")
|
print("notify: \(String(describing: messageMainPeer(message)?.displayTitle)): \(message.id)")
|
||||||
}
|
}
|
||||||
|
|
||||||
strongSelf.notificationMessagesPipe.putNext(messages)
|
strongSelf.notificationMessagesPipe.putNext(messages)
|
||||||
@ -458,7 +457,7 @@ public final class AccountStateManager {
|
|||||||
if self.operations.count > 1 {
|
if self.operations.count > 1 {
|
||||||
self.operations.removeFirst()
|
self.operations.removeFirst()
|
||||||
for (id, f) in preSubscribers {
|
for (id, f) in preSubscribers {
|
||||||
self.addPollCompletion(f, id: id)
|
let _ = self.addPollCompletion(f, id: id)
|
||||||
}
|
}
|
||||||
self.startFirstOperation()
|
self.startFirstOperation()
|
||||||
} else {
|
} else {
|
||||||
@ -477,7 +476,7 @@ public final class AccountStateManager {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (id, f) in subscribers {
|
for (id, f) in subscribers {
|
||||||
strongSelf.addPollCompletion(f, id: id)
|
let _ = strongSelf.addPollCompletion(f, id: id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
strongSelf.startFirstOperation()
|
strongSelf.startFirstOperation()
|
||||||
@ -486,7 +485,7 @@ public final class AccountStateManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(signal |> deliverOn(self.queue)).start(error: { _ in
|
let _ = (signal |> deliverOn(self.queue)).start(error: { _ in
|
||||||
completed()
|
completed()
|
||||||
}, completed: {
|
}, completed: {
|
||||||
completed()
|
completed()
|
||||||
|
|||||||
@ -47,6 +47,8 @@ func applyUpdateMessage(postbox: Postbox, stateManager: AccountStateManager, mes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var sentStickers: [TelegramMediaFile] = []
|
||||||
|
|
||||||
modifier.updateMessage(message.id, update: { currentMessage in
|
modifier.updateMessage(message.id, update: { currentMessage in
|
||||||
let updatedId: MessageId
|
let updatedId: MessageId
|
||||||
if let messageId = messageId {
|
if let messageId = messageId {
|
||||||
@ -97,11 +99,20 @@ func applyUpdateMessage(postbox: Postbox, stateManager: AccountStateManager, mes
|
|||||||
applyMediaResourceChanges(from: fromMedia, to: toMedia, postbox: postbox)
|
applyMediaResourceChanges(from: fromMedia, to: toMedia, postbox: postbox)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for media in media {
|
||||||
|
if let file = media as? TelegramMediaFile, file.isSticker {
|
||||||
|
sentStickers.append(file)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return StoreMessage(id: updatedId, globallyUniqueId: nil, timestamp: updatedTimestamp ?? currentMessage.timestamp, flags: [], tags: tagsForStoreMessage(media), forwardInfo: storeForwardInfo, authorId: currentMessage.author?.id, text: text, attributes: attributes, media: media)
|
return StoreMessage(id: updatedId, globallyUniqueId: nil, timestamp: updatedTimestamp ?? currentMessage.timestamp, flags: [], tags: tagsForStoreMessage(media), forwardInfo: storeForwardInfo, authorId: currentMessage.author?.id, text: text, attributes: attributes, media: media)
|
||||||
})
|
})
|
||||||
if let updatedTimestamp = updatedTimestamp {
|
if let updatedTimestamp = updatedTimestamp {
|
||||||
modifier.offsetPendingMessagesTimestamps(lowerBound: message.id, timestamp: updatedTimestamp)
|
modifier.offsetPendingMessagesTimestamps(lowerBound: message.id, timestamp: updatedTimestamp)
|
||||||
}
|
}
|
||||||
|
for file in sentStickers {
|
||||||
|
modifier.addOrMoveToFirstPositionOrderedItemListItem(collectionId: Namespaces.OrderedItemList.CloudRecentStickers, item: OrderedItemListEntry(id: RecentMediaItemId(file.fileId).rawValue, contents: RecentMediaItem(file)), removeTailIfCountExceeds: 20)
|
||||||
|
}
|
||||||
stateManager.addUpdates(result)
|
stateManager.addUpdates(result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
15
TelegramCore/InteractivePhoneFormatter.swift
Normal file
15
TelegramCore/InteractivePhoneFormatter.swift
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import Foundation
|
||||||
|
import TelegramCorePrivateModule
|
||||||
|
|
||||||
|
public final class InteractivePhoneFormatter {
|
||||||
|
private let formatter = NBAsYouTypeFormatter(regionCode: "US")!
|
||||||
|
|
||||||
|
public init() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public func updateText(_ text: String) -> (String?, String) {
|
||||||
|
self.formatter.clear()
|
||||||
|
let string = self.formatter.inputString(text)
|
||||||
|
return (self.formatter.regionPrefix, string ?? "")
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -29,14 +29,13 @@ public func trace(_ domain: String, what: @autoclosure() -> String) {
|
|||||||
|
|
||||||
var curTime = timeval()
|
var curTime = timeval()
|
||||||
gettimeofday(&curTime, nil)
|
gettimeofday(&curTime, nil)
|
||||||
|
let seconds = curTime.tv_sec
|
||||||
let milliseconds = curTime.tv_usec / 1000
|
let milliseconds = curTime.tv_usec / 1000
|
||||||
|
|
||||||
queue.async {
|
queue.async {
|
||||||
let result = String(format: "[%@] %d-%d-%d %02d:%02d:%03d %@", arguments: [domain, Int(timeinfo.tm_year) + 1900, Int(timeinfo.tm_mon + 1), Int(timeinfo.tm_yday), Int(timeinfo.tm_hour), Int(timeinfo.tm_min), Int(milliseconds), string])
|
let result = String(format: "[%@] %d-%d-%d %02d:%02d:%02d.%03d %@", arguments: [domain, Int(timeinfo.tm_year) + 1900, Int(timeinfo.tm_mon + 1), Int(timeinfo.tm_yday), Int(timeinfo.tm_hour), Int(timeinfo.tm_min), Int(seconds), Int(milliseconds), string])
|
||||||
|
|
||||||
//#if (arch(i386) || arch(x86_64))
|
|
||||||
print(result)
|
print(result)
|
||||||
//#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,10 +43,111 @@ public func registerLoggingFunctions() {
|
|||||||
setBridgingTraceFunction({ domain, what in
|
setBridgingTraceFunction({ domain, what in
|
||||||
if let what = what {
|
if let what = what {
|
||||||
if let domain = domain {
|
if let domain = domain {
|
||||||
trace(domain as String, what: what as String)
|
trace(domain, what: what as String)
|
||||||
} else {
|
} else {
|
||||||
trace(what as String)
|
trace("", what: what as String)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final class Logger {
|
||||||
|
private let queue = DispatchQueue(label: "org.telegram.Telegram.log", qos: .utility)
|
||||||
|
private let maxLength: Int = 512 * 1024
|
||||||
|
private let maxFiles: Int = 20
|
||||||
|
|
||||||
|
private let basePath: String
|
||||||
|
private var file: (Int32, Int)?
|
||||||
|
|
||||||
|
init(basePath: String) {
|
||||||
|
self.basePath = basePath
|
||||||
|
}
|
||||||
|
|
||||||
|
func log(_ tag: String, _ what: @autoclosure () -> String) {
|
||||||
|
let string = what()
|
||||||
|
|
||||||
|
var rawTime = time_t()
|
||||||
|
time(&rawTime)
|
||||||
|
var timeinfo = tm()
|
||||||
|
localtime_r(&rawTime, &timeinfo)
|
||||||
|
|
||||||
|
var curTime = timeval()
|
||||||
|
gettimeofday(&curTime, nil)
|
||||||
|
let seconds = curTime.tv_sec
|
||||||
|
let milliseconds = curTime.tv_usec / 1000
|
||||||
|
|
||||||
|
let content = String(format: "[%@] %d-%d-%d %02d:%02d:%02d.%03d %@", arguments: [tag, Int(timeinfo.tm_year) + 1900, Int(timeinfo.tm_mon + 1), Int(timeinfo.tm_yday), Int(timeinfo.tm_hour), Int(timeinfo.tm_min), Int(seconds), Int(milliseconds), string])
|
||||||
|
|
||||||
|
self.queue.async {
|
||||||
|
var fd: Int32?
|
||||||
|
var createNew = false
|
||||||
|
if let (file, length) = self.file {
|
||||||
|
if length < self.maxLength {
|
||||||
|
close(file)
|
||||||
|
createNew = true
|
||||||
|
} else {
|
||||||
|
fd = file
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let _ = try? FileManager.default.createDirectory(atPath: self.basePath, withIntermediateDirectories: true, attributes: nil)
|
||||||
|
if let files = try? FileManager.default.contentsOfDirectory(at: URL(fileURLWithPath: self.basePath), includingPropertiesForKeys: [URLResourceKey.creationDateKey], options: []) {
|
||||||
|
var minCreationDate: (Date, URL)?
|
||||||
|
var maxCreationDate: (Date, URL)?
|
||||||
|
var count = 0
|
||||||
|
for url in files {
|
||||||
|
if url.lastPathComponent.hasPrefix("log-") {
|
||||||
|
if let values = try? url.resourceValues(forKeys: Set([URLResourceKey.creationDateKey])), let creationDate = values.creationDate {
|
||||||
|
count += 1
|
||||||
|
if minCreationDate == nil || minCreationDate!.0 > creationDate {
|
||||||
|
minCreationDate = (creationDate, url)
|
||||||
|
}
|
||||||
|
if maxCreationDate == nil || maxCreationDate!.0 < creationDate {
|
||||||
|
maxCreationDate = (creationDate, url)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let (_, url) = minCreationDate, count >= self.maxFiles {
|
||||||
|
let _ = try? FileManager.default.removeItem(at: url)
|
||||||
|
}
|
||||||
|
if let (_, url) = maxCreationDate {
|
||||||
|
var value = stat()
|
||||||
|
if stat(url.path, &value) == 0 && Int(value.st_size) < self.maxLength {
|
||||||
|
let handle = open(url.path, O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR)
|
||||||
|
if handle >= 0 {
|
||||||
|
fd = handle
|
||||||
|
self.file = (handle, Int(value.st_size))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
createNew = true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
createNew = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if createNew {
|
||||||
|
let path = self.basePath + "/log-\(Date()).txt"
|
||||||
|
|
||||||
|
let handle = open(path, O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR)
|
||||||
|
if handle >= 0 {
|
||||||
|
fd = handle
|
||||||
|
self.file = (handle, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let fd = fd {
|
||||||
|
if let data = content.data(using: .utf8) {
|
||||||
|
data.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) -> Void in
|
||||||
|
write(fd, bytes, data.count)
|
||||||
|
}
|
||||||
|
if let file = self.file {
|
||||||
|
self.file = (file.0, file.1 + data.count)
|
||||||
|
} else {
|
||||||
|
assertionFailure()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
81
TelegramCore/ManagedRecentStickers.swift
Normal file
81
TelegramCore/ManagedRecentStickers.swift
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
import Foundation
|
||||||
|
#if os(macOS)
|
||||||
|
import PostboxMac
|
||||||
|
import SwiftSignalKitMac
|
||||||
|
#else
|
||||||
|
import Postbox
|
||||||
|
import SwiftSignalKit
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private func hashForIdsReverse(_ ids: [Int64]) -> Int32 {
|
||||||
|
var acc: UInt32 = 0
|
||||||
|
|
||||||
|
for id in ids {
|
||||||
|
let low = UInt32(UInt64(bitPattern: id) & UInt64(0xffffffff))
|
||||||
|
let high = UInt32((UInt64(bitPattern: id) >> 32) & UInt64(0xffffffff))
|
||||||
|
|
||||||
|
acc = (acc &* 20261) &+ high
|
||||||
|
acc = (acc &* 20261) &+ low
|
||||||
|
}
|
||||||
|
return Int32(bitPattern: acc % UInt32(0x7FFFFFFF))
|
||||||
|
}
|
||||||
|
|
||||||
|
private func managedRecentMedia(postbox: Postbox, network: Network, collectionId: Int32, fetch: @escaping (Int32) -> Signal<[OrderedItemListEntry]?, NoError>) -> Signal<Void, NoError> {
|
||||||
|
return postbox.modify { modifier -> Signal<Void, NoError> in
|
||||||
|
let itemIds = modifier.getOrderedListItemIds(collectionId: collectionId).map {
|
||||||
|
RecentMediaItemId($0).mediaId.id
|
||||||
|
}
|
||||||
|
return fetch(hashForIdsReverse(itemIds))
|
||||||
|
|> mapToSignal { items in
|
||||||
|
if let items = items {
|
||||||
|
return postbox.modify { modifier -> Void in
|
||||||
|
modifier.replaceOrderedItemListItems(collectionId: collectionId, items: items)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return .complete()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} |> switchToLatest
|
||||||
|
}
|
||||||
|
|
||||||
|
func managedRecentStickers(postbox: Postbox, network: Network) -> Signal<Void, NoError> {
|
||||||
|
return managedRecentMedia(postbox: postbox, network: network, collectionId: Namespaces.OrderedItemList.CloudRecentStickers, fetch: { hash in
|
||||||
|
return network.request(Api.functions.messages.getRecentStickers(flags: 0, hash: hash))
|
||||||
|
|> retryRequest
|
||||||
|
|> mapToSignal { result -> Signal<[OrderedItemListEntry]?, NoError> in
|
||||||
|
switch result {
|
||||||
|
case .recentStickersNotModified:
|
||||||
|
return .single(nil)
|
||||||
|
case let .recentStickers(_, stickers):
|
||||||
|
var items: [OrderedItemListEntry] = []
|
||||||
|
for sticker in stickers {
|
||||||
|
if let file = telegramMediaFileFromApiDocument(sticker), let id = file.id {
|
||||||
|
items.append(OrderedItemListEntry(id: RecentMediaItemId(id).rawValue, contents: RecentMediaItem(file)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return .single(items)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func managedRecentGifs(postbox: Postbox, network: Network) -> Signal<Void, NoError> {
|
||||||
|
return managedRecentMedia(postbox: postbox, network: network, collectionId: Namespaces.OrderedItemList.CloudRecentGifs, fetch: { hash in
|
||||||
|
return network.request(Api.functions.messages.getSavedGifs(hash: hash))
|
||||||
|
|> retryRequest
|
||||||
|
|> mapToSignal { result -> Signal<[OrderedItemListEntry]?, NoError> in
|
||||||
|
switch result {
|
||||||
|
case .savedGifsNotModified:
|
||||||
|
return .single(nil)
|
||||||
|
case let .savedGifs(_, gifs):
|
||||||
|
var items: [OrderedItemListEntry] = []
|
||||||
|
for gif in gifs {
|
||||||
|
if let file = telegramMediaFileFromApiDocument(gif), let id = file.id {
|
||||||
|
items.append(OrderedItemListEntry(id: RecentMediaItemId(id).rawValue, contents: RecentMediaItem(file)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return .single(items)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
@ -37,8 +37,14 @@ public struct Namespaces {
|
|||||||
public struct ItemCollection {
|
public struct ItemCollection {
|
||||||
public static let CloudStickerPacks: Int32 = 0
|
public static let CloudStickerPacks: Int32 = 0
|
||||||
public static let CloudMaskPacks: Int32 = 1
|
public static let CloudMaskPacks: Int32 = 1
|
||||||
public static let CloudRecentGifs: Int32 = 2
|
public static let CloudRecentStickers: Int32 = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct OrderedItemList {
|
||||||
public static let CloudRecentStickers: Int32 = 0
|
public static let CloudRecentStickers: Int32 = 0
|
||||||
|
public static let CloudRecentGifs: Int32 = 1
|
||||||
|
public static let RecentlySearchedPeerIds: Int32 = 2
|
||||||
|
public static let CloudRecentInlineBots: Int32 = 3
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CachedItemCollection {
|
struct CachedItemCollection {
|
||||||
|
|||||||
@ -130,7 +130,7 @@ func initializedNetwork(datacenterId: Int, keychain: Keychain, networkUsageInfoP
|
|||||||
}
|
}
|
||||||
|
|
||||||
context.keychain = keychain
|
context.keychain = keychain
|
||||||
let mtProto = MTProto(context: context, datacenterId: datacenterId, usageCalculationInfo: networkUsageInfoPath == nil ? nil : MTNetworkUsageCalculationInfo(filePath: networkUsageInfoPath))!
|
let mtProto = MTProto(context: context, datacenterId: datacenterId, usageCalculationInfo: nil)!
|
||||||
|
|
||||||
let connectionStatus = Promise<ConnectionStatus>(.WaitingForNetwork)
|
let connectionStatus = Promise<ConnectionStatus>(.WaitingForNetwork)
|
||||||
|
|
||||||
|
|||||||
@ -42,7 +42,7 @@ public extension Peer {
|
|||||||
switch self {
|
switch self {
|
||||||
case let user as TelegramUser:
|
case let user as TelegramUser:
|
||||||
return user.username
|
return user.username
|
||||||
case let group as TelegramGroup:
|
case let _ as TelegramGroup:
|
||||||
return nil
|
return nil
|
||||||
case let channel as TelegramChannel:
|
case let channel as TelegramChannel:
|
||||||
return channel.username
|
return channel.username
|
||||||
|
|||||||
@ -162,7 +162,7 @@ public final class PendingMessageManager {
|
|||||||
assert(strongSelf.queue.isCurrent())
|
assert(strongSelf.queue.isCurrent())
|
||||||
|
|
||||||
for message in messages {
|
for message in messages {
|
||||||
guard let peer = message.peers[message.id.peerId], let messageContext = strongSelf.messageContexts[message.id] else {
|
guard let messageContext = strongSelf.messageContexts[message.id] else {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,7 +237,7 @@ public final class PendingMessageManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var layer: SecretChatLayer?
|
var layer: SecretChatLayer?
|
||||||
var state = modifier.getPeerChatState(message.id.peerId) as? SecretChatState
|
let state = modifier.getPeerChatState(message.id.peerId) as? SecretChatState
|
||||||
if let state = state {
|
if let state = state {
|
||||||
switch state.embeddedState {
|
switch state.embeddedState {
|
||||||
case .terminated, .handshake:
|
case .terminated, .handshake:
|
||||||
@ -303,7 +303,6 @@ public final class PendingMessageManager {
|
|||||||
} else if let peer = modifier.getPeer(message.id.peerId), let inputPeer = apiInputPeer(peer) {
|
} else if let peer = modifier.getPeer(message.id.peerId), let inputPeer = apiInputPeer(peer) {
|
||||||
var uniqueId: Int64 = 0
|
var uniqueId: Int64 = 0
|
||||||
var forwardSourceInfoAttribute: ForwardSourceInfoAttribute?
|
var forwardSourceInfoAttribute: ForwardSourceInfoAttribute?
|
||||||
var outgoingChatContextResultAttribute: OutgoingChatContextResultMessageAttribute?
|
|
||||||
var replyMessageId: Int32?
|
var replyMessageId: Int32?
|
||||||
|
|
||||||
for attribute in message.attributes {
|
for attribute in message.attributes {
|
||||||
@ -313,13 +312,11 @@ public final class PendingMessageManager {
|
|||||||
uniqueId = outgoingInfo.uniqueId
|
uniqueId = outgoingInfo.uniqueId
|
||||||
} else if let attribute = attribute as? ForwardSourceInfoAttribute {
|
} else if let attribute = attribute as? ForwardSourceInfoAttribute {
|
||||||
forwardSourceInfoAttribute = attribute
|
forwardSourceInfoAttribute = attribute
|
||||||
} else if let attribute = attribute as? OutgoingChatContextResultMessageAttribute {
|
|
||||||
outgoingChatContextResultAttribute = attribute
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var flags: Int32 = 0
|
var flags: Int32 = 0
|
||||||
if let replyMessageId = replyMessageId {
|
if let _ = replyMessageId {
|
||||||
flags |= Int32(1 << 0)
|
flags |= Int32(1 << 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -327,7 +324,7 @@ public final class PendingMessageManager {
|
|||||||
|
|
||||||
let sendMessageRequest: Signal<Api.Updates, NoError>
|
let sendMessageRequest: Signal<Api.Updates, NoError>
|
||||||
switch content {
|
switch content {
|
||||||
case let .text(text):
|
case .text:
|
||||||
sendMessageRequest = network.request(Api.functions.messages.sendMessage(flags: flags, peer: inputPeer, replyToMsgId: replyMessageId, message: message.text, randomId: uniqueId, replyMarkup: nil, entities: nil), tag: dependencyTag)
|
sendMessageRequest = network.request(Api.functions.messages.sendMessage(flags: flags, peer: inputPeer, replyToMsgId: replyMessageId, message: message.text, randomId: uniqueId, replyMarkup: nil, entities: nil), tag: dependencyTag)
|
||||||
|> mapError { _ -> NoError in
|
|> mapError { _ -> NoError in
|
||||||
return NoError()
|
return NoError()
|
||||||
@ -384,9 +381,6 @@ public final class PendingMessageManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func applySentMessage(postbox: Postbox, stateManager: AccountStateManager, message: Message, result: Api.Updates) -> Signal<Void, NoError> {
|
private func applySentMessage(postbox: Postbox, stateManager: AccountStateManager, message: Message, result: Api.Updates) -> Signal<Void, NoError> {
|
||||||
let messageId = result.rawMessageIds.first
|
|
||||||
let apiMessage = result.messages.first
|
|
||||||
|
|
||||||
return applyUpdateMessage(postbox: postbox, stateManager: stateManager, message: message, result: result) |> afterDisposed { [weak self] in
|
return applyUpdateMessage(postbox: postbox, stateManager: stateManager, message: message, result: result) |> afterDisposed { [weak self] in
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
strongSelf.queue.async {
|
strongSelf.queue.async {
|
||||||
|
|||||||
46
TelegramCore/RecentMediaItem.swift
Normal file
46
TelegramCore/RecentMediaItem.swift
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import Foundation
|
||||||
|
#if os(macOS)
|
||||||
|
import PostboxMac
|
||||||
|
#else
|
||||||
|
import Postbox
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public struct RecentMediaItemId {
|
||||||
|
public let rawValue: MemoryBuffer
|
||||||
|
public let mediaId: MediaId
|
||||||
|
|
||||||
|
init(_ rawValue: MemoryBuffer) {
|
||||||
|
self.rawValue = rawValue
|
||||||
|
assert(rawValue.length == 4 + 8)
|
||||||
|
var mediaIdNamespace: Int32 = 0
|
||||||
|
var mediaIdId: Int64 = 0
|
||||||
|
memcpy(&mediaIdNamespace, rawValue.memory, 4)
|
||||||
|
memcpy(&mediaIdId, rawValue.memory.advanced(by: 4), 8)
|
||||||
|
self.mediaId = MediaId(namespace: mediaIdNamespace, id: mediaIdId)
|
||||||
|
}
|
||||||
|
|
||||||
|
init(_ mediaId: MediaId) {
|
||||||
|
self.mediaId = mediaId
|
||||||
|
var mediaIdNamespace: Int32 = mediaId.namespace
|
||||||
|
var mediaIdId: Int64 = mediaId.id
|
||||||
|
self.rawValue = MemoryBuffer(memory: malloc(4 + 8)!, capacity: 4 + 8, length: 4 + 8, freeWhenDone: true)
|
||||||
|
memcpy(self.rawValue.memory, &mediaIdNamespace, 4)
|
||||||
|
memcpy(self.rawValue.memory.advanced(by: 4), &mediaIdId, 8)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class RecentMediaItem: OrderedItemListEntryContents {
|
||||||
|
public let media: Media
|
||||||
|
|
||||||
|
init(_ media: Media) {
|
||||||
|
self.media = media
|
||||||
|
}
|
||||||
|
|
||||||
|
public init(decoder: Decoder) {
|
||||||
|
self.media = decoder.decodeObjectForKey("m") as! Media
|
||||||
|
}
|
||||||
|
|
||||||
|
public func encode(_ encoder: Encoder) {
|
||||||
|
encoder.encodeObject(self.media, forKey: "m")
|
||||||
|
}
|
||||||
|
}
|
||||||
37
TelegramCore/RecentPeerItem.swift
Normal file
37
TelegramCore/RecentPeerItem.swift
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import Foundation
|
||||||
|
#if os(macOS)
|
||||||
|
import PostboxMac
|
||||||
|
#else
|
||||||
|
import Postbox
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public struct RecentPeerItemId {
|
||||||
|
public let rawValue: MemoryBuffer
|
||||||
|
public let peerId: PeerId
|
||||||
|
|
||||||
|
init(_ rawValue: MemoryBuffer) {
|
||||||
|
self.rawValue = rawValue
|
||||||
|
assert(rawValue.length == 8)
|
||||||
|
var idValue: Int64 = 0
|
||||||
|
memcpy(&idValue, rawValue.memory, 8)
|
||||||
|
self.peerId = PeerId(idValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
init(_ peerId: PeerId) {
|
||||||
|
self.peerId = peerId
|
||||||
|
var idValue: Int64 = peerId.toInt64()
|
||||||
|
self.rawValue = MemoryBuffer(memory: malloc(8)!, capacity: 8, length: 8, freeWhenDone: true)
|
||||||
|
memcpy(self.rawValue.memory, &idValue, 8)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class RecentPeerItem: OrderedItemListEntryContents {
|
||||||
|
init() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public init(decoder: Decoder) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public func encode(_ encoder: Encoder) {
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -47,3 +47,67 @@ public func recentPeers(account: Account) -> Signal<[Peer], NoError> {
|
|||||||
}
|
}
|
||||||
return cachedPeers |> then(updatedRemotePeers) |> filter({ !$0.isEmpty })
|
return cachedPeers |> then(updatedRemotePeers) |> filter({ !$0.isEmpty })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func managedRecentlyUsedInlineBots(postbox: Postbox, network: Network) -> Signal<Void, NoError> {
|
||||||
|
let remotePeers = network.request(Api.functions.contacts.getTopPeers(flags: 1 << 2, offset: 0, limit: 16, hash: 0))
|
||||||
|
|> retryRequest
|
||||||
|
|> map { result -> ([Peer], [PeerId: PeerPresence])? in
|
||||||
|
switch result {
|
||||||
|
case let .topPeers(_, _, users):
|
||||||
|
var peers: [Peer] = []
|
||||||
|
var peerPresences: [PeerId: PeerPresence] = [:]
|
||||||
|
for user in users {
|
||||||
|
let telegramUser = TelegramUser(user: user)
|
||||||
|
peers.append(telegramUser)
|
||||||
|
if let presence = TelegramUserPresence(apiUser: user) {
|
||||||
|
peerPresences[telegramUser.id] = presence
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (peers, peerPresences)
|
||||||
|
case .topPeersNotModified:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return ([], [:])
|
||||||
|
}
|
||||||
|
|
||||||
|
let updatedRemotePeers = remotePeers
|
||||||
|
|> mapToSignal { peersAndPresences -> Signal<Void, NoError> in
|
||||||
|
if let (peers, peerPresences) = peersAndPresences {
|
||||||
|
return postbox.modify { modifier -> Void in
|
||||||
|
updatePeers(modifier: modifier, peers: peers, update: { return $1 })
|
||||||
|
modifier.updatePeerPresences(peerPresences)
|
||||||
|
modifier.replaceOrderedItemListItems(collectionId: Namespaces.OrderedItemList.CloudRecentInlineBots, items: peers.map { peer in
|
||||||
|
return OrderedItemListEntry(id: RecentPeerItemId(peer.id).rawValue, contents: RecentPeerItem())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return .complete()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return updatedRemotePeers
|
||||||
|
}
|
||||||
|
|
||||||
|
public func addRecentlyUsedInlineBot(postbox: Postbox, peerId: PeerId) -> Signal<Void, NoError> {
|
||||||
|
return postbox.modify { modifier -> Void in
|
||||||
|
modifier.addOrMoveToFirstPositionOrderedItemListItem(collectionId: Namespaces.OrderedItemList.CloudRecentInlineBots, item: OrderedItemListEntry(id: RecentPeerItemId(peerId).rawValue, contents: RecentPeerItem()), removeTailIfCountExceeds: 20)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func recentlyUsedInlineBots(postbox: Postbox) -> Signal<[Peer], NoError> {
|
||||||
|
return postbox.orderedItemListView(collectionId: Namespaces.OrderedItemList.CloudRecentInlineBots)
|
||||||
|
|> take(1)
|
||||||
|
|> mapToSignal { view -> Signal<[Peer], NoError> in
|
||||||
|
return postbox.modify { modifier -> [Peer] in
|
||||||
|
var peers: [Peer] = []
|
||||||
|
for item in view.items {
|
||||||
|
let peerId = RecentPeerItemId(item.id).peerId
|
||||||
|
if let peer = modifier.getPeer(peerId) {
|
||||||
|
peers.append(peer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return peers
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
31
TelegramCore/RecentlySearchedPeerIds.swift
Normal file
31
TelegramCore/RecentlySearchedPeerIds.swift
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import Foundation
|
||||||
|
#if os(macOS)
|
||||||
|
import PostboxMac
|
||||||
|
import SwiftSignalKitMac
|
||||||
|
#else
|
||||||
|
import Postbox
|
||||||
|
import SwiftSignalKit
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public func addRecentlySearchedPeer(postbox: Postbox, peerId: PeerId) -> Signal<Void, NoError> {
|
||||||
|
return postbox.modify { modifier -> Void in
|
||||||
|
modifier.addOrMoveToFirstPositionOrderedItemListItem(collectionId: Namespaces.OrderedItemList.RecentlySearchedPeerIds, item: OrderedItemListEntry(id: RecentPeerItemId(peerId).rawValue, contents: RecentPeerItem()), removeTailIfCountExceeds: 20)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func recentlySearchedPeers(postbox: Postbox) -> Signal<[Peer], NoError> {
|
||||||
|
return postbox.orderedItemListView(collectionId: Namespaces.OrderedItemList.RecentlySearchedPeerIds)
|
||||||
|
|> take(1)
|
||||||
|
|> mapToSignal { view -> Signal<[Peer], NoError> in
|
||||||
|
return postbox.modify { modifier -> [Peer] in
|
||||||
|
var peers: [Peer] = []
|
||||||
|
for item in view.items {
|
||||||
|
let peerId = RecentPeerItemId(item.id).peerId
|
||||||
|
if let peer = modifier.getPeer(peerId) {
|
||||||
|
peers.append(peer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return peers
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -12,14 +12,14 @@ private func hashForInfos(_ infos: [StickerPackCollectionInfo]) -> Int32 {
|
|||||||
var acc: UInt32 = 0
|
var acc: UInt32 = 0
|
||||||
|
|
||||||
for info in infos {
|
for info in infos {
|
||||||
acc = (acc &* 20261) &+ UInt32(bitPattern: info.hash)
|
acc = UInt32(bitPattern: Int32(bitPattern: acc &* UInt32(20261)) &+ info.hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
return Int32(bitPattern: acc % UInt32(0x7FFFFFFF))
|
return Int32(bitPattern: acc % 0x7FFFFFFF)
|
||||||
}
|
}
|
||||||
|
|
||||||
func manageStickerPacks(network: Network, postbox: Postbox) -> Signal<Void, NoError> {
|
func manageStickerPacks(network: Network, postbox: Postbox) -> Signal<Void, NoError> {
|
||||||
let currentHash = postbox.itemCollectionsView(namespaces: [Namespaces.ItemCollection.CloudStickerPacks], aroundIndex: nil, count: 1)
|
let currentHash = postbox.itemCollectionsView(orderedItemListCollectionIds: [], namespaces: [Namespaces.ItemCollection.CloudStickerPacks], aroundIndex: nil, count: 1)
|
||||||
|> take(1)
|
|> take(1)
|
||||||
|> map { view -> Int32 in
|
|> map { view -> Int32 in
|
||||||
return hashForInfos(view.collectionInfos.map({ $0.1 as! StickerPackCollectionInfo }))
|
return hashForInfos(view.collectionInfos.map({ $0.1 as! StickerPackCollectionInfo }))
|
||||||
@ -28,7 +28,7 @@ func manageStickerPacks(network: Network, postbox: Postbox) -> Signal<Void, NoEr
|
|||||||
let remoteStickerPacks = currentHash
|
let remoteStickerPacks = currentHash
|
||||||
|> mapToSignal { hash -> Signal<Void, NoError> in
|
|> mapToSignal { hash -> Signal<Void, NoError> in
|
||||||
if hash != 0 {
|
if hash != 0 {
|
||||||
//return .never()
|
return .never()
|
||||||
}
|
}
|
||||||
|
|
||||||
return network.request(Api.functions.messages.getAllStickers(hash: hash))
|
return network.request(Api.functions.messages.getAllStickers(hash: hash))
|
||||||
|
|||||||
@ -5,8 +5,6 @@ import Foundation
|
|||||||
import Postbox
|
import Postbox
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//stickerSet#cd303b41 flags:# installed:flags.0?true archived:flags.1?true official:flags.2?true masks:flags.3?true id:long access_hash:long title:string short_name:string count:int hash:int = StickerSet;
|
|
||||||
|
|
||||||
public final class StickerPackCollectionInfo: ItemCollectionInfo, Equatable {
|
public final class StickerPackCollectionInfo: ItemCollectionInfo, Equatable {
|
||||||
public let id: ItemCollectionId
|
public let id: ItemCollectionId
|
||||||
public let accessHash: Int64
|
public let accessHash: Int64
|
||||||
@ -14,7 +12,7 @@ public final class StickerPackCollectionInfo: ItemCollectionInfo, Equatable {
|
|||||||
public let shortName: String
|
public let shortName: String
|
||||||
public let hash: Int32
|
public let hash: Int32
|
||||||
|
|
||||||
init(id: ItemCollectionId, accessHash: Int64, title: String, shortName: String, hash: Int32) {
|
public init(id: ItemCollectionId, accessHash: Int64, title: String, shortName: String, hash: Int32) {
|
||||||
self.id = id
|
self.id = id
|
||||||
self.accessHash = accessHash
|
self.accessHash = accessHash
|
||||||
self.title = title
|
self.title = title
|
||||||
@ -48,7 +46,7 @@ public final class StickerPackItem: ItemCollectionItem, Equatable {
|
|||||||
public let file: TelegramMediaFile
|
public let file: TelegramMediaFile
|
||||||
public var indexKeys: [MemoryBuffer]
|
public var indexKeys: [MemoryBuffer]
|
||||||
|
|
||||||
init(index: ItemCollectionItemIndex, file: TelegramMediaFile, indexKeys: [MemoryBuffer]) {
|
public init(index: ItemCollectionItemIndex, file: TelegramMediaFile, indexKeys: [MemoryBuffer]) {
|
||||||
self.index = index
|
self.index = index
|
||||||
self.file = file
|
self.file = file
|
||||||
self.indexKeys = indexKeys
|
self.indexKeys = indexKeys
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
module TelegramCorePrivateModule {
|
module TelegramCorePrivateModule {
|
||||||
header "../../third-party/libphonenumber-iOS/NBPhoneNumber.h"
|
header "../../third-party/libphonenumber-iOS/NBPhoneNumber.h"
|
||||||
header "../../third-party/libphonenumber-iOS/NBPhoneNumberUtil.h"
|
header "../../third-party/libphonenumber-iOS/NBPhoneNumberUtil.h"
|
||||||
|
header "../../third-party/libphonenumber-iOS/NBAsYouTypeFormatter.h"
|
||||||
header "../NetworkLogging.h"
|
header "../NetworkLogging.h"
|
||||||
header "../TelegramCoreIncludes.h"
|
header "../TelegramCoreIncludes.h"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -126,7 +126,7 @@ public enum UserPresenceStatus: Comparable, Coding {
|
|||||||
public final class TelegramUserPresence: PeerPresence {
|
public final class TelegramUserPresence: PeerPresence {
|
||||||
public let status: UserPresenceStatus
|
public let status: UserPresenceStatus
|
||||||
|
|
||||||
init(status: UserPresenceStatus) {
|
public init(status: UserPresenceStatus) {
|
||||||
self.status = status
|
self.status = status
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -50,6 +50,8 @@ public func updatePeers(modifier: Modifier, peers: [Peer], update: (Peer?, Peer)
|
|||||||
updatedInclusion = .ifHasMessages
|
updatedInclusion = .ifHasMessages
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case .left:
|
||||||
|
updatedInclusion = .never
|
||||||
default:
|
default:
|
||||||
if currentInclusion == .notSpecified {
|
if currentInclusion == .notSpecified {
|
||||||
updatedInclusion = .never
|
updatedInclusion = .never
|
||||||
|
|||||||
@ -33,4 +33,6 @@
|
|||||||
|
|
||||||
@property (nonatomic, assign, readonly) BOOL isSuccessfulFormatting;
|
@property (nonatomic, assign, readonly) BOOL isSuccessfulFormatting;
|
||||||
|
|
||||||
|
@property (nonatomic, strong, readonly) NSString *regionPrefix;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@ -1290,4 +1290,8 @@
|
|||||||
return self.currentOutput_;
|
return self.currentOutput_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSString *)regionPrefix {
|
||||||
|
return self.prefixBeforeNationalNumber_;
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user