mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-11-25 01:22:41 +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 */; };
|
||||
D0448CA51E29215A005A61A7 /* 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 */; };
|
||||
D067066D1D512ADB00DED3E3 /* SwiftSignalKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D06706681D512ADB00DED3E3 /* SwiftSignalKit.framework */; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
@ -575,6 +593,8 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D021E0DE1DB539FC00C6B04F /* StickerPack.swift */,
|
||||
D049EAD41E43D98500A2CD3A /* RecentMediaItem.swift */,
|
||||
D049EAE71E44B67100A2CD3A /* RecentPeerItem.swift */,
|
||||
);
|
||||
name = "Item Collections";
|
||||
sourceTree = "<group>";
|
||||
@ -584,6 +604,7 @@
|
||||
children = (
|
||||
D021E0E11DB5401A00C6B04F /* StickerManagement.swift */,
|
||||
D01D6BF81E42A713006151C6 /* SearchStickers.swift */,
|
||||
D049EAD71E43DAD200A2CD3A /* ManagedRecentStickers.swift */,
|
||||
);
|
||||
name = "Sticker Management";
|
||||
sourceTree = "<group>";
|
||||
@ -643,6 +664,7 @@
|
||||
D03B0CCD1D62239600955575 /* PhoneNumbers.swift */,
|
||||
D0FA8BAC1E1FD6E2001E855B /* MemoryBufferExtensions.swift */,
|
||||
D0448C9E1E27F5EB005A61A7 /* Random.swift */,
|
||||
D050F20F1E48AB0600988324 /* InteractivePhoneFormatter.swift */,
|
||||
);
|
||||
name = Utils;
|
||||
sourceTree = "<group>";
|
||||
@ -796,6 +818,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D03B0D611D631A8B00955575 /* Account.swift */,
|
||||
D049EAF41E44DF3300A2CD3A /* AccountState.swift */,
|
||||
D03B0D621D631A8B00955575 /* AccountSettings.swift */,
|
||||
D03B0D631D631A8B00955575 /* AccountViewTracker.swift */,
|
||||
D03B0D641D631A8B00955575 /* RecentPeers.swift */,
|
||||
@ -946,6 +969,7 @@
|
||||
D0BC386D1E3FDAB70044D6FE /* CreateGroup.swift */,
|
||||
D0BC38741E40A7F70044D6FE /* RemovePeerChat.swift */,
|
||||
D0BC387A1E40D2880044D6FE /* TogglePeerChatPinned.swift */,
|
||||
D049EAEA1E44B71B00A2CD3A /* RecentlySearchedPeerIds.swift */,
|
||||
);
|
||||
name = Peers;
|
||||
sourceTree = "<group>";
|
||||
@ -1182,6 +1206,7 @@
|
||||
D0DF0C911D81A857008AEB01 /* ImageRepresentationsUtils.swift in Sources */,
|
||||
D0E6521F1E3A364A004EEA91 /* UpdateAccountPeerName.swift in Sources */,
|
||||
D03B0D5A1D631A6900955575 /* Api.swift in Sources */,
|
||||
D049EAE81E44B67100A2CD3A /* RecentPeerItem.swift in Sources */,
|
||||
D02ABC7B1E30058F00CAE539 /* DeleteMessagesInteractively.swift in Sources */,
|
||||
D0448C9F1E27F5EB005A61A7 /* Random.swift in Sources */,
|
||||
D0B843B21DA7FF30005F29E1 /* NBAsYouTypeFormatter.m in Sources */,
|
||||
@ -1193,6 +1218,7 @@
|
||||
D03C53771DAFF20F004C17B3 /* MultipartUpload.swift in Sources */,
|
||||
D00C7CE01E3785710080C3D5 /* MarkMessageContentAsConsumedInteractively.swift in Sources */,
|
||||
D0B843811DA6EDAE005F29E1 /* CachedUserData.swift in Sources */,
|
||||
D049EAD51E43D98500A2CD3A /* RecentMediaItem.swift in Sources */,
|
||||
D03B0D0A1D62255C00955575 /* Holes.swift in Sources */,
|
||||
D0B843CB1DA7FF30005F29E1 /* NBPhoneNumberUtil.m in Sources */,
|
||||
D03B0D5E1D631A6900955575 /* Network.swift in Sources */,
|
||||
@ -1202,10 +1228,12 @@
|
||||
D03B0CFB1D62250800955575 /* TelegramMediaWebpage.swift in Sources */,
|
||||
D09A2FEB1D7CDC320018FB72 /* PeerAccessRestrictionInfo.swift in Sources */,
|
||||
D0E35A101DE49E1C00BC6096 /* OutgoingMessageWithChatContextResult.swift in Sources */,
|
||||
D049EAD81E43DAD200A2CD3A /* ManagedRecentStickers.swift in Sources */,
|
||||
D0448C991E268F9A005A61A7 /* SecretApiLayer46.swift in Sources */,
|
||||
D003702B1DA42586004308D3 /* PhoneNumber.swift in Sources */,
|
||||
D03B0CF91D62250800955575 /* TelegramMediaMap.swift in Sources */,
|
||||
D0BC38791E40BAF20044D6FE /* SynchronizePinnedChatsOperation.swift in Sources */,
|
||||
D050F2101E48AB0600988324 /* InteractivePhoneFormatter.swift in Sources */,
|
||||
D03B0D671D631A8B00955575 /* AccountViewTracker.swift in Sources */,
|
||||
D0B843BB1DA7FF30005F29E1 /* NBMetadataCoreTestMapper.m in Sources */,
|
||||
D03B0D101D62255C00955575 /* UpdatesApiUtils.swift in Sources */,
|
||||
@ -1219,6 +1247,7 @@
|
||||
D019B1CC1E2E3B6A00F80DB3 /* SecretChatRekeySession.swift in Sources */,
|
||||
D03B0CD91D62245B00955575 /* PeerUtils.swift in Sources */,
|
||||
D03B0CE41D62249F00955575 /* TextEntitiesMessageAttribute.swift in Sources */,
|
||||
D049EAEB1E44B71B00A2CD3A /* RecentlySearchedPeerIds.swift in Sources */,
|
||||
D03B0CD31D62244300955575 /* Namespaces.swift in Sources */,
|
||||
D01D6BF91E42A713006151C6 /* SearchStickers.swift in Sources */,
|
||||
D0FA8BB91E2240B4001E855B /* SecretChatIncomingDecryptedOperation.swift in Sources */,
|
||||
@ -1258,6 +1287,7 @@
|
||||
D017495E1E118F790057C89A /* AccountStateManager.swift in Sources */,
|
||||
D0FA8BB61E223C16001E855B /* SecretApiLayer8.swift in Sources */,
|
||||
D0B843C71DA7FF30005F29E1 /* NBPhoneNumberDefines.m in Sources */,
|
||||
D049EAF51E44DF3300A2CD3A /* AccountState.swift in Sources */,
|
||||
D03B0D5D1D631A6900955575 /* MultipartFetch.swift in Sources */,
|
||||
D0BC38751E40A7F70044D6FE /* RemovePeerChat.swift in Sources */,
|
||||
D0AB0B961D662F0B002C78E7 /* ManagedChatListHoles.swift in Sources */,
|
||||
@ -1308,6 +1338,7 @@
|
||||
D0F7B1EA1E045C87007EB8A5 /* ChangePeerNotificationSettings.swift in Sources */,
|
||||
D0B418A71D7E0592004562A4 /* Fetch.swift in Sources */,
|
||||
D02ABC7C1E30058F00CAE539 /* DeleteMessagesInteractively.swift in Sources */,
|
||||
D050F2111E48AB0600988324 /* InteractivePhoneFormatter.swift in Sources */,
|
||||
D0B418B81D7E05A6004562A4 /* ContactManagement.swift in Sources */,
|
||||
D0F7B1E91E045C87007EB8A5 /* PeerCommands.swift in Sources */,
|
||||
D00D97C81E32901700E5C2B6 /* PeerInputActivity.swift in Sources */,
|
||||
@ -1343,11 +1374,13 @@
|
||||
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 */,
|
||||
D0F3CC791DDE2859008148FA /* SearchMessages.swift in Sources */,
|
||||
D0B8442B1DAB91E0005F29E1 /* NBMetadataCore.m in Sources */,
|
||||
D00C7CD01E3628180080C3D5 /* UpdateCachedChannelParticipants.swift in Sources */,
|
||||
D049EAE91E44B67100A2CD3A /* RecentPeerItem.swift in Sources */,
|
||||
D001F3F31E128A1C007A8C60 /* UpdateMessageService.swift in Sources */,
|
||||
D0B8442D1DAB91E0005F29E1 /* NBMetadataCoreTest.m in Sources */,
|
||||
D0B844131DAB91CD005F29E1 /* StringFormat.swift in Sources */,
|
||||
@ -1362,6 +1395,7 @@
|
||||
D073CE6E1DCBCF17007511FD /* ForwardSourceInfoAttribute.swift in Sources */,
|
||||
D001F3E81E128A1C007A8C60 /* ChannelState.swift in Sources */,
|
||||
D0B844451DAB91FD005F29E1 /* AccountViewTracker.swift in Sources */,
|
||||
D049EAD91E43DAD200A2CD3A /* ManagedRecentStickers.swift in Sources */,
|
||||
D0B418A61D7E0592004562A4 /* CloudFileMediaResource.swift in Sources */,
|
||||
D073CEA51DCBF3F5007511FD /* StickerManagement.swift in Sources */,
|
||||
D03C536D1DAD5CA9004C17B3 /* ApiGroupOrChannel.swift in Sources */,
|
||||
@ -1427,6 +1461,7 @@
|
||||
D0448CA61E29215A005A61A7 /* MediaResourceApiUtils.swift in Sources */,
|
||||
D001F3F11E128A1C007A8C60 /* SynchronizePeerReadState.swift in Sources */,
|
||||
D0F7B1E81E045C87007EB8A5 /* PeerParticipants.swift in Sources */,
|
||||
D049EAD61E43D98500A2CD3A /* RecentMediaItem.swift in Sources */,
|
||||
D0B844331DAB91E0005F29E1 /* NBPhoneNumber.m in Sources */,
|
||||
D001F3F51E128A1C007A8C60 /* PendingMessageManager.swift in Sources */,
|
||||
D001F3F61E128A1C007A8C60 /* PendingMessageUploadedContent.swift in Sources */,
|
||||
@ -1438,6 +1473,7 @@
|
||||
D0B844301DAB91E0005F29E1 /* NBNumberFormat.m in Sources */,
|
||||
D001F3F71E128A1C007A8C60 /* ApplyUpdateMessage.swift in Sources */,
|
||||
D0B418971D7E0580004562A4 /* TelegramMediaImage.swift in Sources */,
|
||||
D049EAF61E44DF3300A2CD3A /* AccountState.swift in Sources */,
|
||||
D0B844361DAB91E0005F29E1 /* NBPhoneNumberUtil.m in Sources */,
|
||||
D073CE6F1DCBCF17007511FD /* OutgoingMessageInfoAttribute.swift in Sources */,
|
||||
D0B844431DAB91FD005F29E1 /* Account.swift in Sources */,
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
<key>TelegramCoreMac.xcscheme</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>7</integer>
|
||||
<integer>5</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>SuppressBuildableAutocreation</key>
|
||||
|
||||
@ -45,32 +45,6 @@ public func ==(lhs: AccountState, rhs: AccountState) -> Bool {
|
||||
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 final class State: Coding, Equatable, CustomStringConvertible {
|
||||
let pts: Int32
|
||||
@ -177,21 +151,25 @@ public func generateAccountId() -> AccountId {
|
||||
|
||||
public class UnauthorizedAccount {
|
||||
public let id: AccountId
|
||||
public let appGroupPath: String
|
||||
public let basePath: String
|
||||
public let testingEnvironment: Bool
|
||||
public let postbox: Postbox
|
||||
public let network: Network
|
||||
public let logger: Logger
|
||||
|
||||
public var masterDatacenterId: Int32 {
|
||||
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.appGroupPath = appGroupPath
|
||||
self.basePath = basePath
|
||||
self.testingEnvironment = testingEnvironment
|
||||
self.postbox = postbox
|
||||
self.network = network
|
||||
self.logger = logger
|
||||
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)
|
||||
|> 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(CloudChatRemoveChatOperation.self, f: { CloudChatRemoveChatOperation(decoder: $0) })
|
||||
declareEncodable(SynchronizePinnedChatsOperation.self, f: { SynchronizePinnedChatsOperation(decoder: $0) })
|
||||
declareEncodable(RecentMediaItem.self, f: { RecentMediaItem(decoder: $0) })
|
||||
declareEncodable(RecentPeerItem.self, f: { RecentPeerItem(decoder: $0) })
|
||||
|
||||
return
|
||||
}()
|
||||
@ -275,8 +255,13 @@ func accountNetworkUsageInfoPath(basePath: String) -> String {
|
||||
return basePath + "/network-usage"
|
||||
}
|
||||
|
||||
public func accountWithId(_ id: AccountId, appGroupPath: String, testingEnvironment: Bool) -> Signal<Either<UnauthorizedAccount, Account>, NoError> {
|
||||
return Signal<(String, Postbox, AccountState?), NoError> { subscriber in
|
||||
public enum AccountLogger {
|
||||
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 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 postbox = Postbox(basePath: path + "/postbox", globalMessageIdsNamespace: Namespaces.Message.Cloud, seedConfiguration: seedConfiguration)
|
||||
return (postbox.state() |> take(1) |> map { accountState in
|
||||
return (path, postbox, accountState as? AccountState)
|
||||
return (postbox.stateView() |> take(1) |> map { view -> (String, Postbox, Coding?) in
|
||||
let accountState = view.state
|
||||
return (path, postbox, accountState)
|
||||
}).start(next: { args in
|
||||
subscriber.putNext(args)
|
||||
subscriber.putCompletion()
|
||||
@ -304,17 +290,25 @@ public func accountWithId(_ id: AccountId, appGroupPath: String, testingEnvironm
|
||||
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 {
|
||||
switch accountState {
|
||||
case let unauthorizedState as UnauthorizedAccountState:
|
||||
return initializedNetwork(datacenterId: Int(unauthorizedState.masterDatacenterId), keychain: keychain, networkUsageInfoPath: accountNetworkUsageInfoPath(basePath: basePath), testingEnvironment: testingEnvironment)
|
||||
|> 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:
|
||||
return initializedNetwork(datacenterId: Int(authorizedState.masterDatacenterId), keychain: keychain, networkUsageInfoPath: accountNetworkUsageInfoPath(basePath: basePath), testingEnvironment: testingEnvironment)
|
||||
|> 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 _:
|
||||
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)
|
||||
|> 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 peerId: PeerId
|
||||
|
||||
public let logger: Logger
|
||||
|
||||
public private(set) var stateManager: AccountStateManager!
|
||||
public private(set) var viewTracker: AccountViewTracker!
|
||||
public private(set) var pendingMessageManager: PendingMessageManager!
|
||||
@ -426,13 +422,14 @@ public class Account {
|
||||
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.basePath = basePath
|
||||
self.testingEnvironment = testingEnvironment
|
||||
self.postbox = postbox
|
||||
self.network = network
|
||||
self.peerId = peerId
|
||||
self.logger = logger
|
||||
|
||||
self.peerInputActivityManager = 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 langCode = NSLocale.preferredLanguages.first ?? "en"
|
||||
|
||||
#if os(macOS)
|
||||
let pInfo = ProcessInfo.processInfo
|
||||
let systemVersion = pInfo.operatingSystemVersionString
|
||||
@ -506,8 +501,6 @@ public class Account {
|
||||
|
||||
let appVersionString = "\(Bundle.main.infoDictionary?["CFBundleShortVersionString"] ?? "") (\(Bundle.main.infoDictionary?["CFBundleVersion"] ?? ""))"
|
||||
|
||||
let langCode = NSLocale.preferredLanguages.first ?? "en"
|
||||
|
||||
#if os(macOS)
|
||||
let pInfo = ProcessInfo.processInfo
|
||||
let systemVersion = pInfo.operatingSystemVersionString
|
||||
@ -567,6 +560,9 @@ public class Account {
|
||||
self.managedOperationsDisposable.add(managedAutoremoveMessageOperations(postbox: self.postbox).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(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()
|
||||
|> distinctUntilChanged
|
||||
@ -597,8 +593,6 @@ public class Account {
|
||||
return combineLatest(pushStatusOnce, updatePresenceLocally)
|
||||
|> mapToSignal { _ -> Signal<Void, NoError> in return .complete() }
|
||||
}
|
||||
|
||||
return .complete()
|
||||
} else {
|
||||
return .complete()
|
||||
}
|
||||
@ -616,7 +610,7 @@ public class Account {
|
||||
self.managedOperationsDisposable.dispose()
|
||||
}
|
||||
|
||||
public func currentNetworkStats() -> Signal<MTNetworkUsageManagerStats, NoError> {
|
||||
/*public func currentNetworkStats() -> Signal<MTNetworkUsageManagerStats, NoError> {
|
||||
return Signal { subscriber in
|
||||
let manager = MTNetworkUsageManager(info: MTNetworkUsageCalculationInfo(filePath: accountNetworkUsageInfoPath(basePath: self.basePath)))!
|
||||
manager.currentStats().start(next: { next in
|
||||
@ -628,7 +622,7 @@ public class Account {
|
||||
|
||||
return EmptyDisposable
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
public func peerInputActivities(peerId: PeerId) -> Signal<[(PeerId, PeerInputActivity)], NoError> {
|
||||
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 .single(state)
|
||||
}
|
||||
|
||||
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 {
|
||||
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
|
||||
}
|
||||
}
|
||||
@ -1152,7 +1150,7 @@ private func verifyTransaction(_ modifier: Modifier, finalState: AccountMutableS
|
||||
previousStateMatches = true
|
||||
}
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
@ -198,18 +198,17 @@ public final class AccountStateManager {
|
||||
self.currentIsUpdatingValue = true
|
||||
let account = self.account
|
||||
let mediaBox = account.postbox.mediaBox
|
||||
let queue = self.queue
|
||||
let signal = account.postbox.state()
|
||||
|> filter { state in
|
||||
if let _ = state as? AuthorizedAccountState {
|
||||
return true
|
||||
let signal = account.postbox.stateView()
|
||||
|> mapToSignal { view -> Signal<AuthorizedAccountState, NoError> in
|
||||
if let state = view.state as? AuthorizedAccountState {
|
||||
return .single(state)
|
||||
} else {
|
||||
return false
|
||||
return .complete()
|
||||
}
|
||||
}
|
||||
|> take(1)
|
||||
|> 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))
|
||||
|> retryRequest
|
||||
return request |> mapToSignal { difference -> Signal<(Api.updates.Difference?, AccountReplayedFinalState?), NoError> in
|
||||
@ -255,9 +254,9 @@ public final class AccountStateManager {
|
||||
}
|
||||
}
|
||||
|> 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 case let .pollDifference = strongSelf.operations.removeFirst() {
|
||||
if case .pollDifference = strongSelf.operations.removeFirst() {
|
||||
let events: AccountFinalStateEvents
|
||||
if let finalState = 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()
|
||||
@ -441,10 +440,10 @@ public final class AccountStateManager {
|
||||
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 {
|
||||
for message in messages {
|
||||
print("notify: \(messageMainPeer(message)?.displayTitle): \(message.id)")
|
||||
print("notify: \(String(describing: messageMainPeer(message)?.displayTitle)): \(message.id)")
|
||||
}
|
||||
|
||||
strongSelf.notificationMessagesPipe.putNext(messages)
|
||||
@ -458,7 +457,7 @@ public final class AccountStateManager {
|
||||
if self.operations.count > 1 {
|
||||
self.operations.removeFirst()
|
||||
for (id, f) in preSubscribers {
|
||||
self.addPollCompletion(f, id: id)
|
||||
let _ = self.addPollCompletion(f, id: id)
|
||||
}
|
||||
self.startFirstOperation()
|
||||
} else {
|
||||
@ -477,7 +476,7 @@ public final class AccountStateManager {
|
||||
}
|
||||
} else {
|
||||
for (id, f) in subscribers {
|
||||
strongSelf.addPollCompletion(f, id: id)
|
||||
let _ = strongSelf.addPollCompletion(f, id: id)
|
||||
}
|
||||
}
|
||||
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()
|
||||
|
||||
@ -47,6 +47,8 @@ func applyUpdateMessage(postbox: Postbox, stateManager: AccountStateManager, mes
|
||||
}
|
||||
}
|
||||
|
||||
var sentStickers: [TelegramMediaFile] = []
|
||||
|
||||
modifier.updateMessage(message.id, update: { currentMessage in
|
||||
let updatedId: MessageId
|
||||
if let messageId = messageId {
|
||||
@ -97,11 +99,20 @@ func applyUpdateMessage(postbox: Postbox, stateManager: AccountStateManager, mes
|
||||
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)
|
||||
})
|
||||
if let updatedTimestamp = 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)
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
gettimeofday(&curTime, nil)
|
||||
let seconds = curTime.tv_sec
|
||||
let milliseconds = curTime.tv_usec / 1000
|
||||
|
||||
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)
|
||||
//#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -44,10 +43,111 @@ public func registerLoggingFunctions() {
|
||||
setBridgingTraceFunction({ domain, what in
|
||||
if let what = what {
|
||||
if let domain = domain {
|
||||
trace(domain as String, what: what as String)
|
||||
trace(domain, what: what as String)
|
||||
} 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 static let CloudStickerPacks: Int32 = 0
|
||||
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 CloudRecentGifs: Int32 = 1
|
||||
public static let RecentlySearchedPeerIds: Int32 = 2
|
||||
public static let CloudRecentInlineBots: Int32 = 3
|
||||
}
|
||||
|
||||
struct CachedItemCollection {
|
||||
|
||||
@ -130,7 +130,7 @@ func initializedNetwork(datacenterId: Int, keychain: Keychain, networkUsageInfoP
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
|
||||
@ -42,7 +42,7 @@ public extension Peer {
|
||||
switch self {
|
||||
case let user as TelegramUser:
|
||||
return user.username
|
||||
case let group as TelegramGroup:
|
||||
case let _ as TelegramGroup:
|
||||
return nil
|
||||
case let channel as TelegramChannel:
|
||||
return channel.username
|
||||
|
||||
@ -162,7 +162,7 @@ public final class PendingMessageManager {
|
||||
assert(strongSelf.queue.isCurrent())
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@ -237,7 +237,7 @@ public final class PendingMessageManager {
|
||||
}
|
||||
|
||||
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 {
|
||||
switch state.embeddedState {
|
||||
case .terminated, .handshake:
|
||||
@ -303,7 +303,6 @@ public final class PendingMessageManager {
|
||||
} else if let peer = modifier.getPeer(message.id.peerId), let inputPeer = apiInputPeer(peer) {
|
||||
var uniqueId: Int64 = 0
|
||||
var forwardSourceInfoAttribute: ForwardSourceInfoAttribute?
|
||||
var outgoingChatContextResultAttribute: OutgoingChatContextResultMessageAttribute?
|
||||
var replyMessageId: Int32?
|
||||
|
||||
for attribute in message.attributes {
|
||||
@ -313,13 +312,11 @@ public final class PendingMessageManager {
|
||||
uniqueId = outgoingInfo.uniqueId
|
||||
} else if let attribute = attribute as? ForwardSourceInfoAttribute {
|
||||
forwardSourceInfoAttribute = attribute
|
||||
} else if let attribute = attribute as? OutgoingChatContextResultMessageAttribute {
|
||||
outgoingChatContextResultAttribute = attribute
|
||||
}
|
||||
}
|
||||
|
||||
var flags: Int32 = 0
|
||||
if let replyMessageId = replyMessageId {
|
||||
if let _ = replyMessageId {
|
||||
flags |= Int32(1 << 0)
|
||||
}
|
||||
|
||||
@ -327,7 +324,7 @@ public final class PendingMessageManager {
|
||||
|
||||
let sendMessageRequest: Signal<Api.Updates, NoError>
|
||||
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)
|
||||
|> mapError { _ -> NoError in
|
||||
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> {
|
||||
let messageId = result.rawMessageIds.first
|
||||
let apiMessage = result.messages.first
|
||||
|
||||
return applyUpdateMessage(postbox: postbox, stateManager: stateManager, message: message, result: result) |> afterDisposed { [weak self] in
|
||||
if let strongSelf = self {
|
||||
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 })
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
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> {
|
||||
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)
|
||||
|> map { view -> Int32 in
|
||||
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
|
||||
|> mapToSignal { hash -> Signal<Void, NoError> in
|
||||
if hash != 0 {
|
||||
//return .never()
|
||||
return .never()
|
||||
}
|
||||
|
||||
return network.request(Api.functions.messages.getAllStickers(hash: hash))
|
||||
|
||||
@ -5,8 +5,6 @@ import Foundation
|
||||
import Postbox
|
||||
#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 let id: ItemCollectionId
|
||||
public let accessHash: Int64
|
||||
@ -14,7 +12,7 @@ public final class StickerPackCollectionInfo: ItemCollectionInfo, Equatable {
|
||||
public let shortName: String
|
||||
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.accessHash = accessHash
|
||||
self.title = title
|
||||
@ -48,7 +46,7 @@ public final class StickerPackItem: ItemCollectionItem, Equatable {
|
||||
public let file: TelegramMediaFile
|
||||
public var indexKeys: [MemoryBuffer]
|
||||
|
||||
init(index: ItemCollectionItemIndex, file: TelegramMediaFile, indexKeys: [MemoryBuffer]) {
|
||||
public init(index: ItemCollectionItemIndex, file: TelegramMediaFile, indexKeys: [MemoryBuffer]) {
|
||||
self.index = index
|
||||
self.file = file
|
||||
self.indexKeys = indexKeys
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
module TelegramCorePrivateModule {
|
||||
header "../../third-party/libphonenumber-iOS/NBPhoneNumber.h"
|
||||
header "../../third-party/libphonenumber-iOS/NBPhoneNumberUtil.h"
|
||||
header "../../third-party/libphonenumber-iOS/NBAsYouTypeFormatter.h"
|
||||
header "../NetworkLogging.h"
|
||||
header "../TelegramCoreIncludes.h"
|
||||
}
|
||||
|
||||
@ -126,7 +126,7 @@ public enum UserPresenceStatus: Comparable, Coding {
|
||||
public final class TelegramUserPresence: PeerPresence {
|
||||
public let status: UserPresenceStatus
|
||||
|
||||
init(status: UserPresenceStatus) {
|
||||
public init(status: UserPresenceStatus) {
|
||||
self.status = status
|
||||
}
|
||||
|
||||
|
||||
@ -50,6 +50,8 @@ public func updatePeers(modifier: Modifier, peers: [Peer], update: (Peer?, Peer)
|
||||
updatedInclusion = .ifHasMessages
|
||||
}
|
||||
}
|
||||
case .left:
|
||||
updatedInclusion = .never
|
||||
default:
|
||||
if currentInclusion == .notSpecified {
|
||||
updatedInclusion = .never
|
||||
|
||||
@ -33,4 +33,6 @@
|
||||
|
||||
@property (nonatomic, assign, readonly) BOOL isSuccessfulFormatting;
|
||||
|
||||
@property (nonatomic, strong, readonly) NSString *regionPrefix;
|
||||
|
||||
@end
|
||||
|
||||
@ -1290,4 +1290,8 @@
|
||||
return self.currentOutput_;
|
||||
}
|
||||
|
||||
- (NSString *)regionPrefix {
|
||||
return self.prefixBeforeNationalNumber_;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user