mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-15 18:59:54 +00:00
Multiaccount api updates
This commit is contained in:
parent
878c6044e7
commit
3c6f3d9235
@ -117,7 +117,7 @@ class NotificationViewController: UIViewController, UNNotificationContentExtensi
|
||||
|
||||
let appVersion = (Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String) ?? "unknown"
|
||||
|
||||
sharedAccountContext = SharedAccountContext(mainWindow: nil, accountManager: accountManager, applicationBindings: applicationBindings, initialPresentationDataAndSettings: initialPresentationDataAndSettings!, networkArguments: NetworkInitializationArguments(apiId: apiId, languagesCategory: languagesCategory, appVersion: appVersion, voipMaxLayer: 0), rootPath: rootPath, apsNotificationToken: .never(), voipNotificationToken: .never(), setNotificationCall: { _ in })
|
||||
sharedAccountContext = SharedAccountContext(mainWindow: nil, accountManager: accountManager, applicationBindings: applicationBindings, initialPresentationDataAndSettings: initialPresentationDataAndSettings!, networkArguments: NetworkInitializationArguments(apiId: apiId, languagesCategory: languagesCategory, appVersion: appVersion, voipMaxLayer: 0), rootPath: rootPath, apsNotificationToken: .never(), voipNotificationToken: .never(), setNotificationCall: { _ in }, navigateToChat: { _, _, _ in })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@ import TelegramUI
|
||||
import SwiftSignalKit
|
||||
import Postbox
|
||||
|
||||
private var accountCache: (SharedAccountContext, Account)?
|
||||
private var sharedContextCache: SharedAccountContext?
|
||||
|
||||
private var installedSharedLogger = false
|
||||
|
||||
@ -136,9 +136,10 @@ class ShareRootController: UIViewController {
|
||||
}, dismissNativeController: {
|
||||
})
|
||||
|
||||
let account: Signal<(SharedAccountContext, Account), ShareAuthorizationError>
|
||||
if let accountCache = accountCache {
|
||||
account = .single(accountCache)
|
||||
let sharedContext: SharedAccountContext
|
||||
|
||||
if let sharedContextCache = sharedContextCache {
|
||||
sharedContext = sharedContextCache
|
||||
} else {
|
||||
let appVersion = (Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String) ?? "unknown"
|
||||
|
||||
@ -152,43 +153,38 @@ class ShareRootController: UIViewController {
|
||||
})
|
||||
semaphore.wait()
|
||||
|
||||
let sharedContext = SharedAccountContext(mainWindow: nil, accountManager: accountManager, applicationBindings: applicationBindings, initialPresentationDataAndSettings: initialPresentationDataAndSettings!, networkArguments: NetworkInitializationArguments(apiId: apiId, languagesCategory: languagesCategory, appVersion: appVersion, voipMaxLayer: 0), rootPath: rootPath, apsNotificationToken: .never(), voipNotificationToken: .never(), setNotificationCall: { _ in })
|
||||
|
||||
account = accountManager.transaction { transaction -> (SharedAccountContext, LoggingSettings) in
|
||||
return (sharedContext, transaction.getSharedData(SharedDataKeys.loggingSettings) as? LoggingSettings ?? LoggingSettings.defaultSettings)
|
||||
}
|
||||
|> introduceError(ShareAuthorizationError.self)
|
||||
|> mapToSignal { sharedContext, loggingSettings -> Signal<(SharedAccountContext, Account), ShareAuthorizationError> in
|
||||
Logger.shared.logToFile = loggingSettings.logToFile
|
||||
Logger.shared.logToConsole = loggingSettings.logToConsole
|
||||
|
||||
Logger.shared.redactSensitiveData = loggingSettings.redactSensitiveData
|
||||
|
||||
preconditionFailure()
|
||||
|
||||
/*return currentAccount(allocateIfNotExists: false, networkArguments: , supplementary: true, manager: sharedContext.accountManager, rootPath: rootPath, auxiliaryMethods: telegramAccountAuxiliaryMethods)
|
||||
|> introduceError(ShareAuthorizationError.self)
|
||||
|> mapToSignal { account -> Signal<(SharedAccountContext, Account), ShareAuthorizationError> in
|
||||
if let account = account {
|
||||
switch account {
|
||||
case .upgrading:
|
||||
return .complete()
|
||||
case let .authorized(account):
|
||||
return .single((sharedContext, account))
|
||||
case .unauthorized:
|
||||
return .fail(.unauthorized)
|
||||
}
|
||||
} else {
|
||||
return .complete()
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|> take(1)
|
||||
sharedContext = SharedAccountContext(mainWindow: nil, accountManager: accountManager, applicationBindings: applicationBindings, initialPresentationDataAndSettings: initialPresentationDataAndSettings!, networkArguments: NetworkInitializationArguments(apiId: apiId, languagesCategory: languagesCategory, appVersion: appVersion, voipMaxLayer: 0), rootPath: rootPath, apsNotificationToken: .never(), voipNotificationToken: .never(), setNotificationCall: { _ in }, navigateToChat: { _, _, _ in })
|
||||
sharedContextCache = sharedContext
|
||||
}
|
||||
|
||||
let account: Signal<(SharedAccountContext, Account, [AccountWithInfo]), ShareAuthorizationError> = sharedContext.accountManager.transaction { transaction -> (SharedAccountContext, LoggingSettings) in
|
||||
return (sharedContext, transaction.getSharedData(SharedDataKeys.loggingSettings) as? LoggingSettings ?? LoggingSettings.defaultSettings)
|
||||
}
|
||||
|> introduceError(ShareAuthorizationError.self)
|
||||
|> mapToSignal { sharedContext, loggingSettings -> Signal<(SharedAccountContext, Account, [AccountWithInfo]), ShareAuthorizationError> in
|
||||
Logger.shared.logToFile = loggingSettings.logToFile
|
||||
Logger.shared.logToConsole = loggingSettings.logToConsole
|
||||
|
||||
Logger.shared.redactSensitiveData = loggingSettings.redactSensitiveData
|
||||
|
||||
return sharedContext.activeAccountsWithInfo
|
||||
|> introduceError(ShareAuthorizationError.self)
|
||||
|> take(1)
|
||||
|> mapToSignal { primary, accounts -> Signal<(SharedAccountContext, Account, [AccountWithInfo]), ShareAuthorizationError> in
|
||||
guard let primary = primary else {
|
||||
return .fail(.unauthorized)
|
||||
}
|
||||
guard let info = accounts[primary] else {
|
||||
return .fail(.unauthorized)
|
||||
}
|
||||
return .single((sharedContext, info.account, Array(accounts.values)))
|
||||
}
|
||||
}
|
||||
|> take(1)
|
||||
|
||||
let shouldBeMaster = self.shouldBeMaster
|
||||
let applicationInterface = account
|
||||
|> mapToSignal { sharedContext, account -> Signal<(AccountContext, PostboxAccessChallengeData), ShareAuthorizationError> in
|
||||
|> mapToSignal { sharedContext, account, otherAccounts -> Signal<(AccountContext, PostboxAccessChallengeData, [AccountWithInfo]), ShareAuthorizationError> in
|
||||
let limitsConfiguration = account.postbox.transaction { transaction -> LimitsConfiguration in
|
||||
return transaction.getPreferencesEntry(key: PreferencesKeys.limitsConfiguration) as? LimitsConfiguration ?? LimitsConfiguration.defaultValue
|
||||
}
|
||||
@ -196,15 +192,14 @@ class ShareRootController: UIViewController {
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue
|
||||
|> introduceError(ShareAuthorizationError.self)
|
||||
|> map { sharedData, limitsConfiguration, data -> (AccountContext, PostboxAccessChallengeData) in
|
||||
accountCache = (sharedContext, account)
|
||||
|> map { sharedData, limitsConfiguration, data -> (AccountContext, PostboxAccessChallengeData, [AccountWithInfo]) in
|
||||
updateLegacyLocalization(strings: sharedContext.currentPresentationData.with({ $0 }).strings)
|
||||
let context = AccountContext(sharedContext: sharedContext, account: account, limitsConfiguration: limitsConfiguration)
|
||||
return (context, data.data)
|
||||
return (context, data.data, otherAccounts)
|
||||
}
|
||||
}
|
||||
|> deliverOnMainQueue
|
||||
|> afterNext { [weak self] context, accessChallengeData in
|
||||
|> afterNext { [weak self] context, accessChallengeData, otherAccounts in
|
||||
setupAccount(context.account)
|
||||
setupLegacyComponents(context: context)
|
||||
initializeLegacyComponents(application: nil, currentSizeClassGetter: { return .compact }, currentHorizontalClassGetter: { return .compact }, documentsPath: "", currentApplicationBounds: { return CGRect() }, canOpenUrl: { _ in return false}, openUrl: { _ in })
|
||||
@ -280,7 +275,7 @@ class ShareRootController: UIViewController {
|
||||
} else {
|
||||
return .single(.done)
|
||||
}
|
||||
}), externalShare: false)
|
||||
}), externalShare: false, switchableAccounts: otherAccounts)
|
||||
shareController.presentationArguments = ViewControllerPresentationArguments(presentationAnimation: .modalSheet)
|
||||
shareController.dismissed = { _ in
|
||||
self?.extensionContext?.completeRequest(returningItems: nil, completionHandler: nil)
|
||||
@ -390,14 +385,13 @@ class ShareRootController: UIViewController {
|
||||
legacyController.supportedOrientations = ViewControllerSupportedOrientations(regularSize: .portrait, compactSize: .portrait)
|
||||
legacyController.statusBar.statusBarStyle = .White
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
self.disposable.set(applicationInterface.start(next: { _, _ in }, error: { [weak self] error in
|
||||
self.disposable.set(applicationInterface.start(next: { _, _, _ in }, error: { [weak self] error in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
let presentationData = defaultPresentationData()
|
||||
let presentationData = sharedContext.currentPresentationData.with { $0 }
|
||||
let controller = standardTextAlertController(theme: AlertControllerTheme(presentationTheme: presentationData.theme), title: presentationData.strings.Share_AuthTitle, text: presentationData.strings.Share_AuthDescription, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {
|
||||
self?.extensionContext?.completeRequest(returningItems: nil, completionHandler: nil)
|
||||
})])
|
||||
|
||||
@ -619,6 +619,8 @@ private final class SharedApplicationContext {
|
||||
var setPresentationCall: ((PresentationCall?) -> Void)?
|
||||
let sharedContext = SharedAccountContext(mainWindow: self.mainWindow, accountManager: accountManager, applicationBindings: applicationBindings, initialPresentationDataAndSettings: initialPresentationDataAndSettings!, networkArguments: networkArguments, rootPath: rootPath, apsNotificationToken: self.notificationTokenPromise.get() |> map(Optional.init), voipNotificationToken: self.voipTokenPromise.get() |> map(Optional.init), setNotificationCall: { call in
|
||||
setPresentationCall?(call)
|
||||
}, navigateToChat: { accountId, peerId, messageId in
|
||||
self.openChatWhenReady(accountId: accountId, peerId: peerId, messageId: messageId)
|
||||
})
|
||||
sharedContext.presentGlobalController = { [weak self] c, a in
|
||||
guard let strongSelf = self else {
|
||||
@ -675,7 +677,9 @@ private final class SharedApplicationContext {
|
||||
return .single(nil)
|
||||
}
|
||||
}
|
||||
let wakeupManager = SharedWakeupManager(activeAccounts: sharedContext.activeAccounts |> map { ($0.0, $0.1) }, liveLocationPolling: liveLocationPolling, inForeground: applicationBindings.applicationInForeground, hasActiveAudioSession: hasActiveAudioSession.get(), notificationManager: notificationManager, mediaManager: sharedContext.mediaManager, callManager: sharedContext.callManager)
|
||||
let wakeupManager = SharedWakeupManager(activeAccounts: sharedContext.activeAccounts |> map { ($0.0, $0.1) }, liveLocationPolling: liveLocationPolling, inForeground: applicationBindings.applicationInForeground, hasActiveAudioSession: hasActiveAudioSession.get(), notificationManager: notificationManager, mediaManager: sharedContext.mediaManager, callManager: sharedContext.callManager, accountUserInterfaceInUse: { id in
|
||||
return sharedContext.accountUserInterfaceInUse(id)
|
||||
})
|
||||
let sharedApplicationContext = SharedApplicationContext(sharedContext: sharedContext, notificationManager: notificationManager, wakeupManager: wakeupManager)
|
||||
self.sharedContextPromise.set(
|
||||
accountManager.transaction { transaction -> (SharedApplicationContext, LoggingSettings) in
|
||||
@ -810,41 +814,54 @@ private final class SharedApplicationContext {
|
||||
|> deliverOnMainQueue
|
||||
|> mapToSignal { sharedApplicationContext -> Signal<UnauthorizedApplicationContext?, NoError> in
|
||||
return sharedApplicationContext.sharedContext.activeAccounts
|
||||
|> map { _, accounts, auth -> (UnauthorizedAccount, [Account])? in
|
||||
|> map { primary, accounts, auth -> (Account?, UnauthorizedAccount, [Account])? in
|
||||
if let auth = auth {
|
||||
return (auth, Array(accounts.values))
|
||||
return (primary, auth, Array(accounts.values))
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|> distinctUntilChanged(isEqual: { lhs, rhs in
|
||||
if lhs?.0 !== rhs?.0 {
|
||||
if lhs?.1 !== rhs?.1 {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
|> mapToSignal { authAndAccounts -> Signal<(UnauthorizedAccount, [String])?, NoError> in
|
||||
if let (auth, accounts) = authAndAccounts {
|
||||
let phoneNumbers = combineLatest(accounts.map { account -> Signal<String?, NoError> in
|
||||
return account.postbox.transaction { transaction -> String? in
|
||||
return (transaction.getPeer(account.peerId) as? TelegramUser)?.phone
|
||||
|> mapToSignal { authAndAccounts -> Signal<(UnauthorizedAccount, ((String, AccountRecordId)?, [(String, AccountRecordId)]))?, NoError> in
|
||||
if let (primary, auth, accounts) = authAndAccounts {
|
||||
let phoneNumbers = combineLatest(accounts.map { account -> Signal<(AccountRecordId, String)?, NoError> in
|
||||
return account.postbox.transaction { transaction -> (AccountRecordId, String)? in
|
||||
if let phone = (transaction.getPeer(account.peerId) as? TelegramUser)?.phone {
|
||||
return (account.id, phone)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
})
|
||||
return phoneNumbers
|
||||
|> map { phoneNumbers -> (UnauthorizedAccount, [String])? in
|
||||
return (auth, phoneNumbers.compactMap({ $0 }))
|
||||
|> map { phoneNumbers -> (UnauthorizedAccount, ((String, AccountRecordId)?, [(String, AccountRecordId)]))? in
|
||||
var primaryNumber: (String, AccountRecordId)?
|
||||
if let primary = primary {
|
||||
for idAndNumber in phoneNumbers {
|
||||
if let (id, number) = idAndNumber, id == primary.id {
|
||||
primaryNumber = (number, id)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return (auth, (primaryNumber, phoneNumbers.compactMap({ $0.flatMap({ ($0.1, $0.0) }) })))
|
||||
}
|
||||
} else {
|
||||
return .single(nil)
|
||||
}
|
||||
}
|
||||
|> mapToSignal { accountAndOtherAccountPhoneNumbers -> Signal<(UnauthorizedAccount, LimitsConfiguration, CallListSettings, [String])?, NoError> in
|
||||
|> mapToSignal { accountAndOtherAccountPhoneNumbers -> Signal<(UnauthorizedAccount, LimitsConfiguration, CallListSettings, ((String, AccountRecordId)?, [(String, AccountRecordId)]))?, NoError> in
|
||||
return sharedApplicationContext.sharedContext.accountManager.transaction { transaction -> CallListSettings in
|
||||
return transaction.getSharedData(ApplicationSpecificSharedDataKeys.callListSettings) as? CallListSettings ?? CallListSettings.defaultSettings
|
||||
}
|
||||
|> mapToSignal { callListSettings -> Signal<(UnauthorizedAccount, LimitsConfiguration, CallListSettings, [String])?, NoError> in
|
||||
|> mapToSignal { callListSettings -> Signal<(UnauthorizedAccount, LimitsConfiguration, CallListSettings, ((String, AccountRecordId)?, [(String, AccountRecordId)]))?, NoError> in
|
||||
if let (account, otherAccountPhoneNumbers) = accountAndOtherAccountPhoneNumbers {
|
||||
return account.postbox.transaction { transaction -> (UnauthorizedAccount, LimitsConfiguration, CallListSettings, [String])? in
|
||||
return account.postbox.transaction { transaction -> (UnauthorizedAccount, LimitsConfiguration, CallListSettings, ((String, AccountRecordId)?, [(String, AccountRecordId)]))? in
|
||||
let limitsConfiguration = transaction.getPreferencesEntry(key: PreferencesKeys.limitsConfiguration) as? LimitsConfiguration ?? LimitsConfiguration.defaultValue
|
||||
return (account, limitsConfiguration, callListSettings, otherAccountPhoneNumbers)
|
||||
}
|
||||
|
||||
@ -63,7 +63,7 @@ final class UnauthorizedApplicationContext {
|
||||
|
||||
let rootController: AuthorizationSequenceController
|
||||
|
||||
init(sharedContext: SharedAccountContext, account: UnauthorizedAccount, otherAccountPhoneNumbers: [String]) {
|
||||
init(sharedContext: SharedAccountContext, account: UnauthorizedAccount, otherAccountPhoneNumbers: ((String, AccountRecordId)?, [(String, AccountRecordId)])) {
|
||||
self.sharedContext = sharedContext
|
||||
self.account = account
|
||||
self.strings = defaultPresentationStrings
|
||||
@ -134,7 +134,7 @@ final class AuthorizedApplicationContext {
|
||||
}
|
||||
}
|
||||
|
||||
let isReady = ValuePromise<Bool>(false, ignoreRepeated: true)
|
||||
let isReady = Promise<Bool>()
|
||||
|
||||
private var presentationDataDisposable: Disposable?
|
||||
private var displayAlertsDisposable: Disposable?
|
||||
@ -157,13 +157,6 @@ final class AuthorizedApplicationContext {
|
||||
self.replyFromNotificationsActive = replyFromNotificationsActive
|
||||
self.backgroundAudioActive = backgroundAudioActive
|
||||
|
||||
let runningBackgroundLocationTasks: Signal<Bool, NoError>
|
||||
if let liveLocationManager = context.liveLocationManager {
|
||||
runningBackgroundLocationTasks = liveLocationManager.isPolling
|
||||
} else {
|
||||
runningBackgroundLocationTasks = .single(false)
|
||||
}
|
||||
|
||||
let runningWatchTasksPromise = Promise<WatchRunningTasks?>(nil)
|
||||
|
||||
let runningDownloadTasks = combineLatest(context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.automaticMediaDownloadSettings]), context.account.shouldKeepBackgroundDownloadConnections.get())
|
||||
@ -488,7 +481,12 @@ final class AuthorizedApplicationContext {
|
||||
transaction.setAccessChallengeData(data)
|
||||
}).start()
|
||||
}*/
|
||||
strongSelf.isReady.set(true)
|
||||
if let tabsController = strongSelf.rootController.viewControllers.first as? TabBarController, !tabsController.controllers.isEmpty, tabsController.selectedIndex >= 0 {
|
||||
let controller = tabsController.controllers[tabsController.selectedIndex]
|
||||
strongSelf.isReady.set(controller.ready.get())
|
||||
} else {
|
||||
strongSelf.isReady.set(.single(true))
|
||||
}
|
||||
}))
|
||||
|
||||
let accountId = context.account.id
|
||||
|
||||
@ -12,6 +12,7 @@ private struct AccountTasks {
|
||||
let backgroundDownloads: Bool
|
||||
let backgroundAudio: Bool
|
||||
let activeCalls: Bool
|
||||
let userInterfaceInUse: Bool
|
||||
|
||||
var isEmpty: Bool {
|
||||
if self.stateSynchronization {
|
||||
@ -32,6 +33,9 @@ private struct AccountTasks {
|
||||
if self.activeCalls {
|
||||
return false
|
||||
}
|
||||
if self.userInterfaceInUse {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
@ -49,7 +53,7 @@ final class SharedWakeupManager {
|
||||
|
||||
private var accountsAndTasks: [(Account, Bool, AccountTasks)] = []
|
||||
|
||||
init(activeAccounts: Signal<(primary: Account?, accounts: [AccountRecordId: Account]), NoError>, liveLocationPolling: Signal<AccountRecordId?, NoError>, inForeground: Signal<Bool, NoError>, hasActiveAudioSession: Signal<Bool, NoError>, notificationManager: SharedNotificationManager, mediaManager: MediaManager, callManager: PresentationCallManager?) {
|
||||
init(activeAccounts: Signal<(primary: Account?, accounts: [AccountRecordId: Account]), NoError>, liveLocationPolling: Signal<AccountRecordId?, NoError>, inForeground: Signal<Bool, NoError>, hasActiveAudioSession: Signal<Bool, NoError>, notificationManager: SharedNotificationManager, mediaManager: MediaManager, callManager: PresentationCallManager?, accountUserInterfaceInUse: @escaping (AccountRecordId) -> Signal<Bool, NoError>) {
|
||||
assert(Queue.mainQueue().isCurrent())
|
||||
|
||||
self.inForegroundDisposable = (inForeground
|
||||
@ -108,9 +112,11 @@ final class SharedWakeupManager {
|
||||
}
|
||||
|> distinctUntilChanged
|
||||
|
||||
return combineLatest(queue: .mainQueue(), account.importantTasksRunning, notificationManager.isPollingState(accountId: account.id), hasActiveAudio, hasActiveCalls, hasActiveLiveLocationPolling)
|
||||
|> map { importantTasksRunning, isPollingState, hasActiveAudio, hasActiveCalls, hasActiveLiveLocationPolling -> (Account, Bool, AccountTasks) in
|
||||
return (account, primary?.id == account.id, AccountTasks(stateSynchronization: isPollingState, importantTasks: importantTasksRunning, backgroundLocation: hasActiveLiveLocationPolling, backgroundDownloads: false, backgroundAudio: hasActiveAudio, activeCalls: hasActiveCalls))
|
||||
let userInterfaceInUse = accountUserInterfaceInUse(account.id)
|
||||
|
||||
return combineLatest(queue: .mainQueue(), account.importantTasksRunning, notificationManager.isPollingState(accountId: account.id), hasActiveAudio, hasActiveCalls, hasActiveLiveLocationPolling, userInterfaceInUse)
|
||||
|> map { importantTasksRunning, isPollingState, hasActiveAudio, hasActiveCalls, hasActiveLiveLocationPolling, userInterfaceInUse -> (Account, Bool, AccountTasks) in
|
||||
return (account, primary?.id == account.id, AccountTasks(stateSynchronization: isPollingState, importantTasks: importantTasksRunning, backgroundLocation: hasActiveLiveLocationPolling, backgroundDownloads: false, backgroundAudio: hasActiveAudio, activeCalls: hasActiveCalls, userInterfaceInUse: userInterfaceInUse))
|
||||
}
|
||||
}
|
||||
return combineLatest(signals)
|
||||
|
||||
@ -3921,6 +3921,7 @@ Unused sets are archived when you add more.";
|
||||
"ChatList.DeleteChatConfirmation" = "Are you sure you want to delete chat\nwith %@?";
|
||||
"ChatList.DeleteSecretChatConfirmation" = "Are you sure you want to delete secret chat\nwith %@?";
|
||||
"ChatList.LeaveGroupConfirmation" = "Are you sure you want to leave %@?";
|
||||
"ChatList.DeleteSavedMessagesConfirmation" = "Are you sure you want to delete\nSaved Messages?";
|
||||
|
||||
"Undo.Undo" = "Undo";
|
||||
"Undo.MessagesDeleted" = "Messages deleted";
|
||||
@ -3971,3 +3972,6 @@ Unused sets are archived when you add more.";
|
||||
|
||||
"SocksProxySetup.Status" = "Status";
|
||||
"Login.PhoneNumberAlreadyAuthorized" = "This account is already logged in from this app.";
|
||||
"Login.PhoneNumberAlreadyAuthorizedSwitch" = "Switch";
|
||||
|
||||
"Call.AnsweringWithAccount" = "Answering as %@";
|
||||
|
||||
@ -1 +1 @@
|
||||
Subproject commit 711f2e46be8d366805e65166ecade31f8b342eb4
|
||||
Subproject commit e4068e7da4b7c484f82e68108744c2d048d5859a
|
||||
@ -1 +1 @@
|
||||
Subproject commit 947810ca9cef45f04497d064ea6be876cfb524f5
|
||||
Subproject commit 275fd019647a2c1e7940d97458bde38a82f34137
|
||||
@ -1 +1 @@
|
||||
Subproject commit 728a062ab88b3d607bfb61f6fb5dccd6bce7e1ec
|
||||
Subproject commit 03563113d1b2816dbae820bfc358c50169110156
|
||||
@ -1 +1 @@
|
||||
Subproject commit 31106626c209d018ad93c447e373b8ec99508531
|
||||
Subproject commit 94b5a8fa56f7793c3ca32043db2272ea34a8e3fd
|
||||
Loading…
x
Reference in New Issue
Block a user