Move shared account settings to AccountManager

This commit is contained in:
Peter Iakovlev 2019-01-29 14:03:14 +04:00
parent a6c4acc378
commit 84231fb6fc
12 changed files with 223 additions and 150 deletions

View File

@ -196,15 +196,21 @@ public class UnauthorizedAccount {
})
}
public func changedMasterDatacenterId(_ masterDatacenterId: Int32) -> Signal<UnauthorizedAccount, NoError> {
public func changedMasterDatacenterId(accountManager: AccountManager, masterDatacenterId: Int32) -> Signal<UnauthorizedAccount, NoError> {
if masterDatacenterId == Int32(self.network.mtProto.datacenterId) {
return .single(self)
} else {
let keychain = makeExclusiveKeychain(id: self.id, postbox: self.postbox)
return self.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<UnauthorizedAccount, NoError> in
return accountManager.transaction { transaction -> (LocalizationSettings?, ProxySettings?) in
return (transaction.getSharedData(SharedDataKeys.localizationSettings) as? LocalizationSettings, transaction.getSharedData(SharedDataKeys.proxySettings) as? ProxySettings)
}
|> mapToSignal { localizationSettings, proxySettings -> Signal<(LocalizationSettings?, ProxySettings?, NetworkSettings?), NoError> in
return self.postbox.transaction { transaction -> (LocalizationSettings?, ProxySettings?, NetworkSettings?) in
return (localizationSettings, proxySettings, transaction.getPreferencesEntry(key: PreferencesKeys.networkSettings) as? NetworkSettings)
}
}
|> mapToSignal { (localizationSettings, proxySettings, networkSettings) -> Signal<UnauthorizedAccount, NoError> in
return initializedNetwork(arguments: self.networkArguments, supplementary: false, datacenterId: Int(masterDatacenterId), keychain: keychain, basePath: self.basePath, testingEnvironment: self.testingEnvironment, languageCode: localizationSettings?.primaryComponent.languageCode, proxySettings: proxySettings, networkSettings: networkSettings, phoneNumber: nil)
|> map { network in
let updated = UnauthorizedAccount(networkArguments: self.networkArguments, id: self.id, rootPath: self.rootPath, basePath: self.basePath, testingEnvironment: self.testingEnvironment, postbox: self.postbox, network: network)
@ -254,7 +260,7 @@ let telegramPostboxSeedConfiguration: SeedConfiguration = {
}, additionalChatListIndexNamespace: Namespaces.Message.Cloud)
}()
public func accountWithId(networkArguments: NetworkInitializationArguments, id: AccountRecordId, supplementary: Bool, rootPath: String, beginWithTestingEnvironment: Bool, auxiliaryMethods: AccountAuxiliaryMethods, shouldKeepAutoConnection: Bool = true) -> Signal<AccountResult, NoError> {
public func accountWithId(accountManager: AccountManager, networkArguments: NetworkInitializationArguments, id: AccountRecordId, supplementary: Bool, rootPath: String, beginWithTestingEnvironment: Bool, auxiliaryMethods: AccountAuxiliaryMethods, shouldKeepAutoConnection: Bool = true) -> Signal<AccountResult, NoError> {
let path = "\(rootPath)/\(accountRecordIdPathName(id))"
let postbox = openPostbox(basePath: path + "/postbox", globalMessageIdsNamespace: Namespaces.Message.Cloud, seedConfiguration: telegramPostboxSeedConfiguration)
@ -265,15 +271,14 @@ public func accountWithId(networkArguments: NetworkInitializationArguments, id:
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)
return accountManager.transaction { transaction -> (LocalizationSettings?, ProxySettings?) in
return (transaction.getSharedData(SharedDataKeys.localizationSettings) as? LocalizationSettings, transaction.getSharedData(SharedDataKeys.proxySettings) as? ProxySettings)
}
|> mapToSignal { localizationSettings, proxySettings -> Signal<AccountResult, NoError> in
return postbox.transaction { transaction -> (PostboxCoding?, LocalizationSettings?, ProxySettings?, NetworkSettings?) in
return (transaction.getState(), localizationSettings, proxySettings, transaction.getPreferencesEntry(key: PreferencesKeys.networkSettings) as? NetworkSettings)
}
|> mapToSignal { (localizationSettings, proxySettings, networkSettings) -> Signal<AccountResult, NoError> in
let accountState = view.state
|> mapToSignal { (accountState, localizationSettings, proxySettings, networkSettings) -> Signal<AccountResult, NoError> in
let keychain = makeExclusiveKeychain(id: id, postbox: postbox)
if let accountState = accountState {
@ -290,7 +295,7 @@ public func accountWithId(networkArguments: NetworkInitializationArguments, id:
|> mapToSignal { phoneNumber in
return initializedNetwork(arguments: networkArguments, supplementary: supplementary, datacenterId: Int(authorizedState.masterDatacenterId), keychain: keychain, basePath: path, testingEnvironment: authorizedState.isTestingEnvironment, languageCode: localizationSettings?.primaryComponent.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, networkArguments: networkArguments, peerId: authorizedState.peerId, auxiliaryMethods: auxiliaryMethods))
return .authorized(Account(accountManager: accountManager, id: id, basePath: path, testingEnvironment: authorizedState.isTestingEnvironment, postbox: postbox, network: network, networkArguments: networkArguments, peerId: authorizedState.peerId, auxiliaryMethods: auxiliaryMethods))
}
}
case _:
@ -733,6 +738,21 @@ struct MasterNotificationKey: Codable {
let data: Data
}
private struct AccountDatacenterKey: Codable {
let id: Int64
let data: Data
}
private struct AccountDatacenterInfo: Codable {
let masterKey: AccountDatacenterKey
}
private struct StoredAccountInfo: Codable {
let primaryId: Int32
let isTestingEnvironment: Bool
let datacenters: [Int32: AccountDatacenterInfo]
}
func masterNotificationsKey(account: Account, ignoreDisabled: Bool) -> Signal<MasterNotificationKey, NoError> {
return masterNotificationsKey(masterNotificationKeyValue: account.masterNotificationKey, postbox: account.postbox, ignoreDisabled: ignoreDisabled)
}
@ -871,7 +891,7 @@ public class Account {
var transformOutgoingMessageMedia: TransformOutgoingMessageMedia?
public init(id: AccountRecordId, basePath: String, testingEnvironment: Bool, postbox: Postbox, network: Network, networkArguments: NetworkInitializationArguments, peerId: PeerId, auxiliaryMethods: AccountAuxiliaryMethods) {
public init(accountManager: AccountManager, id: AccountRecordId, basePath: String, testingEnvironment: Bool, postbox: Postbox, network: Network, networkArguments: NetworkInitializationArguments, peerId: PeerId, auxiliaryMethods: AccountAuxiliaryMethods) {
self.id = id
self.basePath = basePath
self.testingEnvironment = testingEnvironment
@ -886,7 +906,7 @@ public class Account {
self.callSessionManager = CallSessionManager(postbox: postbox, network: network, maxLayer: networkArguments.voipMaxLayer, addUpdates: { [weak self] updates in
self?.stateManager?.addUpdates(updates)
})
self.stateManager = AccountStateManager(accountPeerId: self.peerId, postbox: self.postbox, network: self.network, callSessionManager: self.callSessionManager, addIsContactUpdates: { [weak self] updates in
self.stateManager = AccountStateManager(accountPeerId: self.peerId, accountManager: accountManager, postbox: self.postbox, network: self.network, callSessionManager: self.callSessionManager, addIsContactUpdates: { [weak self] updates in
self?.contactSyncManager?.addIsContactUpdates(updates)
}, shouldKeepOnlinePresence: self.shouldKeepOnlinePresence.get(), peerInputActivityManager: self.peerInputActivityManager, auxiliaryMethods: auxiliaryMethods)
self.contactSyncManager = ContactSyncManager(postbox: postbox, network: network, accountPeerId: peerId, stateManager: self.stateManager)
@ -897,11 +917,8 @@ public class Account {
}).start()
self.notificationAutolockReportManager = NotificationAutolockReportManager(deadline: self.autolockReportDeadline.get(), network: network)
self.autolockReportDeadline.set(
postbox.combinedView(keys: [.accessChallengeData])
|> map { view -> Int32? in
guard let dataView = view.views[.accessChallengeData] as? AccessChallengeDataView else {
return nil
}
accountManager.accessChallengeData()
|> map { dataView -> Int32? in
guard let autolockDeadline = dataView.data.autolockDeadline else {
return nil
}
@ -1078,23 +1095,50 @@ public class Account {
strongSelf._importantTasksRunning.set(value)
}
}))
self.managedOperationsDisposable.add(managedConfigurationUpdates(postbox: self.postbox, network: self.network).start())
self.managedOperationsDisposable.add((accountManager.sharedData(keys: [SharedDataKeys.proxySettings])
|> map { sharedData -> ProxyServerSettings? in
if let settings = sharedData.entries[SharedDataKeys.proxySettings] as? ProxySettings {
return settings.effectiveActiveServer
} else {
return nil
}
}
|> distinctUntilChanged).start(next: { activeServer in
let updated = activeServer.flatMap { activeServer -> MTSocksProxySettings? in
return activeServer.mtProxySettings
}
network.context.updateApiEnvironment { environment in
let current = environment?.socksProxySettings
let updateNetwork: Bool
if let current = current, let updated = updated {
updateNetwork = !current.isEqual(updated)
} else {
updateNetwork = (current != nil) != (updated != nil)
}
if updateNetwork {
network.dropConnectionStatus()
return environment?.withUpdatedSocksProxySettings(updated)
} else {
return nil
}
}
}))
self.managedOperationsDisposable.add(managedConfigurationUpdates(accountManager: accountManager, postbox: self.postbox, network: self.network).start())
self.managedOperationsDisposable.add(managedVoipConfigurationUpdates(postbox: self.postbox, network: self.network).start())
self.managedOperationsDisposable.add(managedAppConfigurationUpdates(postbox: self.postbox, network: self.network).start())
self.managedOperationsDisposable.add(managedTermsOfServiceUpdates(postbox: self.postbox, network: self.network, stateManager: self.stateManager).start())
self.managedOperationsDisposable.add(managedAppChangelog(postbox: self.postbox, network: self.network, stateManager: self.stateManager, appVersion: self.networkArguments.appVersion).start())
self.managedOperationsDisposable.add(managedProxyInfoUpdates(postbox: self.postbox, network: self.network, viewTracker: self.viewTracker).start())
self.managedOperationsDisposable.add(managedLocalizationUpdatesOperations(postbox: self.postbox, network: self.network).start())
self.managedOperationsDisposable.add(managedLocalizationUpdatesOperations(accountManager: accountManager, postbox: self.postbox, network: self.network).start())
self.managedOperationsDisposable.add(managedPendingPeerNotificationSettings(postbox: self.postbox, network: self.network).start())
self.managedOperationsDisposable.add(managedSynchronizeAppLogEventsOperations(postbox: self.postbox, network: self.network).start())
let storagePreferencesKey: PostboxViewKey = .preferences(keys: Set([PreferencesKeys.cacheStorageSettings]))
let mediaBox = postbox.mediaBox
self.storageSettingsDisposable = self.postbox.combinedView(keys: [storagePreferencesKey]).start(next: { [weak mediaBox] view in
self.storageSettingsDisposable = accountManager.sharedData(keys: [SharedDataKeys.cacheStorageSettings]).start(next: { [weak mediaBox] sharedData in
guard let mediaBox = mediaBox else {
return
}
let settings: CacheStorageSettings = ((view.views[storagePreferencesKey] as? PreferencesView)?.values[PreferencesKeys.cacheStorageSettings] as? CacheStorageSettings) ?? CacheStorageSettings.defaultSettings
let settings: CacheStorageSettings = sharedData.entries[SharedDataKeys.cacheStorageSettings] as? CacheStorageSettings ?? CacheStorageSettings.defaultSettings
mediaBox.setMaxStoreTime(settings.defaultCacheStorageTimeout)
})
@ -1104,6 +1148,24 @@ public class Account {
let _ = try? data.write(to: URL(fileURLWithPath: "\(basePath)/notificationsKey"))
}
})
let primaryDatacenterId = Int32(network.datacenterId)
let context = network.context
context.performBatchUpdates {
var datacenters: [Int32: AccountDatacenterInfo] = [:]
for nId in context.knownDatacenterIds() {
if let id = nId as? Int {
if let authInfo = context.authInfoForDatacenter(withId: id), let authKey = authInfo.authKey {
datacenters[Int32(id)] = AccountDatacenterInfo(masterKey: AccountDatacenterKey(id: authInfo.authKeyId, data: authKey))
}
}
}
let storedInfo = StoredAccountInfo(primaryId: primaryDatacenterId, isTestingEnvironment: testingEnvironment, datacenters: datacenters)
let encoder = JSONEncoder()
if let data = try? encoder.encode(storedInfo) {
let _ = try? data.write(to: URL(fileURLWithPath: "\(basePath)/storedInfo"))
}
}
}
deinit {

View File

@ -209,7 +209,7 @@ public func currentAccount(allocateIfNotExists: Bool, networkArguments: NetworkI
return false
}
})
return accountWithId(networkArguments: networkArguments, id: record.0, supplementary: supplementary, rootPath: rootPath, beginWithTestingEnvironment: beginWithTestingEnvironment, auxiliaryMethods: auxiliaryMethods)
return accountWithId(accountManager: manager, networkArguments: networkArguments, id: record.0, supplementary: supplementary, rootPath: rootPath, beginWithTestingEnvironment: beginWithTestingEnvironment, auxiliaryMethods: auxiliaryMethods)
|> mapToSignal { accountResult -> Signal<AccountResult?, NoError> in
let postbox: Postbox
let initialKind: AccountKind
@ -377,7 +377,7 @@ private func cleanupAccount(networkArguments: NetworkInitializationArguments, ac
return false
}
})
return accountWithId(networkArguments: networkArguments, id: id, supplementary: true, rootPath: rootPath, beginWithTestingEnvironment: beginWithTestingEnvironment, auxiliaryMethods: auxiliaryMethods)
return accountWithId(accountManager: accountManager, networkArguments: networkArguments, id: id, supplementary: true, rootPath: rootPath, beginWithTestingEnvironment: beginWithTestingEnvironment, auxiliaryMethods: auxiliaryMethods)
|> mapToSignal { account -> Signal<Void, NoError> in
switch account {
case .upgrading:

View File

@ -1933,7 +1933,7 @@ private func recordPeerActivityTimestamp(peerId: PeerId, timestamp: Int32, into
}
}
func replayFinalState(accountPeerId: PeerId, mediaBox: MediaBox, transaction: Transaction, auxiliaryMethods: AccountAuxiliaryMethods, finalState: AccountFinalState) -> AccountReplayedFinalState? {
func replayFinalState(accountManager: AccountManager, postbox: Postbox, accountPeerId: PeerId, mediaBox: MediaBox, transaction: Transaction, auxiliaryMethods: AccountAuxiliaryMethods, finalState: AccountFinalState) -> AccountReplayedFinalState? {
let verified = verifyTransaction(transaction, finalState: finalState.state)
if !verified {
Logger.shared.log("State", "failed to verify final state")
@ -2583,30 +2583,34 @@ func replayFinalState(accountPeerId: PeerId, mediaBox: MediaBox, transaction: Tr
if !pollLangPacks.isEmpty {
addSynchronizeLocalizationUpdatesOperation(transaction: transaction)
} else {
outer: for (langCode, langPackDifference) in langPackDifferences {
if !langPackDifference.isEmpty {
let sortedLangPackDifference = langPackDifference.sorted(by: { lhs, rhs in
let lhsVersion: Int32
switch lhs {
case let .langPackDifference(_, fromVersion, _, _):
lhsVersion = fromVersion
}
let rhsVersion: Int32
switch rhs {
case let .langPackDifference(_, fromVersion, _, _):
rhsVersion = fromVersion
}
return lhsVersion < rhsVersion
})
let _ = (accountManager.transaction { transaction -> Void in
outer: for (langCode, langPackDifference) in langPackDifferences {
if !langPackDifference.isEmpty {
let sortedLangPackDifference = langPackDifference.sorted(by: { lhs, rhs in
let lhsVersion: Int32
switch lhs {
case let .langPackDifference(_, fromVersion, _, _):
lhsVersion = fromVersion
}
let rhsVersion: Int32
switch rhs {
case let .langPackDifference(_, fromVersion, _, _):
rhsVersion = fromVersion
}
return lhsVersion < rhsVersion
})
for difference in sortedLangPackDifference {
if !tryApplyingLanguageDifference(transaction: transaction, langCode: langCode, difference: difference) {
addSynchronizeLocalizationUpdatesOperation(transaction: transaction)
break outer
for difference in sortedLangPackDifference {
if !tryApplyingLanguageDifference(transaction: transaction, langCode: langCode, difference: difference) {
let _ = (postbox.transaction { transaction -> Void in
addSynchronizeLocalizationUpdatesOperation(transaction: transaction)
}).start()
break outer
}
}
}
}
}
}).start()
}
addedIncomingMessageIds.append(contentsOf: addedSecretMessageIds)

View File

@ -52,6 +52,7 @@ private final class UpdatedWebpageSubscriberContext {
public final class AccountStateManager {
private let queue = Queue()
private let accountPeerId: PeerId
private let accountManager: AccountManager
private let postbox: Postbox
private let network: Network
private let callSessionManager: CallSessionManager
@ -129,8 +130,9 @@ public final class AccountStateManager {
private let appliedQtsPromise = Promise<Int32?>(nil)
private let appliedQtsDisposable = MetaDisposable()
init(accountPeerId: PeerId, postbox: Postbox, network: Network, callSessionManager: CallSessionManager, addIsContactUpdates: @escaping ([(PeerId, Bool)]) -> Void, shouldKeepOnlinePresence: Signal<Bool, NoError>, peerInputActivityManager: PeerInputActivityManager, auxiliaryMethods: AccountAuxiliaryMethods) {
init(accountPeerId: PeerId, accountManager: AccountManager, postbox: Postbox, network: Network, callSessionManager: CallSessionManager, addIsContactUpdates: @escaping ([(PeerId, Bool)]) -> Void, shouldKeepOnlinePresence: Signal<Bool, NoError>, peerInputActivityManager: PeerInputActivityManager, auxiliaryMethods: AccountAuxiliaryMethods) {
self.accountPeerId = accountPeerId
self.accountManager = accountManager
self.postbox = postbox
self.network = network
self.callSessionManager = callSessionManager
@ -353,6 +355,7 @@ public final class AccountStateManager {
case let .pollDifference(currentEvents):
self.operationTimer?.invalidate()
self.currentIsUpdatingValue = true
let accountManager = self.accountManager
let postbox = self.postbox
let network = self.network
let mediaBox = postbox.mediaBox
@ -401,7 +404,7 @@ public final class AccountStateManager {
}
return postbox.transaction { transaction -> (Api.updates.Difference?, AccountReplayedFinalState?) in
let startTime = CFAbsoluteTimeGetCurrent()
let replayedState = replayFinalState(accountPeerId: accountPeerId, mediaBox: mediaBox, transaction: transaction, auxiliaryMethods: auxiliaryMethods, finalState: finalState)
let replayedState = replayFinalState(accountManager: accountManager, postbox: postbox, accountPeerId: accountPeerId, mediaBox: mediaBox, transaction: transaction, auxiliaryMethods: auxiliaryMethods, finalState: finalState)
let deltaTime = CFAbsoluteTimeGetCurrent() - startTime
if deltaTime > 1.0 {
Logger.shared.log("State", "replayFinalState took \(deltaTime)s")
@ -493,6 +496,7 @@ public final class AccountStateManager {
operationTimer.start()
case let .processUpdateGroups(groups):
self.operationTimer?.invalidate()
let accountManager = self.accountManager
let postbox = self.postbox
let network = self.network
let auxiliaryMethods = self.auxiliaryMethods
@ -511,7 +515,7 @@ public final class AccountStateManager {
return postbox.transaction { transaction -> AccountReplayedFinalState? in
let startTime = CFAbsoluteTimeGetCurrent()
let result = replayFinalState(accountPeerId: accountPeerId, mediaBox: mediaBox, transaction: transaction, auxiliaryMethods: auxiliaryMethods, finalState: finalState)
let result = replayFinalState(accountManager: accountManager, postbox: postbox, accountPeerId: accountPeerId, mediaBox: mediaBox, transaction: transaction, auxiliaryMethods: auxiliaryMethods, finalState: finalState)
let deltaTime = CFAbsoluteTimeGetCurrent() - startTime
if deltaTime > 1.0 {
Logger.shared.log("State", "replayFinalState took \(deltaTime)s")
@ -688,11 +692,13 @@ public final class AccountStateManager {
}
let accountPeerId = self.accountPeerId
let accountManager = self.accountManager
let postbox = self.postbox
let mediaBox = self.postbox.mediaBox
let auxiliaryMethods = self.auxiliaryMethods
let signal = self.postbox.transaction { transaction -> AccountReplayedFinalState? in
let startTime = CFAbsoluteTimeGetCurrent()
let result = replayFinalState(accountPeerId: accountPeerId, mediaBox: mediaBox, transaction: transaction, auxiliaryMethods: auxiliaryMethods, finalState: finalState)
let result = replayFinalState(accountManager: accountManager, postbox: postbox, accountPeerId: accountPeerId, mediaBox: mediaBox, transaction: transaction, auxiliaryMethods: auxiliaryMethods, finalState: finalState)
let deltaTime = CFAbsoluteTimeGetCurrent() - startTime
if deltaTime > 1.0 {
Logger.shared.log("State", "replayFinalState took \(deltaTime)s")

View File

@ -26,7 +26,7 @@ private func switchToAuthorizedAccount(transaction: AccountManagerModifier, acco
transaction.removeAuth()
}
public func sendAuthorizationCode(account: UnauthorizedAccount, phoneNumber: String, apiId: Int32, apiHash: String) -> Signal<UnauthorizedAccount, AuthorizationCodeRequestError> {
public func sendAuthorizationCode(accountManager: AccountManager, account: UnauthorizedAccount, phoneNumber: String, apiId: Int32, apiHash: String) -> Signal<UnauthorizedAccount, AuthorizationCodeRequestError> {
let sendCode = Api.functions.auth.sendCode(flags: 0, phoneNumber: phoneNumber, currentNumber: nil, apiId: apiId, apiHash: apiHash)
let codeAndAccount = account.network.request(sendCode, automaticFloodWait: false)
@ -38,7 +38,7 @@ public func sendAuthorizationCode(account: UnauthorizedAccount, phoneNumber: Str
case Regex("(PHONE_|USER_|NETWORK_)MIGRATE_(\\d+)"):
let range = error.errorDescription.range(of: "MIGRATE_")!
let updatedMasterDatacenterId = Int32(error.errorDescription[range.upperBound ..< error.errorDescription.endIndex])!
let updatedAccount = account.changedMasterDatacenterId(updatedMasterDatacenterId)
let updatedAccount = account.changedMasterDatacenterId(accountManager: accountManager, masterDatacenterId: updatedMasterDatacenterId)
return updatedAccount
|> mapToSignalPromotingError { updatedAccount -> Signal<(Api.auth.SentCode, UnauthorizedAccount), MTRpcError> in
return updatedAccount.network.request(sendCode, automaticFloodWait: false)

View File

@ -43,9 +43,9 @@ public struct CacheStorageSettings: PreferencesEntry, Equatable {
}
}
public func updateCacheStorageSettingsInteractively(postbox: Postbox, _ f: @escaping (CacheStorageSettings) -> CacheStorageSettings) -> Signal<Void, NoError> {
return postbox.transaction { transaction -> Void in
transaction.updatePreferencesEntry(key: PreferencesKeys.cacheStorageSettings, { entry in
public func updateCacheStorageSettingsInteractively(accountManager: AccountManager, _ f: @escaping (CacheStorageSettings) -> CacheStorageSettings) -> Signal<Void, NoError> {
return accountManager.transaction { transaction -> Void in
transaction.updateSharedData(SharedDataKeys.cacheStorageSettings, { entry in
let currentSettings: CacheStorageSettings
if let entry = entry as? CacheStorageSettings {
currentSettings = entry

View File

@ -118,7 +118,7 @@ public enum DownloadAndApplyLocalizationError {
case generic
}
public func downloadAndApplyLocalization(postbox: Postbox, network: Network, languageCode: String) -> Signal<Void, DownloadAndApplyLocalizationError> {
public func downloadAndApplyLocalization(accountManager: AccountManager, postbox: Postbox, network: Network, languageCode: String) -> Signal<Void, DownloadAndApplyLocalizationError> {
return requestLocalizationPreview(network: network, identifier: languageCode)
|> mapError { _ -> DownloadAndApplyLocalizationError in
return .generic
@ -141,35 +141,39 @@ public func downloadAndApplyLocalization(postbox: Postbox, network: Network, lan
if let secondaryCode = preview.baseLanguageCode, components.count > 1 {
secondaryComponent = LocalizationComponent(languageCode: secondaryCode, localizedName: "", localization: components[1], customPluralizationCode: nil)
}
return postbox.transaction { transaction -> Signal<Void, DownloadAndApplyLocalizationError> in
transaction.updatePreferencesEntry(key: PreferencesKeys.localizationSettings, { _ in
return accountManager.transaction { transaction -> Signal<Void, DownloadAndApplyLocalizationError> in
transaction.updateSharedData(SharedDataKeys.localizationSettings, { _ in
return LocalizationSettings(primaryComponent: LocalizationComponent(languageCode: preview.languageCode, localizedName: preview.localizedTitle, localization: primaryLocalization, customPluralizationCode: preview.customPluralizationCode), secondaryComponent: secondaryComponent)
})
updateLocalizationListStateInteractively(transaction: transaction, { state in
var state = state
for i in 0 ..< state.availableSavedLocalizations.count {
if state.availableSavedLocalizations[i].languageCode == preview.languageCode {
state.availableSavedLocalizations.remove(at: i)
break
return postbox.transaction { transaction -> Signal<Void, DownloadAndApplyLocalizationError> in
updateLocalizationListStateInteractively(transaction: transaction, { state in
var state = state
for i in 0 ..< state.availableSavedLocalizations.count {
if state.availableSavedLocalizations[i].languageCode == preview.languageCode {
state.availableSavedLocalizations.remove(at: i)
break
}
}
state.availableSavedLocalizations.insert(preview, at: 0)
return state
})
network.context.updateApiEnvironment { current in
return current?.withUpdatedLangPackCode(preview.languageCode)
}
state.availableSavedLocalizations.insert(preview, at: 0)
return state
})
network.context.updateApiEnvironment { current in
return current?.withUpdatedLangPackCode(preview.languageCode)
}
return network.request(Api.functions.help.test())
|> `catch` { _ -> Signal<Api.Bool, NoError> in
return .complete()
}
|> mapToSignal { _ -> Signal<Void, NoError> in
return .complete()
return network.request(Api.functions.help.test())
|> `catch` { _ -> Signal<Api.Bool, NoError> in
return .complete()
}
|> mapToSignal { _ -> Signal<Void, NoError> in
return .complete()
}
|> introduceError(DownloadAndApplyLocalizationError.self)
}
|> introduceError(DownloadAndApplyLocalizationError.self)
|> switchToLatest
}
|> introduceError(DownloadAndApplyLocalizationError.self)
|> switchToLatest

View File

@ -9,7 +9,7 @@ import Foundation
import MtProtoKitDynamic
#endif
public final class LoggingSettings: AccountSharedData, Equatable {
public final class LoggingSettings: PreferencesEntry, Equatable {
public let logToFile: Bool
public let logToConsole: Bool
public let redactSensitiveData: Bool
@ -63,7 +63,7 @@ public final class LoggingSettings: AccountSharedData, Equatable {
return true
}
public func isEqual(to: AccountSharedData) -> Bool {
public func isEqual(to: PreferencesEntry) -> Bool {
guard let to = to as? LoggingSettings else {
return false
}

View File

@ -9,10 +9,10 @@ import Foundation
import MtProtoKitDynamic
#endif
func managedConfigurationUpdates(postbox: Postbox, network: Network) -> Signal<Void, NoError> {
func managedConfigurationUpdates(accountManager: AccountManager, postbox: Postbox, network: Network) -> Signal<Void, NoError> {
let poll = Signal<Void, NoError> { subscriber in
return (network.request(Api.functions.help.getConfig()) |> retryRequest |> mapToSignal { result -> Signal<Void, NoError> in
return postbox.transaction { transaction -> Void in
return postbox.transaction { transaction -> Signal<Void, NoError> in
switch result {
case let .config(config):
var addressList: [Int: [MTDatacenterAddress]] = [:]
@ -64,21 +64,29 @@ func managedConfigurationUpdates(postbox: Postbox, network: Network) -> Signal<V
updateSearchBotsConfiguration(transaction: transaction, configuration: SearchBotsConfiguration(imageBotUsername: config.imgSearchUsername, gifBotUsername: config.gifSearchUsername, venueBotUsername: config.venueSearchUsername))
let (primary, secondary) = getLocalization(transaction)
var invalidateLocalization = false
if primary.version != config.langPackVersion {
invalidateLocalization = true
}
if let secondary = secondary, let baseLangPackVersion = config.baseLangPackVersion {
if secondary.version != baseLangPackVersion {
return accountManager.transaction { transaction -> Signal<Void, NoError> in
let (primary, secondary) = getLocalization(transaction)
var invalidateLocalization = false
if primary.version != config.langPackVersion {
invalidateLocalization = true
}
if let secondary = secondary, let baseLangPackVersion = config.baseLangPackVersion {
if secondary.version != baseLangPackVersion {
invalidateLocalization = true
}
}
if invalidateLocalization {
return postbox.transaction { transaction -> Void in
addSynchronizeLocalizationUpdatesOperation(transaction: transaction)
}
} else {
return .complete()
}
}
if invalidateLocalization {
addSynchronizeLocalizationUpdatesOperation(transaction: transaction)
}
|> switchToLatest
}
}
|> switchToLatest
}).start()
}

View File

@ -69,7 +69,7 @@ private func withTakenOperation(postbox: Postbox, peerId: PeerId, tag: PeerOpera
} |> switchToLatest
}
func managedLocalizationUpdatesOperations(postbox: Postbox, network: Network) -> Signal<Void, NoError> {
func managedLocalizationUpdatesOperations(accountManager: AccountManager, postbox: Postbox, network: Network) -> Signal<Void, NoError> {
return Signal { _ in
let tag: PeerOperationLogTag = OperationLogTags.SynchronizeLocalizationUpdates
@ -88,7 +88,7 @@ func managedLocalizationUpdatesOperations(postbox: Postbox, network: Network) ->
let signal = withTakenOperation(postbox: postbox, peerId: entry.peerId, tag: tag, tagLocalIndex: entry.tagLocalIndex, { transaction, entry -> Signal<Void, NoError> in
if let entry = entry {
if let _ = entry.contents as? SynchronizeLocalizationUpdatesOperation {
return synchronizeLocalizationUpdates(transaction: transaction, postbox: postbox, network: network)
return synchronizeLocalizationUpdates(accountManager: accountManager, postbox: postbox, network: network)
} else {
assertionFailure()
}
@ -120,9 +120,9 @@ private enum SynchronizeLocalizationUpdatesError {
case reset
}
func getLocalization(_ transaction: Transaction) -> (primary: (code: String, version: Int32, entries: [LocalizationEntry]), secondary: (code: String, version: Int32, entries: [LocalizationEntry])?) {
func getLocalization(_ transaction: AccountManagerModifier) -> (primary: (code: String, version: Int32, entries: [LocalizationEntry]), secondary: (code: String, version: Int32, entries: [LocalizationEntry])?) {
let localizationSettings: LocalizationSettings?
if let current = transaction.getPreferencesEntry(key: PreferencesKeys.localizationSettings) as? LocalizationSettings {
if let current = transaction.getSharedData(SharedDataKeys.localizationSettings) as? LocalizationSettings {
localizationSettings = current
} else {
localizationSettings = nil
@ -152,8 +152,8 @@ private func parseLangPackDifference(_ difference: Api.LangPackDifference) -> (c
}
}
private func synchronizeLocalizationUpdates(transaction: Transaction, postbox: Postbox, network: Network) -> Signal<Void, NoError> {
let currentLanguageAndVersion = postbox.transaction { transaction -> (primary: (code: String, version: Int32), secondary: (code: String, version: Int32)?) in
private func synchronizeLocalizationUpdates(accountManager: AccountManager, postbox: Postbox, network: Network) -> Signal<Void, NoError> {
let currentLanguageAndVersion = accountManager.transaction { transaction -> (primary: (code: String, version: Int32), secondary: (code: String, version: Int32)?) in
let (primary, secondary) = getLocalization(transaction)
return ((primary.code, primary.version), secondary.flatMap({ ($0.code, $0.version) }))
}
@ -171,10 +171,10 @@ private func synchronizeLocalizationUpdates(transaction: Transaction, postbox: P
|> mapError { _ -> SynchronizeLocalizationUpdatesError in return .reset }
|> mapToSignal { differences -> Signal<Void, SynchronizeLocalizationUpdatesError> in
let parsedDifferences = differences.map(parseLangPackDifference)
return postbox.transaction { transaction -> Signal<Void, SynchronizeLocalizationUpdatesError> in
return accountManager.transaction { transaction -> Signal<Void, SynchronizeLocalizationUpdatesError> in
let (primary, secondary) = getLocalization(transaction)
var currentSettings = transaction.getPreferencesEntry(key: PreferencesKeys.localizationSettings) as? LocalizationSettings ?? LocalizationSettings(primaryComponent: LocalizationComponent(languageCode: "en", localizedName: "English", localization: Localization(version: 0, entries: []), customPluralizationCode: nil), secondaryComponent: nil)
var currentSettings = transaction.getSharedData(SharedDataKeys.localizationSettings) as? LocalizationSettings ?? LocalizationSettings(primaryComponent: LocalizationComponent(languageCode: "en", localizedName: "English", localization: Localization(version: 0, entries: []), customPluralizationCode: nil), secondaryComponent: nil)
for difference in parsedDifferences {
let current: (isPrimary: Bool, entries: [LocalizationEntry])
@ -211,7 +211,9 @@ private func synchronizeLocalizationUpdates(transaction: Transaction, postbox: P
}
}
transaction.setPreferencesEntry(key: PreferencesKeys.localizationSettings, value: currentSettings)
transaction.updateSharedData(SharedDataKeys.localizationSettings, { _ in
return currentSettings
})
return .fail(.done)
}
|> mapError { _ -> SynchronizeLocalizationUpdatesError in
@ -227,9 +229,9 @@ private func synchronizeLocalizationUpdates(transaction: Transaction, postbox: P
case .done:
return .fail(Void())
case .reset:
return postbox.transaction { transaction -> Signal<Void, Void> in
return accountManager.transaction { transaction -> Signal<Void, Void> in
let (primary, _) = getLocalization(transaction)
return downloadAndApplyLocalization(postbox: postbox, network: network, languageCode: primary.code)
return downloadAndApplyLocalization(accountManager: accountManager, postbox: postbox, network: network, languageCode: primary.code)
|> mapError { _ -> Void in
return Void()
}
@ -242,7 +244,7 @@ private func synchronizeLocalizationUpdates(transaction: Transaction, postbox: P
}
}
func tryApplyingLanguageDifference(transaction: Transaction, langCode: String, difference: Api.LangPackDifference) -> Bool {
func tryApplyingLanguageDifference(transaction: AccountManagerModifier, langCode: String, difference: Api.LangPackDifference) -> Bool {
let (primary, secondary) = getLocalization(transaction)
switch difference {
case let .langPackDifference(updatedCode, fromVersion, updatedVersion, strings):
@ -284,7 +286,7 @@ func tryApplyingLanguageDifference(transaction: Transaction, langCode: String, d
}
mergedEntries.append(contentsOf: updatedEntries)
let currentSettings = transaction.getPreferencesEntry(key: PreferencesKeys.localizationSettings) as? LocalizationSettings ?? LocalizationSettings(primaryComponent: LocalizationComponent(languageCode: "en", localizedName: "English", localization: Localization(version: 0, entries: []), customPluralizationCode: nil), secondaryComponent: nil)
let currentSettings = transaction.getSharedData(SharedDataKeys.localizationSettings) as? LocalizationSettings ?? LocalizationSettings(primaryComponent: LocalizationComponent(languageCode: "en", localizedName: "English", localization: Localization(version: 0, entries: []), customPluralizationCode: nil), secondaryComponent: nil)
var updatedSettings: LocalizationSettings
if isPrimary {
@ -296,7 +298,9 @@ func tryApplyingLanguageDifference(transaction: Transaction, langCode: String, d
return false
}
transaction.setPreferencesEntry(key: PreferencesKeys.localizationSettings, value: updatedSettings)
transaction.updateSharedData(SharedDataKeys.localizationSettings, { _ in
return updatedSettings
})
return true
}

View File

@ -140,11 +140,8 @@ public extension PeerSummaryCounterTags {
private enum PreferencesKeyValues: Int32 {
case globalNotifications = 0
case cacheStorageSettings = 1
case localizationSettings = 2
case suggestedLocalization = 3
case limitsConfiguration = 4
case proxySettings = 5
case coreSettings = 7
case contentPrivacySettings = 8
case networkSettings = 9
@ -175,18 +172,6 @@ public struct PreferencesKeys {
return key
}()
public static let cacheStorageSettings: ValueBoxKey = {
let key = ValueBoxKey(length: 4)
key.setInt32(0, value: PreferencesKeyValues.cacheStorageSettings.rawValue)
return key
}()
public static let localizationSettings: ValueBoxKey = {
let key = ValueBoxKey(length: 4)
key.setInt32(0, value: PreferencesKeyValues.localizationSettings.rawValue)
return key
}()
public static let suggestedLocalization: ValueBoxKey = {
let key = ValueBoxKey(length: 4)
key.setInt32(0, value: PreferencesKeyValues.suggestedLocalization.rawValue)
@ -199,12 +184,6 @@ public struct PreferencesKeys {
return key
}()
public static let proxySettings: ValueBoxKey = {
let key = ValueBoxKey(length: 4)
key.setInt32(0, value: PreferencesKeyValues.proxySettings.rawValue)
return key
}()
public static let coreSettings: ValueBoxKey = {
let key = ValueBoxKey(length: 4)
key.setInt32(0, value: PreferencesKeyValues.coreSettings.rawValue)
@ -263,6 +242,9 @@ public struct PreferencesKeys {
private enum SharedDataKeyValues: Int32 {
case loggingSettings = 0
case accountInitializationSettings = 1
case cacheStorageSettings = 2
case localizationSettings = 3
case proxySettings = 4
}
public struct SharedDataKeys {
@ -277,6 +259,24 @@ public struct SharedDataKeys {
key.setInt32(0, value: SharedDataKeyValues.accountInitializationSettings.rawValue)
return key
}()
public static let cacheStorageSettings: ValueBoxKey = {
let key = ValueBoxKey(length: 4)
key.setInt32(0, value: SharedDataKeyValues.cacheStorageSettings.rawValue)
return key
}()
public static let localizationSettings: ValueBoxKey = {
let key = ValueBoxKey(length: 4)
key.setInt32(0, value: SharedDataKeyValues.localizationSettings.rawValue)
return key
}()
public static let proxySettings: ValueBoxKey = {
let key = ValueBoxKey(length: 4)
key.setInt32(0, value: SharedDataKeyValues.proxySettings.rawValue)
return key
}()
}
public func applicationSpecificItemCacheCollectionId(_ value: Int8) -> Int8 {

View File

@ -159,9 +159,9 @@ public struct ProxySettings: PreferencesEntry, Equatable {
}
}
public func updateProxySettingsInteractively(postbox: Postbox, network: Network, _ f: @escaping (ProxySettings) -> ProxySettings) -> Signal<Void, NoError> {
return postbox.transaction { transaction -> Void in
updateProxySettingsInteractively(transaction: transaction, network: network, f)
public func updateProxySettingsInteractively(accountManager: AccountManager, _ f: @escaping (ProxySettings) -> ProxySettings) -> Signal<Void, NoError> {
return accountManager.transaction { transaction -> Void in
updateProxySettingsInteractively(transaction: transaction, f)
}
}
@ -176,25 +176,10 @@ extension ProxyServerSettings {
}
}
public func updateProxySettingsInteractively(transaction: Transaction, network: Network, _ f: @escaping (ProxySettings) -> ProxySettings) {
var updateNetwork = false
var updatedSettings: ProxySettings?
transaction.updatePreferencesEntry(key: PreferencesKeys.proxySettings, { current in
public func updateProxySettingsInteractively(transaction: AccountManagerModifier, _ f: @escaping (ProxySettings) -> ProxySettings) {
transaction.updateSharedData(SharedDataKeys.proxySettings, { current in
let previous = (current as? ProxySettings) ?? ProxySettings.defaultSettings
let updated = f(previous)
updatedSettings = updated
if updated.effectiveActiveServer != previous.effectiveActiveServer {
updateNetwork = true
}
return updated
})
if updateNetwork, let updatedSettings = updatedSettings {
network.context.updateApiEnvironment { current in
return current?.withUpdatedSocksProxySettings(updatedSettings.effectiveActiveServer.flatMap { activeServer -> MTSocksProxySettings? in
return activeServer.mtProxySettings
})
}
network.dropConnectionStatus()
}
}