mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2026-02-04 02:15:47 +00:00
no message
This commit is contained in:
@@ -51,18 +51,21 @@ public class AuthorizedAccountState: AccountState {
|
||||
}
|
||||
}
|
||||
|
||||
let isTestingEnvironment: Bool
|
||||
let masterDatacenterId: Int32
|
||||
let peerId: PeerId
|
||||
|
||||
let state: State?
|
||||
|
||||
public required init(decoder: PostboxDecoder) {
|
||||
self.isTestingEnvironment = decoder.decodeInt32ForKey("isTestingEnvironment", orElse: 0) != 0
|
||||
self.masterDatacenterId = decoder.decodeInt32ForKey("masterDatacenterId", orElse: 0)
|
||||
self.peerId = PeerId(decoder.decodeInt64ForKey("peerId", orElse: 0))
|
||||
self.state = decoder.decodeObjectForKey("state", decoder: { return State(decoder: $0) }) as? State
|
||||
}
|
||||
|
||||
public func encode(_ encoder: PostboxEncoder) {
|
||||
encoder.encodeInt32(self.isTestingEnvironment ? 1 : 0, forKey: "isTestingEnvironment")
|
||||
encoder.encodeInt32(self.masterDatacenterId, forKey: "masterDatacenterId")
|
||||
encoder.encodeInt64(self.peerId.toInt64(), forKey: "peerId")
|
||||
if let state = self.state {
|
||||
@@ -70,19 +73,20 @@ public class AuthorizedAccountState: AccountState {
|
||||
}
|
||||
}
|
||||
|
||||
public init(masterDatacenterId: Int32, peerId: PeerId, state: State?) {
|
||||
public init(isTestingEnvironment: Bool, masterDatacenterId: Int32, peerId: PeerId, state: State?) {
|
||||
self.isTestingEnvironment = isTestingEnvironment
|
||||
self.masterDatacenterId = masterDatacenterId
|
||||
self.peerId = peerId
|
||||
self.state = state
|
||||
}
|
||||
|
||||
func changedState(_ state: State) -> AuthorizedAccountState {
|
||||
return AuthorizedAccountState(masterDatacenterId: self.masterDatacenterId, peerId: self.peerId, state: state)
|
||||
return AuthorizedAccountState(isTestingEnvironment: self.isTestingEnvironment, masterDatacenterId: self.masterDatacenterId, peerId: self.peerId, state: state)
|
||||
}
|
||||
|
||||
public func equalsTo(_ other: AccountState) -> Bool {
|
||||
if let other = other as? AuthorizedAccountState {
|
||||
return self.masterDatacenterId == other.masterDatacenterId &&
|
||||
return self.isTestingEnvironment == other.isTestingEnvironment && self.masterDatacenterId == other.masterDatacenterId &&
|
||||
self.peerId == other.peerId &&
|
||||
self.state == other.state
|
||||
} else {
|
||||
@@ -291,62 +295,64 @@ let telegramPostboxSeedConfiguration: SeedConfiguration = {
|
||||
return SeedConfiguration(initializeChatListWithHole: (topLevel: ChatListHole(index: MessageIndex(id: MessageId(peerId: PeerId(namespace: Namespaces.Peer.Empty, id: 0), namespace: Namespaces.Message.Cloud, id: 1), timestamp: Int32.max - 1)), groups: ChatListHole(index: MessageIndex(id: MessageId(peerId: PeerId(namespace: Namespaces.Peer.Empty, id: 0), namespace: Namespaces.Message.Cloud, id: 1), timestamp: 1))), initializeMessageNamespacesWithHoles: initializeMessageNamespacesWithHoles, existingMessageTags: MessageTags.all, messageTagsWithSummary: MessageTags.unseenPersonalMessage, existingGlobalMessageTags: GlobalMessageTags.all, peerNamespacesRequiringMessageTextIndex: [Namespaces.Peer.SecretChat])
|
||||
}()
|
||||
|
||||
public func accountWithId(networkArguments: NetworkInitializationArguments, id: AccountRecordId, supplementary: Bool, rootPath: String, testingEnvironment: Bool, auxiliaryMethods: AccountAuxiliaryMethods, shouldKeepAutoConnection: Bool = true) -> Signal<AccountResult, NoError> {
|
||||
public func accountWithId(networkArguments: NetworkInitializationArguments, id: AccountRecordId, supplementary: Bool, rootPath: String, beginWithTestingEnvironment: Bool, auxiliaryMethods: AccountAuxiliaryMethods, shouldKeepAutoConnection: Bool = true) -> Signal<AccountResult, NoError> {
|
||||
let _ = declaredEncodables
|
||||
|
||||
let path = "\(rootPath)/\(accountRecordIdPathName(id))"
|
||||
|
||||
let postbox = openPostbox(basePath: path + "/postbox", globalMessageIdsNamespace: Namespaces.Message.Cloud, seedConfiguration: telegramPostboxSeedConfiguration)
|
||||
|
||||
return postbox |> mapToSignal { result -> Signal<AccountResult, NoError> in
|
||||
return postbox
|
||||
|> mapToSignal { result -> Signal<AccountResult, NoError> in
|
||||
switch result {
|
||||
case .upgrading:
|
||||
return .single(.upgrading)
|
||||
case let .postbox(postbox):
|
||||
return postbox.stateView()
|
||||
|> take(1)
|
||||
|> mapToSignal { view -> Signal<AccountResult, NoError> in
|
||||
return postbox.transaction { transaction -> (LocalizationSettings?, ProxySettings?, NetworkSettings?) in
|
||||
return (transaction.getPreferencesEntry(key: PreferencesKeys.localizationSettings) as? LocalizationSettings, transaction.getPreferencesEntry(key: PreferencesKeys.proxySettings) as? ProxySettings, transaction.getPreferencesEntry(key: PreferencesKeys.networkSettings) as? NetworkSettings)
|
||||
} |> mapToSignal { (localizationSettings, proxySettings, networkSettings) -> Signal<AccountResult, NoError> in
|
||||
let accountState = view.state
|
||||
|
||||
let keychain = Keychain(get: { key in
|
||||
return postbox.keychainEntryForKey(key)
|
||||
}, set: { (key, data) in
|
||||
postbox.setKeychainEntryForKey(key, value: data)
|
||||
}, remove: { key in
|
||||
postbox.removeKeychainEntryForKey(key)
|
||||
})
|
||||
|
||||
if let accountState = accountState {
|
||||
switch accountState {
|
||||
case let unauthorizedState as UnauthorizedAccountState:
|
||||
return initializedNetwork(arguments: networkArguments, supplementary: supplementary, datacenterId: Int(unauthorizedState.masterDatacenterId), keychain: keychain, basePath: path, testingEnvironment: testingEnvironment, languageCode: localizationSettings?.languageCode, proxySettings: proxySettings, networkSettings: networkSettings, phoneNumber: nil)
|
||||
|> map { network -> AccountResult in
|
||||
return .unauthorized(UnauthorizedAccount(networkArguments: networkArguments, id: id, rootPath: rootPath, basePath: path, testingEnvironment: testingEnvironment, postbox: postbox, network: network, shouldKeepAutoConnection: shouldKeepAutoConnection))
|
||||
}
|
||||
case let authorizedState as AuthorizedAccountState:
|
||||
return postbox.transaction { transaction -> String? in
|
||||
return (transaction.getPeer(authorizedState.peerId) as? TelegramUser)?.phone
|
||||
|> take(1)
|
||||
|> mapToSignal { view -> Signal<AccountResult, NoError> in
|
||||
return postbox.transaction { transaction -> (LocalizationSettings?, ProxySettings?, NetworkSettings?) in
|
||||
return (transaction.getPreferencesEntry(key: PreferencesKeys.localizationSettings) as? LocalizationSettings, transaction.getPreferencesEntry(key: PreferencesKeys.proxySettings) as? ProxySettings, transaction.getPreferencesEntry(key: PreferencesKeys.networkSettings) as? NetworkSettings)
|
||||
}
|
||||
|> mapToSignal { (localizationSettings, proxySettings, networkSettings) -> Signal<AccountResult, NoError> in
|
||||
let accountState = view.state
|
||||
|
||||
let keychain = Keychain(get: { key in
|
||||
return postbox.keychainEntryForKey(key)
|
||||
}, set: { (key, data) in
|
||||
postbox.setKeychainEntryForKey(key, value: data)
|
||||
}, remove: { key in
|
||||
postbox.removeKeychainEntryForKey(key)
|
||||
})
|
||||
|
||||
if let accountState = accountState {
|
||||
switch accountState {
|
||||
case let unauthorizedState as UnauthorizedAccountState:
|
||||
return initializedNetwork(arguments: networkArguments, supplementary: supplementary, datacenterId: Int(unauthorizedState.masterDatacenterId), keychain: keychain, basePath: path, testingEnvironment: unauthorizedState.isTestingEnvironment, languageCode: localizationSettings?.languageCode, proxySettings: proxySettings, networkSettings: networkSettings, phoneNumber: nil)
|
||||
|> map { network -> AccountResult in
|
||||
return .unauthorized(UnauthorizedAccount(networkArguments: networkArguments, id: id, rootPath: rootPath, basePath: path, testingEnvironment: unauthorizedState.isTestingEnvironment, postbox: postbox, network: network, shouldKeepAutoConnection: shouldKeepAutoConnection))
|
||||
}
|
||||
|> mapToSignal { phoneNumber in
|
||||
return initializedNetwork(arguments: networkArguments, supplementary: supplementary, datacenterId: Int(authorizedState.masterDatacenterId), keychain: keychain, basePath: path, testingEnvironment: testingEnvironment, languageCode: localizationSettings?.languageCode, proxySettings: proxySettings, networkSettings: networkSettings, phoneNumber: phoneNumber)
|
||||
|> map { network -> AccountResult in
|
||||
return .authorized(Account(id: id, basePath: path, testingEnvironment: testingEnvironment, postbox: postbox, network: network, peerId: authorizedState.peerId, auxiliaryMethods: auxiliaryMethods))
|
||||
}
|
||||
case let authorizedState as AuthorizedAccountState:
|
||||
return postbox.transaction { transaction -> String? in
|
||||
return (transaction.getPeer(authorizedState.peerId) as? TelegramUser)?.phone
|
||||
}
|
||||
|> mapToSignal { phoneNumber in
|
||||
return initializedNetwork(arguments: networkArguments, supplementary: supplementary, datacenterId: Int(authorizedState.masterDatacenterId), keychain: keychain, basePath: path, testingEnvironment: authorizedState.isTestingEnvironment, languageCode: localizationSettings?.languageCode, proxySettings: proxySettings, networkSettings: networkSettings, phoneNumber: phoneNumber)
|
||||
|> map { network -> AccountResult in
|
||||
return .authorized(Account(id: id, basePath: path, testingEnvironment: authorizedState.isTestingEnvironment, postbox: postbox, network: network, peerId: authorizedState.peerId, auxiliaryMethods: auxiliaryMethods))
|
||||
}
|
||||
case _:
|
||||
assertionFailure("Unexpected accountState \(accountState)")
|
||||
}
|
||||
}
|
||||
|
||||
return initializedNetwork(arguments: networkArguments, supplementary: supplementary, datacenterId: 2, keychain: keychain, basePath: path, testingEnvironment: testingEnvironment, languageCode: localizationSettings?.languageCode, proxySettings: proxySettings, networkSettings: networkSettings, phoneNumber: nil)
|
||||
|> map { network -> AccountResult in
|
||||
return .unauthorized(UnauthorizedAccount(networkArguments: networkArguments, id: id, rootPath: rootPath, basePath: path, testingEnvironment: testingEnvironment, postbox: postbox, network: network, shouldKeepAutoConnection: shouldKeepAutoConnection))
|
||||
}
|
||||
case _:
|
||||
assertionFailure("Unexpected accountState \(accountState)")
|
||||
}
|
||||
}
|
||||
|
||||
return initializedNetwork(arguments: networkArguments, supplementary: supplementary, datacenterId: 2, keychain: keychain, basePath: path, testingEnvironment: beginWithTestingEnvironment, languageCode: localizationSettings?.languageCode, proxySettings: proxySettings, networkSettings: networkSettings, phoneNumber: nil)
|
||||
|> map { network -> AccountResult in
|
||||
return .unauthorized(UnauthorizedAccount(networkArguments: networkArguments, id: id, rootPath: rootPath, basePath: path, testingEnvironment: beginWithTestingEnvironment, postbox: postbox, network: network, shouldKeepAutoConnection: shouldKeepAutoConnection))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -735,10 +741,10 @@ public enum AccountNetworkState: Equatable {
|
||||
|
||||
public final class AccountAuxiliaryMethods {
|
||||
public let updatePeerChatInputState: (PeerChatInterfaceState?, SynchronizeableChatInputState?) -> PeerChatInterfaceState?
|
||||
public let fetchResource: (Account, MediaResource, Signal<IndexSet, NoError>, MediaResourceFetchParameters?) -> Signal<MediaResourceDataFetchResult, NoError>?
|
||||
public let fetchResource: (Account, MediaResource, Signal<IndexSet, NoError>, MediaResourceFetchParameters?) -> Signal<MediaResourceDataFetchResult, MediaResourceDataFetchError>?
|
||||
public let fetchResourceMediaReferenceHash: (MediaResource) -> Signal<Data?, NoError>
|
||||
|
||||
public init(updatePeerChatInputState: @escaping (PeerChatInterfaceState?, SynchronizeableChatInputState?) -> PeerChatInterfaceState?, fetchResource: @escaping (Account, MediaResource, Signal<IndexSet, NoError>, MediaResourceFetchParameters?) -> Signal<MediaResourceDataFetchResult, NoError>?, fetchResourceMediaReferenceHash: @escaping (MediaResource) -> Signal<Data?, NoError>) {
|
||||
public init(updatePeerChatInputState: @escaping (PeerChatInterfaceState?, SynchronizeableChatInputState?) -> PeerChatInterfaceState?, fetchResource: @escaping (Account, MediaResource, Signal<IndexSet, NoError>, MediaResourceFetchParameters?) -> Signal<MediaResourceDataFetchResult, MediaResourceDataFetchError>?, fetchResourceMediaReferenceHash: @escaping (MediaResource) -> Signal<Data?, NoError>) {
|
||||
self.updatePeerChatInputState = updatePeerChatInputState
|
||||
self.fetchResource = fetchResource
|
||||
self.fetchResourceMediaReferenceHash = fetchResourceMediaReferenceHash
|
||||
@@ -1204,7 +1210,7 @@ public typealias FetchCachedResourceRepresentation = (_ account: Account, _ reso
|
||||
public typealias TransformOutgoingMessageMedia = (_ postbox: Postbox, _ network: Network, _ media: AnyMediaReference, _ userInteractive: Bool) -> Signal<AnyMediaReference?, NoError>
|
||||
|
||||
public func setupAccount(_ account: Account, fetchCachedResourceRepresentation: FetchCachedResourceRepresentation? = nil, transformOutgoingMessageMedia: TransformOutgoingMessageMedia? = nil) {
|
||||
account.postbox.mediaBox.fetchResource = { [weak account] resource, ranges, parameters -> Signal<MediaResourceDataFetchResult, NoError> in
|
||||
account.postbox.mediaBox.fetchResource = { [weak account] resource, ranges, parameters -> Signal<MediaResourceDataFetchResult, MediaResourceDataFetchError> in
|
||||
if let strongAccount = account {
|
||||
if let result = fetchResource(account: strongAccount, resource: resource, ranges: ranges, parameters: parameters) {
|
||||
return result
|
||||
|
||||
@@ -69,60 +69,61 @@ public func temporaryAccount(manager: AccountManager, rootPath: String) -> Signa
|
||||
}
|
||||
}
|
||||
|
||||
public func currentAccount(networkArguments: NetworkInitializationArguments, supplementary: Bool, manager: AccountManager, rootPath: String, testingEnvironment: Bool, auxiliaryMethods: AccountAuxiliaryMethods) -> Signal<AccountResult?, NoError> {
|
||||
return manager.allocatedCurrentAccountId()
|
||||
|> distinctUntilChanged(isEqual: { lhs, rhs in
|
||||
return lhs == rhs
|
||||
})
|
||||
|> mapToSignal { id -> Signal<AccountResult?, NoError> in
|
||||
if let id = id {
|
||||
let reload = ValuePromise<Bool>(true, ignoreRepeated: false)
|
||||
return reload.get() |> mapToSignal { _ -> Signal<AccountResult?, NoError> in
|
||||
return accountWithId(networkArguments: networkArguments, id: id, supplementary: supplementary, rootPath: rootPath, testingEnvironment: testingEnvironment, auxiliaryMethods: auxiliaryMethods)
|
||||
|> mapToSignal { accountResult -> Signal<AccountResult?, NoError> in
|
||||
let postbox: Postbox
|
||||
let initialKind: AccountKind
|
||||
switch accountResult {
|
||||
case .upgrading:
|
||||
return .complete()
|
||||
case let .unauthorized(account):
|
||||
postbox = account.postbox
|
||||
initialKind = .unauthorized
|
||||
case let .authorized(account):
|
||||
postbox = account.postbox
|
||||
initialKind = .authorized
|
||||
public func currentAccount(allocateIfNotExists: Bool, networkArguments: NetworkInitializationArguments, supplementary: Bool, manager: AccountManager, rootPath: String, beginWithTestingEnvironment: Bool, auxiliaryMethods: AccountAuxiliaryMethods) -> Signal<AccountResult?, NoError> {
|
||||
return manager.currentAccountId(allocateIfNotExists: allocateIfNotExists)
|
||||
|> distinctUntilChanged(isEqual: { lhs, rhs in
|
||||
return lhs == rhs
|
||||
})
|
||||
|> mapToSignal { id -> Signal<AccountResult?, NoError> in
|
||||
if let id = id {
|
||||
let reload = ValuePromise<Bool>(true, ignoreRepeated: false)
|
||||
return reload.get()
|
||||
|> mapToSignal { _ -> Signal<AccountResult?, NoError> in
|
||||
return accountWithId(networkArguments: networkArguments, id: id, supplementary: supplementary, rootPath: rootPath, beginWithTestingEnvironment: beginWithTestingEnvironment, auxiliaryMethods: auxiliaryMethods)
|
||||
|> mapToSignal { accountResult -> Signal<AccountResult?, NoError> in
|
||||
let postbox: Postbox
|
||||
let initialKind: AccountKind
|
||||
switch accountResult {
|
||||
case .upgrading:
|
||||
return .complete()
|
||||
case let .unauthorized(account):
|
||||
postbox = account.postbox
|
||||
initialKind = .unauthorized
|
||||
case let .authorized(account):
|
||||
postbox = account.postbox
|
||||
initialKind = .authorized
|
||||
}
|
||||
let updatedKind = postbox.stateView()
|
||||
|> map { view -> Bool in
|
||||
let kind: AccountKind
|
||||
if view.state is AuthorizedAccountState {
|
||||
kind = .authorized
|
||||
} else {
|
||||
kind = .unauthorized
|
||||
}
|
||||
let updatedKind = postbox.stateView()
|
||||
|> map { view -> Bool in
|
||||
let kind: AccountKind
|
||||
if view.state is AuthorizedAccountState {
|
||||
kind = .authorized
|
||||
} else {
|
||||
kind = .unauthorized
|
||||
}
|
||||
if kind != initialKind {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|> distinctUntilChanged
|
||||
|
||||
return Signal { subscriber in
|
||||
subscriber.putNext(accountResult)
|
||||
|
||||
return updatedKind.start(next: { value in
|
||||
if value {
|
||||
reload.set(true)
|
||||
}
|
||||
})
|
||||
if kind != initialKind {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|> distinctUntilChanged
|
||||
|
||||
return Signal { subscriber in
|
||||
subscriber.putNext(accountResult)
|
||||
|
||||
return updatedKind.start(next: { value in
|
||||
if value {
|
||||
reload.set(true)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return .single(nil)
|
||||
}
|
||||
} else {
|
||||
return .single(nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func logoutFromAccount(id: AccountRecordId, accountManager: AccountManager) -> Signal<Void, NoError> {
|
||||
@@ -234,28 +235,28 @@ public func managedCleanupAccounts(networkArguments: NetworkInitializationArgume
|
||||
}
|
||||
|
||||
private func cleanupAccount(networkArguments: NetworkInitializationArguments, accountManager: AccountManager, id: AccountRecordId, rootPath: String, auxiliaryMethods: AccountAuxiliaryMethods) -> Signal<Void, NoError> {
|
||||
return accountWithId(networkArguments: networkArguments, id: id, supplementary: true, rootPath: rootPath, testingEnvironment: false, auxiliaryMethods: auxiliaryMethods)
|
||||
|> mapToSignal { account -> Signal<Void, NoError> in
|
||||
switch account {
|
||||
case .upgrading:
|
||||
return .complete()
|
||||
case .unauthorized:
|
||||
return .complete()
|
||||
case let .authorized(account):
|
||||
account.shouldBeServiceTaskMaster.set(.single(.always))
|
||||
return account.network.request(Api.functions.auth.logOut())
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.Bool?, NoError> in
|
||||
return .single(.boolFalse)
|
||||
}
|
||||
|> mapToSignal { _ -> Signal<Void, NoError> in
|
||||
account.shouldBeServiceTaskMaster.set(.single(.never))
|
||||
return accountManager.transaction { transaction -> Void in
|
||||
transaction.updateRecord(id, { _ in
|
||||
return nil
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
return accountWithId(networkArguments: networkArguments, id: id, supplementary: true, rootPath: rootPath, beginWithTestingEnvironment: false, auxiliaryMethods: auxiliaryMethods)
|
||||
|> mapToSignal { account -> Signal<Void, NoError> in
|
||||
switch account {
|
||||
case .upgrading:
|
||||
return .complete()
|
||||
case .unauthorized:
|
||||
return .complete()
|
||||
case let .authorized(account):
|
||||
account.shouldBeServiceTaskMaster.set(.single(.always))
|
||||
return account.network.request(Api.functions.auth.logOut())
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.Bool?, NoError> in
|
||||
return .single(.boolFalse)
|
||||
}
|
||||
|> mapToSignal { _ -> Signal<Void, NoError> in
|
||||
account.shouldBeServiceTaskMaster.set(.single(.never))
|
||||
return accountManager.transaction { transaction -> Void in
|
||||
transaction.updateRecord(id, { _ in
|
||||
return nil
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -317,20 +317,24 @@ public enum UnauthorizedAccountStateContents: PostboxCoding, Equatable {
|
||||
}
|
||||
|
||||
public final class UnauthorizedAccountState: AccountState {
|
||||
public let isTestingEnvironment: Bool
|
||||
public let masterDatacenterId: Int32
|
||||
public let contents: UnauthorizedAccountStateContents
|
||||
|
||||
public init(masterDatacenterId: Int32, contents: UnauthorizedAccountStateContents) {
|
||||
public init(isTestingEnvironment: Bool, masterDatacenterId: Int32, contents: UnauthorizedAccountStateContents) {
|
||||
self.isTestingEnvironment = isTestingEnvironment
|
||||
self.masterDatacenterId = masterDatacenterId
|
||||
self.contents = contents
|
||||
}
|
||||
|
||||
public init(decoder: PostboxDecoder) {
|
||||
self.isTestingEnvironment = decoder.decodeInt32ForKey("isTestingEnvironment", orElse: 0) != 0
|
||||
self.masterDatacenterId = decoder.decodeInt32ForKey("dc", orElse: 0)
|
||||
self.contents = decoder.decodeObjectForKey("c", decoder: { UnauthorizedAccountStateContents(decoder: $0) }) as! UnauthorizedAccountStateContents
|
||||
}
|
||||
|
||||
public func encode(_ encoder: PostboxEncoder) {
|
||||
encoder.encodeInt32(self.isTestingEnvironment ? 1 : 0, forKey: "isTestingEnvironment")
|
||||
encoder.encodeInt32(self.masterDatacenterId, forKey: "dc")
|
||||
encoder.encodeObject(self.contents, forKey: "c")
|
||||
}
|
||||
@@ -339,6 +343,9 @@ public final class UnauthorizedAccountState: AccountState {
|
||||
guard let other = other as? UnauthorizedAccountState else {
|
||||
return false
|
||||
}
|
||||
if self.isTestingEnvironment != other.isTestingEnvironment {
|
||||
return false
|
||||
}
|
||||
if self.masterDatacenterId != other.masterDatacenterId {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -145,7 +145,9 @@ public final class AccountStateManager {
|
||||
self.operations[self.operations.count - 1] = .collectUpdateGroups(currentGroups + groups, timeout)
|
||||
} else {
|
||||
self.operations[self.operations.count - 1] = .processUpdateGroups(currentGroups + groups)
|
||||
self.startFirstOperation()
|
||||
if self.operations.count == 1 {
|
||||
self.startFirstOperation()
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -204,13 +206,16 @@ public final class AccountStateManager {
|
||||
}
|
||||
|
||||
private func replaceOperations(with operation: AccountStateManagerOperation) {
|
||||
var collectedProcessUpdateGroups: [(AccountStateManagerOperation, Bool)] = []
|
||||
var collectedMessageIds: [MessageId] = []
|
||||
var collectedPollCompletionSubscribers: [(Int32, ([MessageId]) -> Void)] = []
|
||||
var collectedReplayAsynchronouslyBuiltFinalState: [(AccountFinalState, () -> Void)] = []
|
||||
var processEvents: [(Int32, AccountFinalStateEvents)] = []
|
||||
|
||||
for operation in self.operations {
|
||||
switch operation {
|
||||
for i in 0 ..< self.operations.count {
|
||||
switch self.operations[i] {
|
||||
case .processUpdateGroups:
|
||||
collectedProcessUpdateGroups.append((self.operations[i], i == 0))
|
||||
case let .pollCompletion(_, messageIds, subscribers):
|
||||
collectedMessageIds.append(contentsOf: messageIds)
|
||||
collectedPollCompletionSubscribers.append(contentsOf: subscribers)
|
||||
@@ -224,6 +229,9 @@ public final class AccountStateManager {
|
||||
}
|
||||
|
||||
self.operations.removeAll()
|
||||
|
||||
self.operations.append(contentsOf: collectedProcessUpdateGroups.map { $0.0 })
|
||||
|
||||
self.operations.append(operation)
|
||||
|
||||
if !collectedPollCompletionSubscribers.isEmpty || !collectedMessageIds.isEmpty {
|
||||
|
||||
@@ -64,7 +64,7 @@ public func sendAuthorizationCode(account: UnauthorizedAccount, phoneNumber: Str
|
||||
parsedNextType = AuthorizationCodeNextType(apiType: nextType)
|
||||
}
|
||||
|
||||
transaction.setState(UnauthorizedAccountState(masterDatacenterId: account.masterDatacenterId, contents: .confirmationCodeEntry(number: phoneNumber, type: SentAuthorizationCodeType(apiType: type), hash: phoneCodeHash, timeout: timeout, nextType: parsedNextType, termsOfService: termsOfService.flatMap(UnauthorizedAccountTermsOfService.init(apiTermsOfService:)))))
|
||||
transaction.setState(UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .confirmationCodeEntry(number: phoneNumber, type: SentAuthorizationCodeType(apiType: type), hash: phoneCodeHash, timeout: timeout, nextType: parsedNextType, termsOfService: termsOfService.flatMap(UnauthorizedAccountTermsOfService.init(apiTermsOfService:)))))
|
||||
}
|
||||
return account
|
||||
} |> mapError { _ -> AuthorizationCodeRequestError in return .generic }
|
||||
@@ -101,7 +101,7 @@ public func resendAuthorizationCode(account: UnauthorizedAccount) -> Signal<Void
|
||||
parsedNextType = AuthorizationCodeNextType(apiType: nextType)
|
||||
}
|
||||
|
||||
transaction.setState(UnauthorizedAccountState(masterDatacenterId: account.masterDatacenterId, contents: .confirmationCodeEntry(number: number, type: SentAuthorizationCodeType(apiType: type), hash: phoneCodeHash, timeout: timeout, nextType: parsedNextType, termsOfService: termsOfService.flatMap(UnauthorizedAccountTermsOfService.init(apiTermsOfService:)))))
|
||||
transaction.setState(UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .confirmationCodeEntry(number: number, type: SentAuthorizationCodeType(apiType: type), hash: phoneCodeHash, timeout: timeout, nextType: parsedNextType, termsOfService: termsOfService.flatMap(UnauthorizedAccountTermsOfService.init(apiTermsOfService:)))))
|
||||
|
||||
}
|
||||
} |> mapError { _ -> AuthorizationCodeRequestError in return .generic }
|
||||
@@ -174,14 +174,14 @@ public func authorizeWithCode(account: UnauthorizedAccount, code: String) -> Sig
|
||||
return account.postbox.transaction { transaction -> Void in
|
||||
switch result {
|
||||
case .signUp:
|
||||
transaction.setState(UnauthorizedAccountState(masterDatacenterId: account.masterDatacenterId, contents: .signUp(number: number, codeHash: hash, code: code, firstName: "", lastName: "")))
|
||||
transaction.setState(UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .signUp(number: number, codeHash: hash, code: code, firstName: "", lastName: "")))
|
||||
case let .password(hint):
|
||||
transaction.setState(UnauthorizedAccountState(masterDatacenterId: account.masterDatacenterId, contents: .passwordEntry(hint: hint, number: number, code: code)))
|
||||
transaction.setState(UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .passwordEntry(hint: hint, number: number, code: code)))
|
||||
case let .authorization(authorization):
|
||||
switch authorization {
|
||||
case let .authorization(_, _, user):
|
||||
let user = TelegramUser(user: user)
|
||||
let state = AuthorizedAccountState(masterDatacenterId: account.masterDatacenterId, peerId: user.id, state: nil)
|
||||
let state = AuthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, peerId: user.id, state: nil)
|
||||
/*transaction.updatePeersInternal([user], update: { current, peer -> Peer? in
|
||||
return peer
|
||||
})*/
|
||||
@@ -227,7 +227,7 @@ public func authorizeWithPassword(account: UnauthorizedAccount, password: String
|
||||
switch result {
|
||||
case let .authorization(_, _, user):
|
||||
let user = TelegramUser(user: user)
|
||||
let state = AuthorizedAccountState(masterDatacenterId: account.masterDatacenterId, peerId: user.id, state: nil)
|
||||
let state = AuthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, peerId: user.id, state: nil)
|
||||
/*transaction.updatePeersInternal([user], update: { current, peer -> Peer? in
|
||||
return peer
|
||||
})*/
|
||||
@@ -296,7 +296,7 @@ public func performPasswordRecovery(account: UnauthorizedAccount, code: String)
|
||||
switch result {
|
||||
case let .authorization(_, _, user):
|
||||
let user = TelegramUser(user: user)
|
||||
let state = AuthorizedAccountState(masterDatacenterId: account.masterDatacenterId, peerId: user.id, state: nil)
|
||||
let state = AuthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, peerId: user.id, state: nil)
|
||||
/*transaction.updatePeersInternal([user], update: { current, peer -> Peer? in
|
||||
return peer
|
||||
})*/
|
||||
@@ -330,9 +330,9 @@ public func performAccountReset(account: UnauthorizedAccount) -> Signal<Void, Ac
|
||||
if let state = transaction.getState() as? UnauthorizedAccountState, case let .passwordEntry(_, number, _) = state.contents {
|
||||
if let timeout = timeout {
|
||||
let timestamp = Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970)
|
||||
transaction.setState(UnauthorizedAccountState(masterDatacenterId: state.masterDatacenterId, contents: .awaitingAccountReset(protectedUntil: timestamp + timeout, number: number)))
|
||||
transaction.setState(UnauthorizedAccountState(isTestingEnvironment: state.isTestingEnvironment, masterDatacenterId: state.masterDatacenterId, contents: .awaitingAccountReset(protectedUntil: timestamp + timeout, number: number)))
|
||||
} else {
|
||||
transaction.setState(UnauthorizedAccountState(masterDatacenterId: state.masterDatacenterId, contents: .empty))
|
||||
transaction.setState(UnauthorizedAccountState(isTestingEnvironment: state.isTestingEnvironment, masterDatacenterId: state.masterDatacenterId, contents: .empty))
|
||||
}
|
||||
}
|
||||
} |> mapError { _ in return AccountResetError.generic }
|
||||
@@ -369,7 +369,7 @@ public func signUpWithName(account: UnauthorizedAccount, firstName: String, last
|
||||
case let .authorization(_, _, user):
|
||||
let user = TelegramUser(user: user)
|
||||
let appliedState = account.postbox.transaction { transaction -> Void in
|
||||
let state = AuthorizedAccountState(masterDatacenterId: account.masterDatacenterId, peerId: user.id, state: nil)
|
||||
let state = AuthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, peerId: user.id, state: nil)
|
||||
transaction.setState(state)
|
||||
}
|
||||
|> introduceError(SignUpError.self)
|
||||
@@ -413,7 +413,7 @@ public enum AuthorizationStateReset {
|
||||
public func resetAuthorizationState(account: UnauthorizedAccount, to value: AuthorizationStateReset) -> Signal<Void, NoError> {
|
||||
return account.postbox.transaction { transaction -> Void in
|
||||
if let state = transaction.getState() as? UnauthorizedAccountState {
|
||||
transaction.setState(UnauthorizedAccountState(masterDatacenterId: state.masterDatacenterId, contents: .empty))
|
||||
transaction.setState(UnauthorizedAccountState(isTestingEnvironment: state.isTestingEnvironment, masterDatacenterId: state.masterDatacenterId, contents: .empty))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import SwiftSignalKit
|
||||
import Photos
|
||||
#endif
|
||||
|
||||
private func fetchCloudMediaLocation(account: Account, resource: TelegramMediaResource, datacenterId: Int, size: Int?, ranges: Signal<IndexSet, NoError>, parameters: MediaResourceFetchParameters?) -> Signal<MediaResourceDataFetchResult, NoError> {
|
||||
private func fetchCloudMediaLocation(account: Account, resource: TelegramMediaResource, datacenterId: Int, size: Int?, ranges: Signal<IndexSet, NoError>, parameters: MediaResourceFetchParameters?) -> Signal<MediaResourceDataFetchResult, MediaResourceDataFetchError> {
|
||||
return multipartFetch(account: account, resource: resource, datacenterId: datacenterId, size: size, ranges: ranges, parameters: parameters)
|
||||
}
|
||||
|
||||
@@ -30,22 +30,28 @@ private func fetchLocalFileResource(path: String, move: Bool) -> Signal<MediaRes
|
||||
}
|
||||
}
|
||||
|
||||
func fetchResource(account: Account, resource: MediaResource, ranges: Signal<IndexSet, NoError>, parameters: MediaResourceFetchParameters?) -> Signal<MediaResourceDataFetchResult, NoError>? {
|
||||
func fetchResource(account: Account, resource: MediaResource, ranges: Signal<IndexSet, NoError>, parameters: MediaResourceFetchParameters?) -> Signal<MediaResourceDataFetchResult, MediaResourceDataFetchError>? {
|
||||
if let _ = resource as? EmptyMediaResource {
|
||||
return .single(.reset) |> then(.never())
|
||||
return .single(.reset)
|
||||
|> then(.never())
|
||||
} else if let secretFileResource = resource as? SecretFileMediaResource {
|
||||
return .single(.dataPart(resourceOffset: 0, data: Data(), range: 0 ..< 0, complete: false)) |> then(fetchSecretFileResource(account: account, resource: secretFileResource, ranges: ranges, parameters: parameters))
|
||||
return .single(.dataPart(resourceOffset: 0, data: Data(), range: 0 ..< 0, complete: false))
|
||||
|> then(fetchSecretFileResource(account: account, resource: secretFileResource, ranges: ranges, parameters: parameters))
|
||||
} else if let cloudResource = resource as? TelegramMultipartFetchableResource {
|
||||
return .single(.dataPart(resourceOffset: 0, data: Data(), range: 0 ..< 0, complete: false)) |> then(fetchCloudMediaLocation(account: account, resource: cloudResource, datacenterId: cloudResource.datacenterId, size: resource.size == 0 ? nil : resource.size, ranges: ranges, parameters: parameters))
|
||||
} else if let webFileResource = resource as? WebFileReferenceMediaResource {
|
||||
return currentWebDocumentsHostDatacenterId(postbox: account.postbox, isTestingEnvironment: account.testingEnvironment)
|
||||
|> mapToSignal { datacenterId -> Signal<MediaResourceDataFetchResult, NoError> in
|
||||
return .single(.dataPart(resourceOffset: 0, data: Data(), range: 0 ..< 0, complete: false)) |> then(fetchCloudMediaLocation(account: account, resource: webFileResource, datacenterId: Int(datacenterId), size: resource.size == 0 ? nil : resource.size, ranges: ranges, parameters: parameters))
|
||||
|> introduceError(MediaResourceDataFetchError.self)
|
||||
|> mapToSignal { datacenterId -> Signal<MediaResourceDataFetchResult, MediaResourceDataFetchError> in
|
||||
return .single(.dataPart(resourceOffset: 0, data: Data(), range: 0 ..< 0, complete: false))
|
||||
|> then(fetchCloudMediaLocation(account: account, resource: webFileResource, datacenterId: Int(datacenterId), size: resource.size == 0 ? nil : resource.size, ranges: ranges, parameters: parameters))
|
||||
}
|
||||
} else if let localFileResource = resource as? LocalFileReferenceMediaResource {
|
||||
return fetchLocalFileResource(path: localFileResource.localFilePath, move: localFileResource.isUniquelyReferencedTemporaryFile)
|
||||
|> introduceError(MediaResourceDataFetchError.self)
|
||||
} else if let httpReference = resource as? HttpReferenceMediaResource {
|
||||
return .single(.dataPart(resourceOffset: 0, data: Data(), range: 0 ..< 0, complete: false)) |> then(fetchHttpResource(url: httpReference.url))
|
||||
return .single(.dataPart(resourceOffset: 0, data: Data(), range: 0 ..< 0, complete: false))
|
||||
|> then(fetchHttpResource(url: httpReference.url))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import Foundation
|
||||
import MtProtoKitDynamic
|
||||
#endif
|
||||
|
||||
public func fetchHttpResource(url: String) -> Signal<MediaResourceDataFetchResult, NoError> {
|
||||
public func fetchHttpResource(url: String) -> Signal<MediaResourceDataFetchResult, MediaResourceDataFetchError> {
|
||||
if let url = URL(string: url) {
|
||||
let signal = MTHttpRequestOperation.data(forHttpUrl: url)!
|
||||
return Signal { subscriber in
|
||||
@@ -19,6 +19,9 @@ public func fetchHttpResource(url: String) -> Signal<MediaResourceDataFetchResul
|
||||
let fetchResult: MediaResourceDataFetchResult = .dataPart(resourceOffset: 0, data: data, range: 0 ..< data.count, complete: true)
|
||||
subscriber.putNext(fetchResult)
|
||||
subscriber.putCompletion()
|
||||
}, error: { _ in
|
||||
subscriber.putError(.generic)
|
||||
}, completed: {
|
||||
})
|
||||
|
||||
return ActionDisposable {
|
||||
|
||||
@@ -9,6 +9,6 @@ import Foundation
|
||||
import MtProtoKitDynamic
|
||||
#endif
|
||||
|
||||
func fetchSecretFileResource(account: Account, resource: SecretFileMediaResource, ranges: Signal<IndexSet, NoError>, parameters: MediaResourceFetchParameters?) -> Signal<MediaResourceDataFetchResult, NoError> {
|
||||
func fetchSecretFileResource(account: Account, resource: SecretFileMediaResource, ranges: Signal<IndexSet, NoError>, parameters: MediaResourceFetchParameters?) -> Signal<MediaResourceDataFetchResult, MediaResourceDataFetchError> {
|
||||
return multipartFetch(account: account, resource: resource, datacenterId: resource.datacenterId, size: resource.size, ranges: ranges, parameters: parameters, encryptionKey: resource.key, decryptedSize: resource.decryptedSize)
|
||||
}
|
||||
|
||||
@@ -132,49 +132,65 @@ func managedCloudChatRemoveMessagesOperations(postbox: Postbox, network: Network
|
||||
private func removeMessages(postbox: Postbox, network: Network, stateManager: AccountStateManager, peer: Peer, operation: CloudChatRemoveMessagesOperation) -> Signal<Void, NoError> {
|
||||
if peer.id.namespace == Namespaces.Peer.CloudChannel {
|
||||
if let inputChannel = apiInputChannel(peer) {
|
||||
return network.request(Api.functions.channels.deleteMessages(channel: inputChannel, id: operation.messageIds.map { $0.id }))
|
||||
var signal: Signal<Void, NoError> = .complete()
|
||||
for s in stride(from: 0, to: operation.messageIds.count, by: 100) {
|
||||
let ids = operation.messageIds[s ..< min(s + 100, operation.messageIds.count)]
|
||||
let partSignal = network.request(Api.functions.channels.deleteMessages(channel: inputChannel, id: ids.map { $0.id }))
|
||||
|> map { result -> Api.messages.AffectedMessages? in
|
||||
return result
|
||||
}
|
||||
|> `catch` { _ in
|
||||
return .single(nil)
|
||||
}
|
||||
|> mapToSignal { result in
|
||||
|> mapToSignal { result -> Signal<Void, NoError> in
|
||||
if let result = result {
|
||||
switch result {
|
||||
case let .affectedMessages(pts, ptsCount):
|
||||
stateManager.addUpdateGroups([.updateChannelPts(channelId: peer.id.id, pts: pts, ptsCount: ptsCount)])
|
||||
case let .affectedMessages(pts, ptsCount):
|
||||
stateManager.addUpdateGroups([.updateChannelPts(channelId: peer.id.id, pts: pts, ptsCount: ptsCount)])
|
||||
}
|
||||
}
|
||||
return .complete()
|
||||
}
|
||||
signal = signal
|
||||
|> then(partSignal)
|
||||
}
|
||||
return signal
|
||||
} else {
|
||||
return .complete()
|
||||
}
|
||||
} else {
|
||||
var flags:Int32
|
||||
var flags: Int32
|
||||
switch operation.type {
|
||||
case .forEveryone:
|
||||
flags = (1 << 0)
|
||||
default:
|
||||
flags = 0
|
||||
case .forEveryone:
|
||||
flags = (1 << 0)
|
||||
default:
|
||||
flags = 0
|
||||
}
|
||||
return network.request(Api.functions.messages.deleteMessages(flags: flags, id: operation.messageIds.map { $0.id }))
|
||||
|
||||
var signal: Signal<Void, NoError> = .complete()
|
||||
for s in stride(from: 0, to: operation.messageIds.count, by: 100) {
|
||||
let ids = operation.messageIds[s ..< min(s + 100, operation.messageIds.count)]
|
||||
let partSignal = network.request(Api.functions.messages.deleteMessages(flags: flags, id: ids.map { $0.id }))
|
||||
|> map { result -> Api.messages.AffectedMessages? in
|
||||
return result
|
||||
}
|
||||
|> `catch` { _ in
|
||||
return .single(nil)
|
||||
}
|
||||
|> mapToSignal { result in
|
||||
|> mapToSignal { result -> Signal<Void, NoError> in
|
||||
if let result = result {
|
||||
switch result {
|
||||
case let .affectedMessages(pts, ptsCount):
|
||||
stateManager.addUpdateGroups([.updatePts(pts: pts, ptsCount: ptsCount)])
|
||||
case let .affectedMessages(pts, ptsCount):
|
||||
stateManager.addUpdateGroups([.updatePts(pts: pts, ptsCount: ptsCount)])
|
||||
}
|
||||
}
|
||||
return .complete()
|
||||
}
|
||||
|
||||
signal = signal
|
||||
|> then(partSignal)
|
||||
}
|
||||
return signal
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -635,7 +635,7 @@ private final class MultipartFetchManager {
|
||||
}
|
||||
}
|
||||
|
||||
func multipartFetch(account: Account, resource: TelegramMediaResource, datacenterId: Int, size: Int?, ranges: Signal<IndexSet, NoError>, parameters: MediaResourceFetchParameters?, encryptionKey: SecretFileEncryptionKey? = nil, decryptedSize: Int32? = nil) -> Signal<MediaResourceDataFetchResult, NoError> {
|
||||
func multipartFetch(account: Account, resource: TelegramMediaResource, datacenterId: Int, size: Int?, ranges: Signal<IndexSet, NoError>, parameters: MediaResourceFetchParameters?, encryptionKey: SecretFileEncryptionKey? = nil, decryptedSize: Int32? = nil) -> Signal<MediaResourceDataFetchResult, MediaResourceDataFetchError> {
|
||||
return Signal { subscriber in
|
||||
let location: MultipartFetchMasterLocation
|
||||
if let resource = resource as? TelegramCloudMediaResource {
|
||||
|
||||
Reference in New Issue
Block a user